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.

1936 lines
59 KiB

  1. #define UNICODE
  2. #define _UNICODE
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <wtypes.h>
  7. #include <mountmgr.h>
  8. #include <winioctl.h>
  9. #include <ntddvol.h>
  10. #include <ntddscsi.h>
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <tchar.h>
  16. #ifdef UNICODE
  17. # define _stnprintf _snwprintf
  18. #else
  19. # define _stnprintf _snprintf
  20. #endif
  21. #define BUFFER_SIZE 64*1024*sizeof(TCHAR)
  22. #define MIN_BUFFER_SIZE 1024*sizeof(TCHAR)
  23. #define MAX_BUFFER_SIZE 10*1024*1024*sizeof(TCHAR)
  24. #define MAXSTR 4*1024
  25. #define DEFAULT_HISTORYFILES 10
  26. VOID
  27. PrintLoadedDrivers(
  28. HANDLE hFile
  29. );
  30. ULONG
  31. LogSystemSnapshot(
  32. LPCTSTR *lpStrings,
  33. PLONG BuffSize,
  34. LPTSTR lpszBuff
  35. );
  36. UINT LogSystemSnapshotToFile(
  37. HANDLE hFile
  38. );
  39. void WriteToLogFileW(
  40. HANDLE hFile,
  41. LPCWSTR lpwszInput
  42. )
  43. {
  44. DWORD dwWriten;
  45. BYTE *bBuffer;
  46. int nLen, nRetLen;
  47. nLen = wcslen(lpwszInput);
  48. bBuffer = (BYTE*)malloc(nLen * sizeof(WCHAR));
  49. if(bBuffer == 0)
  50. return;
  51. nRetLen = WideCharToMultiByte(CP_ACP, 0, lpwszInput, -1, (LPSTR)bBuffer, nLen * sizeof(WCHAR), NULL, NULL);
  52. if(nRetLen != 0){
  53. WriteFile(hFile, (LPVOID)bBuffer, nRetLen-1, &dwWriten, NULL);
  54. }
  55. free(bBuffer);
  56. }
  57. void WriteToLogFileA(
  58. HANDLE hFile,
  59. LPCSTR lpszInput
  60. )
  61. {
  62. DWORD dwWriten;
  63. WriteFile(hFile, (LPVOID)lpszInput, strlen(lpszInput), &dwWriten, NULL);
  64. }
  65. void WriteToLogFile(
  66. HANDLE hFile,
  67. LPCTSTR lpszInput
  68. )
  69. {
  70. DWORD dwWriten;
  71. #ifdef _UNICODE
  72. WriteToLogFileW(hFile, lpszInput);
  73. #else
  74. WriteToLogFileA(hFile, lpszInput);
  75. #endif //_UNICODE
  76. }
  77. void
  78. LogLogicalDriveInfo(
  79. HANDLE hFile
  80. );
  81. void
  82. LogHardwareInfo(
  83. HANDLE hFile
  84. );
  85. void
  86. LogPhyicalDiskInfo(
  87. HANDLE hFile
  88. );
  89. void
  90. LogHotfixes(
  91. HANDLE hFile
  92. );
  93. void
  94. LogOsInfo(
  95. HANDLE hFile
  96. );
  97. void
  98. LogBIOSInfo(
  99. HANDLE hFile
  100. );
  101. NTSTATUS
  102. SnapshotRegOpenKey(
  103. IN LPCWSTR lpKeyName,
  104. IN ACCESS_MASK DesiredAccess,
  105. OUT PHANDLE KeyHandle
  106. );
  107. NTSTATUS
  108. SnapshotRegQueryValueKey(
  109. IN HANDLE KeyHandle,
  110. IN LPCWSTR lpValueName,
  111. IN ULONG Length,
  112. OUT PVOID KeyValue,
  113. OUT PULONG ResultLength
  114. );
  115. NTSTATUS
  116. SnapshotRegEnumKey(
  117. IN HANDLE KeyHandle,
  118. IN ULONG Index,
  119. OUT LPWSTR lpKeyName,
  120. OUT PULONG lpNameLength
  121. );
  122. void
  123. DeleteOldFiles(
  124. LPCTSTR lpPath
  125. );
  126. ULONG CurrentBufferSize;
  127. LPCTSTR StateTable[] = {
  128. TEXT("Initialized"),
  129. TEXT("Ready"),
  130. TEXT("Running"),
  131. TEXT("Standby"),
  132. TEXT("Terminated"),
  133. TEXT("Wait:"),
  134. TEXT("Transition"),
  135. TEXT("Unknown"),
  136. TEXT("Unknown"),
  137. TEXT("Unknown"),
  138. TEXT("Unknown"),
  139. TEXT("Unknown")
  140. };
  141. LPCTSTR WaitTable[] = {
  142. TEXT("Executive"),
  143. TEXT("FreePage"),
  144. TEXT("PageIn"),
  145. TEXT("PoolAllocation"),
  146. TEXT("DelayExecution"),
  147. TEXT("Suspended"),
  148. TEXT("UserRequest"),
  149. TEXT("Executive"),
  150. TEXT("FreePage"),
  151. TEXT("PageIn"),
  152. TEXT("PoolAllocation"),
  153. TEXT("DelayExecution"),
  154. TEXT("Suspended"),
  155. TEXT("UserRequest"),
  156. TEXT("EventPairHigh"),
  157. TEXT("EventPairLow"),
  158. TEXT("LpcReceive"),
  159. TEXT("LpcReply"),
  160. TEXT("VirtualMemory"),
  161. TEXT("PageOut"),
  162. TEXT("Spare1"),
  163. TEXT("Spare2"),
  164. TEXT("Spare3"),
  165. TEXT("Spare4"),
  166. TEXT("Spare5"),
  167. TEXT("Spare6"),
  168. TEXT("Spare7"),
  169. TEXT("Unknown"),
  170. TEXT("Unknown"),
  171. TEXT("Unknown")
  172. };
  173. LPCTSTR Empty = TEXT(" ");
  174. BOOLEAN fUserOnly = TRUE;
  175. BOOLEAN fSystemOnly = TRUE;
  176. BOOLEAN fVerbose = FALSE;
  177. BOOLEAN fPrintIt;
  178. TCHAR lpszBuffer[BUFFER_SIZE];
  179. TCHAR lpszFileName[MAX_PATH * sizeof(TCHAR)] ;
  180. TCHAR lpszHdrBuffer[MAX_PATH* sizeof(TCHAR)] ;
  181. ULONG LogSystemSnapshot(DWORD Flags, LPCTSTR *lpStrings, PLONG BuffSize, LPTSTR lpszBuff)
  182. {
  183. SYSTEMTIME systime;
  184. TIME_ZONE_INFORMATION TimeZone ;
  185. LPTSTR lpszTemp;
  186. HANDLE hFile = NULL;
  187. UINT res = 0;
  188. LONG lBuffSize ;
  189. GetLocalTime(&systime);
  190. lBuffSize = *BuffSize ;
  191. *BuffSize = 0 ;
  192. // Set up the log path %SYSTEMDIR%\Logfiles\Shutdown
  193. GetSystemDirectory(lpszFileName, MAX_PATH);
  194. lstrcat(lpszFileName, TEXT("\\LogFiles")); // making sure the path ..
  195. CreateDirectory(lpszFileName, NULL);
  196. lstrcat(lpszFileName, TEXT("\\ShutDown")); // .. exists
  197. CreateDirectory(lpszFileName, NULL);
  198. DeleteOldFiles(lpszFileName);
  199. lstrcat(lpszFileName, TEXT("\\ShutDown_"));
  200. lpszTemp = (LPTSTR)(lpszFileName + (lstrlen(lpszFileName)));
  201. _stnprintf(lpszTemp,MAX_PATH - (lstrlen(lpszFileName)),
  202. TEXT("%4d%02d%02d%02d%02d%02d.state"),
  203. systime.wYear, systime.wMonth, systime.wDay,
  204. systime.wHour, systime.wMinute, systime.wSecond);
  205. hFile = CreateFile(lpszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  206. if (hFile == INVALID_HANDLE_VALUE)
  207. return HandleToUlong(INVALID_HANDLE_VALUE);
  208. GetTimeZoneInformation(&TimeZone);
  209. _stnprintf(lpszHdrBuffer, MAX_PATH,
  210. TEXT("System State Snapshot of System %s on Shutdown\n")
  211. TEXT("Initiated by %s at %d-%d-%d %d:%d:%d (%s(%d))\n")
  212. TEXT("Reason = %s/%s\n")
  213. TEXT("Type = %s\n")
  214. TEXT("Comment = %s\n\n"),
  215. lpStrings[1],lpStrings[0],
  216. systime.wYear, systime.wMonth, systime.wDay,
  217. systime.wHour, systime.wMinute, systime.wSecond,
  218. TimeZone.StandardName,TimeZone.Bias,
  219. lpStrings[2],lpStrings[3],lpStrings[4],lpStrings[5]);
  220. WriteToLogFile(hFile, lpszHdrBuffer);
  221. // Ok write the snapshot to the file
  222. res = LogSystemSnapshotToFile(hFile);
  223. CloseHandle(hFile);
  224. if (lBuffSize >= (LONG)_tcslen(lpszFileName)) {
  225. wsprintf(lpszBuff,TEXT("%s"),lpszFileName);
  226. *BuffSize = _tcslen(lpszFileName) ;
  227. }
  228. return res;
  229. }
  230. UINT LogSystemSnapshotToFile(
  231. HANDLE hFile
  232. )
  233. {
  234. PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  235. PSYSTEM_THREAD_INFORMATION ThreadInfo;
  236. BYTE* LargeBuffer1;
  237. NTSTATUS status;
  238. ULONG i;
  239. ULONG TotalOffset = 0;
  240. TIME_FIELDS UserTime;
  241. TIME_FIELDS KernelTime;
  242. TIME_FIELDS UpTime;
  243. SYSTEM_BASIC_INFORMATION BasicInfo;
  244. SYSTEM_TIMEOFDAY_INFORMATION TimeOfDayInfo;
  245. PSYSTEM_PAGEFILE_INFORMATION PageFileInfo;
  246. LARGE_INTEGER Time;
  247. ANSI_STRING pname;
  248. SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
  249. SYSTEM_FILECACHE_INFORMATION FileCache;
  250. SIZE_T SumCommit;
  251. SIZE_T SumWorkingSet;
  252. if (hFile == INVALID_HANDLE_VALUE)
  253. return 1;
  254. //SetFileApisToOEM();
  255. LargeBuffer1 = (BYTE*) VirtualAlloc (NULL,
  256. MAX_BUFFER_SIZE,
  257. MEM_RESERVE,
  258. PAGE_READWRITE);
  259. if (LargeBuffer1 == NULL) {
  260. WriteToLogFile(hFile, TEXT("Memory allocation failed\n"));
  261. return 0;
  262. }
  263. if (VirtualAlloc (LargeBuffer1,
  264. BUFFER_SIZE,
  265. MEM_COMMIT,
  266. PAGE_READWRITE) == NULL) {
  267. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE);
  268. WriteToLogFile(hFile, TEXT("Memory commit failed\n"));
  269. return 0;
  270. }
  271. CurrentBufferSize = BUFFER_SIZE;
  272. status = NtQuerySystemInformation(
  273. SystemBasicInformation,
  274. &BasicInfo,
  275. sizeof(SYSTEM_BASIC_INFORMATION),
  276. NULL
  277. );
  278. if (!NT_SUCCESS(status)) {
  279. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE | MEM_DECOMMIT);
  280. wsprintf(lpszBuffer, TEXT("Query info failed %lx\n"),status);
  281. WriteToLogFile(hFile, lpszBuffer);
  282. return(status);
  283. }
  284. status = NtQuerySystemInformation(
  285. SystemTimeOfDayInformation,
  286. &TimeOfDayInfo,
  287. sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
  288. NULL
  289. );
  290. if (!NT_SUCCESS(status)) {
  291. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE | MEM_DECOMMIT);
  292. wsprintf(lpszBuffer, TEXT("Query info failed %lx\n"),status);
  293. WriteToLogFile(hFile, lpszBuffer);
  294. return(status);
  295. }
  296. Time.QuadPart = TimeOfDayInfo.CurrentTime.QuadPart -
  297. TimeOfDayInfo.BootTime.QuadPart;
  298. RtlTimeToElapsedTimeFields ( &Time, &UpTime);
  299. _stnprintf(lpszBuffer, BUFFER_SIZE,
  300. TEXT("memory: %4ld kb uptime:%3ld %2ld:%02ld:%02ld.%03ld \n\n"),
  301. BasicInfo.NumberOfPhysicalPages * (BasicInfo.PageSize/1024),
  302. UpTime.Day,
  303. UpTime.Hour,
  304. UpTime.Minute,
  305. UpTime.Second,
  306. UpTime.Milliseconds);
  307. WriteToLogFile(hFile, lpszBuffer);
  308. PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)LargeBuffer1;
  309. status = NtQuerySystemInformation(
  310. SystemPageFileInformation,
  311. PageFileInfo,
  312. CurrentBufferSize,
  313. NULL
  314. );
  315. if (NT_SUCCESS(status)) {
  316. //
  317. // Print out the page file information.
  318. //
  319. if (PageFileInfo->TotalSize == 0) {
  320. WriteToLogFile(hFile, TEXT("no page files in use\n"));
  321. } else {
  322. for (; ; ) {
  323. _stnprintf(lpszBuffer, BUFFER_SIZE,
  324. TEXT("PageFile: %ls\n"), PageFileInfo->PageFileName.Buffer);
  325. WriteToLogFile(hFile, lpszBuffer);
  326. _stnprintf(lpszBuffer, BUFFER_SIZE,
  327. TEXT("\tCurrent Size: %6ld kb Total Used: %6ld kb Peak Used %6ld kb\n"),
  328. PageFileInfo->TotalSize*(BasicInfo.PageSize/1024),
  329. PageFileInfo->TotalInUse*(BasicInfo.PageSize/1024),
  330. PageFileInfo->PeakUsage*(BasicInfo.PageSize/1024));
  331. WriteToLogFile(hFile, lpszBuffer);
  332. if (PageFileInfo->NextEntryOffset == 0) {
  333. break;
  334. }
  335. PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)(
  336. (PCHAR)PageFileInfo + PageFileInfo->NextEntryOffset);
  337. }
  338. }
  339. }
  340. retry:
  341. status = NtQuerySystemInformation(
  342. SystemProcessInformation,
  343. LargeBuffer1,
  344. CurrentBufferSize,
  345. NULL
  346. );
  347. if (status == STATUS_INFO_LENGTH_MISMATCH) {
  348. //
  349. // Increase buffer size.
  350. //
  351. CurrentBufferSize += 8192;
  352. if (VirtualAlloc (LargeBuffer1,
  353. CurrentBufferSize,
  354. MEM_COMMIT,
  355. PAGE_READWRITE) == NULL) {
  356. WriteToLogFile(hFile, TEXT("Memory commit failed\n"));
  357. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
  358. return 0;
  359. }
  360. goto retry;
  361. }
  362. if (!NT_SUCCESS(status)) {
  363. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query info failed %lx\n"),status);
  364. WriteToLogFile(hFile,lpszBuffer);
  365. return(status);
  366. }
  367. //
  368. // display pmon style process output, then detailed output that includes
  369. // per thread stuff
  370. //
  371. TotalOffset = 0;
  372. SumCommit = 0;
  373. SumWorkingSet = 0;
  374. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  375. while (TRUE) {
  376. SumCommit += ProcessInfo->PrivatePageCount / 1024;
  377. SumWorkingSet += ProcessInfo->WorkingSetSize / 1024;
  378. if (ProcessInfo->NextEntryOffset == 0) {
  379. break;
  380. }
  381. TotalOffset += ProcessInfo->NextEntryOffset;
  382. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  383. }
  384. status = NtQuerySystemInformation(
  385. SystemPerformanceInformation,
  386. &PerfInfo,
  387. sizeof(PerfInfo),
  388. NULL
  389. );
  390. if ( !NT_SUCCESS(status) ) {
  391. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
  392. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query perf Failed %lx\n"),status);
  393. WriteToLogFile(hFile, lpszBuffer);
  394. return 0;
  395. }
  396. status = NtQuerySystemInformation(
  397. SystemFileCacheInformation,
  398. &FileCache,
  399. sizeof(FileCache),
  400. NULL
  401. );
  402. if ( !NT_SUCCESS(status) ) {
  403. VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
  404. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query file cache Failed %lx\n"),status);
  405. WriteToLogFile(hFile, lpszBuffer);
  406. return 0;
  407. }
  408. NtQuerySystemInformation(
  409. SystemBasicInformation,
  410. &BasicInfo,
  411. sizeof(BasicInfo),
  412. NULL
  413. );
  414. SumWorkingSet += FileCache.CurrentSize/1024;
  415. _stnprintf (lpszBuffer, BUFFER_SIZE,
  416. TEXT("\n Memory:%7ldK Avail:%7ldK TotalWs:%7ldK InRam Kernel:%5ldK P:%5ldK\n"),
  417. BasicInfo.NumberOfPhysicalPages*(BasicInfo.PageSize/1024),
  418. PerfInfo.AvailablePages*(BasicInfo.PageSize/1024),
  419. SumWorkingSet,
  420. (PerfInfo.ResidentSystemCodePage + PerfInfo.ResidentSystemDriverPage)*(BasicInfo.PageSize/1024),
  421. (PerfInfo.ResidentPagedPoolPage)*(BasicInfo.PageSize/1024)
  422. );
  423. WriteToLogFile(hFile, lpszBuffer);
  424. _stnprintf(lpszBuffer, BUFFER_SIZE,
  425. TEXT(" Commit:%7ldK/%7ldK Limit:%7ldK Peak:%7ldK Pool N:%5ldK P:%5ldK\n"),
  426. PerfInfo.CommittedPages*(BasicInfo.PageSize/1024),
  427. SumCommit,
  428. PerfInfo.CommitLimit*(BasicInfo.PageSize/1024),
  429. PerfInfo.PeakCommitment*(BasicInfo.PageSize/1024),
  430. PerfInfo.NonPagedPoolPages*(BasicInfo.PageSize/1024),
  431. PerfInfo.PagedPoolPages*(BasicInfo.PageSize/1024)
  432. );
  433. WriteToLogFile(hFile, lpszBuffer);
  434. TotalOffset = 0;
  435. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  436. WriteToLogFile(hFile, TEXT("\n"));
  437. WriteToLogFile(hFile, TEXT(" User Time Kernel Time Ws Faults Commit Pri Hnd Thd Pid Name\n"));
  438. _stnprintf(lpszBuffer, BUFFER_SIZE,
  439. TEXT(" %6ld %8ld %s\n"),
  440. FileCache.CurrentSize/1024,
  441. FileCache.PageFaultCount,
  442. TEXT("File Cache")
  443. );
  444. WriteToLogFile(hFile, lpszBuffer);
  445. while (TRUE) {
  446. pname.Buffer = NULL;
  447. if ( ProcessInfo->ImageName.Buffer ) {
  448. RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
  449. }
  450. RtlTimeToElapsedTimeFields ( &ProcessInfo->UserTime, &UserTime);
  451. RtlTimeToElapsedTimeFields ( &ProcessInfo->KernelTime, &KernelTime);
  452. _stnprintf(lpszBuffer, BUFFER_SIZE,
  453. TEXT("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld"),
  454. UserTime.Hour,
  455. UserTime.Minute,
  456. UserTime.Second,
  457. UserTime.Milliseconds,
  458. KernelTime.Hour,
  459. KernelTime.Minute,
  460. KernelTime.Second,
  461. KernelTime.Milliseconds
  462. );
  463. WriteToLogFile(hFile, lpszBuffer);
  464. _stnprintf(lpszBuffer, BUFFER_SIZE,
  465. TEXT("%6ld %8ld %7ld"),
  466. ProcessInfo->WorkingSetSize / 1024,
  467. ProcessInfo->PageFaultCount,
  468. ProcessInfo->PrivatePageCount / 1024
  469. );
  470. WriteToLogFile(hFile, lpszBuffer);
  471. #ifdef _UNICODE
  472. _stnprintf(lpszBuffer, BUFFER_SIZE,
  473. TEXT(" %2ld %4ld %3ld %3ld %S\n"),
  474. ProcessInfo->BasePriority,
  475. ProcessInfo->HandleCount,
  476. ProcessInfo->NumberOfThreads,
  477. HandleToUlong(ProcessInfo->UniqueProcessId),
  478. ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
  479. ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
  480. );
  481. #else
  482. _stnprintf(lpszBuffer, BUFFER_SIZE,
  483. TEXT(" %2ld %4ld %3ld %3ld %s\n"),
  484. ProcessInfo->BasePriority,
  485. ProcessInfo->HandleCount,
  486. ProcessInfo->NumberOfThreads,
  487. HandleToUlong(ProcessInfo->UniqueProcessId),
  488. ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
  489. ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
  490. );
  491. #endif //_UNICODE
  492. WriteToLogFile(hFile, lpszBuffer);
  493. if ( pname.Buffer ) {
  494. RtlFreeAnsiString(&pname);
  495. }
  496. if (ProcessInfo->NextEntryOffset == 0) {
  497. break;
  498. }
  499. TotalOffset += ProcessInfo->NextEntryOffset;
  500. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  501. }
  502. //
  503. // Beginning of normal old style pstat output
  504. //
  505. /*
  506. if (0==1) {
  507. TotalOffset = 0;
  508. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  509. WriteToLogFile(hFile, TEXT("\n"));
  510. while (TRUE) {
  511. fPrintIt = FALSE;
  512. if ( (ProcessInfo->ImageName.Buffer && fUserOnly) ||
  513. (ProcessInfo->ImageName.Buffer==NULL && fSystemOnly) ) {
  514. fPrintIt = TRUE;
  515. pname.Buffer = NULL;
  516. if ( ProcessInfo->ImageName.Buffer ) {
  517. RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
  518. }
  519. wsprintf(lpszBuffer, TEXT("pid:%3lx pri:%2ld Hnd:%5ld Pf:%7ld Ws:%7ldK %s\n"),
  520. HandleToUlong(ProcessInfo->UniqueProcessId),
  521. ProcessInfo->BasePriority,
  522. ProcessInfo->HandleCount,
  523. ProcessInfo->PageFaultCount,
  524. ProcessInfo->WorkingSetSize / 1024,
  525. ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
  526. ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
  527. );
  528. WriteToLogFile(hFile, lpszBuffer);
  529. if ( pname.Buffer ) {
  530. RtlFreeAnsiString(&pname);
  531. }
  532. }
  533. i = 0;
  534. ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
  535. if (ProcessInfo->NumberOfThreads) {
  536. WriteToLogFile(hFile, TEXT(" tid pri Ctx Swtch StrtAddr User Time Kernel Time State\n"));
  537. }
  538. while (i < ProcessInfo->NumberOfThreads) {
  539. RtlTimeToElapsedTimeFields ( &ThreadInfo->UserTime, &UserTime);
  540. RtlTimeToElapsedTimeFields ( &ThreadInfo->KernelTime, &KernelTime);
  541. if ( fPrintIt ) {
  542. wsprintf(lpszBuffer, TEXT(" %3lx %2ld %9ld %p"),
  543. ProcessInfo->UniqueProcessId == 0 ? 0 : HandleToUlong(ThreadInfo->ClientId.UniqueThread),
  544. ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->Priority,
  545. ThreadInfo->ContextSwitches,
  546. ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->StartAddress
  547. );
  548. WriteToLogFile(hFile, lpszBuffer);
  549. wsprintf(lpszBuffer, TEXT(" %2ld:%02ld:%02ld.%03ld %2ld:%02ld:%02ld.%03ld"),
  550. UserTime.Hour,
  551. UserTime.Minute,
  552. UserTime.Second,
  553. UserTime.Milliseconds,
  554. KernelTime.Hour,
  555. KernelTime.Minute,
  556. KernelTime.Second,
  557. KernelTime.Milliseconds
  558. );
  559. WriteToLogFile(hFile, lpszBuffer);
  560. wsprintf(lpszBuffer, TEXT(" %s%s\n"),
  561. StateTable[ThreadInfo->ThreadState],
  562. (ThreadInfo->ThreadState == 5) ?
  563. WaitTable[ThreadInfo->WaitReason] : Empty
  564. );
  565. WriteToLogFile(hFile, lpszBuffer);
  566. }
  567. ThreadInfo += 1;
  568. i += 1;
  569. }
  570. if (ProcessInfo->NextEntryOffset == 0) {
  571. break;
  572. }
  573. TotalOffset += ProcessInfo->NextEntryOffset;
  574. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  575. if ( fPrintIt ) {
  576. WriteToLogFile(hFile, TEXT("\n"));
  577. }
  578. }
  579. }
  580. */
  581. PrintLoadedDrivers(hFile);
  582. //Now let us log the hardware and logical drive info
  583. WriteToLogFile(hFile, TEXT("\n"));
  584. LogOsInfo(hFile);
  585. LogHotfixes(hFile);
  586. LogBIOSInfo(hFile);
  587. LogHardwareInfo(hFile);
  588. LogPhyicalDiskInfo(hFile);
  589. LogLogicalDriveInfo(hFile);
  590. return 0;
  591. }
  592. typedef struct _MODULE_DATA {
  593. ULONG CodeSize;
  594. ULONG DataSize;
  595. ULONG BssSize;
  596. ULONG RoDataSize;
  597. ULONG ImportDataSize;
  598. ULONG ExportDataSize;
  599. ULONG ResourceDataSize;
  600. ULONG PagedSize;
  601. ULONG InitSize;
  602. ULONG CheckSum;
  603. ULONG TimeDateStamp;
  604. } MODULE_DATA, *PMODULE_DATA;
  605. typedef struct _LOADED_IMAGE {
  606. BYTE* MappedAddress;
  607. PIMAGE_NT_HEADERS FileHeader;
  608. PIMAGE_SECTION_HEADER LastRvaSection;
  609. int NumberOfSections;
  610. PIMAGE_SECTION_HEADER Sections;
  611. } LOADED_IMAGE, *PLOADED_IMAGE;
  612. VOID
  613. SumModuleData(
  614. PMODULE_DATA Sum,
  615. PMODULE_DATA Current
  616. )
  617. {
  618. Sum->CodeSize += Current->CodeSize;
  619. Sum->DataSize += Current->DataSize;
  620. Sum->BssSize += Current->BssSize;
  621. Sum->RoDataSize += Current->RoDataSize;
  622. Sum->ImportDataSize += Current->ImportDataSize;
  623. Sum->ExportDataSize += Current->ExportDataSize;
  624. Sum->ResourceDataSize += Current->ResourceDataSize;
  625. Sum->PagedSize += Current->PagedSize;
  626. Sum->InitSize += Current->InitSize;
  627. }
  628. VOID
  629. PrintModuleSeperator(
  630. HANDLE hFile
  631. )
  632. {
  633. WriteToLogFile(hFile, TEXT("------------------------------------------------------------------------------\n"));
  634. }
  635. VOID
  636. PrintModuleHeader(
  637. HANDLE hFile
  638. )
  639. {
  640. WriteToLogFile(hFile, TEXT(" ModuleName Load Addr Code Data Paged LinkDate\n"));
  641. PrintModuleSeperator(hFile);
  642. }
  643. VOID
  644. GetModuleData(
  645. HANDLE hFile,
  646. PMODULE_DATA Mod
  647. )
  648. {
  649. HANDLE hMappedFile;
  650. PIMAGE_DOS_HEADER DosHeader;
  651. LOADED_IMAGE LoadedImage;
  652. ULONG SectionAlignment;
  653. PIMAGE_SECTION_HEADER Section;
  654. int i;
  655. ULONG Size;
  656. hMappedFile = CreateFileMapping(
  657. hFile,
  658. NULL,
  659. PAGE_READONLY,
  660. 0,
  661. 0,
  662. NULL
  663. );
  664. if ( !hMappedFile ) {
  665. return;
  666. }
  667. LoadedImage.MappedAddress = (BYTE*) MapViewOfFile(
  668. hMappedFile,
  669. FILE_MAP_READ,
  670. 0,
  671. 0,
  672. 0
  673. );
  674. CloseHandle(hMappedFile);
  675. if ( !LoadedImage.MappedAddress ) {
  676. return;
  677. }
  678. //
  679. // Everything is mapped. Now check the image and find nt image headers
  680. //
  681. DosHeader = (PIMAGE_DOS_HEADER)LoadedImage.MappedAddress;
  682. if ( DosHeader->e_magic != IMAGE_DOS_SIGNATURE ) {
  683. UnmapViewOfFile(LoadedImage.MappedAddress);
  684. return;
  685. }
  686. LoadedImage.FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
  687. if ( LoadedImage.FileHeader->Signature != IMAGE_NT_SIGNATURE ) {
  688. UnmapViewOfFile(LoadedImage.MappedAddress);
  689. return;
  690. }
  691. LoadedImage.NumberOfSections = LoadedImage.FileHeader->FileHeader.NumberOfSections;
  692. LoadedImage.Sections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)LoadedImage.FileHeader + sizeof(IMAGE_NT_HEADERS));
  693. LoadedImage.LastRvaSection = LoadedImage.Sections;
  694. //
  695. // Walk through the sections and tally the dater
  696. //
  697. SectionAlignment = LoadedImage.FileHeader->OptionalHeader.SectionAlignment;
  698. for (Section = LoadedImage.Sections,i=0; i<LoadedImage.NumberOfSections; i++,Section++) {
  699. Size = Section->Misc.VirtualSize;
  700. if (Size == 0) {
  701. Size = Section->SizeOfRawData;
  702. }
  703. Size = (Size + SectionAlignment - 1) & ~(SectionAlignment - 1);
  704. if (!memcmp((const char*) Section->Name,"PAGE", 4 )) {
  705. Mod->PagedSize += Size;
  706. } else if (!_stricmp((const char*) Section->Name,"INIT" )) {
  707. Mod->InitSize += Size;
  708. } else if (!_stricmp((const char*) Section->Name,".bss" )) {
  709. Mod->BssSize = Size;
  710. } else if (!_stricmp((const char*) Section->Name,".edata" )) {
  711. Mod->ExportDataSize = Size;
  712. } else if (!_stricmp((const char*) Section->Name,".idata" )) {
  713. Mod->ImportDataSize = Size;
  714. } else if (!_stricmp((const char*) Section->Name,".rsrc" )) {
  715. Mod->ResourceDataSize = Size;
  716. } else if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
  717. Mod->CodeSize += Size;
  718. } else if (Section->Characteristics & IMAGE_SCN_MEM_WRITE) {
  719. Mod->DataSize += Size;
  720. } else if (Section->Characteristics & IMAGE_SCN_MEM_READ) {
  721. Mod->RoDataSize += Size;
  722. } else {
  723. Mod->DataSize += Size;
  724. }
  725. }
  726. Mod->CheckSum = LoadedImage.FileHeader->OptionalHeader.CheckSum;
  727. Mod->TimeDateStamp = LoadedImage.FileHeader->FileHeader.TimeDateStamp;
  728. UnmapViewOfFile(LoadedImage.MappedAddress);
  729. return;
  730. }
  731. TCHAR lpszTimeBuffer[MAX_PATH];
  732. VOID
  733. PrintLoadedDrivers(
  734. HANDLE hFile
  735. )
  736. {
  737. ULONG i, j, ulLen;
  738. LPSTR s;
  739. TCHAR ModuleName[MAX_PATH];
  740. HANDLE FileHandle;
  741. TCHAR KernelPath[MAX_PATH];
  742. TCHAR DriversPath[MAX_PATH];
  743. LPTSTR ModuleInfo;
  744. ULONG ModuleInfoLength;
  745. ULONG ReturnedLength;
  746. PRTL_PROCESS_MODULES Modules;
  747. PRTL_PROCESS_MODULE_INFORMATION Module;
  748. NTSTATUS Status;
  749. MODULE_DATA Sum;
  750. MODULE_DATA Current;
  751. __int64 timeStamp;
  752. FILETIME ft;
  753. SYSTEMTIME st;
  754. WriteToLogFile(hFile, TEXT("\n"));
  755. //
  756. // Locate system drivers.
  757. //
  758. ModuleInfoLength = 64000;
  759. while (1) {
  760. ModuleInfo = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ModuleInfoLength * sizeof(TCHAR));
  761. if (ModuleInfo == NULL) {
  762. wsprintf (lpszBuffer, TEXT("Failed to allocate memory for module information buffer of size %d\n"),
  763. ModuleInfoLength);
  764. WriteToLogFile(hFile, lpszBuffer);
  765. return;
  766. }
  767. Status = NtQuerySystemInformation (
  768. SystemModuleInformation,
  769. ModuleInfo,
  770. ModuleInfoLength * sizeof(TCHAR),
  771. &ReturnedLength);
  772. if (!NT_SUCCESS(Status)) {
  773. HeapFree(GetProcessHeap(), 0, (LPVOID)ModuleInfo);
  774. if (Status == STATUS_INFO_LENGTH_MISMATCH &&
  775. ReturnedLength > ModuleInfoLength * sizeof(TCHAR)) {
  776. ModuleInfoLength = ReturnedLength / sizeof(TCHAR);
  777. continue;
  778. }
  779. _stnprintf(lpszBuffer, BUFFER_SIZE,
  780. TEXT("query system info failed status - %lx\n"),Status);
  781. WriteToLogFile(hFile, lpszBuffer);
  782. return;
  783. }
  784. break;
  785. }
  786. GetSystemDirectory(KernelPath,sizeof(KernelPath)/sizeof(TCHAR));
  787. lstrcpy(DriversPath, KernelPath);
  788. lstrcat(DriversPath,TEXT("\\Drivers"));
  789. ZeroMemory(&Sum,sizeof(Sum));
  790. PrintModuleHeader(hFile);
  791. Modules = (PRTL_PROCESS_MODULES)ModuleInfo;
  792. Module = &Modules->Modules[ 0 ];
  793. for (i=0; i<Modules->NumberOfModules; i++) {
  794. ZeroMemory(&Current,sizeof(Current));
  795. s = (LPSTR)&Module->FullPathName[ Module->OffsetToFileName ];
  796. //
  797. // try to open the file
  798. //
  799. SetCurrentDirectory(KernelPath);
  800. #ifdef _UNICODE
  801. MultiByteToWideChar(CP_ACP, 0, s, -1, ModuleName, MAX_PATH);
  802. #else
  803. strcpy(ModuleName, s);
  804. #endif //_UNICODE
  805. FileHandle = CreateFile(
  806. ModuleName,
  807. GENERIC_READ,
  808. FILE_SHARE_READ,
  809. NULL,
  810. OPEN_EXISTING,
  811. 0,
  812. NULL
  813. );
  814. if ( FileHandle == INVALID_HANDLE_VALUE ) {
  815. SetCurrentDirectory(DriversPath);
  816. FileHandle = CreateFile(
  817. ModuleName,
  818. GENERIC_READ,
  819. FILE_SHARE_READ,
  820. NULL,
  821. OPEN_EXISTING,
  822. 0,
  823. NULL
  824. );
  825. }
  826. if ( FileHandle != INVALID_HANDLE_VALUE ) {
  827. GetModuleData(FileHandle,&Current);
  828. CloseHandle(FileHandle);
  829. }
  830. else
  831. continue;
  832. SumModuleData(&Sum,&Current);
  833. if (Current.TimeDateStamp) {
  834. timeStamp = Current.TimeDateStamp;
  835. timeStamp += (__int64)11644444799; //difference between filetime and time_t in seconds.
  836. timeStamp *= 10000000; // turn into 100 nano seconds.
  837. ft.dwLowDateTime = (DWORD)timeStamp;
  838. for (j = 0; j < 32; j++)
  839. timeStamp /= 2;
  840. ft.dwHighDateTime = (DWORD)timeStamp;
  841. FileTimeToSystemTime(&ft, &st);
  842. _stnprintf(lpszTimeBuffer, BUFFER_SIZE,
  843. TEXT("%d-%d-%d %d:%d:%d\n"), st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond);
  844. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12s %p %7d %7d %7d "),//%12s %p
  845. ModuleName,
  846. Module->ImageBase,
  847. Current.CodeSize,
  848. Current.DataSize,
  849. Current.PagedSize
  850. );
  851. WriteToLogFile(hFile, lpszBuffer);
  852. WriteToLogFile(hFile, lpszTimeBuffer);
  853. } else {
  854. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12s %p %7d %7d %7d %S"),
  855. ModuleName,
  856. Module->ImageBase,
  857. Current.CodeSize,
  858. Current.DataSize,
  859. Current.PagedSize,
  860. "\n"
  861. );
  862. WriteToLogFile(hFile, lpszBuffer);
  863. }
  864. Module++;
  865. }
  866. PrintModuleSeperator(hFile);
  867. _stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12S %7d %7d %7d\n"),
  868. "Total",
  869. Sum.CodeSize,
  870. Sum.DataSize,
  871. Sum.PagedSize
  872. );
  873. WriteToLogFile(hFile, lpszBuffer);
  874. HeapFree(GetProcessHeap(), 0, (LPVOID)ModuleInfo);
  875. }
  876. void
  877. LogLogicalDriveInfo(
  878. HANDLE hFile
  879. )
  880. {
  881. DWORD dwDriveMask;
  882. static TCHAR* tszDrives = TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  883. ULARGE_INTEGER i64FreeBytesToCaller;
  884. ULARGE_INTEGER i64TotalBytesToCaller;
  885. ULARGE_INTEGER i64TotalFreeBytesOnDrive;
  886. int iMask;
  887. TCHAR tszDrive[5]; //Buffer for drive such as "A:\".
  888. TCHAR tszBuffer[1024]; //buffer to contain info for one logical drive.
  889. int i;
  890. dwDriveMask = GetLogicalDrives();
  891. if(dwDriveMask != 0){
  892. WriteToLogFile(hFile, TEXT("Logical Drive Info:\n"));
  893. }
  894. for(i = 0; i < (int)_tcslen(tszDrives); i++){
  895. iMask = dwDriveMask & 0x1;
  896. _stprintf(tszDrive, TEXT("%c:\\"), tszDrives[i]);
  897. dwDriveMask >>= 1;
  898. if(iMask && GetDriveType(tszDrive) == DRIVE_FIXED
  899. && GetDiskFreeSpaceEx(tszDrive, &i64FreeBytesToCaller, &i64TotalBytesToCaller, &i64TotalFreeBytesOnDrive))
  900. {
  901. _stprintf(tszBuffer, TEXT("\t%s\n")
  902. TEXT("\t\t Free Disk Space(Bytes): %I64d\n")
  903. TEXT("\t\tTotal Disk Space(Bytes): %I64d\n"),
  904. tszDrive,
  905. i64TotalFreeBytesOnDrive,
  906. i64TotalBytesToCaller
  907. );
  908. WriteToLogFile(hFile, tszBuffer);
  909. }
  910. }
  911. WriteToLogFile(hFile, TEXT("\n"));
  912. }
  913. NTSTATUS
  914. SnapshotRegOpenKey(
  915. IN LPCWSTR lpKeyName,
  916. IN ACCESS_MASK DesiredAccess,
  917. OUT PHANDLE KeyHandle
  918. )
  919. {
  920. OBJECT_ATTRIBUTES ObjectAttributes;
  921. UNICODE_STRING KeyName;
  922. RtlInitUnicodeString( &KeyName, lpKeyName );
  923. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  924. NTSTATUS Status;
  925. InitializeObjectAttributes(
  926. &ObjectAttributes,
  927. &KeyName,
  928. OBJ_CASE_INSENSITIVE,
  929. NULL,
  930. NULL
  931. );
  932. Status = (NTSTATUS)NtOpenKey( KeyHandle, KEY_READ, &ObjectAttributes );
  933. return Status;
  934. }
  935. NTSTATUS
  936. SnapshotRegQueryValueKey(
  937. IN HANDLE KeyHandle,
  938. IN LPCWSTR lpValueName,
  939. IN ULONG Length,
  940. OUT PVOID KeyValue,
  941. OUT PULONG ResultLength
  942. )
  943. {
  944. UNICODE_STRING ValueName;
  945. ULONG BufferLength;
  946. NTSTATUS Status;
  947. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  948. RtlInitUnicodeString( &ValueName, lpValueName );
  949. BufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + Length;
  950. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) malloc(BufferLength);
  951. if (KeyValueInformation == NULL) {
  952. return STATUS_NO_MEMORY;
  953. }
  954. Status = NtQueryValueKey(
  955. KeyHandle,
  956. &ValueName,
  957. KeyValuePartialInformation,
  958. KeyValueInformation,
  959. BufferLength,
  960. ResultLength
  961. );
  962. if (NT_SUCCESS(Status)) {
  963. RtlCopyMemory(KeyValue,
  964. KeyValueInformation->Data,
  965. KeyValueInformation->DataLength
  966. );
  967. *ResultLength = KeyValueInformation->DataLength;
  968. if (KeyValueInformation->Type == REG_SZ) {
  969. if (KeyValueInformation->DataLength + sizeof(WCHAR) > Length) {
  970. KeyValueInformation->DataLength -= sizeof(WCHAR);
  971. }
  972. ((PUCHAR)KeyValue)[KeyValueInformation->DataLength++] = 0;
  973. ((PUCHAR)KeyValue)[KeyValueInformation->DataLength] = 0;
  974. *ResultLength = KeyValueInformation->DataLength + sizeof(WCHAR);
  975. }
  976. }
  977. free(KeyValueInformation);
  978. return Status;
  979. }
  980. NTSTATUS
  981. SnapshotRegEnumKey(
  982. IN HANDLE KeyHandle,
  983. IN ULONG Index,
  984. OUT LPWSTR lpKeyName,
  985. OUT PULONG lpNameLength
  986. )
  987. {
  988. UNICODE_STRING ValueName;
  989. ULONG BufferLength;
  990. NTSTATUS Status;
  991. PKEY_BASIC_INFORMATION pKeyBasicInformation;
  992. RtlInitUnicodeString( &ValueName, lpKeyName );
  993. BufferLength = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + *lpNameLength;
  994. pKeyBasicInformation = (PKEY_BASIC_INFORMATION) malloc(BufferLength);
  995. if (pKeyBasicInformation == NULL) {
  996. return STATUS_NO_MEMORY;
  997. }
  998. Status = NtEnumerateKey(
  999. KeyHandle,
  1000. Index,
  1001. KeyBasicInformation,
  1002. (PVOID)pKeyBasicInformation,
  1003. BufferLength,
  1004. lpNameLength
  1005. );
  1006. if (NT_SUCCESS(Status)) {
  1007. RtlCopyMemory(lpKeyName,
  1008. pKeyBasicInformation->Name,
  1009. pKeyBasicInformation->NameLength
  1010. );
  1011. *lpNameLength = pKeyBasicInformation->NameLength;
  1012. if(*lpNameLength > 0)
  1013. lpKeyName[(*lpNameLength) - 1] = L'\0';
  1014. else lpKeyName[0] = L'\0';
  1015. }
  1016. free((BYTE*)pKeyBasicInformation);
  1017. return Status;
  1018. }
  1019. void
  1020. LogHardwareInfo(
  1021. HANDLE hFile
  1022. )
  1023. {
  1024. LPCWSTR ComputerNameKey = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
  1025. LPCWSTR ComputerNameValsz = L"ComputerName";
  1026. LPCWSTR ProcessorKey = L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
  1027. LPCWSTR ProcessorSpeedValdw = L"~MHz";
  1028. LPCWSTR ProcessorIdentifierValsz = L"Identifier";
  1029. LPCWSTR ProcessorVendorValsz = L"VendorIdentifier";
  1030. LPCWSTR NetcardKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
  1031. LPCWSTR NetcardDescsz = L"Description";
  1032. LPCWSTR NetcardServiceNamesz = L"ServiceName";
  1033. HANDLE hKey;
  1034. HANDLE hSubkey;
  1035. WCHAR szVal[MAX_PATH];
  1036. WCHAR szSubkey[MAX_PATH];
  1037. DWORD dwVal;
  1038. DWORD dwSize;
  1039. DWORD dwSubkeyIndex;
  1040. DWORD dwRes;
  1041. NTSTATUS Status = STATUS_SUCCESS;
  1042. //Get Computer Name
  1043. Status = SnapshotRegOpenKey(ComputerNameKey, KEY_READ, &hKey);
  1044. if(!NT_SUCCESS(Status)){
  1045. WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
  1046. return;
  1047. }
  1048. dwSize = MAX_PATH * sizeof(WCHAR);
  1049. Status = SnapshotRegQueryValueKey(hKey, ComputerNameValsz, dwSize, szVal, &dwSize);
  1050. if(!NT_SUCCESS(Status)){
  1051. NtClose(hKey);
  1052. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1053. return;
  1054. }
  1055. NtClose(hKey);
  1056. WriteToLogFile(hFile, TEXT("Active Computer Name: "));
  1057. szVal[dwSize] = '\0';
  1058. WriteToLogFileW(hFile, szVal);
  1059. WriteToLogFile(hFile, TEXT("\n"));
  1060. //Get Processor Info
  1061. Status = SnapshotRegOpenKey(ProcessorKey, KEY_READ, &hKey);
  1062. if(!NT_SUCCESS(Status)){
  1063. WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
  1064. return;
  1065. }
  1066. dwSubkeyIndex = 0;
  1067. dwSize = MAX_PATH * sizeof(WCHAR);
  1068. WriteToLogFile(hFile, TEXT("Processor Info:\n"));
  1069. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1070. while(NT_SUCCESS(Status)){
  1071. wcscpy(szVal, ProcessorKey);
  1072. wcscat(szVal, L"\\");
  1073. wcscat(szVal, szSubkey);
  1074. Status = SnapshotRegOpenKey(szVal, KEY_READ, &hSubkey);
  1075. if(!NT_SUCCESS(Status)){
  1076. NtClose(hKey);
  1077. WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
  1078. return;
  1079. }
  1080. dwSize = sizeof(DWORD);
  1081. Status = SnapshotRegQueryValueKey(hSubkey, ProcessorSpeedValdw, dwSize, &dwVal, &dwSize);
  1082. if(!NT_SUCCESS(Status)){
  1083. NtClose(hKey);
  1084. NtClose(hSubkey);
  1085. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1086. return;
  1087. }
  1088. _stnprintf(lpszBuffer, BUFFER_SIZE,
  1089. TEXT("\tProcessor %s:\n")
  1090. TEXT("\t\tSpeed(~MHz): %d\n"),
  1091. szSubkey, dwVal);
  1092. WriteToLogFile(hFile, lpszBuffer);
  1093. dwSize = MAX_PATH * sizeof(WCHAR);
  1094. Status = SnapshotRegQueryValueKey(hSubkey, ProcessorIdentifierValsz, dwSize, szVal, &dwSize);
  1095. if(!NT_SUCCESS(Status)){
  1096. NtClose(hKey);
  1097. NtClose(hSubkey);
  1098. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1099. return;
  1100. }
  1101. WriteToLogFile(hFile, TEXT("\t\tIdentifier: "));
  1102. WriteToLogFileW(hFile, szVal);
  1103. WriteToLogFile(hFile, TEXT("\n"));
  1104. dwSize = MAX_PATH * sizeof(WCHAR);
  1105. Status = SnapshotRegQueryValueKey(hSubkey, ProcessorVendorValsz, dwSize, &szVal, &dwSize);
  1106. if(!NT_SUCCESS(Status)){
  1107. NtClose(hKey);
  1108. NtClose(hSubkey);
  1109. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1110. return;
  1111. }
  1112. WriteToLogFile(hFile, TEXT("\t\tVendor Identifier: "));
  1113. WriteToLogFileW(hFile, szVal);
  1114. WriteToLogFile(hFile, TEXT("\n"));
  1115. NtClose(hSubkey);
  1116. dwSubkeyIndex++;
  1117. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1118. }
  1119. NtClose(hKey);
  1120. //Get NetCard Info
  1121. Status = SnapshotRegOpenKey(NetcardKey, KEY_READ, &hKey);
  1122. if(!NT_SUCCESS(Status)){
  1123. WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
  1124. return;
  1125. }
  1126. WriteToLogFile(hFile, TEXT("NIC Info:\n"));
  1127. dwSubkeyIndex = 0;
  1128. dwSize = MAX_PATH * sizeof(WCHAR);
  1129. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1130. while(NT_SUCCESS(Status)){
  1131. wcscpy(szVal, NetcardKey);
  1132. wcscat(szVal, L"\\");
  1133. wcscat(szVal, szSubkey);
  1134. Status = SnapshotRegOpenKey(szVal, KEY_READ, &hSubkey);
  1135. if(!NT_SUCCESS(Status)){
  1136. NtClose(hKey);
  1137. WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
  1138. return;
  1139. }
  1140. dwSize = MAX_PATH * sizeof(WCHAR);
  1141. Status = SnapshotRegQueryValueKey(hSubkey, NetcardDescsz, dwSize, &szVal, &dwSize);
  1142. if(!NT_SUCCESS(Status)){
  1143. NtClose(hKey);
  1144. NtClose(hSubkey);
  1145. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1146. return;
  1147. }
  1148. _stnprintf(lpszBuffer, BUFFER_SIZE,
  1149. TEXT("\tNIC %s:\n"),
  1150. szSubkey);
  1151. WriteToLogFile(hFile, lpszBuffer);
  1152. WriteToLogFile(hFile, TEXT("\t\tDescription: "));
  1153. WriteToLogFileW(hFile, szVal);
  1154. WriteToLogFile(hFile, TEXT("\n"));
  1155. dwSize = MAX_PATH * sizeof(WCHAR);
  1156. Status = SnapshotRegQueryValueKey(hSubkey, NetcardServiceNamesz, dwSize, &szVal, &dwSize);
  1157. if(!NT_SUCCESS(Status)){
  1158. NtClose(hKey);
  1159. NtClose(hSubkey);
  1160. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
  1161. return;
  1162. }
  1163. WriteToLogFile(hFile, TEXT("\t\tService Name: "));
  1164. WriteToLogFileW(hFile, szVal);
  1165. WriteToLogFile(hFile, TEXT("\n"));
  1166. NtClose(hSubkey);
  1167. dwSubkeyIndex++;
  1168. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1169. }
  1170. NtClose(hKey);
  1171. }
  1172. BOOL
  1173. SnapshotIsVolumeName(
  1174. LPWSTR Name
  1175. )
  1176. {
  1177. if (Name[0] == '\\' &&
  1178. (Name[1] == '?' || Name[1] == '\\') &&
  1179. Name[2] == '?' &&
  1180. Name[3] == '\\' &&
  1181. Name[4] == 'V' &&
  1182. Name[5] == 'o' &&
  1183. Name[6] == 'l' &&
  1184. Name[7] == 'u' &&
  1185. Name[8] == 'm' &&
  1186. Name[9] == 'e' &&
  1187. Name[10] == '{' &&
  1188. Name[19] == '-' &&
  1189. Name[24] == '-' &&
  1190. Name[29] == '-' &&
  1191. Name[34] == '-' &&
  1192. Name[47] == '}' ) {
  1193. return TRUE;
  1194. }
  1195. return FALSE;
  1196. }
  1197. void
  1198. LogPhyicalDiskInfo(
  1199. HANDLE hFile
  1200. )
  1201. {
  1202. PMOUNTMGR_MOUNT_POINTS mountPoints;
  1203. MOUNTMGR_MOUNT_POINT mountPoint;
  1204. ULONG returnSize, success;
  1205. SYSTEM_DEVICE_INFORMATION DevInfo;
  1206. NTSTATUS Status = STATUS_SUCCESS;
  1207. ULONG NumberOfDisks;
  1208. PWCHAR deviceNameBuffer;
  1209. ULONG i;
  1210. OBJECT_ATTRIBUTES ObjectAttributes;
  1211. IO_STATUS_BLOCK IoStatus;
  1212. DISK_GEOMETRY disk_geometry;
  1213. PDISK_CACHE_INFORMATION disk_cache;
  1214. PSCSI_ADDRESS scsi_address;
  1215. PWCHAR KeyName;
  1216. WCHAR wszVal[MAXSTR];
  1217. HANDLE hDisk = INVALID_HANDLE_VALUE;
  1218. UNICODE_STRING UnicodeName;
  1219. ULONG SizeNeeded;
  1220. HKEY KeyHandle;
  1221. DWORD dwSize;
  1222. //
  1223. // Get the Number of Physical Disks
  1224. //
  1225. RtlZeroMemory(&DevInfo, sizeof(DevInfo));
  1226. Status = NtQuerySystemInformation(
  1227. SystemDeviceInformation,
  1228. &DevInfo, sizeof (DevInfo), NULL);
  1229. if (!NT_SUCCESS(Status)) {
  1230. WriteToLogFile(hFile, TEXT("Failed to query system information.\n\n"));
  1231. return;
  1232. }
  1233. NumberOfDisks = DevInfo.NumberOfDisks;
  1234. //
  1235. // Open Each Physical Disk and get Disk Layout information
  1236. //
  1237. WriteToLogFile(hFile, TEXT("Physical Disk Info:\n"));
  1238. for (i=0; i < NumberOfDisks; i++) {
  1239. DISK_CACHE_INFORMATION cacheInfo;
  1240. WCHAR driveBuffer[20];
  1241. HANDLE PartitionHandle;
  1242. HANDLE KeyHandle;
  1243. ULONG DataLength;
  1244. //
  1245. // Get Partition0 handle to get the Disk layout
  1246. //
  1247. deviceNameBuffer = (PWCHAR) lpszBuffer;
  1248. swprintf(deviceNameBuffer, L"\\Device\\Harddisk%d\\Partition0", i);
  1249. RtlInitUnicodeString(&UnicodeName, deviceNameBuffer);
  1250. InitializeObjectAttributes(
  1251. &ObjectAttributes,
  1252. &UnicodeName,
  1253. OBJ_CASE_INSENSITIVE,
  1254. NULL,
  1255. NULL
  1256. );
  1257. Status = NtOpenFile(
  1258. &PartitionHandle,
  1259. FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  1260. &ObjectAttributes,
  1261. &IoStatus,
  1262. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1263. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
  1264. );
  1265. if (!NT_SUCCESS(Status)) {
  1266. WriteToLogFile(hFile, TEXT("Failed calling NtOpenFile.\n\n"));
  1267. return;
  1268. }
  1269. RtlZeroMemory(&disk_geometry, sizeof(DISK_GEOMETRY));
  1270. // get geomerty information, the caller wants this
  1271. Status = NtDeviceIoControlFile(PartitionHandle,
  1272. 0,
  1273. NULL,
  1274. NULL,
  1275. &IoStatus,
  1276. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  1277. NULL,
  1278. 0,
  1279. &disk_geometry,
  1280. sizeof (DISK_GEOMETRY)
  1281. );
  1282. if (!NT_SUCCESS(Status)) {
  1283. NtClose(PartitionHandle);
  1284. WriteToLogFile(hFile, TEXT("Failed calling NtDeviceIoControlFile 1.\n\n"));
  1285. return;
  1286. }
  1287. scsi_address = (PSCSI_ADDRESS) lpszBuffer;
  1288. Status = NtDeviceIoControlFile(PartitionHandle,
  1289. 0,
  1290. NULL,
  1291. NULL,
  1292. &IoStatus,
  1293. IOCTL_SCSI_GET_ADDRESS,
  1294. NULL,
  1295. 0,
  1296. scsi_address,
  1297. sizeof (SCSI_ADDRESS)
  1298. );
  1299. NtClose(PartitionHandle);
  1300. if (!NT_SUCCESS(Status)) {
  1301. WriteToLogFile(hFile, TEXT("Failed calling NtDeviceIoControlFile 2.\n\n"));
  1302. return;
  1303. }
  1304. //
  1305. // Get Manufacturer's name from Registry
  1306. // We need to get the SCSI Address and then query the Registry with it.
  1307. //
  1308. KeyName = (PWCHAR) lpszBuffer;
  1309. swprintf(KeyName,
  1310. L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target ID %d\\Logical Unit Id %d",
  1311. scsi_address->PortNumber, scsi_address->PathId, scsi_address->TargetId, scsi_address->Lun
  1312. );
  1313. Status = SnapshotRegOpenKey(KeyName, KEY_READ, &KeyHandle);
  1314. if (!NT_SUCCESS(Status)){
  1315. WriteToLogFile(hFile, TEXT("Failed to open registry key for physical disk information\n\n"));
  1316. return;
  1317. }
  1318. else {
  1319. dwSize = MAXSTR * sizeof(WCHAR);
  1320. Status = SnapshotRegQueryValueKey(KeyHandle, L"Identifier", dwSize, wszVal, &dwSize);
  1321. if(!NT_SUCCESS(Status)){
  1322. NtClose(KeyHandle);
  1323. WriteToLogFile(hFile, TEXT("Failed to query registry value for physical disk information\n\n"));
  1324. return;
  1325. }
  1326. NtClose(KeyHandle);
  1327. }
  1328. //
  1329. // Package all information about this disk and write an event record
  1330. //
  1331. _stnprintf(lpszBuffer, BUFFER_SIZE,
  1332. TEXT("\tDisk %d:\n")
  1333. TEXT("\t\tBytes Per Sector: %d\n")
  1334. TEXT("\t\tSectors Per Track: %d\n")
  1335. TEXT("\t\tTracks Per Cylinder: %d\n")
  1336. TEXT("\t\tNumber of Cylinders: %I64d\n")
  1337. TEXT("\t\tPort Number: %d\n")
  1338. TEXT("\t\tPath ID: %d\n")
  1339. TEXT("\t\tTarget ID: %d\n")
  1340. TEXT("\t\tLun: %d\n"),
  1341. i,
  1342. disk_geometry.BytesPerSector,
  1343. disk_geometry.SectorsPerTrack,
  1344. disk_geometry.TracksPerCylinder,
  1345. disk_geometry.Cylinders.QuadPart,
  1346. scsi_address->PortNumber,
  1347. scsi_address->PathId,
  1348. scsi_address->TargetId,
  1349. scsi_address->Lun
  1350. );
  1351. WriteToLogFile(hFile, lpszBuffer);
  1352. WriteToLogFile(hFile, TEXT("\t\tManufacturer: "));
  1353. WriteToLogFileW(hFile, wszVal);
  1354. WriteToLogFile(hFile, TEXT("\n"));
  1355. }
  1356. //
  1357. // Get Logical Disk Information
  1358. //
  1359. wcscpy(wszVal, MOUNTMGR_DEVICE_NAME);
  1360. RtlInitUnicodeString(&UnicodeName, (LPWSTR)wszVal);
  1361. UnicodeName.MaximumLength = MAXSTR;
  1362. InitializeObjectAttributes(
  1363. &ObjectAttributes,
  1364. &UnicodeName,
  1365. OBJ_CASE_INSENSITIVE,
  1366. NULL,
  1367. NULL );
  1368. Status = NtCreateFile(
  1369. &hDisk,
  1370. GENERIC_READ | SYNCHRONIZE,
  1371. &ObjectAttributes,
  1372. &IoStatus,
  1373. NULL,
  1374. FILE_ATTRIBUTE_NORMAL,
  1375. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1376. FILE_OPEN_IF,
  1377. FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,
  1378. NULL, 0);
  1379. if (!NT_SUCCESS(Status) ) {
  1380. WriteToLogFile(hFile, TEXT("Failed calling NtCreateFile\n\n"));
  1381. return;
  1382. }
  1383. RtlZeroMemory(lpszBuffer, MAXSTR*sizeof(WCHAR));
  1384. RtlZeroMemory(&mountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
  1385. returnSize = 0;
  1386. mountPoints = (PMOUNTMGR_MOUNT_POINTS) &lpszBuffer[0];
  1387. Status = NtDeviceIoControlFile(hDisk,
  1388. 0,
  1389. NULL,
  1390. NULL,
  1391. &IoStatus,
  1392. IOCTL_MOUNTMGR_QUERY_POINTS,
  1393. mountPoints,
  1394. sizeof(MOUNTMGR_MOUNT_POINT),
  1395. mountPoints,
  1396. 4096
  1397. );
  1398. if (NT_SUCCESS(Status)) {
  1399. WCHAR name[MAX_PATH];
  1400. CHAR OutBuffer[MAXSTR];
  1401. PMOUNTMGR_MOUNT_POINT point;
  1402. UNICODE_STRING VolumePoint;
  1403. PVOLUME_DISK_EXTENTS VolExt;
  1404. PDISK_EXTENT DiskExt;
  1405. ULONG i;
  1406. int iDisk, iPartition;
  1407. iDisk = -1;
  1408. WriteToLogFile(hFile, TEXT("Disk Partition Info:\n"));
  1409. for (i=0; i<mountPoints->NumberOfMountPoints; i++) {
  1410. point = &mountPoints->MountPoints[i];
  1411. if (point->SymbolicLinkNameLength) {
  1412. RtlCopyMemory(name,
  1413. (PCHAR) mountPoints + point->SymbolicLinkNameOffset,
  1414. point->SymbolicLinkNameLength);
  1415. name[point->SymbolicLinkNameLength/sizeof(WCHAR)] = 0;
  1416. if (SnapshotIsVolumeName(name)) {
  1417. continue;
  1418. }
  1419. }
  1420. if (point->DeviceNameLength) {
  1421. HANDLE hVolume;
  1422. ULONG dwBytesReturned;
  1423. PSTORAGE_DEVICE_NUMBER Number;
  1424. DWORD IErrorMode;
  1425. RtlCopyMemory(name,
  1426. (PCHAR) mountPoints + point->DeviceNameOffset,
  1427. point->DeviceNameLength);
  1428. name[point->DeviceNameLength/sizeof(WCHAR)] = 0;
  1429. RtlInitUnicodeString(&UnicodeName, name);
  1430. UnicodeName.MaximumLength = MAXSTR;
  1431. //
  1432. // If the device name does not have the harddisk prefix
  1433. // then it may be a floppy or cdrom and we want avoid
  1434. // calling NtCreateFile on them.
  1435. //
  1436. if(_wcsnicmp(name,L"\\device\\harddisk",16)) {
  1437. continue;
  1438. }
  1439. InitializeObjectAttributes(
  1440. &ObjectAttributes,
  1441. &UnicodeName,
  1442. OBJ_CASE_INSENSITIVE,
  1443. NULL,
  1444. NULL );
  1445. //
  1446. // We do not want any pop up dialog here in case we are unable to
  1447. // access the volume.
  1448. //
  1449. IErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
  1450. Status = NtCreateFile(
  1451. &hVolume,
  1452. GENERIC_READ | SYNCHRONIZE,
  1453. &ObjectAttributes,
  1454. &IoStatus,
  1455. NULL,
  1456. FILE_ATTRIBUTE_NORMAL,
  1457. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1458. FILE_OPEN_IF,
  1459. FILE_SYNCHRONOUS_IO_NONALERT,
  1460. NULL, 0);
  1461. SetErrorMode(IErrorMode);
  1462. if (!NT_SUCCESS(Status)) {
  1463. continue;
  1464. }
  1465. RtlZeroMemory(OutBuffer, MAXSTR);
  1466. dwBytesReturned = 0;
  1467. VolExt = (PVOLUME_DISK_EXTENTS) &OutBuffer;
  1468. Status = NtDeviceIoControlFile(hVolume,
  1469. 0,
  1470. NULL,
  1471. NULL,
  1472. &IoStatus,
  1473. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
  1474. NULL,
  1475. 0,
  1476. &OutBuffer,
  1477. 4096
  1478. );
  1479. if (NT_SUCCESS(Status) ) {
  1480. ULONG j;
  1481. ULONG NumberOfExtents = VolExt->NumberOfDiskExtents;
  1482. TCHAR tszTemp[MAXSTR];
  1483. if(iDisk == -1 || iDisk != (&VolExt->Extents[0])->DiskNumber){
  1484. _stnprintf(tszTemp, MAXSTR, TEXT("\tDisk %d:\n"), (&VolExt->Extents[0])->DiskNumber);
  1485. WriteToLogFile(hFile, tszTemp);
  1486. iDisk = (&VolExt->Extents[0])->DiskNumber;
  1487. iPartition = 0;
  1488. }
  1489. _stnprintf(tszTemp, MAXSTR,
  1490. TEXT("\t\tPartition %d:\n"),
  1491. iPartition);
  1492. WriteToLogFile(hFile, tszTemp);
  1493. for (j=0; j < NumberOfExtents; j++) {
  1494. DiskExt = &VolExt->Extents[j];
  1495. _stnprintf(tszTemp, MAXSTR,
  1496. TEXT("\t\t\tExtent %d(disk %d):\n")
  1497. TEXT("\t\t\t\tStartingOffset: %I64d\n")
  1498. TEXT("\t\t\t\tPartitionSize: %I64d\n"),
  1499. j,
  1500. DiskExt->DiskNumber,
  1501. DiskExt->StartingOffset.QuadPart,
  1502. DiskExt->ExtentLength.QuadPart);
  1503. WriteToLogFile(hFile, tszTemp);
  1504. }
  1505. iPartition++;
  1506. }
  1507. NtClose(hVolume);
  1508. }
  1509. }
  1510. }
  1511. NtClose(hDisk);
  1512. }
  1513. void
  1514. LogHotfixes(
  1515. HANDLE hFile
  1516. )
  1517. {
  1518. LPCWSTR HotFixKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix";
  1519. LPCWSTR wszValName = L"Installed";
  1520. HANDLE hKey, hSubkey;
  1521. NTSTATUS Status = STATUS_SUCCESS;
  1522. UINT i;
  1523. DWORD dwSize, dwVal, dwSubkeyIndex;
  1524. WCHAR szKey[MAXSTR];
  1525. WCHAR szSubkey[MAXSTR];
  1526. Status = SnapshotRegOpenKey(HotFixKey, KEY_READ, &hKey);
  1527. if (!NT_SUCCESS(Status) ) {
  1528. WriteToLogFile(hFile, TEXT("Hotfix registry key does not exist or open failed\n\n"));
  1529. return;
  1530. }
  1531. WriteToLogFile(hFile, TEXT("Hotfix Info:\n"));
  1532. dwSubkeyIndex = 0;
  1533. dwSize = MAXSTR * sizeof(WCHAR);
  1534. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1535. while(NT_SUCCESS(Status)){
  1536. wcscpy(szKey, HotFixKey);
  1537. wcscat(szKey, L"\\");
  1538. wcscat(szKey, szSubkey);
  1539. Status = SnapshotRegOpenKey(szKey, KEY_READ, &hSubkey);
  1540. if(!NT_SUCCESS(Status)){
  1541. NtClose(hKey);
  1542. return;
  1543. }
  1544. dwSize = sizeof(DWORD);
  1545. Status = SnapshotRegQueryValueKey(hSubkey, wszValName, dwSize, &dwVal, &dwSize);
  1546. if(!NT_SUCCESS(Status)){
  1547. NtClose(hKey);
  1548. NtClose(hSubkey);
  1549. WriteToLogFile(hFile, TEXT("Failed to query registry key value for hotfix info\n\n"));
  1550. return;
  1551. }
  1552. _stnprintf(lpszBuffer, BUFFER_SIZE,
  1553. TEXT("\t%s: %d\n"),
  1554. szSubkey, dwVal);
  1555. WriteToLogFile(hFile, lpszBuffer);
  1556. NtClose(hSubkey);
  1557. dwSubkeyIndex++;
  1558. Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
  1559. }
  1560. NtClose(hKey);
  1561. }
  1562. void
  1563. LogOsInfo(
  1564. HANDLE hFile
  1565. )
  1566. {
  1567. LPCWSTR OsInfoKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion";
  1568. LPCWSTR awszValName[] = {
  1569. L"BuildLab",
  1570. L"CurrentBuildNumber",
  1571. L"CurrentType",
  1572. L"CurrentVersion",
  1573. //L"InstallDate",
  1574. L"PathName",
  1575. L"ProductId",
  1576. L"ProductName",
  1577. L"RegDone",
  1578. L"RegisteredOrgnization",
  1579. L"RegisteredOwner",
  1580. L"SoftwareType",
  1581. L"SourcePath",
  1582. L"SystemRoot",
  1583. L"CSDVersion"
  1584. };
  1585. UINT uVals = sizeof(awszValName) / sizeof(LPCWSTR);
  1586. HANDLE hKey;
  1587. NTSTATUS Status = STATUS_SUCCESS;
  1588. UINT i;
  1589. WCHAR wszVal[MAXSTR];
  1590. DWORD dwSize;
  1591. Status = SnapshotRegOpenKey(OsInfoKey, KEY_READ, &hKey);
  1592. if (!NT_SUCCESS(Status) ) {
  1593. WriteToLogFile(hFile, TEXT("Failed to open registry key for os version info\n\n"));
  1594. return;
  1595. }
  1596. WriteToLogFile(hFile, TEXT("OS Version Info:\n"));
  1597. for(i = 0; i < uVals; i++){
  1598. dwSize = MAXSTR * sizeof(WCHAR);
  1599. Status = SnapshotRegQueryValueKey(hKey, awszValName[i], dwSize, wszVal, &dwSize);
  1600. if(!NT_SUCCESS(Status)){
  1601. continue;
  1602. }
  1603. WriteToLogFile(hFile, TEXT("\t"));
  1604. WriteToLogFileW(hFile, awszValName[i]);
  1605. WriteToLogFile(hFile, TEXT(": "));
  1606. WriteToLogFileW(hFile, wszVal);
  1607. WriteToLogFile(hFile, TEXT("\n"));
  1608. }
  1609. NtClose(hKey);
  1610. }
  1611. void
  1612. LogBIOSInfo(
  1613. HANDLE hFile
  1614. )
  1615. {
  1616. LPCWSTR BiosInfoKey = L"\\Registry\\Machine\\Hardware\\Description\\System";
  1617. LPCWSTR awszValName[] = {
  1618. L"Identifier",
  1619. L"SystemBiosDate",
  1620. L"SystemBiosVersion",
  1621. L"VideoBiosDate",
  1622. L"VideoBiosVersion"
  1623. };
  1624. UINT uVals = sizeof(awszValName) / sizeof(LPCWSTR);
  1625. HANDLE hKey;
  1626. NTSTATUS Status = STATUS_SUCCESS;
  1627. UINT i;
  1628. WCHAR wszVal[MAXSTR];
  1629. LPWSTR pwsz;
  1630. DWORD dwSize, dwLen;
  1631. Status = SnapshotRegOpenKey(BiosInfoKey, KEY_READ, &hKey);
  1632. if (!NT_SUCCESS(Status) ) {
  1633. WriteToLogFile(hFile, TEXT("Failed to open registry key for BIOS info\n\n"));
  1634. return;
  1635. }
  1636. WriteToLogFile(hFile, TEXT("BIOS Info:\n"));
  1637. for(i = 0; i < uVals; i++){
  1638. dwSize = MAXSTR * sizeof(WCHAR);
  1639. Status = SnapshotRegQueryValueKey(hKey, awszValName[i], dwSize, wszVal, &dwSize);
  1640. if(!NT_SUCCESS(Status)){
  1641. continue;
  1642. }
  1643. WriteToLogFile(hFile, TEXT("\t"));
  1644. WriteToLogFileW(hFile, awszValName[i]);
  1645. WriteToLogFile(hFile, TEXT(": "));
  1646. dwLen = 0;
  1647. pwsz = wszVal;
  1648. while(dwLen + 1< dwSize / sizeof(WCHAR)){
  1649. if(dwLen != 0)
  1650. WriteToLogFile(hFile, TEXT(" "));
  1651. WriteToLogFileW(hFile, pwsz);
  1652. dwLen += wcslen(pwsz) + 1;
  1653. pwsz += wcslen(pwsz) + 1;
  1654. }
  1655. WriteToLogFile(hFile, TEXT("\n"));
  1656. }
  1657. NtClose(hKey);
  1658. }
  1659. void
  1660. DeleteOldFiles(
  1661. LPCTSTR lpPath
  1662. )
  1663. {
  1664. LPCWSTR ReliabilityKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Reliability";
  1665. LPCWSTR lpValName = L"SnapshotHistoryFiles";
  1666. HANDLE hKey, hFile;
  1667. NTSTATUS Status = STATUS_SUCCESS;
  1668. DWORD dwSize, dwVal;
  1669. TCHAR szFileName[MAX_PATH];
  1670. WIN32_FIND_DATA winData;
  1671. BOOL bFound = TRUE;
  1672. SYSTEMTIME systime;
  1673. FILETIME filetime;
  1674. __int64 i64Filetime, i64Filetime1;
  1675. GetSystemTime(&systime);
  1676. SystemTimeToFileTime(&systime, &filetime);
  1677. i64Filetime = (__int64)filetime.dwHighDateTime;
  1678. i64Filetime <<= 32;
  1679. i64Filetime |= (__int64)filetime.dwLowDateTime;
  1680. Status = SnapshotRegOpenKey(ReliabilityKey, KEY_ALL_ACCESS, &hKey);
  1681. if (NT_SUCCESS(Status)){
  1682. dwSize = sizeof(DWORD);
  1683. Status = SnapshotRegQueryValueKey(hKey, lpValName, dwSize, &dwVal, &dwSize);
  1684. if(!NT_SUCCESS(Status)){
  1685. dwVal = DEFAULT_HISTORYFILES;
  1686. }
  1687. NtClose(hKey);
  1688. }
  1689. else {
  1690. dwVal = DEFAULT_HISTORYFILES;
  1691. }
  1692. lstrcpy(szFileName, lpPath);
  1693. lstrcat(szFileName, TEXT("\\ShutDown_on_*"));
  1694. hFile = FindFirstFile(szFileName, &winData);
  1695. while(hFile != INVALID_HANDLE_VALUE && bFound){
  1696. i64Filetime1 = (__int64)winData.ftCreationTime.dwHighDateTime;
  1697. i64Filetime1 <<= 32;
  1698. i64Filetime1 |= (__int64)winData.ftCreationTime.dwLowDateTime;
  1699. if(i64Filetime - i64Filetime1 >= (const __int64)24*60*60*10000000 * dwVal){
  1700. lstrcpy(szFileName, lpPath);
  1701. lstrcat(szFileName, TEXT("\\"));
  1702. lstrcat(szFileName,winData.cFileName);
  1703. DeleteFile(szFileName);
  1704. }
  1705. bFound = FindNextFile(hFile, &winData);
  1706. }
  1707. if(hFile != INVALID_HANDLE_VALUE)
  1708. FindClose(hFile);
  1709. }