#include #include #include #include #include #include #include #define ONEK 1000 #define FIVEK 5000 #define TENK 10000 #define ONEHUNK 100000 #define ONEMIL 1000000 // // Define local types. // typedef struct _PERFINFO { DWORD StartTime; DWORD StopTime; LPSTR Title; DWORD Iterations; } PERFINFO, *PPERFINFO; VOID FinishBenchMark ( IN PPERFINFO PerfInfo ) { DWORD ContextSwitches; DWORD Duration; DWORD Performance; // // Print results and announce end of test. // PerfInfo->StopTime = GetTickCount(); Duration = PerfInfo->StopTime - PerfInfo->StartTime; printf(" Test time in milliseconds %d\n", Duration); printf(" Number of iterations %d\n", PerfInfo->Iterations); Performance = PerfInfo->Iterations * 1000 / Duration; printf(" Iterations per second %d\n", Performance); printf("*** End of Test ***\n\n"); return; } VOID StartBenchMark ( IN PCHAR Title, IN DWORD Iterations, IN PPERFINFO PerfInfo ) { // // Announce start of test and the number of iterations. // printf("*** Start of test ***\n %s\n", Title); PerfInfo->Title = Title; PerfInfo->Iterations = Iterations; PerfInfo->StartTime = GetTickCount(); return; } HANDLE APIENTRY FastFindOpenDir( LPCWSTR lpFileName ) { HANDLE hFindFile; NTSTATUS Status; OBJECT_ATTRIBUTES Obja; UNICODE_STRING FileName; UNICODE_STRING PathName; IO_STATUS_BLOCK IoStatusBlock; BOOLEAN TranslationStatus; RTL_RELATIVE_NAME RelativeName; PVOID FreeBuffer; UNICODE_STRING UnicodeInput; BOOLEAN EndsInDot; RtlInitUnicodeString(&UnicodeInput,lpFileName); // // Bogus code to workaround ~* problem // if ( UnicodeInput.Buffer[(UnicodeInput.Length>>1)-1] == (WCHAR)'.' ) { EndsInDot = TRUE; } else { EndsInDot = FALSE; } TranslationStatus = RtlDosPathNameToNtPathName_U( lpFileName, &PathName, &FileName.Buffer, &RelativeName ); if ( !TranslationStatus ) { return NULL; } FreeBuffer = PathName.Buffer; InitializeObjectAttributes( &Obja, &PathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); // // Open the directory for list access // Status = NtOpenFile( &hFindFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, &Obja, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT ); if ( !NT_SUCCESS(Status) ) { return NULL; } return hFindFile; } BOOL FastFind( HANDLE hFindFile, LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData ) { NTSTATUS Status; OBJECT_ATTRIBUTES Obja; UNICODE_STRING FileName; UNICODE_STRING PathName; IO_STATUS_BLOCK IoStatusBlock; BOOLEAN TranslationStatus; RTL_RELATIVE_NAME RelativeName; PVOID FreeBuffer; UNICODE_STRING UnicodeInput; BOOLEAN EndsInDot; PFILE_BOTH_DIR_INFORMATION DirectoryInfo; CHAR Buffer[MAX_PATH*2 + sizeof(FILE_BOTH_DIR_INFORMATION)]; RtlInitUnicodeString(&FileName,lpFileName); DirectoryInfo = (PFILE_BOTH_DIR_INFORMATION)Buffer; Status = NtQueryDirectoryFile( hFindFile, NULL, NULL, NULL, &IoStatusBlock, DirectoryInfo, sizeof(Buffer), FileBothDirectoryInformation, TRUE, &FileName, TRUE ); if ( !NT_SUCCESS(Status) ) { return FALSE; } // // Attributes are composed of the attributes returned by NT. // lpFindFileData->dwFileAttributes = DirectoryInfo->FileAttributes; lpFindFileData->ftCreationTime = *(LPFILETIME)&DirectoryInfo->CreationTime; lpFindFileData->ftLastAccessTime = *(LPFILETIME)&DirectoryInfo->LastAccessTime; lpFindFileData->ftLastWriteTime = *(LPFILETIME)&DirectoryInfo->LastWriteTime; lpFindFileData->nFileSizeHigh = DirectoryInfo->EndOfFile.HighPart; lpFindFileData->nFileSizeLow = DirectoryInfo->EndOfFile.LowPart; RtlMoveMemory( lpFindFileData->cFileName, DirectoryInfo->FileName, DirectoryInfo->FileNameLength ); lpFindFileData->cFileName[DirectoryInfo->FileNameLength >> 1] = UNICODE_NULL; RtlMoveMemory( lpFindFileData->cAlternateFileName, DirectoryInfo->ShortName, DirectoryInfo->ShortNameLength ); lpFindFileData->cAlternateFileName[DirectoryInfo->ShortNameLength >> 1] = UNICODE_NULL; return TRUE; } VOID FastFindTest( VOID ) { PERFINFO PerfInfo; int i; HANDLE hFind; WIN32_FIND_DATAW FindFileData; BOOL b; hFind = FastFindOpenDir(L"d:\\testdir\\client1\\bench"); if ( !hFind ) { printf("Failed\n"); return; } StartBenchMark( "FastFind Test", ONEK, &PerfInfo ); for ( i=0;i<5*ONEK;i++) { // // do 5 calls 3 work, 2 don't // b = FastFind(hFind,L"a",&FindFileData); if ( !b ) { printf("Test Failure a\n"); ExitProcess(0); } b = FastFind(hFind,L"ab",&FindFileData); if ( b ) { printf("Test Failure ab\n"); ExitProcess(0); } b = FastFind(hFind,L"abc",&FindFileData); if ( !b ) { printf("Test Failure abc\n"); ExitProcess(0); } b = FastFind(hFind,L"da",&FindFileData); if ( b ) { printf("Test Failure da\n"); ExitProcess(0); } b = FastFind(hFind,L"dxxa",&FindFileData); if ( !b ) { printf("Test Failure dxxa\n"); ExitProcess(0); } } FinishBenchMark(&PerfInfo); } VOID FindFirstTest( VOID ) { PERFINFO PerfInfo; int i; HANDLE hFind; WIN32_FIND_DATAW FindFileData; BOOL b; StartBenchMark( "Stock FindFirst Test", ONEK, &PerfInfo ); for ( i=0;i<5*ONEK;i++) { // // do 5 calls 3 work, 2 don't // hFind = FindFirstFileW(L"d:\\testdir\\client1\\bench\\a",&FindFileData); if ( hFind == INVALID_HANDLE_VALUE ) { printf("Test Failure a\n"); ExitProcess(0); } FindClose(hFind); hFind = FindFirstFileW(L"d:\\testdir\\client1\\bench\\ab",&FindFileData); if ( hFind != INVALID_HANDLE_VALUE ) { printf("Test Failure ab\n"); ExitProcess(0); } hFind = FindFirstFileW(L"d:\\testdir\\client1\\bench\\abc",&FindFileData); if ( hFind == INVALID_HANDLE_VALUE ) { printf("Test Failure abc\n"); ExitProcess(0); } FindClose(hFind); hFind = FindFirstFileW(L"d:\\testdir\\client1\\bench\\da",&FindFileData); if ( hFind != INVALID_HANDLE_VALUE ) { printf("Test Failure da\n"); ExitProcess(0); } hFind = FindFirstFileW(L"d:\\testdir\\client1\\bench\\dxxa",&FindFileData); if ( hFind == INVALID_HANDLE_VALUE ) { printf("Test Failure dxxa\n"); ExitProcess(0); } FindClose(hFind); } FinishBenchMark(&PerfInfo); } VOID APIENTRY CreateOpenDirObja( LPCWSTR lpFileName, POBJECT_ATTRIBUTES Obja, PUNICODE_STRING PathName, LPCWSTR DirName ) { UNICODE_STRING FileName; IO_STATUS_BLOCK IoStatusBlock; BOOLEAN TranslationStatus; RTL_RELATIVE_NAME RelativeName; PVOID FreeBuffer; HANDLE hDir; NTSTATUS Status; if ( ARGUMENT_PRESENT(DirName) ) { TranslationStatus = RtlDosPathNameToNtPathName_U( DirName, PathName, &FileName.Buffer, &RelativeName ); if ( TranslationStatus ) { // // Open the directory for list access // InitializeObjectAttributes( Obja, PathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenFile( &hDir, FILE_LIST_DIRECTORY | SYNCHRONIZE, Obja, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT ); if ( !NT_SUCCESS(Status) ) { printf("Open faild %x\n",Status); ExitProcess(1); } } } else { hDir = NULL; } TranslationStatus = RtlDosPathNameToNtPathName_U( lpFileName, PathName, &FileName.Buffer, &RelativeName ); if ( !TranslationStatus ) { return; } if ( hDir ) { PathName->Buffer = PathName->Buffer + 15; PathName->Length -= 30; PathName->MaximumLength -= 30; } FreeBuffer = PathName->Buffer; InitializeObjectAttributes( Obja, PathName, OBJ_CASE_INSENSITIVE, hDir, NULL ); } VOID APIENTRY OpenCloseDir( POBJECT_ATTRIBUTES Obja ) { HANDLE hDir; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; // // Open the directory for list access // Status = NtOpenFile( &hDir, FILE_LIST_DIRECTORY | SYNCHRONIZE, Obja, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT ); if ( !NT_SUCCESS(Status) ) { printf("Open faild %x\n",Status); ExitProcess(1); } NtClose(hDir); } VOID OpenDirTest( VOID ) { PERFINFO PerfInfo; int i; HANDLE hDir; OBJECT_ATTRIBUTES Obja; UNICODE_STRING PathName; FILE_BASIC_INFORMATION BasicInfo; #if 0 CreateOpenDirObja( L"d:\\testdir\\client1\\bench", &Obja, &PathName, NULL ); StartBenchMark( "Open Dir NTFS d:\\testdir\\client1\\bench", FIVEK, &PerfInfo ); for ( i=0;iCryptoExponent; printf("Key %x\n",CryptoKey); p = &(USER_SHARED_DATA->CryptoExponent); *p = 1; //OpenDirTest(); //FastFindTest(); //FindFirstTest(); return 0; }