570 lines
13 KiB
C
570 lines
13 KiB
C
|
/*++
|
||
|
|
||
|
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:
|
||
|
|
||
|
<alias> <date> <comments>
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|