2020-09-30 17:12:29 +02:00

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 );
}