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.

690 lines
17 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994.
  5. //
  6. // File: bm_filio.cxx
  7. //
  8. // Contents: Basic File IO test
  9. //
  10. // Classes: CFileIOTest
  11. //
  12. // History: 04-Aug-94 t-vadims Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <headers.cxx>
  16. #pragma hdrstop
  17. #include <bm_filio.hxx>
  18. #include <memory.h>
  19. #define DEF_DATASIZE 16384
  20. TCHAR *CFileIOTest::Name ()
  21. {
  22. return TEXT("FileIOTest");
  23. }
  24. SCODE CFileIOTest::Setup (CTestInput *pInput)
  25. {
  26. SCODE sc;
  27. TCHAR pszValue[16];
  28. ULONG i;
  29. CTestBase::Setup(pInput);
  30. // get iteration count
  31. m_ulIterations = pInput->GetIterations(Name());
  32. sc = InitCOM();
  33. if (FAILED(sc))
  34. {
  35. Log (TEXT("Setup - CoInitialize failed."), sc);
  36. return sc;
  37. }
  38. // get malloc interface for this task
  39. m_piMalloc = NULL;
  40. sc = CoGetMalloc(MEMCTX_TASK, &m_piMalloc);
  41. if (FAILED(sc))
  42. {
  43. Log (TEXT("Setup - CoGetMalloc"), sc);
  44. Cleanup();
  45. return sc;
  46. }
  47. // get values of various paremeters from ini file
  48. m_iStartSize = pInput->GetConfigInt(Name(), TEXT("StartSize"), 16);
  49. if(m_iStartSize <= 0)
  50. m_iStartSize = 16;
  51. m_iEndSize = pInput->GetConfigInt(Name(), TEXT("EndSize"), DEF_DATASIZE);
  52. // initialize array to be written to the file.
  53. m_pbData = (BYTE *)m_piMalloc->Alloc(m_iEndSize);
  54. if(m_pbData == NULL)
  55. {
  56. Log (TEXT("Setup - Cannot allocate memory"), E_OUTOFMEMORY);
  57. Cleanup();
  58. return E_OUTOFMEMORY;
  59. }
  60. for (i=0; i < m_iEndSize; i++)
  61. m_pbData[i] = (BYTE)i;
  62. m_iRepeatFactor = pInput->GetConfigInt(Name(), TEXT("RepeatFactor"), 1);
  63. if (m_iRepeatFactor > MAX_REPS)
  64. m_iRepeatFactor = MAX_REPS;
  65. // Figure out how many different sizes we're going to write.
  66. // and the size of the final file.
  67. m_ulTotalSize = 0;
  68. for(m_ulNumSizes = 0, i = m_iStartSize; i <= m_iEndSize; i *=2, m_ulNumSizes++)
  69. m_ulTotalSize += i * m_iRepeatFactor;
  70. if (m_iRepeatFactor * m_ulNumSizes > MAX_READS)
  71. {
  72. Log(TEXT("Too many different sizes and/or repeat factor is too big"), E_FAIL);
  73. Cleanup();
  74. return E_FAIL;
  75. }
  76. m_flStandardCreateFlags = 0;
  77. // get file name to be used and values of other parameters
  78. pInput->GetConfigString(Name(), TEXT("FileName"), TEXT("stgtest.bm"),
  79. m_pszFile, MAX_PATH);
  80. pInput->GetConfigString(Name(), TEXT("WriteThrough"), TEXT("OFF"), pszValue, 15);
  81. if (lstrcmpi(pszValue, TEXT("ON")) == 0)
  82. m_flStandardCreateFlags |= FILE_FLAG_WRITE_THROUGH;
  83. pInput->GetConfigString(Name(), TEXT("AccessMode"), TEXT("NORMAL"), m_pszAccessMode, 15);
  84. if (lstrcmpi(m_pszAccessMode, TEXT("ASYNC")) == 0)
  85. {
  86. m_flAccessMode = AM_ASYNC;
  87. m_flStandardCreateFlags |= FILE_FLAG_OVERLAPPED;
  88. }
  89. else if (lstrcmpi(m_pszAccessMode, TEXT("MAPPED")) == 0)
  90. {
  91. m_flAccessMode = AM_MAPPED;
  92. }
  93. else
  94. m_flAccessMode = AM_NORMAL;
  95. pInput->GetConfigString(Name(), TEXT("Flush"), TEXT("OFF"), pszValue, 15);
  96. if (lstrcmpi(pszValue, TEXT("ON")) == 0)
  97. m_bFlush = TRUE;
  98. else
  99. m_bFlush = 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 CFileIOTest::InitTimings()
  110. {
  111. ULONG i;
  112. // initialize timing arrays
  113. INIT_RESULTS(m_ulOpenFileW);
  114. INIT_RESULTS(m_ulClose1);
  115. INIT_RESULTS(m_ulOpenFileR);
  116. INIT_RESULTS(m_ulClose2);
  117. ZERO_RESULTS(m_ulWriteTotal);
  118. ZERO_RESULTS(m_ulReadTotal);
  119. ZERO_RESULTS(m_ulSeekTotal);
  120. INIT_RESULTS(m_ulCreateFileMappingW);
  121. INIT_RESULTS(m_ulMapViewW);
  122. INIT_RESULTS(m_ulCloseMap1);
  123. INIT_RESULTS(m_ulUnmapView1);
  124. ZERO_RESULTS(m_ulFlush1);
  125. INIT_RESULTS(m_ulCreateFileMappingR);
  126. INIT_RESULTS(m_ulMapViewR);
  127. INIT_RESULTS(m_ulCloseMap2);
  128. INIT_RESULTS(m_ulUnmapView2);
  129. ZERO_RESULTS(m_ulFlush2);
  130. for (i = 0; i < MAX_READS; i++)
  131. {
  132. INIT_RESULTS(m_ulWrite[i]);
  133. INIT_RESULTS(m_ulRead[i]);
  134. INIT_RESULTS(m_ulSeek[i]);
  135. }
  136. for (i = 0; i < 2; i++ )
  137. ZERO_RESULTS(m_ulTotal[i]);
  138. }
  139. SCODE CFileIOTest::Cleanup ()
  140. {
  141. // delete the file
  142. DeleteFile (m_pszFile);
  143. if(m_piMalloc)
  144. {
  145. if (m_pbData)
  146. m_piMalloc->Free(m_pbData);
  147. m_pbData = NULL;
  148. m_piMalloc->Release();
  149. m_piMalloc = NULL;
  150. }
  151. UninitCOM();
  152. return S_OK;
  153. }
  154. SCODE CFileIOTest::Run ()
  155. {
  156. CStopWatch sw;
  157. ULONG iIter;
  158. HANDLE hFile;
  159. ULONG cb;
  160. ULONG iSize;
  161. ULONG i, iCount;
  162. ULONG cbCurOffset;
  163. // Async mode variables
  164. OVERLAPPED ov;
  165. LPOVERLAPPED lpov;
  166. BOOL fRes;
  167. // file-mapped mode variables
  168. LPBYTE lpbFileData;
  169. HANDLE hMap;
  170. ov.Offset = 0;
  171. ov.OffsetHigh = 0;
  172. ov.hEvent = NULL;
  173. if (IsAsyncMode())
  174. lpov = &ov;
  175. else
  176. lpov = NULL;
  177. // create normal file and write some data to it
  178. for (iIter = 0; iIter < m_ulIterations; iIter++)
  179. {
  180. sw.Reset();
  181. hFile = CreateFile(m_pszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  182. m_flStandardCreateFlags | FILE_ATTRIBUTE_NORMAL, NULL);
  183. m_ulOpenFileW[iIter] = sw.Read();
  184. Log(TEXT("CreateFile for writing"),
  185. (hFile != INVALID_HANDLE_VALUE) ? S_OK : E_FAIL);
  186. if(hFile == INVALID_HANDLE_VALUE)
  187. return E_FAIL;
  188. if (IsMappedMode()) // create file mapping
  189. {
  190. sw.Reset();
  191. hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, m_ulTotalSize, NULL);
  192. m_ulCreateFileMappingW[iIter] = sw.Read();
  193. Log(TEXT("CreateFileMapping"), (hMap != NULL) ? S_OK : E_FAIL);
  194. if(hMap == NULL)
  195. {
  196. TCHAR szBuf[80];
  197. wsprintf(szBuf, TEXT("GetLastError = %ld , FileSize = %ld"), GetLastError(), m_ulTotalSize);
  198. Log(szBuf, E_FAIL);
  199. CloseHandle(hFile);
  200. return E_FAIL;
  201. }
  202. sw.Reset();
  203. lpbFileData = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
  204. m_ulMapViewW[iIter] = sw.Read();
  205. Log(TEXT("MapViewOfFile"), (lpbFileData != NULL) ? S_OK : E_FAIL);
  206. if(lpbFileData == NULL)
  207. {
  208. TCHAR szBuf[80];
  209. wsprintf(szBuf, TEXT("GetLastError = %ld"), GetLastError());
  210. Log(szBuf, E_FAIL);
  211. CloseHandle(hMap);
  212. CloseHandle(hFile);
  213. return E_FAIL;
  214. }
  215. }
  216. cbCurOffset = 0;
  217. iCount = 0;
  218. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  219. {
  220. for (i = 0; i < m_iRepeatFactor; i++)
  221. {
  222. if (IsMappedMode())
  223. {
  224. sw.Reset();
  225. memcpy(lpbFileData + cbCurOffset, m_pbData, iSize);
  226. m_ulWrite[iCount][iIter] = sw.Read();
  227. cb = iSize; // force correct cb for error check
  228. }
  229. else
  230. {
  231. ov.Offset = cbCurOffset;
  232. sw.Reset();
  233. fRes = WriteFile(hFile, (LPSTR)m_pbData, iSize, &cb, lpov);
  234. m_ulWrite[iCount][iIter] = sw.Read();
  235. }
  236. m_ulWriteTotal[iIter] += m_ulWrite[iCount][iIter];
  237. if (IsAsyncMode()) // if in async mode wait for result
  238. {
  239. if(!fRes)
  240. {
  241. Log(TEXT("Doing Actual Async call"), S_OK);
  242. GetOverlappedResult(hFile, lpov, &cb, TRUE);
  243. }
  244. }
  245. Log(TEXT("Writing data"), cb == iSize ? S_OK : E_FAIL);
  246. cbCurOffset += iSize;
  247. iCount++;
  248. }
  249. }
  250. Log(TEXT("WriteFile X bytes"), S_OK );
  251. if (IsMappedMode())
  252. {
  253. if (m_bFlush)
  254. {
  255. sw.Reset();
  256. fRes = FlushViewOfFile((LPVOID) lpbFileData, 0);
  257. m_ulFlush1[iIter] = sw.Read();
  258. Log(TEXT("FlushViewOfFile"), fRes ? S_OK : E_FAIL);
  259. }
  260. sw.Reset();
  261. fRes = UnmapViewOfFile((LPVOID) lpbFileData);
  262. m_ulUnmapView1[iIter] = sw.Read();
  263. Log(TEXT("UnmapViewOfFile"), fRes ? S_OK : E_FAIL);
  264. sw.Reset();
  265. CloseHandle(hMap);
  266. m_ulCloseMap1[iIter] = sw.Read();
  267. Log(TEXT("CloseHandle of file-mapping"), S_OK);
  268. }
  269. else if (m_bFlush)
  270. {
  271. sw.Reset();
  272. fRes = FlushFileBuffers(hFile);
  273. m_ulFlush1[iIter] = sw.Read();
  274. Log(TEXT("FlushFileBuffers"), fRes ? S_OK : E_FAIL);
  275. }
  276. sw.Reset();
  277. CloseHandle(hFile);
  278. m_ulClose1[iIter] = sw.Read();
  279. m_ulTotal[0][iIter] = m_ulOpenFileW[iIter] +
  280. m_ulWriteTotal[iIter] +
  281. m_ulFlush1[iIter] +
  282. m_ulClose1[iIter];
  283. if (IsMappedMode())
  284. {
  285. m_ulTotal[0][iIter] += m_ulCreateFileMappingW[iIter] +
  286. m_ulMapViewW[iIter] +
  287. m_ulUnmapView1[iIter] +
  288. m_ulCloseMap1[iIter];
  289. }
  290. }
  291. // try to read from that file
  292. for (iIter = 0; iIter < m_ulIterations; iIter++)
  293. {
  294. sw.Reset();
  295. hFile = CreateFile(m_pszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  296. m_flStandardCreateFlags | FILE_ATTRIBUTE_NORMAL, NULL);
  297. m_ulOpenFileR[iIter] = sw.Read();
  298. Log(TEXT("CreateFile for reading"),
  299. (hFile != INVALID_HANDLE_VALUE) ? S_OK : E_FAIL);
  300. if(hFile == INVALID_HANDLE_VALUE)
  301. return E_FAIL;
  302. if (IsMappedMode()) // create file mapping
  303. {
  304. sw.Reset();
  305. hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  306. m_ulCreateFileMappingR[iIter] = sw.Read();
  307. Log(TEXT("CreateFileMapping"), (hMap != NULL) ? S_OK : E_FAIL);
  308. if(hMap == NULL)
  309. {
  310. CloseHandle(hFile);
  311. return E_FAIL;
  312. }
  313. sw.Reset();
  314. lpbFileData = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
  315. m_ulMapViewR[iIter] = sw.Read();
  316. Log(TEXT("MapViewOfFile"), (lpbFileData != NULL) ? S_OK : E_FAIL);
  317. if(lpbFileData == NULL)
  318. {
  319. CloseHandle(hMap);
  320. CloseHandle(hFile);
  321. return E_FAIL;
  322. }
  323. }
  324. cbCurOffset = 0;
  325. iCount = 0;
  326. if (m_bSequentialRead)
  327. {
  328. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  329. {
  330. for (i =0; i < m_iRepeatFactor; i++)
  331. {
  332. if (IsMappedMode())
  333. {
  334. sw.Reset();
  335. memcpy(m_pbData, lpbFileData + cbCurOffset, iSize);
  336. m_ulRead[iCount][iIter] = sw.Read();
  337. cb = iSize; // force correct cb for error check
  338. }
  339. else
  340. {
  341. ov.Offset = cbCurOffset;
  342. sw.Reset();
  343. fRes = ReadFile(hFile, (LPSTR)m_pbData, iSize, &cb, lpov);
  344. m_ulRead[iCount][iIter] = sw.Read();
  345. }
  346. m_ulReadTotal[iIter] += m_ulRead[iCount][iIter];
  347. if (IsAsyncMode()) // in async mode wait for result
  348. {
  349. if(!fRes)
  350. {
  351. Log(TEXT("Doing Actual Async call"), S_OK);
  352. GetOverlappedResult(hFile, lpov, &cb, TRUE);
  353. }
  354. }
  355. Log(TEXT("Reading data"), cb == iSize ? S_OK : E_FAIL);
  356. cbCurOffset += iSize;
  357. iCount++;
  358. }
  359. }
  360. Log(TEXT("ReadFile Sequential"), S_OK);
  361. }
  362. else
  363. {
  364. cbCurOffset = m_ulTotalSize;
  365. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  366. {
  367. for ( i =0; i< m_iRepeatFactor; i++)
  368. {
  369. cbCurOffset -= iSize;
  370. ov.Offset = cbCurOffset;
  371. if (IsNormalMode())
  372. {
  373. sw.Reset();
  374. SetFilePointer(hFile, cbCurOffset, NULL, FILE_BEGIN);
  375. m_ulSeek[iCount][iIter] = sw.Read();
  376. m_ulSeekTotal[iIter] += m_ulSeek[iCount][iIter];
  377. }
  378. if (IsMappedMode())
  379. {
  380. sw.Reset();
  381. memcpy(m_pbData, lpbFileData + cbCurOffset, iSize);
  382. m_ulRead[iCount][iIter] = sw.Read();
  383. cb = iSize; // force correct cb for error check.
  384. }
  385. else
  386. {
  387. sw.Reset();
  388. fRes = ReadFile(hFile, (LPSTR)m_pbData, iSize, &cb, lpov);
  389. m_ulRead[iCount][iIter] = sw.Read();
  390. }
  391. m_ulReadTotal[iIter] = m_ulRead[iCount][iIter];
  392. if (IsAsyncMode())
  393. {
  394. if(!fRes)
  395. {
  396. Log(TEXT("Doing Actual Async call"), S_OK);
  397. GetOverlappedResult(hFile, lpov, &cb, TRUE);
  398. }
  399. }
  400. Log(TEXT("Reading data"), cb == iSize ? S_OK : E_FAIL);
  401. iCount++;
  402. }
  403. }
  404. Log(TEXT("ReadFile Random"), S_OK);
  405. }
  406. if (IsMappedMode())
  407. {
  408. if (m_bFlush)
  409. {
  410. sw.Reset();
  411. fRes = FlushViewOfFile((LPVOID) lpbFileData, 0);
  412. m_ulFlush2[iIter] = sw.Read();
  413. Log(TEXT("FlushViewOfFile"), fRes ? S_OK : E_FAIL);
  414. }
  415. sw.Reset();
  416. fRes = UnmapViewOfFile((LPVOID) lpbFileData);
  417. m_ulUnmapView2[iIter] = sw.Read();
  418. Log(TEXT("UnmapViewOfFile"), fRes ? S_OK : E_FAIL);
  419. sw.Reset();
  420. CloseHandle(hMap);
  421. m_ulCloseMap2[iIter] = sw.Read();
  422. Log(TEXT("CloseHandle of file-mapping"), S_OK);
  423. }
  424. else if ( m_bFlush)
  425. {
  426. sw.Reset();
  427. fRes = FlushFileBuffers(hFile);
  428. m_ulFlush2[iIter] = sw.Read();
  429. Log(TEXT("FlushFileBuffers"), fRes ? S_OK : E_FAIL);
  430. }
  431. sw.Reset();
  432. CloseHandle(hFile);
  433. m_ulClose2[iIter] = sw.Read();
  434. Log(TEXT("CloseHandle of File"), S_OK);
  435. m_ulTotal[1][iIter] = m_ulOpenFileR[iIter] +
  436. m_ulSeekTotal[iIter] +
  437. m_ulReadTotal[iIter] +
  438. m_ulFlush2[iIter] +
  439. m_ulClose2[iIter];
  440. if (IsMappedMode())
  441. {
  442. m_ulTotal[1][iIter] += m_ulCreateFileMappingR[iIter] +
  443. m_ulMapViewR[iIter] +
  444. m_ulUnmapView2[iIter] +
  445. m_ulCloseMap2[iIter];
  446. }
  447. }
  448. return S_OK;
  449. }
  450. SCODE CFileIOTest::Report (CTestOutput &output)
  451. {
  452. TCHAR pszBuf[80];
  453. ULONG i, iSize, iCount;
  454. wsprintf(pszBuf, TEXT("File IO in %s Mode with %s Read/Writes"),
  455. m_pszAccessMode, m_pszReadMode);
  456. output.WriteSectionHeader (Name(), pszBuf, *m_pInput);
  457. wsprintf(pszBuf, TEXT("WriteThrough is %s\n"),
  458. (m_flStandardCreateFlags & FILE_FLAG_WRITE_THROUGH) ? TEXT("ON") : TEXT("OFF"));
  459. output.WriteString (pszBuf);
  460. wsprintf(pszBuf, TEXT("Flush is %s\n\n"), m_bFlush ? TEXT("ON") : TEXT("OFF"));
  461. output.WriteString (pszBuf);
  462. output.WriteResults (TEXT("CreateFile WRITE "), m_ulIterations,
  463. m_ulOpenFileW);
  464. if (IsMappedMode())
  465. {
  466. output.WriteResults(TEXT("CreateFileMapping"), m_ulIterations,
  467. m_ulCreateFileMappingW);
  468. output.WriteResults(TEXT("MapViewOfFile "), m_ulIterations,
  469. m_ulMapViewW);
  470. }
  471. output.WriteString (TEXT("\n"));
  472. iCount = 0;
  473. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  474. {
  475. for (i = 0; i < m_iRepeatFactor; i++)
  476. {
  477. wsprintf(pszBuf, TEXT("WriteFile %-9d"), iSize);
  478. output.WriteResults (pszBuf, m_ulIterations, m_ulWrite[iCount]);
  479. iCount++;
  480. }
  481. }
  482. output.WriteResults (TEXT("Write Total "), m_ulIterations, m_ulWriteTotal);
  483. output.WriteString (TEXT("\n"));
  484. if (IsMappedMode())
  485. {
  486. if (m_bFlush)
  487. output.WriteResults(TEXT("FlushViewOfFile "), m_ulIterations,
  488. m_ulFlush1);
  489. output.WriteResults(TEXT("UnmapViewOfFile "), m_ulIterations,
  490. m_ulUnmapView1);
  491. output.WriteResults(TEXT("CloseMapping "), m_ulIterations,
  492. m_ulCloseMap1);
  493. }
  494. else if (m_bFlush)
  495. output.WriteResults(TEXT("FlushFileBuffers "), m_ulIterations,
  496. m_ulFlush1);
  497. output.WriteResults (TEXT("CloseHandle "), m_ulIterations,
  498. m_ulClose1);
  499. output.WriteResults (TEXT("Total "), m_ulIterations,
  500. m_ulTotal[0]);
  501. output.WriteString (TEXT("\n\n"));
  502. output.WriteResults (TEXT("CreateFile READ "), m_ulIterations,
  503. m_ulOpenFileR);
  504. if (IsMappedMode())
  505. {
  506. output.WriteResults(TEXT("CreateFileMapping"), m_ulIterations,
  507. m_ulCreateFileMappingR);
  508. output.WriteResults(TEXT("MapViewOfFile "), m_ulIterations,
  509. m_ulMapViewR);
  510. }
  511. output.WriteString (TEXT("\n"));
  512. iCount =0;
  513. for (iSize = m_iStartSize ; iSize <= m_iEndSize ; iSize *= 2)
  514. {
  515. for (i=0; i < m_iRepeatFactor; i++)
  516. {
  517. if (!m_bSequentialRead && IsNormalMode())
  518. {
  519. wsprintf(pszBuf, TEXT("SetFilePosition %-9d"), m_iEndSize - iSize);
  520. output.WriteResults (pszBuf, m_ulIterations, m_ulSeek[iCount]);
  521. }
  522. wsprintf(pszBuf, TEXT("ReadFile %-9d"), iSize);
  523. output.WriteResults (pszBuf, m_ulIterations, m_ulRead[iCount]);
  524. iCount++;
  525. }
  526. }
  527. if (!m_bSequentialRead && IsNormalMode())
  528. output.WriteResults (TEXT("Seek Total "), m_ulIterations, m_ulSeekTotal);
  529. output.WriteResults (TEXT("Read Total "), m_ulIterations, m_ulReadTotal);
  530. output.WriteString (TEXT("\n"));
  531. if (IsMappedMode())
  532. {
  533. if (m_bFlush)
  534. output.WriteResults(TEXT("FlushViewOfFile "), m_ulIterations,
  535. m_ulFlush2);
  536. output.WriteResults(TEXT("UnmapViewOfFile "), m_ulIterations,
  537. m_ulUnmapView2);
  538. output.WriteResults(TEXT("CloseMapping "), m_ulIterations,
  539. m_ulCloseMap2);
  540. }
  541. else if ( m_bFlush)
  542. output.WriteResults(TEXT("FlushFileBuffers "), m_ulIterations,
  543. m_ulFlush2);
  544. output.WriteResults (TEXT("CloseHandle "), m_ulIterations,
  545. m_ulClose2);
  546. output.WriteResults (TEXT("Total "), m_ulIterations,
  547. m_ulTotal[1]);
  548. output.WriteString (TEXT("\n"));
  549. return S_OK;
  550. }