399 lines
9.3 KiB
C++
399 lines
9.3 KiB
C++
#include <windows.h>
|
|
#include <ole2.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <io.h>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
//
|
|
// 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 );
|
|
}
|