Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

614 lines
12 KiB

  1. #include "std.h"
  2. // {6249D949-5263-4d6a-883C-78EFAF85D5E3}
  3. static const GUID g_lhcHandleGUID =
  4. {
  5. // This guid will be used to identify LCHHANDLE structures to
  6. // help prevent accessing invalid items
  7. 0x6249d949, 0x5263, 0x4d6a,
  8. {
  9. 0x88, 0x3c, 0x78, 0xef, 0xaf, 0x85, 0xd5, 0xe3
  10. }
  11. };
  12. // {40A71300-B2C7-4d4f-808F-52643110B329}
  13. static const GUID g_lhcLibraryGUID =
  14. {
  15. // This guid will be used to identify LIBRARY_NODE structures to
  16. // help prevent accessing invalid items
  17. 0x40a71300, 0xb2c7, 0x4d4f,
  18. {
  19. 0x80, 0x8f, 0x52, 0x64, 0x31, 0x10, 0xb3, 0x29
  20. }
  21. };
  22. PLIBRARY_NODE g_pLibraryList = NULL;
  23. PLHCSTRUCT g_pObjectList = NULL;
  24. CRITICAL_SECTION g_csTableControl;
  25. BOOL lhcpIsValidHandle(PLHCSTRUCT pObject);
  26. PLIBRARY_NODE lhcpNewLibraryNode();
  27. void lhcpFreeLibraryNode(PLIBRARY_NODE pNode);
  28. PLHCSTRUCT lhcpNewObjectHandle();
  29. void lhcpFreeObjectHandle(PLHCSTRUCT pNode);
  30. BOOL lhcpIsValidHandle(PLHCSTRUCT pObject);
  31. PWSTR lhcpGetExeDirectory();
  32. PLHCSTRUCT lhcpCreateHandle(
  33. PLIBRARY_DESCRIPTOR pLibrary,
  34. PLHCOBJECT_DESCRIPTOR pObject);
  35. void lhcpDestroyHandle(PLHCSTRUCT pNode);
  36. BOOL lhcpIsValidHandle(PLHCSTRUCT pObject)
  37. {
  38. BOOL bResult;
  39. __try
  40. {
  41. bResult = IsEqualGUID(
  42. &g_lhcHandleGUID,
  43. &pObject->m_Secret);
  44. }
  45. __except(EXCEPTION_EXECUTE_HANDLER)
  46. {
  47. SetLastError(
  48. ERROR_INVALID_HANDLE);
  49. bResult = FALSE;
  50. goto Done;
  51. }
  52. Done:
  53. return bResult;
  54. }
  55. PLIBRARY_NODE lhcpNewLibraryNode()
  56. {
  57. //
  58. // Create the new node, zero out the memory and copy in the secret
  59. //
  60. PLIBRARY_NODE pNode = malloc(
  61. sizeof(LIBRARY_NODE));
  62. if (pNode!=NULL)
  63. {
  64. ZeroMemory(
  65. pNode,
  66. sizeof(LIBRARY_NODE));
  67. CopyMemory(
  68. &pNode->m_Secret,
  69. &g_lhcLibraryGUID,
  70. sizeof(GUID));
  71. }
  72. return pNode;
  73. }
  74. void lhcpFreeLibraryNode(PLIBRARY_NODE pNode)
  75. {
  76. ZeroMemory(
  77. pNode,
  78. sizeof(LIBRARY_NODE));
  79. free(
  80. pNode);
  81. }
  82. PLHCSTRUCT lhcpNewObjectHandle()
  83. {
  84. //
  85. // Create the new node, zero out the memory and copy in the secret
  86. //
  87. PLHCSTRUCT pNode = malloc(
  88. sizeof(LHCSTRUCT));
  89. if (pNode!=NULL)
  90. {
  91. ZeroMemory(
  92. pNode,
  93. sizeof(LHCSTRUCT));
  94. CopyMemory(
  95. &pNode->m_Secret,
  96. &g_lhcHandleGUID,
  97. sizeof(GUID));
  98. }
  99. return pNode;
  100. }
  101. void lhcpFreeObjectHandle(PLHCSTRUCT pNode)
  102. {
  103. ZeroMemory(
  104. pNode,
  105. sizeof(LHCSTRUCT));
  106. free(
  107. pNode);
  108. }
  109. PWSTR lhcpGetExeDirectory()
  110. {
  111. DWORD dwSize = 64;
  112. PWSTR pszBuffer = NULL;
  113. PWSTR pszReturn;
  114. DWORD dwResult;
  115. BOOL bResult;
  116. PWSTR pszLastBackslash;
  117. do
  118. {
  119. pszBuffer = malloc(
  120. dwSize * sizeof(WCHAR));
  121. if (NULL==pszBuffer)
  122. {
  123. SetLastError(
  124. ERROR_NOT_ENOUGH_MEMORY);
  125. goto Error;
  126. }
  127. dwResult = GetModuleFileNameW(
  128. NULL,
  129. pszBuffer,
  130. dwSize);
  131. if (0==dwResult)
  132. {
  133. goto Error;
  134. }
  135. if (dwSize==dwResult) // INSUFFICIENT_BUFFER
  136. {
  137. dwSize *= 2; // Double the buffer length
  138. free(
  139. pszBuffer);
  140. pszBuffer = NULL;
  141. dwResult = 0;
  142. }
  143. } while (0==dwResult && dwSize<=65536);
  144. if (dwSize>65536)
  145. {
  146. SetLastError(
  147. ERROR_INSUFFICIENT_BUFFER);
  148. goto Error;
  149. }
  150. pszLastBackslash = wcsrchr(
  151. pszBuffer,
  152. L'\\');
  153. if (NULL==pszLastBackslash)
  154. {
  155. SetLastError(
  156. ERROR_GEN_FAILURE);
  157. goto Error;
  158. }
  159. pszLastBackslash++;
  160. *pszLastBackslash = L'\0';
  161. pszReturn = malloc(
  162. (wcslen(pszBuffer)+MAX_PATH+1)*sizeof(WCHAR));
  163. if (NULL==pszReturn)
  164. {
  165. SetLastError(
  166. ERROR_NOT_ENOUGH_MEMORY);
  167. goto Error;
  168. }
  169. wcscpy(
  170. pszReturn,
  171. pszBuffer);
  172. free(
  173. pszBuffer);
  174. return pszReturn;
  175. Error:
  176. if (pszBuffer!=NULL)
  177. {
  178. free(
  179. pszBuffer);
  180. }
  181. return NULL;
  182. }
  183. PLHCSTRUCT lhcpCreateHandle(
  184. PLIBRARY_DESCRIPTOR pLibrary,
  185. PLHCOBJECT_DESCRIPTOR pObject)
  186. {
  187. PLHCSTRUCT pNode = lhcpNewObjectHandle();
  188. if (pNode!=NULL)
  189. {
  190. EnterCriticalSection(
  191. &g_csTableControl);
  192. pNode->m_pObject = pObject;
  193. pNode->m_pLibrary = pLibrary;
  194. pNode->m_pNext = g_pObjectList;
  195. pNode->m_ppThis = &g_pObjectList;
  196. if (pNode->m_pNext!=NULL)
  197. {
  198. pNode->m_pNext->m_ppThis = &pNode->m_pNext;
  199. }
  200. g_pObjectList = pNode;
  201. LeaveCriticalSection(
  202. &g_csTableControl);
  203. }
  204. else
  205. {
  206. SetLastError(
  207. ERROR_NOT_ENOUGH_MEMORY);
  208. }
  209. return pNode;
  210. }
  211. void lhcpDestroyHandle(PLHCSTRUCT pNode)
  212. {
  213. EnterCriticalSection(
  214. &g_csTableControl);
  215. // Remove this node from the list of handles.
  216. *(pNode->m_ppThis) = pNode->m_pNext;
  217. if (pNode->m_pNext!=NULL)
  218. {
  219. pNode->m_pNext->m_ppThis = pNode->m_ppThis;
  220. }
  221. lhcpFreeObjectHandle(
  222. pNode); // Invalidates the structure and frees the memory
  223. LeaveCriticalSection(
  224. &g_csTableControl);
  225. }
  226. BOOL lhcInitialize()
  227. {
  228. PWSTR pszPath = NULL;
  229. PWSTR pszFileName;
  230. HANDLE hFind = INVALID_HANDLE_VALUE;
  231. WIN32_FIND_DATA FindData;
  232. BOOL bResult;
  233. PLIBRARY_DESCRIPTOR pLibrary = NULL;
  234. PLIBRARY_NODE pNode = NULL;
  235. WCHAR pszLibraryName[64];
  236. InitializeCriticalSection(
  237. &g_csTableControl);
  238. pszPath = lhcpGetExeDirectory();
  239. if (NULL==pszPath)
  240. {
  241. goto Error;
  242. }
  243. pszFileName = pszPath + wcslen(pszPath);
  244. wcscat(
  245. pszFileName,
  246. L"*.lhc");
  247. hFind = FindFirstFileW(
  248. pszPath,
  249. &FindData);
  250. bResult = (hFind!=INVALID_HANDLE_VALUE);
  251. if (!bResult)
  252. {
  253. goto Error;
  254. }
  255. while (bResult)
  256. {
  257. wcscpy(
  258. pszFileName,
  259. FindData.cFileName);
  260. pLibrary = lhclLoadLibrary(
  261. pszPath);
  262. if (pLibrary==NULL)
  263. {
  264. wprintf(
  265. L"Unable to load %s (%u).\n",
  266. pszFileName,
  267. GetLastError());
  268. }
  269. else
  270. {
  271. lhclGetLibraryName(
  272. pLibrary,
  273. pszLibraryName,
  274. 64);
  275. wprintf(
  276. L"Loaded %s library.\n",
  277. pszLibraryName);
  278. pNode = lhcpNewLibraryNode();
  279. if (NULL==pNode)
  280. {
  281. SetLastError(
  282. ERROR_NOT_ENOUGH_MEMORY);
  283. goto Error;
  284. // Out of memory is fatal
  285. }
  286. pNode->m_pLibrary = pLibrary;
  287. pNode->m_pNext = g_pLibraryList;
  288. g_pLibraryList = pNode;
  289. pNode = NULL;
  290. pLibrary = NULL;
  291. }
  292. bResult = FindNextFileW(
  293. hFind,
  294. &FindData);
  295. }
  296. FindClose(hFind);
  297. free(pszPath);
  298. return g_pLibraryList!=NULL;
  299. Error:
  300. if (pLibrary!=NULL)
  301. {
  302. lhclFreeLibrary(pLibrary);
  303. }
  304. if (pszPath!=NULL)
  305. {
  306. free(pszPath);
  307. }
  308. if (pNode!=NULL)
  309. {
  310. free(pszPath);
  311. }
  312. if (hFind!=INVALID_HANDLE_VALUE)
  313. {
  314. FindClose(hFind);
  315. }
  316. // We need to unload the libraries that successfully loaded.
  317. lhcFinalize();
  318. return FALSE;
  319. }
  320. void lhcFinalize()
  321. {
  322. PLIBRARY_NODE pNode;
  323. WCHAR pszLibraryName[64];
  324. while (g_pObjectList!=NULL)
  325. {
  326. lhcClose(
  327. g_pObjectList);
  328. }
  329. while (g_pLibraryList!=NULL)
  330. {
  331. pNode = g_pLibraryList;
  332. g_pLibraryList = g_pLibraryList->m_pNext;
  333. lhclGetLibraryName(
  334. pNode->m_pLibrary,
  335. pszLibraryName,
  336. 64);
  337. lhclFreeLibrary(
  338. pNode->m_pLibrary);
  339. wprintf(
  340. L"Unloaded %s library.\n",
  341. pszLibraryName);
  342. lhcpFreeLibraryNode(
  343. pNode);
  344. }
  345. }
  346. LHCHANDLE lhcOpen(PCWSTR pcszPortSpec)
  347. {
  348. PLIBRARY_NODE pLibraryNode = g_pLibraryList;
  349. PLHCOBJECT_DESCRIPTOR pObject = NULL;
  350. DWORD dwRetError = ERROR_INVALID_PARAMETER;
  351. PLHCSTRUCT hObject;
  352. DWORD dwError;
  353. while (pLibraryNode!=NULL && pObject==NULL)
  354. {
  355. // Try libraries one at a time until one opens successfully
  356. pObject = lhclOpen(
  357. pLibraryNode->m_pLibrary,
  358. pcszPortSpec);
  359. if (!pObject)
  360. {
  361. dwError = GetLastError();
  362. if (dwError!=ERROR_INVALID_PARAMETER)
  363. {
  364. dwRetError = dwError;
  365. }
  366. pLibraryNode = pLibraryNode->m_pNext;
  367. }
  368. }
  369. if (!pObject)
  370. {
  371. SetLastError(dwRetError);
  372. goto Error;
  373. }
  374. hObject = lhcpCreateHandle(
  375. pLibraryNode->m_pLibrary,
  376. pObject);
  377. if (hObject==NULL)
  378. {
  379. SetLastError(
  380. ERROR_NOT_ENOUGH_MEMORY);
  381. goto Error;
  382. }
  383. return hObject;
  384. Error:
  385. if (pObject!=NULL && pLibraryNode!=NULL)
  386. {
  387. lhclClose(
  388. pLibraryNode->m_pLibrary,
  389. pObject);
  390. }
  391. return NULL;
  392. }
  393. BOOL lhcRead(
  394. LHCHANDLE hObject,
  395. PVOID pBuffer,
  396. DWORD dwBufferSize,
  397. PDWORD pdwBytesRead)
  398. {
  399. PLIBRARY_DESCRIPTOR pLibrary;
  400. PLHCOBJECT_DESCRIPTOR pObject;
  401. if (!lhcpIsValidHandle(hObject))
  402. {
  403. goto Error;
  404. }
  405. EnterCriticalSection(
  406. &g_csTableControl);
  407. // Ensure consistent information
  408. pLibrary = ((PLHCSTRUCT)hObject)->m_pLibrary;
  409. pObject = ((PLHCSTRUCT)hObject)->m_pObject;
  410. LeaveCriticalSection(
  411. &g_csTableControl);
  412. return lhclRead(
  413. pLibrary,
  414. pObject,
  415. pBuffer,
  416. dwBufferSize,
  417. pdwBytesRead);
  418. Error:
  419. return FALSE;
  420. }
  421. BOOL lhcWrite(
  422. LHCHANDLE hObject,
  423. PVOID pBuffer,
  424. DWORD dwBufferSize)
  425. {
  426. PLIBRARY_DESCRIPTOR pLibrary;
  427. PLHCOBJECT_DESCRIPTOR pObject;
  428. if (!lhcpIsValidHandle(hObject))
  429. {
  430. goto Error;
  431. }
  432. // Ensure consistent information by using the critical section
  433. EnterCriticalSection(
  434. &g_csTableControl);
  435. // Ensure consistent information
  436. pLibrary = ((PLHCSTRUCT)hObject)->m_pLibrary;
  437. pObject = ((PLHCSTRUCT)hObject)->m_pObject;
  438. LeaveCriticalSection(
  439. &g_csTableControl);
  440. return lhclWrite(
  441. pLibrary,
  442. pObject,
  443. pBuffer,
  444. dwBufferSize);
  445. Error:
  446. return FALSE;
  447. }
  448. BOOL lhcClose(
  449. LHCHANDLE hObject)
  450. {
  451. PLIBRARY_DESCRIPTOR pLibrary;
  452. PLHCOBJECT_DESCRIPTOR pObject;
  453. if (!lhcpIsValidHandle(hObject))
  454. {
  455. goto Error;
  456. }
  457. // Ensure consistent information by using the critical section
  458. EnterCriticalSection(
  459. &g_csTableControl);
  460. // Ensure consistent information
  461. pLibrary = ((PLHCSTRUCT)hObject)->m_pLibrary;
  462. pObject = ((PLHCSTRUCT)hObject)->m_pObject;
  463. lhcpDestroyHandle(
  464. hObject);
  465. LeaveCriticalSection(
  466. &g_csTableControl);
  467. return lhclClose(
  468. pLibrary,
  469. pObject);
  470. Error:
  471. return FALSE;
  472. }
  473. void lhcUsage()
  474. {
  475. PLIBRARY_NODE pLibraryNode = g_pLibraryList;
  476. while (pLibraryNode!=NULL)
  477. {
  478. lhclUsage(
  479. pLibraryNode->m_pLibrary);
  480. wprintf(L"\n");
  481. pLibraryNode = pLibraryNode->m_pNext;
  482. }
  483. }