Source code of Windows XP (NT5)
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.

891 lines
21 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 2000
  6. //
  7. // File: filedata.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // FileData.cpp: implementation of the CFileData class.
  11. //
  12. //////////////////////////////////////////////////////////////////////
  13. #ifndef NO_STRICT
  14. #ifndef STRICT
  15. #define STRICT 1
  16. #endif
  17. #endif /* NO_STRICT */
  18. #include <WINDOWS.H>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <wtypes.h>
  23. #include <winnt.h>
  24. #include <time.h>
  25. #include "FileData.h"
  26. #include "Globals.h"
  27. #include "Version.h"
  28. #include "Processes.h"
  29. #include "ProcessInfo.h"
  30. #include "Modules.h"
  31. #include "UtilityFunctions.h"
  32. //////////////////////////////////////////////////////////////////////
  33. // Construction/Destruction
  34. //////////////////////////////////////////////////////////////////////
  35. CFileData::CFileData()
  36. {
  37. m_dwGetLastError = 0;
  38. m_hFileHandle = INVALID_HANDLE_VALUE;
  39. m_tszFilePath = NULL;
  40. m_szLINEBUFFER[0] = 0;
  41. m_hFileMappingObject = NULL;
  42. m_lpBaseAddress = NULL;
  43. m_lpCurrentFilePointer = NULL;
  44. m_lpCurrentLocationInLINEBUFFER = NULL;
  45. }
  46. CFileData::~CFileData()
  47. {
  48. if (m_tszFilePath)
  49. delete [] m_tszFilePath;
  50. if (m_lpBaseAddress)
  51. UnmapViewOfFile(m_lpBaseAddress);
  52. if (m_hFileMappingObject)
  53. CloseHandle(m_hFileMappingObject);
  54. }
  55. bool CFileData::SetFilePath(LPTSTR tszFilePath)
  56. {
  57. // Did we get a proper string?
  58. if (!tszFilePath)
  59. return false;
  60. if (m_tszFilePath)
  61. delete [] m_tszFilePath;
  62. m_tszFilePath = new TCHAR[(_tcsclen(tszFilePath)+1)];
  63. if (!m_tszFilePath)
  64. return false;
  65. _tcscpy(m_tszFilePath, tszFilePath);
  66. return true;
  67. }
  68. LPTSTR CFileData::GetFilePath()
  69. {
  70. return m_tszFilePath;
  71. }
  72. bool CFileData::VerifyFileDirectory()
  73. {
  74. if (!m_tszFilePath)
  75. return false;
  76. TCHAR tszDrive[_MAX_DRIVE];
  77. TCHAR tszDirectory[_MAX_DIR];
  78. TCHAR tszDirectoryPath[_MAX_PATH];
  79. // Get just the directory...
  80. _tsplitpath(m_tszFilePath, tszDrive, tszDirectory, NULL, NULL);
  81. // Now, recompose this into a directory path...
  82. _tcscpy(tszDirectoryPath, tszDrive);
  83. _tcscat(tszDirectoryPath, tszDirectory);
  84. _tcscat(tszDirectoryPath, TEXT("*.*"));
  85. WIN32_FIND_DATA FindFileData;
  86. HANDLE hDirectoryHandle = FindFirstFile(tszDirectoryPath, &FindFileData);
  87. if (hDirectoryHandle == INVALID_HANDLE_VALUE)
  88. {
  89. // Failure to find the directory...
  90. SetLastError();
  91. return false;
  92. }
  93. // Close this now that we're done...
  94. FindClose(hDirectoryHandle);
  95. return true;
  96. }
  97. /*
  98. DWORD CFileData::GetLastError()
  99. {
  100. return m_dwGetLastError;
  101. }
  102. */
  103. bool CFileData::OpenFile(DWORD dwCreateOption, bool fReadOnlyMode)
  104. {
  105. if (!m_tszFilePath)
  106. {
  107. return false;
  108. }
  109. // Open the file for read/write
  110. m_hFileHandle = CreateFile(m_tszFilePath,
  111. fReadOnlyMode ? ( GENERIC_READ )
  112. : ( GENERIC_READ | GENERIC_WRITE ),
  113. 0, // Not shareable
  114. NULL, // Default security descriptor
  115. dwCreateOption,
  116. FILE_ATTRIBUTE_NORMAL,
  117. NULL);
  118. if (m_hFileHandle == INVALID_HANDLE_VALUE)
  119. {
  120. SetLastError();
  121. return false;
  122. }
  123. return true;
  124. }
  125. bool CFileData::CloseFile()
  126. {
  127. if (m_hFileHandle == INVALID_HANDLE_VALUE)
  128. {
  129. return false;
  130. }
  131. if (!CloseHandle(m_hFileHandle))
  132. {
  133. SetLastError();
  134. return false;
  135. }
  136. m_hFileHandle = INVALID_HANDLE_VALUE;
  137. return true;
  138. }
  139. bool CFileData::WriteString(LPTSTR tszString, bool fHandleQuotes /* = false */)
  140. {
  141. DWORD dwByteCount = 0;
  142. DWORD dwBytesWritten;
  143. LPSTR szStringBuffer = NULL; // Pointer to the ANSI string (after conversion if necessary)
  144. bool fReturn = false;
  145. if (m_hFileHandle == INVALID_HANDLE_VALUE)
  146. {
  147. goto cleanup;
  148. }
  149. // We'll first convert the string if we need to...
  150. szStringBuffer = CUtilityFunctions::CopyTSTRStringToAnsi(tszString);
  151. if (!szStringBuffer)
  152. goto cleanup;
  153. dwByteCount = _tcsclen(tszString); // This is the number of characters (not bytes!)
  154. // See if we were asked to handle quotes, and if there exists a comma or quote in the string
  155. if ( fHandleQuotes == true && ((strchr(szStringBuffer, ',') || strchr(szStringBuffer, '"' ))) )
  156. {
  157. unsigned int iQuotedStringIndex = 0;
  158. unsigned int iStringBufferIndex = 0;
  159. // Special processing is required... this doesn't happen often, so this
  160. // allocation which I'm about to make won't be done regularly...
  161. LPSTR szQuotedStringBuffer = new char[1024];
  162. // Did we successfully allocate storage?
  163. if (!szQuotedStringBuffer)
  164. goto cleanup;
  165. // Keep going until we're at the end of the string...
  166. // We start by adding a quote (since we know that we have a comma or quote somewhere...
  167. szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
  168. // Keep going until the end of the string...
  169. while (szStringBuffer[iStringBufferIndex] != '\0')
  170. {
  171. // We found a quote
  172. if (szStringBuffer[iStringBufferIndex] == '"')
  173. {
  174. // We found a quote... I'll copy another quote in, and the quote already here
  175. // will ensure we have two quotes together "" which in a CSV file represents a
  176. // single quote...
  177. szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
  178. }
  179. // Copy the source char to the dest...
  180. szQuotedStringBuffer[iQuotedStringIndex++] = szStringBuffer[iStringBufferIndex++];
  181. }
  182. // Append the final quote (and \0)...
  183. szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
  184. szQuotedStringBuffer[iQuotedStringIndex++] = '\0';
  185. // Just write out the data the nice, fast way...
  186. if (!WriteFile(m_hFileHandle, szQuotedStringBuffer, strlen(szQuotedStringBuffer), &dwBytesWritten, NULL))
  187. {
  188. delete [] szQuotedStringBuffer;
  189. goto cleanup;
  190. }
  191. delete [] szQuotedStringBuffer;
  192. } else
  193. {
  194. // Just write out the data the nice, fast way...
  195. if (!WriteFile(m_hFileHandle, szStringBuffer, dwByteCount, &dwBytesWritten, NULL))
  196. {
  197. goto cleanup;
  198. }
  199. }
  200. fReturn = true;
  201. cleanup:
  202. if (szStringBuffer)
  203. delete [] szStringBuffer;
  204. return fReturn;
  205. }
  206. bool CFileData::WriteDWORD(DWORD dwNumber)
  207. {
  208. TCHAR tszBuffer[10+1]; // 0xFFFFFFFF == 4294967295 (10 characters) + 1 for the \0
  209. _stprintf(tszBuffer, TEXT("%u"), dwNumber);
  210. if (!WriteString(tszBuffer))
  211. return false;
  212. return true;
  213. }
  214. bool CFileData::WriteTimeDateString(time_t Time)
  215. {
  216. enum {BUFFERSIZE = 128};
  217. TCHAR tszBuffer[BUFFERSIZE];
  218. struct tm * localTime = localtime(&Time);
  219. if (localTime)
  220. {
  221. // This top version seems to be better Y2K friendly as I spit out the full year...
  222. _tcsftime(tszBuffer, BUFFERSIZE, TEXT("%B %d, %Y %H:%M:%S"), localTime);
  223. //_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
  224. if (!WriteString(tszBuffer, true))
  225. return false;
  226. } else
  227. { // A bad TimeDate stamp was provided
  228. if (!WriteString(TEXT("<INVALID DATE>"), true))
  229. return false;
  230. }
  231. return true;
  232. }
  233. bool CFileData::WriteFileHeader()
  234. {
  235. enum {BUFFERSIZE = 128};
  236. TCHAR tszBuffer[BUFFERSIZE];
  237. DWORD dwNum = BUFFERSIZE;
  238. // Write the Checksym version info...
  239. _stprintf(tszBuffer, TEXT("CHECKSYM, (%d.%d:%d.%d)\r\n"), VERSION_FILEVERSION);
  240. if (!WriteString(tszBuffer))
  241. return false;
  242. // Write the current date/time info...
  243. if (!WriteString(TEXT("Created:,")))
  244. return false;
  245. time_t Time;
  246. time(&Time);
  247. if (!WriteTimeDateString(Time))
  248. return false;
  249. // Write the carriage-return line-feed combo...
  250. if (!WriteString(TEXT("\r\n")))
  251. return false;
  252. // Spit out the computername
  253. if (!GetComputerName(tszBuffer, &dwNum))
  254. return false;
  255. if (!WriteString(TEXT("Computer:,")))
  256. return false;
  257. if (!WriteString(tszBuffer))
  258. return false;
  259. // Write the carriage-return line-feed combo... (a couple of times)...
  260. if (!WriteString(TEXT("\r\n")))
  261. return false;
  262. return true;
  263. }
  264. void CFileData::PrintLastError()
  265. {
  266. CUtilityFunctions::PrintMessageString(GetLastError());
  267. }
  268. bool CFileData::CreateFileMapping()
  269. {
  270. m_hFileMappingObject = ::CreateFileMapping(m_hFileHandle,
  271. NULL,
  272. PAGE_READONLY | SEC_COMMIT,
  273. 0,
  274. 0,
  275. NULL);
  276. if (m_hFileMappingObject == NULL)
  277. {
  278. SetLastError();
  279. return false;
  280. }
  281. // Okay, we'll map the view as well...
  282. m_lpBaseAddress = MapViewOfFile(m_hFileMappingObject,
  283. FILE_MAP_READ,
  284. 0,
  285. 0,
  286. 0);
  287. if (m_lpBaseAddress == NULL)
  288. {
  289. SetLastError();
  290. return false;
  291. }
  292. m_lpCurrentFilePointer = (LPSTR) m_lpBaseAddress;
  293. return true;
  294. }
  295. bool CFileData::ReadFileHeader()
  296. {
  297. // For starters, let's read a line...
  298. if (!ReadFileLine())
  299. return false;
  300. enum { BUFFER_SIZE = 128};
  301. char szTemporaryBuffer[BUFFER_SIZE];
  302. DWORD cbBytesRead;
  303. cbBytesRead = ReadString(szTemporaryBuffer, BUFFER_SIZE);
  304. // We gotta read something?
  305. if (0 == cbBytesRead)
  306. return false;
  307. // Look for our "Magic" Value
  308. if (_stricmp(szTemporaryBuffer, "CHECKSYM"))
  309. {
  310. _tprintf(TEXT("Error: Input file has invalid header. Missing CHECKSYM keyword!\n"));
  311. return false;
  312. }
  313. // Read version number
  314. // We'll do this later if needed...
  315. // Read Created Time
  316. if (!ReadFileLine())
  317. return false;
  318. // Read Computer this was created on
  319. if (!ReadFileLine())
  320. return false;
  321. return true;
  322. }
  323. bool CFileData::ReadFileLine()
  324. {
  325. // We're ansi oriented (since this is a CSV file -- in case you were wondering)
  326. size_t pos;
  327. // Find the first \r or \n character (if we're point to \0, we'll figure that out)
  328. pos = strcspn(m_lpCurrentFilePointer, "\r\n");
  329. // Hmm... we don't read a line that starts on \r\n very well...
  330. if (pos == 0)
  331. {
  332. m_szLINEBUFFER[0] = '\0';
  333. ResetBufferPointerToStart();
  334. return false;
  335. }
  336. // Read the line into our buffer
  337. strncpy(m_szLINEBUFFER, m_lpCurrentFilePointer, pos);
  338. // Null terminate for ease of use...
  339. m_szLINEBUFFER[pos] = '\0';
  340. ResetBufferPointerToStart();
  341. // Advance the current file pointer to just beyond the last character we read...
  342. // This should advance to the \r\n or \0
  343. m_lpCurrentFilePointer += pos;
  344. // We want this file pointer to advance beyond any \r \n chars we may have found...
  345. while (*m_lpCurrentFilePointer)
  346. {
  347. // Advance pointer to non- \r or \n
  348. if ( (*m_lpCurrentFilePointer == '\r') ||
  349. (*m_lpCurrentFilePointer == '\n') )
  350. {
  351. m_lpCurrentFilePointer++;
  352. }
  353. else
  354. {
  355. break; // Found either the \0 or something else...
  356. }
  357. }
  358. return true;
  359. }
  360. DWORD CFileData::ReadString(LPSTR szStringBuffer, DWORD iStringBufferSize)
  361. {
  362. // If we give a buffer size, we have to give a buffer...
  363. if ( szStringBuffer == NULL && iStringBufferSize )
  364. return 0;
  365. // The ReadFileLine() call puts us at the start of a line (after
  366. // the \r \n combinations... It's possible that we're at the
  367. // end...
  368. // If we're pointing to the end of the file, let's bail...
  369. if (*m_lpCurrentLocationInLINEBUFFER == '\0')
  370. return 0;
  371. DWORD iBytesCopied = 0;
  372. bool fFinished = false;
  373. bool fFoundSeparatorChars = false; // These might be '\r', '\n', or ','
  374. bool fQuoteMode = false;
  375. while (!fFinished)
  376. {
  377. switch (*m_lpCurrentLocationInLINEBUFFER)
  378. {
  379. case '"':
  380. // Okay, we found a quote... that's cool.. but are we quoting a quote,
  381. // or... are we in quote mode?
  382. // Probe ahead... is the next char a '"' also?
  383. if ( *(m_lpCurrentLocationInLINEBUFFER+1) == '"')
  384. {
  385. // Yes it is... so go ahead and copy the quote
  386. CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
  387. if (!fFinished)
  388. *(m_lpCurrentLocationInLINEBUFFER++); // Skip the quote
  389. }
  390. else
  391. {
  392. *(m_lpCurrentLocationInLINEBUFFER++);
  393. fQuoteMode = !fQuoteMode; // Toggle the quote mode...
  394. continue;
  395. }
  396. case '\0':
  397. fFinished = true;
  398. break;
  399. case ',':
  400. if (!fQuoteMode)
  401. { // If we're not in quote mode, then this marks the end of a field...
  402. fFinished = true;
  403. fFoundSeparatorChars = true;
  404. *(m_lpCurrentLocationInLINEBUFFER++);
  405. }
  406. else
  407. {
  408. // Okay, this marks a new character that happens to be a comma...
  409. CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
  410. }
  411. break;
  412. case '\r':
  413. case '\n':
  414. // We note that we found these, and simply advance the pointer...
  415. fFoundSeparatorChars = true;
  416. *(m_lpCurrentLocationInLINEBUFFER++);
  417. break;
  418. default:
  419. if (fFoundSeparatorChars)
  420. {
  421. // We were scanning... found a separator after some data... so we bail
  422. fFinished = true;
  423. break;
  424. }
  425. CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
  426. }
  427. }
  428. if (iStringBufferSize) // We only NULL terminate a buffer if one was provided...
  429. szStringBuffer[iBytesCopied] = '\0'; // Null terminate this puppy...
  430. return iBytesCopied;
  431. }
  432. //
  433. // This function is responsible for reading through the CSV file and creating any necessary
  434. // objects and populating them with data...
  435. //
  436. bool CFileData::DispatchCollectionObject(CProcesses ** lplpProcesses, CProcessInfo ** lplpProcess, CModules ** lplpModules, CModules ** lplpKernelModeDrivers, CModuleInfoCache * lpModuleInfoCache, CFileData * lpOutputFile)
  437. {
  438. enum { BUFFER_SIZE = 128};
  439. char szTemporaryBuffer[BUFFER_SIZE];
  440. TCHAR tszTemporaryBuffer[BUFFER_SIZE];
  441. DWORD cbBytesRead;
  442. bool fContinueReading = true;
  443. // Read the Output Type
  444. if (!ReadFileLine())
  445. return false;
  446. while (fContinueReading)
  447. {
  448. // If this is the second iteration (or more) we may not be at the
  449. // start of our buffer (causing the read of the output type to fail)
  450. ResetBufferPointerToStart();
  451. // Read the Output Type line...
  452. cbBytesRead = ReadString(szTemporaryBuffer, BUFFER_SIZE);
  453. // We gotta read something?
  454. if (0 == cbBytesRead)
  455. return true;
  456. // I hate to do this... but we read this stuff as ASCII... may need to
  457. // convert to a TCHAR format to be neutral...
  458. CUtilityFunctions::CopyAnsiStringToTSTR(szTemporaryBuffer, tszTemporaryBuffer, cbBytesRead+1);
  459. // Printout the section we're attempting to read...
  460. if (!g_lpProgramOptions->GetMode(CProgramOptions::QuietMode))
  461. _tprintf(TEXT(" Reading %s data...\n"), tszTemporaryBuffer);
  462. if ( _tcsicmp(g_tszCollectionArray[Processes].tszCSVLabel, tszTemporaryBuffer) == 0 )
  463. {
  464. /*
  465. [PROCESSES]
  466. */
  467. // Read to the end of the line
  468. if (!ReadFileLine())
  469. return false;
  470. // Yup, it is... let's create a Processes Object
  471. if (*lplpProcesses == NULL)
  472. {
  473. // Allocate a structure for our Processes Object.
  474. *lplpProcesses = new CProcesses();
  475. if (!*lplpProcesses)
  476. {
  477. _tprintf(TEXT("Unable to allocate memory for the processes object!\n"));
  478. goto cleanup;
  479. }
  480. // The Processes Object will init differently depending on what
  481. // Command-Line arguments have been provided...
  482. if (!(*lplpProcesses)->Initialize(lpModuleInfoCache, this, lpOutputFile))
  483. {
  484. _tprintf(TEXT("Unable to initialize Processes Object!\n"));
  485. goto cleanup;
  486. }
  487. }
  488. // Okay, go get the Process Data...
  489. (*lplpProcesses)->GetProcessesData();
  490. } else
  491. if ( _tcsicmp(g_tszCollectionArray[Process].tszCSVLabel, tszTemporaryBuffer) == 0 )
  492. {
  493. /*
  494. [PROCESS]
  495. */
  496. // Read to the end of the line
  497. if (!ReadFileLine())
  498. return false;
  499. // Yup, it is... let's create a ProcessInfo Object
  500. if (*lplpProcess== NULL)
  501. {
  502. // Allocate a structure for our ProcessInfo Object.
  503. *lplpProcess = new CProcessInfo();
  504. if (!*lplpProcess)
  505. {
  506. _tprintf(TEXT("Unable to allocate memory for the processinfo object!\n"));
  507. goto cleanup;
  508. }
  509. // The Modules Object will init differently depending on what
  510. // Command-Line arguments have been provided...
  511. if (!(*lplpProcess)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
  512. {
  513. _tprintf(TEXT("Unable to initialize Modules Object!\n"));
  514. goto cleanup;
  515. }
  516. }
  517. // Okay, go get the Process Data
  518. (*lplpProcess)->GetProcessData();
  519. } else
  520. if ( _tcsicmp(g_tszCollectionArray[Modules].tszCSVLabel, tszTemporaryBuffer) == 0 )
  521. {
  522. /*
  523. [MODULES]
  524. */
  525. // Read to the end of the line
  526. if (!ReadFileLine())
  527. return false;
  528. // Yup, it is... let's create a Modules Object
  529. if (*lplpModules == NULL)
  530. {
  531. // Allocate a structure for our Modules Object.
  532. *lplpModules = new CModules();
  533. if (!*lplpModules)
  534. {
  535. _tprintf(TEXT("Unable to allocate memory for the modules object!\n"));
  536. goto cleanup;
  537. }
  538. // The Modules Object will init differently depending on what
  539. // Command-Line arguments have been provided...
  540. if (!(*lplpModules)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
  541. {
  542. _tprintf(TEXT("Unable to initialize Modules Object!\n"));
  543. goto cleanup;
  544. }
  545. }
  546. // Okay, go get the Modules Data (collected from the filesystem)
  547. (*lplpModules)->GetModulesData(CProgramOptions::InputModulesDataFromFileSystemMode, true);
  548. } else
  549. if ( _tcsicmp(g_tszCollectionArray[KernelModeDrivers].tszCSVLabel, tszTemporaryBuffer) == 0 )
  550. {
  551. /*
  552. [KERNEL-MODE DRIVERS]
  553. */
  554. // Read to the end of the line
  555. if (!ReadFileLine())
  556. return false;
  557. // Yup, it is... let's create a Modules Object
  558. if (*lplpKernelModeDrivers == NULL)
  559. {
  560. // Allocate a structure for our Modules Object.
  561. *lplpKernelModeDrivers = new CModules();
  562. if (!*lplpKernelModeDrivers)
  563. {
  564. _tprintf(TEXT("Unable to allocate memory for the modules object!\n"));
  565. goto cleanup;
  566. }
  567. // The Modules Object will init differently depending on what
  568. // Command-Line arguments have been provided...
  569. if (!(*lplpKernelModeDrivers)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
  570. {
  571. _tprintf(TEXT("Unable to initialize Modules Object!\n"));
  572. goto cleanup;
  573. }
  574. }
  575. // Okay, go get the Modules Data (collected from the filesystem)
  576. (*lplpKernelModeDrivers)->GetModulesData(CProgramOptions::InputDriversFromLiveSystemMode, true);
  577. } else
  578. {
  579. _tprintf(TEXT("Unrecognized section %s found!\n"), tszTemporaryBuffer);
  580. return false;
  581. }
  582. }
  583. cleanup:
  584. return false;
  585. }
  586. bool CFileData::ReadDWORD(LPDWORD lpDWORD)
  587. {
  588. char szTempBuffer[10+1]; // 0xFFFFFFFF == 4294967295 (10 characters) + 1 for the \0
  589. if (!ReadString(szTempBuffer, 10+1))
  590. return false;
  591. // Convert it... baby...
  592. *lpDWORD = atoi(szTempBuffer);
  593. return true;
  594. }
  595. bool CFileData::CopyCharIfRoom(DWORD iStringBufferSize, LPSTR szStringBuffer, LPDWORD piBytesCopied, bool *pfFinished)
  596. {
  597. if (iStringBufferSize)
  598. {
  599. // If we have room to copy the data... let's do it...
  600. if (*piBytesCopied < iStringBufferSize)
  601. {
  602. szStringBuffer[(*piBytesCopied)++] = *(m_lpCurrentLocationInLINEBUFFER++);
  603. } else
  604. {
  605. // No room... we're done.
  606. *pfFinished = true;
  607. }
  608. } else
  609. {
  610. // Just advance the pointer... we have no buffer to copy to...
  611. *(m_lpCurrentLocationInLINEBUFFER++);
  612. }
  613. return true;
  614. }
  615. bool CFileData::ResetBufferPointerToStart()
  616. {
  617. // Reset the Pointer with our line buffer to the start of this buffer
  618. m_lpCurrentLocationInLINEBUFFER = m_szLINEBUFFER;
  619. return true;
  620. }
  621. bool CFileData::EndOfFile()
  622. {
  623. //return (*m_lpCurrentFilePointer == '\0');
  624. return (*m_lpCurrentLocationInLINEBUFFER == '\0');
  625. }
  626. bool CFileData::WriteFileTimeString(FILETIME ftFileTime)
  627. {
  628. enum {BUFFERSIZE = 128};
  629. TCHAR tszBuffer[BUFFERSIZE];
  630. FILETIME ftLocalFileTime;
  631. SYSTEMTIME lpSystemTime;
  632. int cch = 0;
  633. // Let's convert this to a local file time first...
  634. if (!FileTimeToLocalFileTime(&ftFileTime, &ftLocalFileTime))
  635. return false;
  636. FileTimeToSystemTime( &ftLocalFileTime, &lpSystemTime );
  637. cch = GetDateFormat( LOCALE_USER_DEFAULT,
  638. 0,
  639. &lpSystemTime,
  640. TEXT("MMMM d',' yyyy"),
  641. tszBuffer,
  642. BUFFERSIZE );
  643. if (!cch)
  644. return false;
  645. tszBuffer[cch-1] = TEXT(' ');
  646. //
  647. // Get time and format to characters
  648. //
  649. GetTimeFormat( LOCALE_USER_DEFAULT,
  650. 0,
  651. &lpSystemTime, // use current time
  652. NULL, // use default format
  653. tszBuffer + cch,
  654. BUFFERSIZE - cch );
  655. // <Full Month Name> <day>, <Year with Century> <Hour>:<Minute>:<Second>
  656. //_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%B %d, %Y %H:%M:%S"), localtime(&Time));
  657. //_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
  658. if (!WriteString(tszBuffer, true))
  659. return false;
  660. return true;
  661. }
  662. // Exception Monitor prefers a MM/DD/YYYY HH:MM:SS format...
  663. bool CFileData::WriteTimeDateString2(time_t Time)
  664. {
  665. enum {BUFFERSIZE = 128};
  666. TCHAR tszBuffer[BUFFERSIZE];
  667. // This top version seems to be better Y2K friendly as I spit out the full year...
  668. _tcsftime(tszBuffer, BUFFERSIZE, TEXT("%m/%d/%Y %H:%M:%S"), localtime(&Time));
  669. //_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
  670. if (!WriteString(tszBuffer, true))
  671. return false;
  672. return true;
  673. }
  674. // Exception Monitor prefers a MM/DD/YYYY HH:MM:SS format...
  675. bool CFileData::WriteFileTimeString2(FILETIME ftFileTime)
  676. {
  677. enum {BUFFERSIZE = 128};
  678. TCHAR tszBuffer[BUFFERSIZE];
  679. FILETIME ftLocalFileTime;
  680. SYSTEMTIME lpSystemTime;
  681. int cch = 0;
  682. // Let's convert this to a local file time first...
  683. if (!FileTimeToLocalFileTime(&ftFileTime, &ftLocalFileTime))
  684. return false;
  685. FileTimeToSystemTime( &ftLocalFileTime, &lpSystemTime );
  686. cch = GetDateFormat( LOCALE_USER_DEFAULT,
  687. 0,
  688. &lpSystemTime,
  689. TEXT("MM/dd/yyyy"),
  690. tszBuffer,
  691. BUFFERSIZE );
  692. if (!cch)
  693. return false;
  694. tszBuffer[cch-1] = TEXT(' ');
  695. //
  696. // Get time and format to characters
  697. //
  698. GetTimeFormat( LOCALE_USER_DEFAULT,
  699. 0,
  700. &lpSystemTime, // use current time
  701. TEXT("HH:mm:ss"), // use default format
  702. tszBuffer + cch,
  703. BUFFERSIZE - cch );
  704. if (!WriteString(tszBuffer, true))
  705. return false;
  706. return true;
  707. }
  708. //#endif