#include #include #include #include #include #include #include #include // // generate a 4mb Doc file // #define NUMBER_OF_IOS (2048) #define DATA_IO_SIZE 2048 char Buffer[DATA_IO_SIZE]; #define CREATEMODE_ROOT STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE #define CREATEMODE_STREAM STGM_CREATE | STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE #define OPENMODE_ROOT STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE #define OPENMODE_STREAM STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE BOOL fOleMode = TRUE; BOOL fCreateMode = TRUE; BOOL fWriteMode = TRUE; BOOL fReadMode = FALSE; BOOL fDirectMode = FALSE; BOOL fSimulateMode = FALSE; HANDLE Mutex1, Mutex2; #define TEST_REPEAT_COUNT 10 VOID WINAPI ShowUsage( VOID ); VOID WINAPI ParseSwitch( CHAR chSwitch, int *pArgc, char **pArgv[] ); VOID WINAPI Win32FileBench( VOID ) { BOOL b; HANDLE hFile; DWORD BytesTransferred; int IoCount; DWORD filepos; LONG i; hFile = CreateFile( "StorPerf.doc", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, fCreateMode ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { fprintf(stdout, "OLEDOC: Open Doc File failed %x\n",GetLastError()); exit(1); } for (IoCount = 0, filepos = 0; IoCount < NUMBER_OF_IOS; IoCount++, filepos += DATA_IO_SIZE){ if ( fSimulateMode ) { WaitForSingleObject(Mutex1,60000); WaitForSingleObject(Mutex2,INFINITE); ReleaseMutex(Mutex2); ReleaseMutex(Mutex1); SetFilePointer(hFile,filepos,NULL,FILE_BEGIN); IsBadWritePtr(&BytesTransferred,4); IsBadReadPtr(Buffer,DATA_IO_SIZE); InterlockedIncrement(&i); InterlockedDecrement(&i); InterlockedIncrement(&i); InterlockedDecrement(&i); InterlockedIncrement(&i); InterlockedDecrement(&i); InterlockedIncrement(&i); InterlockedDecrement(&i); InterlockedIncrement(&i); InterlockedDecrement(&i); } if ( fWriteMode ) { b = WriteFile(hFile,Buffer, DATA_IO_SIZE, &BytesTransferred,NULL); } else { b = ReadFile(hFile,Buffer, DATA_IO_SIZE, &BytesTransferred, NULL); } if (!b || BytesTransferred != DATA_IO_SIZE) { fprintf(stdout, "OLEDOC: %s Failed on op#%d transferred %d bytes %x\n", fWriteMode ? "Write" : "Read", IoCount, BytesTransferred, GetLastError() ); exit(1); } } CloseHandle(hFile); } VOID WINAPI OleDocFileBench( VOID ) { HRESULT hr; IStorage *pIStorage; IStream *pIStream; DWORD BytesTransferred; int IoCount; if ( fCreateMode ) { hr = StgCreateDocfile( L"StorPerf.doc", fDirectMode ? CREATEMODE_STREAM : CREATEMODE_ROOT, 0, &pIStorage ); if (hr != S_OK) { fprintf(stdout, "OLEDOC: StgCreateDocFile failed %x\n",hr); exit(1); } hr = pIStorage->CreateStream(L"Data", CREATEMODE_STREAM, 0, 0, &pIStream); if (hr != S_OK) { fprintf(stdout, "OLEDOC: CreateStream failed %x\n",hr); exit(1); } } else { hr = StgOpenStorage( L"StorPerf.doc", NULL, fDirectMode ? OPENMODE_STREAM : OPENMODE_ROOT, NULL, 0, &pIStorage ); if (hr != S_OK) { fprintf(stdout, "OLEDOC: StgOpenDocFile failed %x\n",hr); exit(1); } hr = pIStorage->OpenStream(L"Data", 0, OPENMODE_STREAM, 0, &pIStream); if (hr != S_OK) { fprintf(stdout, "OLEDOC: OpenStream failed %x\n",hr); exit(1); } } if ( fWriteMode ) { ULARGE_INTEGER Size; Size.QuadPart = NUMBER_OF_IOS * DATA_IO_SIZE; hr = pIStream->SetSize(Size); if (hr != S_OK ) { fprintf(stdout, "OLEDOC: SetSize Failed %x\n", hr ); exit(1); } } for (IoCount = 0; IoCount < NUMBER_OF_IOS; IoCount++){ if ( fWriteMode ) { hr = pIStream->Write(Buffer, DATA_IO_SIZE, &BytesTransferred); } else { BytesTransferred = DATA_IO_SIZE; hr = pIStream->Read(Buffer, DATA_IO_SIZE, &BytesTransferred); } if (hr != S_OK || BytesTransferred != DATA_IO_SIZE) { fprintf(stdout, "OLEDOC: %s Failed on op#%d transferred %d bytes %x\n", fWriteMode ? "Write" : "Read", IoCount, BytesTransferred, hr ); exit(1); } } pIStream->Release(); if (fWriteMode && !fDirectMode ) { pIStorage->Commit(STGC_DEFAULT); } pIStorage->Release(); } int _CRTAPI1 main( int argc, char *argv[], char *envp[] ) { HRESULT hr; IStorage *pIStorage; IStream *pIStream; DWORD BytesTransferred; char chChar, *pchChar; char *TestType; int TestNumber; double fDiff, fSec, fKb, fSumKbs; DWORD Diff; DWORD Start[TEST_REPEAT_COUNT]; DWORD End[TEST_REPEAT_COUNT]; LARGE_INTEGER fp; int IoCount; while (--argc) { pchChar = *++argv; if (*pchChar == '/' || *pchChar == '-') { while (chChar = *++pchChar) { ParseSwitch( chChar, &argc, &argv ); } } } if ( fOleMode ) { hr = OleInitialize( NULL ); if (hr != S_OK) { fprintf(stdout, "OLEDOC: Unable to OleInitialize.\n"); exit(1); } } else { if ( fSimulateMode ) { Mutex1 = CreateMutex(NULL,FALSE,NULL); Mutex2 = CreateMutex(NULL,FALSE,NULL); if ( !Mutex1 || !Mutex2 ) { fprintf(stdout, "OLEDOC: Unable to Create Mutexs.\n"); exit(1); } } } if ( fCreateMode ) { if ( fWriteMode ) { TestType = "Create/Write Doc File"; } else { TestType = "Create/Read Doc File"; } } else { if ( fWriteMode ) { TestType = "Open/Write Doc File"; } else { TestType = "Open/Read Doc File"; } } fSumKbs = 0.0; for (TestNumber = 0; TestNumber < TEST_REPEAT_COUNT; TestNumber++ ) { Start[TestNumber] = GetTickCount(); if ( fOleMode ) { OleDocFileBench(); } else { Win32FileBench(); } End[TestNumber] = GetTickCount(); // // Dump the results // Diff = End[TestNumber] - Start[TestNumber]; fDiff = Diff; fSec = fDiff/1000.0; fKb = ( (NUMBER_OF_IOS * DATA_IO_SIZE) / 1024 ); fSumKbs += (fKb / fSec); printf("Test %2d %s (%s) %3.3fs I/O Rate %4.3f Kb/S\n", TestNumber, TestType, fOleMode ? (fDirectMode ? "Ole Direct" : "Ole Transacted") : "Win32 Mode", fSec, fKb / fSec ); } // // Average // printf("\n Average Throughput %4.3f\n\n", fSumKbs/TEST_REPEAT_COUNT ); return(0); } VOID WINAPI ParseSwitch( CHAR chSwitch, int *pArgc, char **pArgv[] ) { switch (toupper( chSwitch )) { case '?': ShowUsage(); break; case 'C': fCreateMode = TRUE; break; case 'O': fCreateMode = FALSE; break; case 'W': fWriteMode = TRUE; break; case 'R': fWriteMode = FALSE; fCreateMode = FALSE; break; case 'D': fDirectMode = TRUE; break; case 'S': fSimulateMode = TRUE; fOleMode = FALSE; break; case 'N': fOleMode = FALSE; break; default: fprintf( stderr, "OLEDOC: Invalid switch - /%c\n", chSwitch ); ShowUsage(); break; } } VOID WINAPI ShowUsage( VOID ) { fputs( "usage: OLEDOC [switches]\n" " [-?] show this message\n" " [-c] just time creates\n" " [-o] just time opens\n" " [-w] write-mode (default)\n" " [-r] read-mode to read an existing doc file\n" " [-d] direct-mode I/O\n" " [-s] simulate ole by duplicating ole kernel32 calls in nt mode\n" " [-n] Native Win32 Mode I/O\n" ,stderr ); exit( 1 ); }