/*++ 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; iName.Buffer ); p = p->HashLink; } } } fprintf( LogFile, "\n" ); #endif fprintf( LogFile, "List of paths with non-zero successful open counts\n" ); for (i=0; iOpenCount != 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; iFailedOpenCount != 0) { fprintf( LogFile, " %4u %ws\n", p->FailedOpenCount, p->Name.Buffer ); } p = p->HashLink; } } } fprintf( LogFile, "\n" ); return; }