1// Functions the windows crates and arboard import from DLLs Windows 7 lacks, defined here
2// under their own names and as the `__imp_` pointers an import library would supply, so the
3// linker takes these and the executable never names those DLLs.
4#include <string.h>
5#include <wchar.h>
6
7typedef long HRESULT;
8typedef int BOOL;
9#define S_OK ((HRESULT)0)
10#define S_FALSE ((HRESULT)1)
11#define E_INVALIDARG ((HRESULT)0x80070057L)
12
13__declspec(dllimport) void *__stdcall LoadLibraryA(const char *name);
14__declspec(dllimport) void *__stdcall GetProcAddress(void *module, const char *name);
15
16// combase.dll (Windows 8): Windows 7's ole32.dll exports the same two.
17static void *ole32(const char *name) {
18 return GetProcAddress(LoadLibraryA("ole32.dll"), name);
19}
20
21HRESULT __stdcall CoCreateFreeThreadedMarshaler(void *outer, void **marshaler) {
22 static HRESULT(__stdcall * real)(void *, void **);
23 if (!real) real = (HRESULT(__stdcall *)(void *, void **))ole32("CoCreateFreeThreadedMarshaler");
24 return real(outer, marshaler);
25}
26
27void __stdcall CoTaskMemFree(void *memory) {
28 static void(__stdcall * real)(void *);
29 if (!real) real = (void(__stdcall *)(void *))ole32("CoTaskMemFree");
30 real(memory);
31}
32
33// api-ms-win-core-winrt-error-l1-1-0.dll (Windows 8): nothing records an origin.
34BOOL __stdcall RoOriginateErrorW(HRESULT error, unsigned length, const wchar_t *message) {
35 (void)error, (void)length, (void)message;
36 return 0;
37}
38
39// api-ms-win-core-path-l1-1-0.dll (Windows 8): `\\?\C:\x` becomes `C:\x` and
40// `\\?\UNC\server\x` becomes `\\server\x`; S_FALSE where there was no prefix.
41HRESULT __stdcall PathCchStripPrefix(wchar_t *path, size_t length) {
42 if (!path) return E_INVALIDARG;
43 if (wcsncmp(path, L"\\\\?\\UNC\\", 8) == 0) {
44 if (length < 8) return E_INVALIDARG;
45 memmove(path + 2, path + 8, (wcslen(path + 8) + 1) * sizeof(wchar_t));
46 return S_OK;
47 }
48 if (wcsncmp(path, L"\\\\?\\", 4) == 0 && path[4] && path[5] == L':') {
49 memmove(path, path + 4, (wcslen(path + 4) + 1) * sizeof(wchar_t));
50 return S_OK;
51 }
52 return S_FALSE;
53}
54
55void *__imp_CoCreateFreeThreadedMarshaler = CoCreateFreeThreadedMarshaler;
56void *__imp_CoTaskMemFree = CoTaskMemFree;
57void *__imp_RoOriginateErrorW = RoOriginateErrorW;
58void *__imp_PathCchStripPrefix = PathCchStripPrefix;