| 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 | |
| 7 | typedef long HRESULT; |
| 8 | typedef 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. |
| 17 | static void *ole32(const char *name) { |
| 18 | return GetProcAddress(LoadLibraryA("ole32.dll"), name); |
| 19 | } |
| 20 | |
| 21 | HRESULT __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 | |
| 27 | void __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. |
| 34 | BOOL __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. |
| 41 | HRESULT __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 | |
| 55 | void *__imp_CoCreateFreeThreadedMarshaler = CoCreateFreeThreadedMarshaler; |
| 56 | void *__imp_CoTaskMemFree = CoTaskMemFree; |
| 57 | void *__imp_RoOriginateErrorW = RoOriginateErrorW; |
| 58 | void *__imp_PathCchStripPrefix = PathCchStripPrefix; |