/*++ Copyright (c) 1992 Microsoft Corporation Module Name: pdc.h Abstract: This is the main source file for the Windows/NT PDC API demonstration program. This include file defines macros, data structures and procedure prototypes for the code contained in the PDC.C source file. --*/ // // Include file for using the Win32 API // #include // // C Runtime include files used by the program. // #include #include #include #include #include #include #include #include #include #include // // Macro definitions // // // Useful rounding macros that the rounding amount is always a // power of two. // #define ROUND_DOWN( Size, Amount ) ((DWORD)(Size) & ~((Amount) - 1)) #define ROUND_UP( Size, Amount ) (((DWORD)(Size) + ((Amount) - 1)) & ~((Amount) - 1)) // // Pseudo keywords for documentation purposes. // #define IN #define OUT #define OPTIONAL // // Determine if an argument is present by testing a value of NULL // #define ARGUMENT_PRESENT( ArgumentPointer ) (\ (LPSTR)(ArgumentPointer) != (LPSTR)(NULL) ) // // Calculate the address of the base of the structure given its type, and an // address of a field within the structure. // #define CONTAINING_RECORD( address, type, field ) ((type *)( \ (PCHAR)(address) - \ (PCHAR)(&((type *)0)->field))) // // Virtual Buffer data structure and function prototypes. // typedef struct _VIRTUAL_BUFFER { LPVOID Base; ULONG PageSize; LPVOID CommitLimit; LPVOID ReserveLimit; } VIRTUAL_BUFFER, *PVIRTUAL_BUFFER; BOOL CreateVirtualBuffer( OUT PVIRTUAL_BUFFER Buffer, IN DWORD CommitSize, IN DWORD ReserveSize OPTIONAL ); BOOL ExtendVirtualBuffer( IN PVIRTUAL_BUFFER Buffer, IN LPVOID Address ); BOOL TrimVirtualBuffer( IN PVIRTUAL_BUFFER Buffer ); BOOL FreeVirtualBuffer( IN PVIRTUAL_BUFFER Buffer ); int VirtualBufferExceptionFilter( IN DWORD ExceptionCode, IN PEXCEPTION_POINTERS ExceptionInfo, IN OUT PVIRTUAL_BUFFER Buffer ); // // Directory enumeration and file notification definitions. // typedef VOID (*PDIRECTORY_ENUMERATE_ROUTINE)( LPSTR Path, PWIN32_FIND_DATA FindFileData, PVOID EnumerateParameter ); BOOL EnumerateDirectoryTree( LPSTR DirectoryPath, PDIRECTORY_ENUMERATE_ROUTINE EnumerateRoutine, PVOID EnumerateParameter ); // // Data structures private to the EnumerateDirectoryTree function. // typedef struct _ENUMERATE_DIRECTORY_STACK { LPSTR PathEnd; HANDLE FindHandle; } ENUMERATE_DIRECTORY_STACK, *PENUMERATE_DIRECTORY_STACK; #define MAX_DEPTH 256 typedef struct _ENUMERATE_DIRECTORY_STATE { DWORD Depth; ENUMERATE_DIRECTORY_STACK Stack[ MAX_DEPTH ]; CHAR Path[ MAX_PATH ]; } ENUMERATE_DIRECTORY_STATE, *PENUMERATE_DIRECTORY_STATE; // // Doubly-linked list manipulation routines. Implemented as macros // but logically these are procedures. // // // VOID // InitializeListHead( // PLIST_ENTRY ListHead // ); // #define InitializeListHead(ListHead) (\ (ListHead)->Flink = (ListHead)->Blink = (ListHead) ) // // BOOLEAN // IsListEmpty( // PLIST_ENTRY ListHead // ); // #define IsListEmpty(ListHead) (\ ( ((ListHead)->Flink == (ListHead)) ? TRUE : FALSE ) ) // // PLIST_ENTRY // RemoveHeadList( // PLIST_ENTRY ListHead // ); // #define RemoveHeadList(ListHead) \ (ListHead)->Flink;\ {\ PLIST_ENTRY FirstEntry;\ FirstEntry = (ListHead)->Flink;\ FirstEntry->Flink->Blink = (ListHead);\ (ListHead)->Flink = FirstEntry->Flink;\ } // // VOID // RemoveEntryList( // PLIST_ENTRY Entry // ); // #define RemoveEntryList(Entry) {\ PLIST_ENTRY _EX_Entry;\ _EX_Entry = (Entry);\ _EX_Entry->Blink->Flink = _EX_Entry->Flink;\ _EX_Entry->Flink->Blink = _EX_Entry->Blink;\ } // // VOID // InsertTailList( // PLIST_ENTRY ListHead, // PLIST_ENTRY Entry // ); // #define InsertTailList(ListHead,Entry) \ (Entry)->Flink = (ListHead);\ (Entry)->Blink = (ListHead)->Blink;\ (ListHead)->Blink->Flink = (Entry);\ (ListHead)->Blink = (Entry) // // VOID // InsertHeadList( // PLIST_ENTRY ListHead, // PLIST_ENTRY Entry // ); // #define InsertHeadList(ListHead,Entry) \ (Entry)->Flink = (ListHead)->Flink;\ (Entry)->Blink = (ListHead);\ (ListHead)->Flink->Blink = (Entry);\ (ListHead)->Flink = (Entry) // // Worker thread definitions // typedef VOID (*PWORKER_ROUTINE)( IN struct _WORK_QUEUE_ITEM *WorkItem ); typedef struct _WORK_QUEUE { CRITICAL_SECTION CriticalSection; HANDLE Semaphore; LIST_ENTRY Queue; BOOL Terminating; PWORKER_ROUTINE WorkerRoutine; DWORD NumberOfWorkerThreads; HANDLE WorkerThreads[ 1 ]; // Variable length array } WORK_QUEUE, *PWORK_QUEUE; typedef struct _WORK_QUEUE_ITEM { LIST_ENTRY List; DWORD Reason; PWORK_QUEUE WorkQueue; } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM; #define WORK_INITIALIZE_ITEM 0 #define WORK_ITEM 1 #define WORK_TERMINATE_ITEM 2 DWORD WorkerThread( LPVOID lpThreadParameter ); PWORK_QUEUE CreateWorkQueue( IN DWORD NumberOfWorkerThreads, IN PWORKER_ROUTINE WorkerRoutine ); BOOL QueueWorkItem( IN OUT PWORK_QUEUE WorkQueue, IN PWORK_QUEUE_ITEM WorkItem ); VOID DestroyWorkQueue( IN OUT PWORK_QUEUE WorkQueue ); // // Main procedure prototypes // BOOL ProcessCommandLineArguments( int argc, char *argv[] ); VOID QueueSearchFile( LPSTR Path, PWIN32_FIND_DATA FindFileData, PVOID EnumerateParameter ); typedef struct _SEARCH_REQUEST_STATE { VIRTUAL_BUFFER Buffer; LPSTR CurrentOutput; } SEARCH_REQUEST_STATE, *PSEARCH_REQUEST_STATE; typedef struct _SEARCH_REQUEST { WORK_QUEUE_ITEM WorkItem; DWORD FileSize; LPSTR FileData; HANDLE File; OVERLAPPED OverlappedIO; CHAR FullPathName[ 1 ]; // Variable length array } SEARCH_REQUEST, *PSEARCH_REQUEST; VOID ProcessRequest( IN PWORK_QUEUE_ITEM WorkItem ); VOID ProcessReadFileCompletion( DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped ); VOID ProcessSearchFile( IN PSEARCH_REQUEST WorkerRequest, IN PSEARCH_REQUEST_STATE State ); // // Global variables // DWORD TlsIndex; INT NumberOfWorkerThreads; BOOL Verbose; BOOL IgnoreCase; BOOL MappedFileIO; BOOL ASyncIO; BOOL SyncIO; LPSTR DirectoryPath; LPSTR SearchString; DWORD SearchStringLength; DWORD SearchedFileCount; DWORD MatchedFileCount; DWORD MatchedLineCount; DWORD OutstandingIOOperations; HANDLE IoCompletedEvent; typedef int (_CRTAPI1 *PCOMPARE_ROUTINE)( IN const char *, IN const char *, IN size_t ); PCOMPARE_ROUTINE SearchFunction;