/mordor/runtime_linking.cpp
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}