610 lines
13 KiB
C
610 lines
13 KiB
C
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
#include <nturtl.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
|
|||
|
#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;i<FIVEK;i++) {
|
|||
|
|
|||
|
OpenCloseDir(&Obja);
|
|||
|
}
|
|||
|
|
|||
|
FinishBenchMark(&PerfInfo);
|
|||
|
|
|||
|
StartBenchMark(
|
|||
|
"NtQueryAttributes Dir NTFS d:\\testdir\\client1\\bench",
|
|||
|
FIVEK,
|
|||
|
&PerfInfo
|
|||
|
);
|
|||
|
|
|||
|
for ( i=0;i<FIVEK;i++) {
|
|||
|
|
|||
|
NtQueryAttributesFile( &Obja, &BasicInfo );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
FinishBenchMark(&PerfInfo);
|
|||
|
|
|||
|
|
|||
|
CreateOpenDirObja(
|
|||
|
L"c:\\testdir\\client1\\bench",
|
|||
|
&Obja,
|
|||
|
&PathName,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
StartBenchMark(
|
|||
|
"Open Dir FAT c:\\testdir\\client1\\bench",
|
|||
|
FIVEK,
|
|||
|
&PerfInfo
|
|||
|
);
|
|||
|
|
|||
|
for ( i=0;i<FIVEK;i++) {
|
|||
|
|
|||
|
OpenCloseDir(&Obja);
|
|||
|
}
|
|||
|
|
|||
|
FinishBenchMark(&PerfInfo);
|
|||
|
#endif
|
|||
|
|
|||
|
CreateOpenDirObja(
|
|||
|
L"d:\\testdir\\client1\\bench",
|
|||
|
&Obja,
|
|||
|
&PathName,
|
|||
|
L"d:\\"
|
|||
|
);
|
|||
|
|
|||
|
StartBenchMark(
|
|||
|
"VOL Rel Open Dir NTFS d:\\testdir\\client1\\bench",
|
|||
|
FIVEK,
|
|||
|
&PerfInfo
|
|||
|
);
|
|||
|
|
|||
|
for ( i=0;i<FIVEK;i++) {
|
|||
|
|
|||
|
OpenCloseDir(&Obja);
|
|||
|
}
|
|||
|
|
|||
|
FinishBenchMark(&PerfInfo);
|
|||
|
|
|||
|
|
|||
|
CreateOpenDirObja(
|
|||
|
L"c:\\testdir\\client1\\bench",
|
|||
|
&Obja,
|
|||
|
&PathName,
|
|||
|
L"c:\\"
|
|||
|
);
|
|||
|
|
|||
|
StartBenchMark(
|
|||
|
"Vol Rel Open Dir FAT c:\\testdir\\client1\\bench",
|
|||
|
FIVEK,
|
|||
|
&PerfInfo
|
|||
|
);
|
|||
|
|
|||
|
for ( i=0;i<FIVEK;i++) {
|
|||
|
|
|||
|
OpenCloseDir(&Obja);
|
|||
|
}
|
|||
|
|
|||
|
FinishBenchMark(&PerfInfo);
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
_cdecl
|
|||
|
main(
|
|||
|
int argc,
|
|||
|
char *argv[],
|
|||
|
char *envp[]
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
DWORD CryptoKey;
|
|||
|
PDWORD p;
|
|||
|
|
|||
|
printf("sixeof teb %x\n",sizeof(TEB));
|
|||
|
|
|||
|
CryptoKey = USER_SHARED_DATA->CryptoExponent;
|
|||
|
|
|||
|
printf("Key %x\n",CryptoKey);
|
|||
|
|
|||
|
p = &(USER_SHARED_DATA->CryptoExponent);
|
|||
|
*p = 1;
|
|||
|
|
|||
|
//OpenDirTest();
|
|||
|
//FastFindTest();
|
|||
|
//FindFirstTest();
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|