PageRenderTime 71ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/mordor/runtime_linking.cpp

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