/*++ Copyright (c) 1999 Microsoft Corporation Module Name: lib.c Abstract: Implements a lib interface for reading hwcomp.dat. Author: Jim Schmidt (jimschm) 08-Feb-1999 Revision History: --*/ #include "pch.h" #include "hwcompp.h" typedef struct { HASHTABLE PnpIdTable; HASHTABLE UnSupPnpIdTable; HASHTABLE InfFileTable; DWORD Checksum; BOOL Loaded; HANDLE File; DWORD InfListOffset; CHAR HwCompDatPath[MAX_MBCHAR_PATH]; } HWCOMPSTRUCT, *PHWCOMPSTRUCT; BOOL pReadDword ( IN HANDLE File, OUT PDWORD Data ) /*++ Routine Description: pReadDword reads the next DWORD at the current file position of File. Arguments: File - Specifies file to read Data - Receives the DWORD Return Value: TRUE if the function completes successfully, or FALSE if it fails. Call GetLastError for additional failure information. --*/ { DWORD BytesRead; if (!ReadFile (File, Data, sizeof (DWORD), &BytesRead, NULL) || BytesRead != sizeof (DWORD) ) { return FALSE; } return TRUE; } BOOL pReadWord ( IN HANDLE File, OUT PWORD Data ) /*++ Routine Description: pReadWord reads the next WORD at the current file position of File. Arguments: File - Specifies file to read Data - Receive s the WORD Return Value: TRUE if the function completes successfully, or FALSE if it fails. Call GetLastError for additional failure information. --*/ { DWORD BytesRead; if (!ReadFile (File, Data, sizeof (WORD), &BytesRead, NULL) || BytesRead != sizeof (WORD) ) { return FALSE; } return TRUE; } BOOL pReadString ( IN HANDLE File, OUT PTSTR Buf, IN UINT BufSizeInBytes ) /*++ Routine Description: pReadString reads a WORD length from File, and then reads in the string from File. Arguments: File - Specifies file to read Buf - Receives the zero-terminated string BufSizeInBytes - Specifies the size of Buf in bytes Return Value: TRUE if the function completes successfully, or FALSE if it fails. This function will fail if the string is larger than Buf. Call GetLastError for additional failure information. --*/ { DWORD BytesRead; WORD Length; if (!pReadWord (File, &Length)) { DEBUGMSG ((DBG_ERROR, "pReadString: Can't get string length")); return FALSE; } if (Length > BufSizeInBytes - 2) { DEBUGMSG ((DBG_ERROR, "pReadString: Can't read string of %u bytes", Length)); return FALSE; } if (Length) { if (!ReadFile (File, Buf, Length, &BytesRead, NULL) || Length != BytesRead ) { LOG ((LOG_ERROR, "Can't read string from file.")); return FALSE; } } *((PBYTE) Buf + Length ) = 0; *((PBYTE) Buf + Length + 1) = 0; return TRUE; } DWORD pOpenAndLoadHwCompDatA ( IN PCSTR HwCompDatPath, // NULL if PrevStruct is not NULL IN BOOL Load, IN BOOL Dump, IN BOOL DumpInf, IN PHWCOMPSTRUCT PrevStruct, OPTIONAL IN HASHTABLE PnpIdTable, OPTIONAL IN HASHTABLE UnSupPnpIdTable, OPTIONAL IN HASHTABLE InfFileTable OPTIONAL ) { PHWCOMPSTRUCT Struct; DWORD Result = 0; CHAR Buf[sizeof (HWCOMPDAT_SIGNATURE) + 2]; CHAR PnpId[MAX_PNP_ID+2]; BOOL AllocatedStruct = FALSE; DWORD BytesRead; CHAR InfFile[MAX_MBCHAR_PATH]; HASHITEM InfOffset; HASHITEM hashResult; // // !!! IMPORTANT !!! // // hwcomp.dat is used by other parts of NT. *DO NOT* change it without first e-mailing // the NT group. Also, be sure to keep code in hwcomp.c in sync with changes. // __try { if (!PrevStruct) { Struct = (PHWCOMPSTRUCT) MemAlloc (g_hHeap, 0, sizeof (HWCOMPSTRUCT)); if (!Struct) { __leave; } ZeroMemory (Struct, sizeof (HWCOMPSTRUCT)); Struct->File = INVALID_HANDLE_VALUE; StringCopy (Struct->HwCompDatPath, HwCompDatPath); AllocatedStruct = TRUE; } else { Struct = PrevStruct; if (HwCompDatPath) { SetLastError (ERROR_INVALID_PARAMETER); __leave; } HwCompDatPath = Struct->HwCompDatPath; } if (Struct->File == INVALID_HANDLE_VALUE) { // // Try to open the file // Struct->File = CreateFile ( HwCompDatPath, GENERIC_READ, FILE_SHARE_READ, NULL, // no security attribs OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL // no template ); } if (Struct->File == INVALID_HANDLE_VALUE) { __leave; } if (AllocatedStruct) { // // Create hash tables // Struct->PnpIdTable = PnpIdTable ? PnpIdTable : HtAllocWithData (sizeof (UINT)); Struct->UnSupPnpIdTable = UnSupPnpIdTable ? UnSupPnpIdTable : HtAllocWithData (sizeof (UINT)); Struct->InfFileTable = InfFileTable ? InfFileTable : HtAlloc(); if (!Struct->PnpIdTable || !Struct->InfFileTable) { __leave; } // // Look at the signature // ZeroMemory (Buf, sizeof(Buf)); SetFilePointer (Struct->File, 0, NULL, FILE_BEGIN); if (!ReadFile (Struct->File, Buf, ByteCount (HWCOMPDAT_SIGNATURE), &BytesRead, NULL) || !StringMatch (HWCOMPDAT_SIGNATURE, Buf) ) { SetLastError (ERROR_BAD_FORMAT); __leave; } // // Get INF checksum // if (!pReadDword (Struct->File, &Struct->Checksum)) { SetLastError (ERROR_BAD_FORMAT); __leave; } Struct->InfListOffset = SetFilePointer (Struct->File, 0, NULL, FILE_CURRENT); } if (Load || Dump) { SetFilePointer (Struct->File, Struct->InfListOffset, NULL, FILE_BEGIN); // // Read in all INFs // for (;;) { // // Get INF file name. If empty, we are done. // if (!pReadString (Struct->File, InfFile, sizeof (InfFile))) { SetLastError (ERROR_BAD_FORMAT); __leave; } if (*InfFile == 0) { break; } if (Load) { // // Add to hash table // InfOffset = HtAddString (Struct->InfFileTable, InfFile); if (!InfOffset) { __leave; } } // // Read in all PNP IDs for the INF // for (;;) { // // Get the PNP ID. If empty, we are done. // if (!pReadString (Struct->File, PnpId, sizeof (PnpId))) { __leave; } if (*PnpId == 0) { break; } if (Load) { // // Add to hash table // if (*PnpId == '!') { hashResult = HtAddStringAndData ( Struct->UnSupPnpIdTable, PnpId + 1, &InfOffset ); } else { hashResult = HtAddStringAndData ( Struct->PnpIdTable, PnpId, &InfOffset ); } if (!hashResult) { __leave; } } if (Dump) { if (*PnpId == '!') { if (DumpInf) { printf ("%s\t%s (unsupported)\n", InfFile, PnpId + 1); } else { printf ("%s (unsupported)\n", PnpId + 1); } } else { if (DumpInf) { printf ("%s\t%s\n", InfFile, PnpId); } else { printf ("%s\n", PnpId); } } } } if (Dump) { printf ("\n"); } } } Result = (DWORD) Struct; if (Load) { Struct->Loaded = TRUE; CloseHandle (Struct->File); Struct->File = INVALID_HANDLE_VALUE; } } __finally { if (!Result) { if (AllocatedStruct) { CloseHwCompDat ((DWORD) Struct); } if (Dump) { printf ("Can't open %s\n", HwCompDatPath); } } } return Result; } DWORD OpenHwCompDatA ( IN PCSTR HwCompDatPath ) { return pOpenAndLoadHwCompDatA (HwCompDatPath, FALSE, FALSE, FALSE, NULL, NULL, NULL, NULL); } DWORD LoadHwCompDat ( IN DWORD HwCompDatId ) { return pOpenAndLoadHwCompDatA (NULL, TRUE, FALSE, FALSE, (PHWCOMPSTRUCT) HwCompDatId, NULL, NULL, NULL); } DWORD GetHwCompDatChecksum ( IN DWORD HwCompDatId ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; if (Struct) { return Struct->Checksum; } return 0; } VOID DumpHwCompDatA ( IN PCSTR HwCompDatPath, IN BOOL IncludeInf ) { CloseHwCompDat (pOpenAndLoadHwCompDatA (HwCompDatPath, FALSE, TRUE, IncludeInf, NULL, NULL, NULL, NULL)); } DWORD OpenAndLoadHwCompDatA ( IN PCSTR HwCompDatPath ) { return pOpenAndLoadHwCompDatA (HwCompDatPath, TRUE, FALSE, FALSE, NULL, NULL, NULL, NULL); } DWORD OpenAndLoadHwCompDatExA ( IN PCSTR HwCompDatPath, IN HASHTABLE PnpIdTable, OPTIONAL IN HASHTABLE UnSupPnpIdTable, OPTIONAL IN HASHTABLE InfFileTable OPTIONAL ) { return pOpenAndLoadHwCompDatA (HwCompDatPath, TRUE, FALSE, FALSE, NULL, PnpIdTable, UnSupPnpIdTable, InfFileTable); } VOID TakeHwCompHashTables ( IN DWORD HwCompDatId, OUT HASHTABLE *PnpIdTable, OUT HASHTABLE *UnSupPnpIdTable, OUT HASHTABLE *InfFileTable ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; if (Struct) { *PnpIdTable = Struct->PnpIdTable; Struct->PnpIdTable = NULL; *UnSupPnpIdTable = Struct->UnSupPnpIdTable; Struct->UnSupPnpIdTable = NULL; *InfFileTable = Struct->InfFileTable; Struct->InfFileTable = NULL; } } VOID CloseHwCompDat ( IN DWORD HwCompDatId ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; if (Struct) { HtFree (Struct->PnpIdTable); HtFree (Struct->UnSupPnpIdTable); HtFree (Struct->InfFileTable); if (Struct->File != INVALID_HANDLE_VALUE) { CloseHandle (Struct->File); } MemFree (g_hHeap, 0, Struct); } } VOID SetWorkingTables ( IN DWORD HwCompDatId, IN HASHTABLE PnpIdTable, IN HASHTABLE UnSupPnpIdTable, IN HASHTABLE InfFileTable ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; if (Struct) { Struct->PnpIdTable = PnpIdTable; Struct->UnSupPnpIdTable = UnSupPnpIdTable; Struct->InfFileTable = InfFileTable; } } BOOL IsPnpIdSupportedByNtA ( IN DWORD HwCompDatId, IN PCSTR PnpId ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; BOOL b = FALSE; if (Struct) { b = HtFindString (Struct->PnpIdTable, PnpId) != 0; } return b; } BOOL IsPnpIdUnsupportedByNtA ( IN DWORD HwCompDatId, IN PCSTR PnpId ) { PHWCOMPSTRUCT Struct = (PHWCOMPSTRUCT) HwCompDatId; BOOL b = FALSE; if (Struct) { b = HtFindString (Struct->UnSupPnpIdTable, PnpId) != 0; } return b; }