Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

624 lines
17 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993.
  5. //
  6. // File: bm_stg.cxx
  7. //
  8. // Contents: Basic Storage test
  9. //
  10. // Classes: CStorageTest
  11. //
  12. // History: 7-June-94 t-vadims Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <headers.cxx>
  16. #pragma hdrstop
  17. #include <bm_stg.hxx>
  18. #define DEF_DATASIZE 16384
  19. //#define TIME_FILEIO // define this macro to do timing of ole32.dll internal file io
  20. // requires special ole32.dll
  21. #ifdef TIME_FILEIO
  22. #include <extimeio.hxx>
  23. #endif
  24. TCHAR *CStorageTest::Name ()
  25. {
  26. return TEXT("StorageTest");
  27. }
  28. SCODE CStorageTest::Setup (CTestInput *pInput)
  29. {
  30. SCODE sc;
  31. TCHAR pszValue[16];
  32. ULONG i;
  33. CTestBase::Setup(pInput);
  34. // get iteration count
  35. m_ulIterations = pInput->GetIterations(Name());
  36. sc = InitCOM();
  37. if (FAILED(sc))
  38. {
  39. Log (TEXT("Setup - CoInitialize failed."), sc);
  40. return sc;
  41. }
  42. // get malloc interface for this task
  43. m_piMalloc = NULL;
  44. sc = CoGetMalloc(MEMCTX_TASK, &m_piMalloc);
  45. if (FAILED(sc))
  46. {
  47. Log (TEXT("Setup - CoGetMalloc"), sc);
  48. Cleanup();
  49. return sc;
  50. }
  51. // get values of various paremeters from ini file
  52. m_iStartSize = pInput->GetConfigInt(Name(), TEXT("StartSize"), 16);
  53. if(m_iStartSize <= 0)
  54. m_iStartSize = 16;
  55. m_iEndSize = pInput->GetConfigInt(Name(), TEXT("EndSize"), DEF_DATASIZE);
  56. // initialize array to be written to the file.
  57. m_pbData = (BYTE *)m_piMalloc->Alloc(m_iEndSize);
  58. if(m_pbData == NULL)
  59. {
  60. Log (TEXT("Setup - Cannot allocate memory"), E_OUTOFMEMORY);
  61. Cleanup();
  62. return E_OUTOFMEMORY;
  63. }
  64. for (i=0; i < m_iEndSize; i++)
  65. m_pbData[i] = (BYTE)i;
  66. m_iRepeatFactor = pInput->GetConfigInt(Name(), TEXT("RepeatFactor"), 1);
  67. if (m_iRepeatFactor > MAX_REPS)
  68. m_iRepeatFactor = MAX_REPS;
  69. // Figure out how many different sizes we're going to write.
  70. // and the size of the final file.
  71. m_ulTotalSize = 0;
  72. for(m_ulNumSizes = 0, i = m_iStartSize; i <= m_iEndSize; i *=2, m_ulNumSizes++)
  73. m_ulTotalSize += i * m_iRepeatFactor;
  74. if (m_iRepeatFactor * m_ulNumSizes > MAX_READS)
  75. {
  76. Log(TEXT("Too many different sizes and/or repeat factor is too big"), E_FAIL);
  77. Cleanup();
  78. return E_FAIL;
  79. }
  80. m_flStgCreateFlags = 0;
  81. // get file name to be used and values of other parameters
  82. pInput->GetConfigString(Name(), TEXT("FileName"), TEXT("stgtest.bm"),
  83. m_pszFile, MAX_PATH);
  84. #ifdef UNICODE
  85. wcscpy(m_pwszFile, m_pszFile);
  86. #else
  87. mbstowcs(m_pwszFile, m_pszFile, strlen(m_pszFile)+1);
  88. #endif
  89. pInput->GetConfigString(Name(), TEXT("FileMode"), TEXT("DIRECT"),
  90. m_pszFileMode, 15);
  91. if(lstrcmpi(m_pszFileMode, TEXT("DIRECT")) == 0)
  92. m_flStgCreateFlags |= STGM_DIRECT;
  93. else
  94. m_flStgCreateFlags |= STGM_TRANSACTED;
  95. pInput->GetConfigString(Name(), TEXT("SetSize"), TEXT("OFF"), pszValue, 15);
  96. if (lstrcmpi(pszValue, TEXT("ON")) == 0)
  97. m_bDoSetSize = TRUE;
  98. else
  99. m_bDoSetSize = FALSE;
  100. pInput->GetConfigString(Name(), TEXT("ReadMode"), TEXT("SEQUENTIAL"),
  101. m_pszReadMode, 15);
  102. if(lstrcmpi(m_pszReadMode, TEXT("SEQUENTIAL")) == 0)
  103. m_bSequentialRead = TRUE;
  104. else
  105. m_bSequentialRead = FALSE;
  106. InitTimings();
  107. return S_OK;
  108. }
  109. void CStorageTest::InitTimings()
  110. {
  111. ULONG i;
  112. // initialize timing arrays
  113. INIT_RESULTS(m_ulIsStorageFileYES);
  114. INIT_RESULTS(m_ulIsStorageFileNO);
  115. INIT_RESULTS(m_ulStgOpenStorageDRFAIL);
  116. INIT_RESULTS(m_ulStgCreateDocfile);
  117. INIT_RESULTS(m_ulCreateStream);
  118. ZERO_RESULTS(m_ulSetSize);
  119. INIT_RESULTS(m_ulStreamRelease1);
  120. ZERO_RESULTS(m_ulStorageCommit);
  121. INIT_RESULTS(m_ulStorageRelease1);
  122. INIT_RESULTS(m_ulStgOpenStorage);
  123. INIT_RESULTS(m_ulOpenStream);
  124. INIT_RESULTS(m_ulStreamRelease2);
  125. INIT_RESULTS(m_ulStorageRelease2);
  126. ZERO_RESULTS(m_ulStreamWriteTotal);
  127. ZERO_RESULTS(m_ulStreamReadTotal);
  128. ZERO_RESULTS(m_ulStreamSeekTotal);
  129. for (i = 0; i < MAX_READS; i++)
  130. {
  131. INIT_RESULTS(m_ulStreamWrite[i]);
  132. INIT_RESULTS(m_ulStreamRead[i]);
  133. INIT_RESULTS(m_ulStreamSeek[i]);
  134. #ifdef TIME_FILEIO
  135. INIT_RESULTS(m_ulActualWrite[i]);
  136. INIT_RESULTS(m_ulActualRead[i]);
  137. #endif
  138. }
  139. #ifdef TIME_FILEIO
  140. INIT_RESULTS(m_ulActualFlush1);
  141. INIT_RESULTS(m_ulActualFlush2);
  142. INIT_RESULTS(m_ulActualCommitW);
  143. #endif
  144. for (i = 0; i < 2; i++ )
  145. ZERO_RESULTS(m_ulTotal[i]);
  146. }
  147. SCODE CStorageTest::Cleanup ()
  148. {
  149. // delete the file
  150. DeleteFile (m_pszFile);
  151. if(m_piMalloc)
  152. {
  153. if (m_pbData)
  154. m_piMalloc->Free(m_pbData);
  155. m_pbData = NULL;
  156. m_piMalloc->Release();
  157. m_piMalloc = NULL;
  158. }
  159. UninitCOM();
  160. return S_OK;
  161. }
  162. SCODE CStorageTest::Run ()
  163. {
  164. CStopWatch sw;
  165. HRESULT hr;
  166. LPSTORAGE piStorage;
  167. LPSTREAM piStream;
  168. ULONG cb;
  169. ULONG iIter;
  170. ULONG iSize;
  171. ULONG i, iCount;
  172. ULARGE_INTEGER li;
  173. #ifdef TIME_FILEIO
  174. ULONG ulTempTime;
  175. #endif
  176. //Create and then write to docfile in selected mode
  177. for (iIter=0; iIter<m_ulIterations; iIter++)
  178. {
  179. sw.Reset();
  180. hr = StgCreateDocfile(m_pwszFile, m_flStgCreateFlags | STGM_WRITE
  181. | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &piStorage);
  182. m_ulStgCreateDocfile[iIter] = sw.Read();
  183. Log(TEXT("StgCreateDocfile for writing"), hr);
  184. if(FAILED(hr))
  185. return hr;
  186. sw.Reset();
  187. hr = piStorage->CreateStream(L"CONTENTS", STGM_DIRECT |
  188. STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
  189. 0, 0, &piStream);
  190. m_ulCreateStream[iIter] = sw.Read();
  191. Log(TEXT("CreateStream"), hr);
  192. if (m_bDoSetSize)
  193. {
  194. ULISet32(li, m_ulTotalSize);
  195. sw.Reset();
  196. hr = piStream->SetSize(li);
  197. m_ulSetSize[iIter] = sw.Read();
  198. Log(TEXT("IStream::SetSize"), hr);
  199. }
  200. #ifdef TIME_FILEIO
  201. // reset all timings
  202. GetFlushTiming(NULL, TRUE);
  203. GetWriteTiming(NULL, TRUE);
  204. GetReadTiming(NULL, TRUE);
  205. GetSetFileTiming(NULL, TRUE);
  206. #endif
  207. iCount = 0;
  208. for ( iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  209. {
  210. for ( i = 0; i < m_iRepeatFactor; i++)
  211. {
  212. sw.Reset();
  213. hr = piStream->Write((LPVOID)m_pbData, iSize, &cb);
  214. m_ulStreamWrite[iCount][iIter] = sw.Read();
  215. m_ulStreamWriteTotal[iIter] += m_ulStreamWrite[iCount][iIter];
  216. #ifdef TIME_FILEIO
  217. GetWriteTiming(&m_ulActualWrite[iCount][iIter], TRUE);
  218. GetSetFileTiming(&ulTempTime, TRUE);
  219. m_ulActualWrite[iCount][iIter] += ulTempTime;
  220. #endif
  221. iCount++;
  222. }
  223. }
  224. Log(TEXT("IStream->Write X bytes"), hr);
  225. sw.Reset();
  226. piStream->Release();
  227. m_ulStreamRelease1[iIter] = sw.Read();
  228. if(m_flStgCreateFlags == STGM_TRANSACTED)
  229. {
  230. sw.Reset();
  231. piStorage->Commit(STGC_DEFAULT);
  232. m_ulStorageCommit[iIter] = sw.Read();
  233. }
  234. sw.Reset();
  235. piStorage->Release();
  236. m_ulStorageRelease1[iIter] = sw.Read();
  237. #ifdef TIME_FILEIO
  238. GetFlushTiming(&m_ulActualFlush1[iIter], TRUE);
  239. GetWriteTiming(&m_ulActualCommitW[iIter], TRUE);
  240. #endif
  241. m_ulTotal[0][iIter] = m_ulStgCreateDocfile[iIter] +
  242. m_ulCreateStream[iIter] +
  243. m_ulSetSize[iIter] +
  244. m_ulStreamWriteTotal[iIter] +
  245. m_ulStreamRelease1[iIter] +
  246. m_ulStorageCommit[iIter] +
  247. m_ulStorageRelease1[iIter];
  248. }
  249. // now try reading from the file.
  250. for (iIter=0; iIter<m_ulIterations; iIter++)
  251. {
  252. sw.Reset();
  253. hr = StgOpenStorage(m_pwszFile, NULL, m_flStgCreateFlags | STGM_READ
  254. | STGM_SHARE_EXCLUSIVE, NULL, 0, &piStorage);
  255. m_ulStgOpenStorage[iIter] = sw.Read();
  256. Log(TEXT("StgOpenStorage for reading"), hr);
  257. sw.Reset();
  258. hr = piStorage->OpenStream(L"CONTENTS", NULL, STGM_DIRECT | STGM_READ
  259. | STGM_SHARE_EXCLUSIVE, 0, &piStream);
  260. m_ulOpenStream[iIter] = sw.Read();
  261. Log(TEXT("IStorage->OpenStream"), hr);
  262. #ifdef TIME_FILEIO
  263. GetReadTiming(NULL, TRUE);
  264. GetSetFileTiming(NULL, TRUE);
  265. #endif
  266. iCount = 0;
  267. if (m_bSequentialRead)
  268. {
  269. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  270. {
  271. for (i = 0; i < m_iRepeatFactor; i++)
  272. {
  273. sw.Reset();
  274. hr = piStream->Read((LPVOID)m_pbData, iSize, &cb);
  275. m_ulStreamRead[iCount][iIter] = sw.Read();
  276. m_ulStreamReadTotal[iIter] += m_ulStreamRead[iCount][iIter];
  277. #ifdef TIME_FILEIO
  278. GetReadTiming(&m_ulActualRead[iCount][iIter], TRUE);
  279. GetSetFileTiming(&ulTempTime, TRUE);
  280. m_ulActualRead[iCount][iIter] += ulTempTime;
  281. #endif
  282. iCount++;
  283. }
  284. }
  285. Log(TEXT("IStorage->Read Sequential"), hr);
  286. }
  287. else
  288. {
  289. LARGE_INTEGER liSeekSize;
  290. ULONG cbCurOffset = m_ulTotalSize;
  291. iCount = 0;
  292. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  293. {
  294. for ( i =0; i< m_iRepeatFactor; i++)
  295. {
  296. cbCurOffset -= iSize;
  297. LISet32(liSeekSize, cbCurOffset);
  298. sw.Reset();
  299. hr = piStream->Seek(liSeekSize, STREAM_SEEK_SET, NULL);
  300. m_ulStreamSeek[iCount][iIter] = sw.Read();
  301. m_ulStreamSeekTotal[iIter] += m_ulStreamSeek[iCount][iIter];
  302. sw.Reset();
  303. hr = piStream->Read((LPVOID)m_pbData, iSize, &cb);
  304. m_ulStreamRead[iCount][iIter] = sw.Read();
  305. m_ulStreamReadTotal[iIter] += m_ulStreamRead[i][iIter];
  306. #ifdef TIME_FILEIO
  307. GetReadTiming(&m_ulActualRead[iCount][iIter], TRUE);
  308. GetSetFileTiming(&ulTempTime, TRUE);
  309. m_ulActualRead[iCount][iIter] += ulTempTime;
  310. #endif
  311. iCount++;
  312. }
  313. }
  314. Log(TEXT("IStorage->Read Random"), hr);
  315. }
  316. sw.Reset();
  317. piStream->Release();
  318. m_ulStreamRelease2[iIter] = sw.Read();
  319. sw.Reset();
  320. piStorage->Release();
  321. m_ulStorageRelease2[iIter] = sw.Read();
  322. #ifdef TIME_FILEIO
  323. GetFlushTiming(&m_ulActualFlush2[iIter], TRUE);
  324. #endif
  325. m_ulTotal[1][iIter] = m_ulStgOpenStorage[iIter] +
  326. m_ulOpenStream[iIter] +
  327. m_ulStreamSeekTotal[iIter] +
  328. m_ulStreamReadTotal[iIter] +
  329. m_ulStreamRelease2[iIter] +
  330. m_ulStorageRelease2[iIter];
  331. }
  332. // test if its a storage file (should be yes).
  333. for (iIter=0; iIter<m_ulIterations; iIter++)
  334. {
  335. sw.Reset();
  336. hr = StgIsStorageFile(m_pwszFile);
  337. m_ulIsStorageFileYES[iIter] = sw.Read();
  338. Log(TEXT("StgIsStorageFile on storage file"), hr);
  339. }
  340. // create a non-storage file and check if it is storage file
  341. HANDLE hFile = CreateFile(m_pszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL,
  342. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  343. if (hFile == INVALID_HANDLE_VALUE)
  344. {
  345. Log(TEXT("Creation of non storage file"), E_FAIL);
  346. return E_FAIL;
  347. }
  348. WriteFile(hFile, (LPSTR)m_pbData, m_iEndSize, &cb, NULL);
  349. CloseHandle(hFile);
  350. for (iIter=0; iIter<m_ulIterations; iIter++)
  351. {
  352. LPSTORAGE piStorage;
  353. sw.Reset();
  354. hr = StgIsStorageFile(m_pwszFile);
  355. m_ulIsStorageFileNO[iIter] = sw.Read();
  356. Log(TEXT("StgIsStorageFile on Non-storage file"),
  357. (hr != S_OK) ? S_OK : E_FAIL);
  358. sw.Reset();
  359. hr =StgOpenStorage(m_pwszFile, NULL, STGM_DIRECT | STGM_READ
  360. | STGM_SHARE_EXCLUSIVE, NULL, 0, &piStorage);
  361. m_ulStgOpenStorageDRFAIL[iIter] = sw.Read();
  362. Log(TEXT("StgOpenStorage on Non-storage file"),
  363. (hr != S_OK) ? S_OK : E_FAIL);
  364. }
  365. return S_OK;
  366. }
  367. SCODE CStorageTest::Report (CTestOutput &output)
  368. {
  369. TCHAR pszBuf[80];
  370. ULONG i, iSize, iCount;
  371. #ifdef TIME_FILEIO
  372. ULONG ulActualTotal[TEST_MAX_ITERATIONS];
  373. #endif
  374. wsprintf(pszBuf, TEXT("Storage Test in %s Mode with %s Read/Writes"),
  375. m_pszFileMode, m_pszReadMode);
  376. output.WriteSectionHeader (Name(), pszBuf, *m_pInput);
  377. wsprintf(pszBuf, TEXT("SetSize is %s\n\n"), m_bDoSetSize ? TEXT("ON") : TEXT("OFF"));
  378. output.WriteString (pszBuf);
  379. output.WriteResults (TEXT("IsStorageFile - YES"), m_ulIterations,
  380. m_ulIsStorageFileYES);
  381. output.WriteResults (TEXT("IsStorageFile - NO "), m_ulIterations,
  382. m_ulIsStorageFileNO);
  383. output.WriteResults (TEXT("StgOpenStorage D/R/FAIL"), m_ulIterations,
  384. m_ulStgOpenStorageDRFAIL);
  385. output.WriteString (TEXT("\n"));
  386. output.WriteResults (TEXT("StgCreateDocfile "), m_ulIterations,
  387. m_ulStgCreateDocfile);
  388. output.WriteResults (TEXT("CreateStream "), m_ulIterations,
  389. m_ulCreateStream);
  390. output.WriteString (TEXT("\n"));
  391. if (m_bDoSetSize)
  392. output.WriteResults (TEXT("Stream SetSize "), m_ulIterations,
  393. m_ulSetSize);
  394. #ifdef TIME_FILEIO
  395. ZERO_RESULTS(ulActualTotal);
  396. #endif
  397. iCount = 0;
  398. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  399. {
  400. for (i = 0; i < m_iRepeatFactor; i++)
  401. {
  402. wsprintf(pszBuf, TEXT("StreamWrite %-9d"), iSize);
  403. output.WriteResults (pszBuf, m_ulIterations, m_ulStreamWrite[iCount]);
  404. #ifdef TIME_FILEIO
  405. output.WriteResults (TEXT("Disk-hit time "), m_ulIterations, m_ulActualWrite[iCount]);
  406. for ( ULONG xx = 0; xx < m_ulIterations; xx++)
  407. ulActualTotal[xx] += m_ulActualWrite[iCount][xx];
  408. #endif
  409. iCount++;
  410. }
  411. }
  412. output.WriteResults (TEXT("StreamWrite Total "), m_ulIterations,
  413. m_ulStreamWriteTotal);
  414. #ifdef TIME_FILEIO
  415. output.WriteResults (TEXT("Actual Write Total "), m_ulIterations,
  416. ulActualTotal);
  417. #endif
  418. output.WriteString (TEXT("\n"));
  419. output.WriteResults (TEXT("StreamRelease "), m_ulIterations,
  420. m_ulStreamRelease1);
  421. if (m_flStgCreateFlags == STGM_TRANSACTED)
  422. {
  423. output.WriteResults (TEXT("StorageCommit "), m_ulIterations,
  424. m_ulStorageCommit);
  425. #ifdef TIME_FILEIO
  426. output.WriteResults (TEXT("Disk hit time "), m_ulIterations,
  427. m_ulActualCommitW);
  428. #endif
  429. }
  430. output.WriteResults (TEXT("StorageRelease "), m_ulIterations,
  431. m_ulStorageRelease1);
  432. #ifdef TIME_FILEIO
  433. output.WriteResults (TEXT("Actual Flush time "), m_ulIterations,
  434. m_ulActualFlush1);
  435. #endif
  436. output.WriteResults (TEXT("Total "), m_ulIterations,
  437. m_ulTotal[0]);
  438. output.WriteString (TEXT("\n\n"));
  439. output.WriteResults (TEXT("StgOpenStorage "), m_ulIterations,
  440. m_ulStgOpenStorage);
  441. output.WriteResults (TEXT("OpenStream "), m_ulIterations,
  442. m_ulOpenStream);
  443. output.WriteString (TEXT("\n"));
  444. #ifdef TIME_FILEIO
  445. ZERO_RESULTS(ulActualTotal);
  446. #endif
  447. iCount = 0;
  448. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  449. {
  450. for (i = 0; i < m_iRepeatFactor; i++)
  451. {
  452. if (!m_bSequentialRead)
  453. {
  454. wsprintf(pszBuf, TEXT("StreamSeek %-9d"), m_iEndSize - iSize);
  455. output.WriteResults (pszBuf, m_ulIterations, m_ulStreamSeek[iCount]);
  456. }
  457. wsprintf(pszBuf, TEXT("StreamRead %-9d"), iSize);
  458. output.WriteResults (pszBuf, m_ulIterations, m_ulStreamRead[iCount]);
  459. #ifdef TIME_FILEIO
  460. output.WriteResults (TEXT("Disk-hit time "), m_ulIterations, m_ulActualRead[iCount]);
  461. for ( ULONG xx = 0; xx < m_ulIterations; xx++)
  462. ulActualTotal[xx] += m_ulActualRead[iCount][xx];
  463. #endif
  464. iCount++;
  465. }
  466. }
  467. if (!m_bSequentialRead)
  468. output.WriteResults (TEXT("StreamSeek Total "), m_ulIterations,
  469. m_ulStreamSeekTotal);
  470. output.WriteResults (TEXT("StreamRead Total "), m_ulIterations,
  471. m_ulStreamReadTotal);
  472. #ifdef TIME_FILEIO
  473. output.WriteResults (TEXT("Actual Read Total "), m_ulIterations,
  474. ulActualTotal);
  475. #endif
  476. output.WriteString (TEXT("\n"));
  477. output.WriteResults (TEXT("StreamRelease "), m_ulIterations,
  478. m_ulStreamRelease2);
  479. output.WriteResults (TEXT("StorageRelease "), m_ulIterations,
  480. m_ulStorageRelease2);
  481. #ifdef TIME_FILEIO
  482. output.WriteResults (TEXT("Actual Flush time "), m_ulIterations,
  483. m_ulActualFlush2);
  484. #endif
  485. output.WriteResults (TEXT("Total "), m_ulIterations,
  486. m_ulTotal[1]);
  487. output.WriteString (TEXT("\n"));
  488. return S_OK;
  489. }