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.

569 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. lib.c
  5. Abstract:
  6. Implements a lib interface for reading hwcomp.dat.
  7. Author:
  8. Jim Schmidt (jimschm) 08-Feb-1999
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. #include "hwcompp.h"
  14. typedef struct {
  15. HASHTABLE PnpIdTable;
  16. HASHTABLE UnSupPnpIdTable;
  17. HASHTABLE InfFileTable;
  18. DWORD Checksum;
  19. BOOL Loaded;
  20. HANDLE File;
  21. DWORD InfListOffset;
  22. CHAR HwCompDatPath[MAX_MBCHAR_PATH];
  23. } HWCOMPSTRUCT, *PHWCOMPSTRUCT;
  24. BOOL
  25. pReadDword (
  26. IN HANDLE File,
  27. OUT PDWORD Data
  28. )
  29. /*++
  30. Routine Description:
  31. pReadDword reads the next DWORD at the current file position of File.
  32. Arguments:
  33. File - Specifies file to read
  34. Data - Receives the DWORD
  35. Return Value:
  36. TRUE if the function completes successfully, or FALSE if it fails.
  37. Call GetLastError for additional failure information.
  38. --*/
  39. {
  40. DWORD BytesRead;
  41. if (!ReadFile (File, Data, sizeof (DWORD), &BytesRead, NULL) ||
  42. BytesRead != sizeof (DWORD)
  43. ) {
  44. return FALSE;
  45. }
  46. return TRUE;
  47. }
  48. BOOL
  49. pReadWord (
  50. IN HANDLE File,
  51. OUT PWORD Data
  52. )
  53. /*++
  54. Routine Description:
  55. pReadWord reads the next WORD at the current file position of File.
  56. Arguments:
  57. File - Specifies file to read
  58. Data - Receive s the WORD
  59. Return Value:
  60. TRUE if the function completes successfully, or FALSE if it fails.
  61. Call GetLastError for additional failure information.
  62. --*/
  63. {
  64. DWORD BytesRead;
  65. if (!ReadFile (File, Data, sizeof (WORD), &BytesRead, NULL) ||
  66. BytesRead != sizeof (WORD)
  67. ) {
  68. return FALSE;
  69. }
  70. return TRUE;
  71. }
  72. BOOL
  73. pReadString (
  74. IN HANDLE File,
  75. OUT PTSTR Buf,
  76. IN UINT BufSizeInBytes
  77. )
  78. /*++
  79. Routine Description:
  80. pReadString reads a WORD length from File, and then reads in the
  81. string from File.
  82. Arguments:
  83. File - Specifies file to read
  84. Buf - Receives the zero-terminated string
  85. BufSizeInBytes - Specifies the size of Buf in bytes
  86. Return Value:
  87. TRUE if the function completes successfully, or FALSE if it fails.
  88. This function will fail if the string is larger than Buf.
  89. Call GetLastError for additional failure information.
  90. --*/
  91. {
  92. DWORD BytesRead;
  93. WORD Length;
  94. if (!pReadWord (File, &Length)) {
  95. DEBUGMSG ((DBG_ERROR, "pReadString: Can't get string length"));
  96. return FALSE;
  97. }
  98. if (Length > BufSizeInBytes - 2) {
  99. DEBUGMSG ((DBG_ERROR, "pReadString: Can't read string of %u bytes", Length));
  100. return FALSE;
  101. }
  102. if (Length) {
  103. if (!ReadFile (File, Buf, Length, &BytesRead, NULL) ||
  104. Length != BytesRead
  105. ) {
  106. LOG ((LOG_ERROR, "Can't read string from file."));
  107. return FALSE;
  108. }
  109. }
  110. *((PBYTE) Buf + Length ) = 0;
  111. *((PBYTE) Buf + Length + 1) = 0;
  112. return TRUE;
  113. }
  114. DWORD
  115. pOpenAndLoadHwCompDatA (
  116. IN PCSTR HwCompDatPath, // NULL if PrevStruct is not NULL
  117. IN BOOL Load,
  118. IN BOOL Dump,
  119. IN BOOL DumpInf,
  120. IN PHWCOMPSTRUCT PrevStruct, OPTIONAL
  121. IN HASHTABLE PnpIdTable, OPTIONAL
  122. IN HASHTABLE UnSupPnpIdTable, OPTIONAL
  123. IN HASHTABLE InfFileTable OPTIONAL
  124. )
  125. {
  126. PHWCOMPSTRUCT Struct;
  127. DWORD Result = 0;
  128. CHAR Buf[sizeof (HWCOMPDAT_SIGNATURE) + 2];
  129. CHAR PnpId[MAX_PNP_ID+2];
  130. BOOL AllocatedStruct = FALSE;
  131. DWORD BytesRead;
  132. CHAR InfFile[MAX_MBCHAR_PATH];
  133. HASHITEM InfOffset;
  134. HASHITEM hashResult;
  135. //
  136. // !!! IMPORTANT !!!
  137. //
  138. // hwcomp.dat is used by other parts of NT. *DO NOT* change it without first e-mailing
  139. // the NT group. Also, be sure to keep code in hwcomp.c in sync with changes.
  140. //
  141. __try {
  142. if (!PrevStruct) {
  143. Struct = (PHWCOMPSTRUCT) MemAlloc (g_hHeap, 0, sizeof (HWCOMPSTRUCT));
  144. if (!Struct) {
  145. __leave;
  146. }
  147. ZeroMemory (Struct, sizeof (HWCOMPSTRUCT));
  148. Struct->File = INVALID_HANDLE_VALUE;
  149. StringCopy (Struct->HwCompDatPath, HwCompDatPath);
  150. AllocatedStruct = TRUE;
  151. } else {
  152. Struct = PrevStruct;
  153. if (HwCompDatPath) {
  154. SetLastError (ERROR_INVALID_PARAMETER);
  155. __leave;
  156. }
  157. HwCompDatPath = Struct->HwCompDatPath;
  158. }
  159. if (Struct->File == INVALID_HANDLE_VALUE) {
  160. //
  161. // Try to open the file
  162. //
  163. Struct->File = CreateFile (
  164. HwCompDatPath,
  165. GENERIC_READ,
  166. FILE_SHARE_READ,
  167. NULL, // no security attribs
  168. OPEN_EXISTING,
  169. FILE_ATTRIBUTE_NORMAL,
  170. NULL // no template
  171. );
  172. }
  173. if (Struct->File == INVALID_HANDLE_VALUE) {
  174. __leave;
  175. }
  176. if (AllocatedStruct) {
  177. //
  178. // Create hash tables
  179. //
  180. Struct->PnpIdTable = PnpIdTable ? PnpIdTable : HtAllocWithData (sizeof (UINT));
  181. Struct->UnSupPnpIdTable = UnSupPnpIdTable ? UnSupPnpIdTable : HtAllocWithData (sizeof (UINT));
  182. Struct->InfFileTable = InfFileTable ? InfFileTable : HtAlloc();
  183. if (!Struct->PnpIdTable || !Struct->InfFileTable) {
  184. __leave;
  185. }
  186. //
  187. // Look at the signature
  188. //
  189. ZeroMemory (Buf, sizeof(Buf));
  190. SetFilePointer (Struct->File, 0, NULL, FILE_BEGIN);
  191. if (!ReadFile (Struct->File, Buf, ByteCount (HWCOMPDAT_SIGNATURE), &BytesRead, NULL) ||
  192. !StringMatch (HWCOMPDAT_SIGNATURE, Buf)
  193. ) {
  194. SetLastError (ERROR_BAD_FORMAT);
  195. __leave;
  196. }
  197. //
  198. // Get INF checksum
  199. //
  200. if (!pReadDword (Struct->File, &Struct->Checksum)) {
  201. SetLastError (ERROR_BAD_FORMAT);
  202. __leave;
  203. }
  204. Struct->InfListOffset = SetFilePointer (Struct->File, 0, NULL, FILE_CURRENT);
  205. }
  206. if (Load || Dump) {
  207. SetFilePointer (Struct->File, Struct->InfListOffset, NULL, FILE_BEGIN);
  208. //
  209. // Read in all INFs
  210. //
  211. for (;;) {
  212. //
  213. // Get INF file name. If empty, we are done.
  214. //
  215. if (!pReadString (Struct->File, InfFile, sizeof (InfFile))) {
  216. SetLastError (ERROR_BAD_FORMAT);
  217. __leave;
  218. }
  219. if (*InfFile == 0) {
  220. break;
  221. }
  222. if (Load) {
  223. //
  224. // Add to hash table
  225. //
  226. InfOffset = HtAddString (Struct->InfFileTable, InfFile);
  227. if (!InfOffset) {
  228. __leave;
  229. }
  230. }
  231. //
  232. // Read in all PNP IDs for the INF
  233. //
  234. for (;;) {
  235. //
  236. // Get the PNP ID. If empty, we are done.
  237. //
  238. if (!pReadString (Struct->File, PnpId, sizeof (PnpId))) {
  239. __leave;
  240. }
  241. if (*PnpId == 0) {
  242. break;
  243. }
  244. if (Load) {
  245. //
  246. // Add to hash table
  247. //
  248. if (*PnpId == '!') {
  249. hashResult = HtAddStringAndData (
  250. Struct->UnSupPnpIdTable,
  251. PnpId + 1,
  252. &InfOffset
  253. );
  254. } else {
  255. hashResult = HtAddStringAndData (
  256. Struct->PnpIdTable,
  257. PnpId,
  258. &InfOffset
  259. );
  260. }
  261. if (!hashResult) {
  262. __leave;
  263. }
  264. }
  265. if (Dump) {
  266. if (*PnpId == '!') {
  267. if (DumpInf) {
  268. printf ("%s\t%s (unsupported)\n", InfFile, PnpId + 1);
  269. } else {
  270. printf ("%s (unsupported)\n", PnpId + 1);
  271. }
  272. } else {
  273. if (DumpInf) {
  274. printf ("%s\t%s\n", InfFile, PnpId);
  275. } else {
  276. printf ("%s\n", PnpId);
  277. }
  278. }
  279. }
  280. }
  281. if (Dump) {
  282. printf ("\n");
  283. }
  284. }
  285. }
  286. Result = (DWORD) Struct;
  287. if (Load) {
  288. Struct->Loaded = TRUE;
  289. CloseHandle (Struct->File);
  290. Struct->File = INVALID_HANDLE_VALUE;
  291. }
  292. }
  293. __finally {
  294. if (!Result) {
  295. if (AllocatedStruct) {
  296. CloseHwCompDat ((DWORD) Struct);
  297. }
  298. if (Dump) {
  299. printf ("Can't open %s\n", HwCompDatPath);
  300. }
  301. }
  302. }
  303. return Result;
  304. }
  305. DWORD
  306. OpenHwCompDatA (
  307. IN PCSTR HwCompDatPath
  308. )
  309. {
  310. return pOpenAndLoadHwCompDatA (HwCompDatPath, FALSE, FALSE, FALSE, NULL, NULL, NULL, NULL);
  311. }
  312. DWORD
  313. LoadHwCompDat (
  314. IN DWORD HwCompDatId
  315. )
  316. {
  317. return pOpenAndLoadHwCompDatA (NULL, TRUE, FALSE, FALSE, (PHWCOMPSTRUCT) HwCompDatId, NULL, NULL, NULL);
  318. }
  319. DWORD
  320. GetHwCompDatChecksum (
  321. IN DWORD HwCompDatId
  322. )
  323. {
  324. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  325. if (Struct) {
  326. return Struct->Checksum;
  327. }
  328. return 0;
  329. }
  330. VOID
  331. DumpHwCompDatA (
  332. IN PCSTR HwCompDatPath,
  333. IN BOOL IncludeInf
  334. )
  335. {
  336. CloseHwCompDat (pOpenAndLoadHwCompDatA (HwCompDatPath, FALSE, TRUE, IncludeInf, NULL, NULL, NULL, NULL));
  337. }
  338. DWORD
  339. OpenAndLoadHwCompDatA (
  340. IN PCSTR HwCompDatPath
  341. )
  342. {
  343. return pOpenAndLoadHwCompDatA (HwCompDatPath, TRUE, FALSE, FALSE, NULL, NULL, NULL, NULL);
  344. }
  345. DWORD
  346. OpenAndLoadHwCompDatExA (
  347. IN PCSTR HwCompDatPath,
  348. IN HASHTABLE PnpIdTable, OPTIONAL
  349. IN HASHTABLE UnSupPnpIdTable, OPTIONAL
  350. IN HASHTABLE InfFileTable OPTIONAL
  351. )
  352. {
  353. return pOpenAndLoadHwCompDatA (HwCompDatPath, TRUE, FALSE, FALSE, NULL, PnpIdTable, UnSupPnpIdTable, InfFileTable);
  354. }
  355. VOID
  356. TakeHwCompHashTables (
  357. IN DWORD HwCompDatId,
  358. OUT HASHTABLE *PnpIdTable,
  359. OUT HASHTABLE *UnSupPnpIdTable,
  360. OUT HASHTABLE *InfFileTable
  361. )
  362. {
  363. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  364. if (Struct) {
  365. *PnpIdTable = Struct->PnpIdTable;
  366. Struct->PnpIdTable = NULL;
  367. *UnSupPnpIdTable = Struct->UnSupPnpIdTable;
  368. Struct->UnSupPnpIdTable = NULL;
  369. *InfFileTable = Struct->InfFileTable;
  370. Struct->InfFileTable = NULL;
  371. }
  372. }
  373. VOID
  374. CloseHwCompDat (
  375. IN DWORD HwCompDatId
  376. )
  377. {
  378. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  379. if (Struct) {
  380. HtFree (Struct->PnpIdTable);
  381. HtFree (Struct->UnSupPnpIdTable);
  382. HtFree (Struct->InfFileTable);
  383. if (Struct->File != INVALID_HANDLE_VALUE) {
  384. CloseHandle (Struct->File);
  385. }
  386. MemFree (g_hHeap, 0, Struct);
  387. }
  388. }
  389. VOID
  390. SetWorkingTables (
  391. IN DWORD HwCompDatId,
  392. IN HASHTABLE PnpIdTable,
  393. IN HASHTABLE UnSupPnpIdTable,
  394. IN HASHTABLE InfFileTable
  395. )
  396. {
  397. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  398. if (Struct) {
  399. Struct->PnpIdTable = PnpIdTable;
  400. Struct->UnSupPnpIdTable = UnSupPnpIdTable;
  401. Struct->InfFileTable = InfFileTable;
  402. }
  403. }
  404. BOOL
  405. IsPnpIdSupportedByNtA (
  406. IN DWORD HwCompDatId,
  407. IN PCSTR PnpId
  408. )
  409. {
  410. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  411. BOOL b = FALSE;
  412. if (Struct) {
  413. b = HtFindString (Struct->PnpIdTable, PnpId) != 0;
  414. }
  415. return b;
  416. }
  417. BOOL
  418. IsPnpIdUnsupportedByNtA (
  419. IN DWORD HwCompDatId,
  420. IN PCSTR PnpId
  421. )
  422. {
  423. PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId;
  424. BOOL b = FALSE;
  425. if (Struct) {
  426. b = HtFindString (Struct->UnSupPnpIdTable, PnpId) != 0;
  427. }
  428. return b;
  429. }