PageRenderTime 235ms CodeModel.GetById 80ms app.highlight 117ms RepoModel.GetById 34ms app.codeStats 0ms

/mordor/runtime_linking.cpp

http://github.com/mozy/mordor
C++ | 441 lines | 404 code | 35 blank | 2 comment | 68 complexity | 677ef37e6b90d2b22f5783017580f7dd MD5 | raw file
  1// Copyright (c) 2009 - Mozy, Inc.
  2
  3#include "runtime_linking.h"
  4
  5#include <IPHlpApi.h>
  6#include <wspiapi.h>
  7
  8#pragma comment(lib, "ws2_32")
  9
 10namespace Mordor {
 11
 12MORDOR_RUNTIME_LINK_DEFINITION(CancelIoEx, BOOL, WINAPI,
 13    (HANDLE hFile, LPOVERLAPPED lpOverlapped),
 14    (hFile, lpOverlapped),
 15    L"kernel32.dll")
 16{
 17    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 18    return FALSE;
 19}
 20
 21MORDOR_RUNTIME_LINK_DEFINITION(ConvertFiberToThread, BOOL, WINAPI,
 22    (VOID),
 23    (),
 24    L"kernel32.dll")
 25{
 26    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 27    return FALSE;
 28}
 29
 30MORDOR_RUNTIME_LINK_DEFINITION(CreateFiberEx, LPVOID, WINAPI,
 31    (SIZE_T dwStackCommitSize, SIZE_T dwStackReserveSize, DWORD dwFlags, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter),
 32    (dwStackCommitSize, dwStackReserveSize, dwFlags, lpStartAddress, lpParameter),
 33    L"kernel32.dll")
 34{
 35    return CreateFiber(dwStackCommitSize, lpStartAddress, lpParameter);
 36}
 37
 38MORDOR_RUNTIME_LINK_DEFINITION(FindFirstStreamW, HANDLE, WINAPI,
 39    (LPCWSTR lpFileName, STREAM_INFO_LEVELS InfoLevel, LPVOID lpFindStreamData, DWORD dwFlags),
 40    (lpFileName, InfoLevel, lpFindStreamData, dwFlags),
 41    L"kernel32.dll")
 42{
 43    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 44    return INVALID_HANDLE_VALUE;
 45}
 46
 47MORDOR_RUNTIME_LINK_DEFINITION(FindNextStreamW, BOOL, APIENTRY,
 48    (HANDLE hFindStream, LPVOID lpFindStreamData),
 49    (hFindStream, lpFindStreamData),
 50    L"kernel32.dll")
 51{
 52    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 53    return FALSE;
 54}
 55
 56MORDOR_RUNTIME_LINK_DEFINITION(FlsAlloc, DWORD, WINAPI,
 57    (PFLS_CALLBACK_FUNCTION LpCallback),
 58    (LpCallback),
 59    L"kernel32.dll")
 60{
 61    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 62    return FLS_OUT_OF_INDEXES;
 63}
 64
 65MORDOR_RUNTIME_LINK_DEFINITION(FlsFree, BOOL, WINAPI,
 66    (DWORD dwFlsIndex),
 67    (dwFlsIndex),
 68    L"kernel32.dll")
 69{
 70    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 71    return FALSE;
 72}
 73
 74MORDOR_RUNTIME_LINK_DEFINITION(FlsGetValue, PVOID, WINAPI,
 75    (DWORD dwFlsIndex),
 76    (dwFlsIndex),
 77    L"kernel32.dll")
 78{
 79    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 80    return NULL;
 81}
 82
 83MORDOR_RUNTIME_LINK_DEFINITION(FlsSetValue, BOOL, WINAPI,
 84    (DWORD dwFlsIndex, PVOID lpFlsData),
 85    (dwFlsIndex, lpFlsData),
 86    L"kernel32.dll")
 87{
 88    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 89    return FALSE;
 90}
 91
 92MORDOR_RUNTIME_LINK_DEFINITION(FreeAddrInfoW, VOID, WSAAPI,
 93    (PADDRINFOW pAddrInfo),
 94    (pAddrInfo),
 95    L"ws2_32.dll")
 96{
 97    ADDRINFOW *nextw = pAddrInfo;
 98    while (nextw) {
 99        if (nextw->ai_canonname)
100            LocalFree((HLOCAL)nextw->ai_canonname);
101        if (nextw->ai_addr)
102            LocalFree((HLOCAL)nextw->ai_addr);
103        nextw = nextw->ai_next;
104    }
105    if (pAddrInfo)
106        LocalFree((HLOCAL)pAddrInfo);
107}
108
109MORDOR_RUNTIME_LINK_DEFINITION(GetAdaptersAddresses, ULONG, WINAPI,
110    (ULONG Family, ULONG Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES AdapterAddresses, PULONG SizePointer),
111    (Family, Flags, Reserved, AdapterAddresses, SizePointer),
112    L"iphlpapi.dll")
113{
114    return ERROR_CALL_NOT_IMPLEMENTED;
115}
116
117MORDOR_RUNTIME_LINK_DEFINITION(GetAddrInfoW, INT, WSAAPI,
118    (PCWSTR pNodeName, PCWSTR pServiceName, const ADDRINFOW *pHints, PADDRINFOW *ppResult),
119    (pNodeName, pServiceName, pHints, ppResult),
120    L"ws2_32.dll")
121{
122    int result = 0;
123    addrinfo hintsA;
124    addrinfo *pResultA = NULL;
125    size_t count = 0;
126    ADDRINFOW *nextw;
127    addrinfo *nexta;
128    char *pNodeNameA = NULL, *pServiceNameA = NULL;
129
130    if (!ppResult)
131        return WSA_INVALID_PARAMETER;
132    if (pHints)
133        if (pHints->ai_addrlen != 0 ||
134            pHints->ai_canonname != NULL ||
135            pHints->ai_addr != NULL ||
136            pHints->ai_next != NULL)
137            return WSA_INVALID_PARAMETER;
138    *ppResult = NULL;
139    if (pNodeName) {
140        int len = WideCharToMultiByte(CP_THREAD_ACP, 0, pNodeName, -1, NULL, 0, NULL, NULL);
141        if (len <= 0) {
142            result = WSANO_RECOVERY;
143            goto out;
144        }
145        pNodeNameA = (char *)LocalAlloc(LMEM_FIXED, len);
146        if (!pNodeNameA) {
147            result = WSA_NOT_ENOUGH_MEMORY;
148            goto out;
149        }
150        int newlen = WideCharToMultiByte(CP_THREAD_ACP, 0, pNodeName, -1, pNodeNameA, len, NULL, NULL);
151        if (len != newlen) {
152            result = WSANO_RECOVERY;
153            goto out;
154        }
155    }
156    if (pServiceName) {
157        int len = WideCharToMultiByte(CP_THREAD_ACP, 0, pServiceName, -1, NULL, 0, NULL, NULL);
158        if (len <= 0) {
159            result = WSANO_RECOVERY;
160            goto out;
161        }
162        pServiceNameA = (char *)LocalAlloc(LMEM_FIXED, len);
163        if (!pServiceNameA) {
164            result = WSA_NOT_ENOUGH_MEMORY;
165            goto out;
166        }
167        int newlen = WideCharToMultiByte(CP_THREAD_ACP, 0, pServiceName, -1, pServiceNameA, len, NULL, NULL);
168        if (len != newlen) {
169            result = WSANO_RECOVERY;
170            goto out;
171        }
172    }
173
174    if (pHints) {
175        pResultA = &hintsA;
176        hintsA.ai_flags = pHints->ai_flags;
177        hintsA.ai_family = pHints->ai_family;
178        hintsA.ai_socktype = pHints->ai_socktype;
179        hintsA.ai_protocol = pHints->ai_protocol;
180        hintsA.ai_addrlen = 0;
181        hintsA.ai_canonname = NULL;
182        hintsA.ai_addr = NULL;
183        hintsA.ai_next = NULL;
184    }
185
186    result = getaddrinfo(pNodeNameA, pServiceNameA, pResultA, &pResultA);
187    if (result == 0) {
188        count = 0;
189        nexta = pResultA;
190        while (nexta) {
191            ++count;
192            nexta = nexta->ai_next;
193        }
194        if (count) {
195            *ppResult = (ADDRINFOW*)LocalAlloc(LMEM_FIXED, count * sizeof(ADDRINFOW));
196            if (!*ppResult) {
197                result = WSA_NOT_ENOUGH_MEMORY;
198                goto out;
199            }
200            for (size_t i = 0; i < count; ++i) {
201                (*ppResult)[i].ai_canonname = NULL;
202                if (i + 1 == count)
203                    (*ppResult)[i].ai_next = NULL;
204                else
205                    (*ppResult)[i].ai_next = &(*ppResult)[i + 1];
206            }
207            nextw = *ppResult;
208            nexta = pResultA;
209            while (nexta) {
210                nextw->ai_flags = nexta->ai_flags;
211                nextw->ai_family = nexta->ai_family;
212                nextw->ai_socktype = nexta->ai_socktype;
213                nextw->ai_protocol = nexta->ai_protocol;
214                nextw->ai_addrlen = nexta->ai_addrlen;
215                nextw->ai_addr = nexta->ai_addr;
216                if (nexta->ai_addr) {
217                    nextw->ai_addr = (sockaddr*)LocalAlloc(LMEM_FIXED, nextw->ai_addrlen);
218                    if (!nextw->ai_addr) {
219                        result = WSA_NOT_ENOUGH_MEMORY;
220                        goto out;
221                    }
222                    memcpy(nextw->ai_addr, nexta->ai_addr, nextw->ai_addrlen);
223                }
224                if (nexta->ai_canonname) {
225                    int len = MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, nexta->ai_canonname, -1, NULL, 0);
226                    if (len <= 0) {
227                        result = WSANO_RECOVERY;
228                        goto out;
229                    }
230                    nextw->ai_canonname = (PWSTR)LocalAlloc(LMEM_FIXED, len * sizeof(WCHAR));
231                    if (!nexta->ai_canonname) {
232                        result = WSA_NOT_ENOUGH_MEMORY;
233                        goto out;
234                    }
235                    int newlen = MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, nexta->ai_canonname, -1, nextw->ai_canonname, len);
236                    if (len != newlen) {
237                        result = WSANO_RECOVERY;
238                        goto out;
239                    }
240                }
241                nexta = nexta->ai_next;
242                nextw = nextw->ai_next;
243            }
244        }
245    }
246
247out:
248    if (result != 0) {
249        nextw = *ppResult;
250        while (nextw) {
251            if (nextw->ai_canonname)
252                LocalFree((HLOCAL)nextw->ai_canonname);
253            if (nextw->ai_addr)
254                LocalFree((HLOCAL)nextw->ai_addr);
255            nextw = nextw->ai_next;
256        }
257        if (*ppResult) {
258            LocalFree((HLOCAL)*ppResult);
259            *ppResult = NULL;
260        }
261    }
262    if (pNodeNameA)
263        LocalFree((HLOCAL)pNodeNameA);
264    if (pServiceNameA)
265        LocalFree((HLOCAL)pServiceNameA);
266    if (pResultA)
267        freeaddrinfo(pResultA);
268    return result;
269}
270
271MORDOR_RUNTIME_LINK_DEFINITION(GetQueuedCompletionStatusEx, BOOL, WINAPI,
272    (HANDLE CompletionPort, LPOVERLAPPED_ENTRY lpCompletionPortEntries, ULONG ulCount, PULONG ulNumEntriesRemoved, DWORD dwMilliseconds, BOOL fAlertable),
273    (CompletionPort, lpCompletionPortEntries, ulCount, ulNumEntriesRemoved, dwMilliseconds, fAlertable),
274    L"kernel32.dll")
275{
276    if (ulNumEntriesRemoved)
277        *ulNumEntriesRemoved = 0;
278    if (fAlertable || ulCount == 0 || !ulNumEntriesRemoved || !lpCompletionPortEntries) {
279        SetLastError(ERROR_INVALID_PARAMETER);
280        return FALSE;
281    }
282    BOOL bRet = GetQueuedCompletionStatus(CompletionPort,
283        &lpCompletionPortEntries->dwNumberOfBytesTransferred,
284        &lpCompletionPortEntries->lpCompletionKey,
285        &lpCompletionPortEntries->lpOverlapped,
286        dwMilliseconds);
287    if (!bRet && !lpCompletionPortEntries->lpOverlapped)
288        return FALSE;
289    *ulNumEntriesRemoved = 1;
290    return TRUE;
291}
292
293MORDOR_RUNTIME_LINK_DEFINITION(IsThreadAFiber, BOOL, WINAPI,
294    (VOID),
295    (),
296    L"kernel32.dll")
297{
298    PVOID fiber = GetCurrentFiber();
299    return (fiber == NULL || fiber == (PVOID)0x1e00) ? FALSE : TRUE;
300}
301
302MORDOR_RUNTIME_LINK_DEFINITION(RtlCaptureStackBackTrace, WORD, NTAPI,
303    (DWORD FramesToSkip, DWORD FramesToCapture, PVOID *BackTrace, PDWORD BackTraceHash),
304    (FramesToSkip, FramesToCapture, BackTrace, BackTraceHash),
305    L"kernel32.dll")
306{
307    // TODO: asm implementation for x86
308    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
309    return 0;
310}
311
312MORDOR_RUNTIME_LINK_DEFINITION(RtlNtStatusToDosError, ULONG, NTAPI,
313    (NTSTATUS Status),
314    (Status),
315    L"ntdll.dll")
316{
317    return ERROR_CALL_NOT_IMPLEMENTED;
318}
319
320MORDOR_RUNTIME_LINK_DEFINITION(SetFileCompletionNotificationModes, BOOL, WINAPI,
321    (HANDLE FileHandle, UCHAR Flags),
322    (FileHandle, Flags),
323    L"kernel32.dll")
324{
325    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
326    return FALSE;
327}
328
329MORDOR_RUNTIME_LINK_DEFINITION(SymFromAddr, BOOL, __stdcall,
330    (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol),
331    (hProcess, Address, Displacement, Symbol),
332    L"dbghelp.dll")
333{
334    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
335    return FALSE;
336}
337
338MORDOR_RUNTIME_LINK_DEFINITION(SymGetLineFromAddr64, BOOL, __stdcall,
339    (HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64),
340    (hProcess, qwAddr, pdwDisplacement, Line64),
341    L"dbghelp.dll")
342{
343    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
344    return FALSE;
345}
346
347MORDOR_RUNTIME_LINK_DEFINITION(WinHttpCloseHandle, BOOL, WINAPI,
348    (HINTERNET hInternet),
349    (hInternet),
350    L"winhttp.dll")
351{
352    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
353    return FALSE;
354}
355
356MORDOR_RUNTIME_LINK_DEFINITION(WinHttpGetDefaultProxyConfiguration, BOOL, WINAPI,
357    (WINHTTP_PROXY_INFO *pProxyInfo),
358    (pProxyInfo),
359    L"winhttp.dll")
360{
361    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
362    return FALSE;
363}
364
365MORDOR_RUNTIME_LINK_DEFINITION(WinHttpGetIEProxyConfigForCurrentUser, BOOL, WINAPI,
366    (WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig),
367    (pProxyConfig),
368    L"winhttp.dll")
369{
370    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
371    return FALSE;
372}
373
374MORDOR_RUNTIME_LINK_DEFINITION(WinHttpGetProxyForUrl, BOOL, WINAPI,
375    (HINTERNET hSession, LPCWSTR lpcwszUrl, WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, WINHTTP_PROXY_INFO *pProxyInfo),
376    (hSession, lpcwszUrl, pAutoProxyOptions, pProxyInfo),
377    L"winhttp.dll")
378{
379    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
380    return FALSE;
381}
382
383MORDOR_RUNTIME_LINK_DEFINITION(WinHttpDetectAutoProxyConfigUrl, BOOL, WINAPI,
384    (DWORD dwAutoDetectFlags, LPWSTR *ppwstrAutoConfigUrl),
385    (dwAutoDetectFlags, ppwstrAutoConfigUrl),
386    L"winhttp.dll")
387{
388    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
389    return FALSE;
390}
391
392MORDOR_RUNTIME_LINK_DEFINITION(WinHttpOpen, HINTERNET, WINAPI,
393    (LPCWSTR pszAgentW, DWORD dwAccessType, LPCWSTR pszProxyW, LPCWSTR pszProxyBypassW, DWORD dwFlags),
394    (pszAgentW, dwAccessType, pszProxyW, pszProxyBypassW, dwFlags),
395    L"winhttp.dll")
396{
397    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
398    return NULL;
399}
400
401MORDOR_RUNTIME_LINK_DEFINITION(inet_pton, INT, WSAAPI,
402    (INT Family, PCSTR pszAddrString, PVOID pAddrBuf),
403    (Family, pszAddrString, pAddrBuf),
404    L"ws2_32.dll")
405{
406    switch (Family) {
407        case AF_INET:
408        case AF_INET6:
409            {
410                addrinfo hints, *results;
411                memset(&hints, 0, sizeof(addrinfo));
412                hints.ai_flags = AI_NUMERICHOST;
413                hints.ai_family = Family;
414                int error = getaddrinfo(pszAddrString, NULL, &hints, &results);
415                if (error == EAI_NONAME) {
416                    return 0;
417                } else if (error == EAI_FAMILY) {
418                    SetLastError(WSAEAFNOSUPPORT);
419                    return -1;
420                } else if (error) {
421                    SetLastError(error);
422                    return -1;
423                }
424                if (Family == AF_INET6)
425                    memcpy(pAddrBuf,
426                        &((sockaddr_in6 *)results->ai_addr)->sin6_addr,
427                        sizeof(in6_addr));
428                else
429                    memcpy(pAddrBuf,
430                        &((sockaddr_in *)results->ai_addr)->sin_addr,
431                        sizeof(in_addr));
432                freeaddrinfo(results);
433                return 1;
434            }
435        default:
436            SetLastError(WSAEAFNOSUPPORT);
437            return -1;
438    }
439}
440
441}