windows-nt/Source/XPSP1/NT/base/tools/instaler/namedb.c
2020-09-26 16:20:57 +08:00

178 lines
3.8 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
namedb.c
Abstract:
This module maintains a database of path names detected by the INSTALER program
Author:
Steve Wood (stevewo) 20-Aug-1994
Revision History:
--*/
#include "instaler.h"
typedef struct _NAME_TABLE_ENTRY {
struct _NAME_TABLE_ENTRY *HashLink;
UNICODE_STRING Name;
ULONG OpenCount;
ULONG FailedOpenCount;
} NAME_TABLE_ENTRY, *PNAME_TABLE_ENTRY;
#define NUMBER_OF_HASH_BUCKETS 37
PNAME_TABLE_ENTRY NameTableBuckets[ NUMBER_OF_HASH_BUCKETS ];
BOOLEAN
IncrementOpenCount(
PWSTR Name,
BOOLEAN CallSuccessful
)
{
PNAME_TABLE_ENTRY p;
p = (PNAME_TABLE_ENTRY)Name - 1;
if (p->Name.Buffer == Name) {
if (CallSuccessful) {
p->OpenCount += 1;
}
else {
p->FailedOpenCount += 1;
}
return TRUE;
}
else {
return FALSE;
}
}
ULONG
QueryOpenCount(
PWSTR Name,
BOOLEAN CallSuccessful
)
{
PNAME_TABLE_ENTRY p;
p = (PNAME_TABLE_ENTRY)Name - 1;
if (p->Name.Buffer == Name) {
if (CallSuccessful) {
return p->OpenCount;
}
else {
return p->FailedOpenCount;
}
}
else {
return 0;
}
}
PWSTR
AddName(
PUNICODE_STRING Name
)
{
ULONG n, Hash;
WCHAR c;
PWCH s;
PNAME_TABLE_ENTRY *pp, p;
n = Name->Length / sizeof( c );
s = Name->Buffer;
Hash = 0;
while (n--) {
c = RtlUpcaseUnicodeChar( *s++ );
Hash = Hash + (c << 1) + (c >> 1) + c;
}
pp = &NameTableBuckets[ Hash % NUMBER_OF_HASH_BUCKETS ];
while (p = *pp) {
if (RtlEqualUnicodeString( &p->Name, Name, TRUE )) {
return p->Name.Buffer;
}
else {
pp = &p->HashLink;
}
}
p = AllocMem( sizeof( *p ) + Name->Length + sizeof( UNICODE_NULL ) );
if (p == NULL) {
printf ("Memory allocation failure\n");
ExitProcess (0);
}
*pp = p;
p->HashLink = NULL;
p->Name.Buffer = (PWSTR)(p + 1);
p->Name.Length = Name->Length;
p->Name.MaximumLength = (USHORT)(Name->Length + sizeof( UNICODE_NULL ));
RtlMoveMemory( p->Name.Buffer, Name->Buffer, Name->Length );
p->Name.Buffer[ Name->Length / sizeof( WCHAR ) ] = UNICODE_NULL;
return p->Name.Buffer;
}
VOID
DumpNameDataBase(
FILE *LogFile
)
{
ULONG i;
PNAME_TABLE_ENTRY p;
#if 0
fprintf( LogFile, "Name Data Base entries:\n" );
for (i=0; i<NUMBER_OF_HASH_BUCKETS; i++) {
p = NameTableBuckets[ i ];
if (p != NULL) {
fprintf( LogFile, "Bucket[ %02u ]:\n", i );
while (p) {
fprintf( LogFile, " %ws\n", p->Name.Buffer );
p = p->HashLink;
}
}
}
fprintf( LogFile, "\n" );
#endif
fprintf( LogFile, "List of paths with non-zero successful open counts\n" );
for (i=0; i<NUMBER_OF_HASH_BUCKETS; i++) {
p = NameTableBuckets[ i ];
if (p != NULL) {
while (p) {
if (p->OpenCount != 0) {
fprintf( LogFile, " %4u %ws\n", p->OpenCount, p->Name.Buffer );
}
p = p->HashLink;
}
}
}
fprintf( LogFile, "\n" );
fprintf( LogFile, "List of paths with non-zero failed open counts\n" );
for (i=0; i<NUMBER_OF_HASH_BUCKETS; i++) {
p = NameTableBuckets[ i ];
if (p != NULL) {
while (p) {
if (p->FailedOpenCount != 0) {
fprintf( LogFile, " %4u %ws\n", p->FailedOpenCount, p->Name.Buffer );
}
p = p->HashLink;
}
}
}
fprintf( LogFile, "\n" );
return;
}