/*++ Copyright (c) 1989 Microsoft Corporation Module Name: tprefix.c Abstract: Test program for the Prefix table package Author: Gary Kimura [GaryKi] 03-Aug-1989 Revision History: --*/ #include #include #include "nt.h" #include "ntrtl.h" // // Routines and types for generating random prefixes // ULONG RtlRandom ( IN OUT PULONG Seed ); ULONG Seed; PSZ AnotherPrefix(IN ULONG MaxNameLength); ULONG AlphabetLength; //PSZ Alphabet = "AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJuliettKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu"; PSZ Alphabet = "\ Aa\ BBbb\ CCCccc\ DDDDdddd\ EEEEEeeeee\ FFFFFFffffff\ GGGGGGGggggggg\ HHHHHHHHhhhhhhhh\ IIIIIIIIIiiiiiiiii\ JJJJJJJJJJjjjjjjjjjj\ KKKKKKKKKKKkkkkkkkkkkk\ LLLLLLLLLLLLllllllllllll\ MMMMMMMMMMMMMmmmmmmmmmmmmm\ NNNNNNNNNNNNNNnnnnnnnnnnnnnn\ OOOOOOOOOOOOOOOooooooooooooooo\ PPPPPPPPPPPPPPPPpppppppppppppppp\ QQQQQQQQQQQQQQQQQqqqqqqqqqqqqqqqqq\ RRRRRRRRRRRRRRRRRRrrrrrrrrrrrrrrrrrr\ SSSSSSSSSSSSSSSSSSSsssssssssssssssssss\ TTTTTTTTTTTTTTTTTTTTtttttttttttttttttttt\ UUUUUUUUUUUUUUUUUUUUUuuuuuuuuuuuuuuuuuuuuu\ VVVVVVVVVVVVVVVVVVVVVVvvvvvvvvvvvvvvvvvvvvvv\ WWWWWWWWWWWWWWWWWWWWWWWwwwwwwwwwwwwwwwwwwwwwww\ XXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxx\ YYYYYYYYYYYYYYYYYYYYYYYYYyyyyyyyyyyyyyyyyyyyyyyyyy\ ZZZZZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzzzzzzzzzz"; #define BUFFER_LENGTH 8192 CHAR Buffer[BUFFER_LENGTH]; ULONG NextBufferChar = 0; // // record structure and variables for the prefix table and it // elements // typedef struct _PREFIX_NODE { PREFIX_TABLE_ENTRY PfxEntry; STRING String; } PREFIX_NODE; typedef PREFIX_NODE *PPREFIX_NODE; #define PREFIXES 512 PREFIX_NODE Prefixes[PREFIXES]; PREFIX_TABLE PrefixTable; int main( int argc, char *argv[] ) { ULONG i; PSZ Psz; PPREFIX_TABLE_ENTRY PfxEntry; PPREFIX_NODE PfxNode; STRING String; // // We're starting the test // DbgPrint("Start Prefix Test\n"); // // Calculate the alphabet size for use by AnotherPrefix // AlphabetLength = strlen(Alphabet); // // Initialize the prefix table // PfxInitialize(&PrefixTable); // // Insert the root prefix // RtlInitString( &Prefixes[i].String, "\\" ); if (PfxInsertPrefix( &PrefixTable, &Prefixes[0].String, &Prefixes[0].PfxEntry )) { DbgPrint("Insert root prefix\n"); } else { DbgPrint("error inserting root prefix\n"); } // // Insert prefixes // Seed = 0; for (i = 1, Psz = AnotherPrefix(3); (i < PREFIXES) && (Psz != NULL); i += 1, Psz = AnotherPrefix(3)) { DbgPrint("[0x%x] = ", i); DbgPrint("\"%s\"", Psz); RtlInitString(&Prefixes[i].String, Psz); if (PfxInsertPrefix( &PrefixTable, &Prefixes[i].String, &Prefixes[i].PfxEntry )) { DbgPrint(" inserted in table\n"); } else { DbgPrint(" already in table\n"); } } // // Enumerate the prefix table // DbgPrint("Enumerate Prefix Table the first time\n"); for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("%s\n", PfxNode->String.Buffer); } DbgPrint("Start Prefix search 0x%x\n", NextBufferChar); // // Search for prefixes // for (Psz = AnotherPrefix(4); Psz != NULL; Psz = AnotherPrefix(4)) { DbgPrint("0x%x ", NextBufferChar); RtlInitString(&String, Psz); PfxEntry = PfxFindPrefix( &PrefixTable, &String, FALSE ); if (PfxEntry == NULL) { PfxEntry = PfxFindPrefix( &PrefixTable, &String, TRUE ); if (PfxEntry == NULL) { DbgPrint("Not found \"%s\"\n", Psz); NOTHING; } else { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("Case blind \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer); PfxRemovePrefix( &PrefixTable, PfxEntry ); } } else { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint( "Case sensitive \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer); if (PfxNode != &Prefixes[0]) { PfxRemovePrefix( &PrefixTable, PfxEntry ); } } } // // Enumerate the prefix table // DbgPrint("Enumerate Prefix Table a second time\n"); for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("%s\n", PfxNode->String.Buffer); } // // Now enumerate and zero out the table // for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("Delete %s\n", PfxNode->String.Buffer); PfxRemovePrefix( &PrefixTable, PfxEntry ); } // // Enumerate again but this time the table should be empty // for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE); PfxEntry != NULL; PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) { PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry); DbgPrint("This Node should be gone \"%s\"\n", PfxNode->String.Buffer); } DbgPrint("End PrefixTest()\n"); return TRUE; } PSZ AnotherPrefix(IN ULONG MaxNameLength) { ULONG AlphabetPosition; ULONG NameLength; ULONG IndividualNameLength; ULONG StartBufferPosition; ULONG i; ULONG j; // // Check if there is enough room for another name // if (NextBufferChar > (BUFFER_LENGTH - (MaxNameLength * 4))) { return NULL; } // // Where in the alphabet soup we start // AlphabetPosition = RtlRandom(&Seed) % AlphabetLength; // // How many names we want in our prefix // NameLength = (RtlRandom(&Seed) % MaxNameLength) + 1; // // Compute each name // StartBufferPosition = NextBufferChar; for (i = 0; i < NameLength; i += 1) { Buffer[NextBufferChar++] = '\\'; IndividualNameLength = (RtlRandom(&Seed) % 3) + 1; for (j = 0; j < IndividualNameLength; j += 1) { Buffer[NextBufferChar++] = Alphabet[AlphabetPosition]; AlphabetPosition = (AlphabetPosition + 1) % AlphabetLength; } } Buffer[NextBufferChar++] = '\0'; return &Buffer[StartBufferPosition]; }