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.

1945 lines
60 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. tracehw.c
  5. Abstract:
  6. This routine dumps the hardware configuration of the machine to the
  7. logfile.
  8. Author:
  9. 04-Jul-2000 Melur Raghuraman
  10. 09-Sep-2001 Nitin Choubey
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h> // for ntutrl.h
  15. #include <nturtl.h> // for RTL_CRITICAL_SECTION in winbase.h/wtypes.h
  16. #include <wtypes.h> // for LPGUID in wmium.h
  17. #include <mountmgr.h>
  18. #include <winioctl.h>
  19. #include <ntddvol.h>
  20. #include <ntddscsi.h>
  21. #include <regstr.h>
  22. #include <iptypes.h>
  23. #include <ntstatus.h>
  24. #include "wmiump.h"
  25. #include "evntrace.h"
  26. #include "traceump.h"
  27. #include <strsafe.h>
  28. extern
  29. PVOID
  30. EtwpGetTraceBuffer(
  31. IN PWMI_LOGGER_CONTEXT Logger,
  32. IN PSYSTEM_THREAD_INFORMATION pThread,
  33. IN ULONG GroupType,
  34. IN ULONG RequiredSize
  35. );
  36. extern EtwpSetHWConfigFunction(PVOID,ULONG);
  37. __inline ULONG EtwpSetDosError(IN ULONG DosError);
  38. #define EtwpNtStatusToDosError(Status) \
  39. ((ULONG)((Status == STATUS_SUCCESS)?ERROR_SUCCESS:RtlNtStatusToDosError(Status)))
  40. #define COMPUTERNAME_ROOT \
  41. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName"
  42. #define CPU_ROOT \
  43. L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"
  44. #define COMPUTERNAME_VALUE_NAME \
  45. L"ComputerName"
  46. #define NETWORKCARDS_ROOT \
  47. L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"
  48. #define MHZ_VALUE_NAME \
  49. L"~MHz"
  50. #define NIC_VALUE_NAME \
  51. L"Description"
  52. #define REG_PATH_VIDEO_DEVICE_MAP \
  53. L"\\Registry\\Machine\\Hardware\\DeviceMap\\Video"
  54. #define REG_PATH_VIDEO_HARDWARE_PROFILE \
  55. L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\Video"
  56. #define REG_PATH_SERVICES \
  57. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video"
  58. typedef BOOL WINAPI T_EnumDisplayDevicesW( LPWSTR lpDevice,
  59. DWORD iDevNum,
  60. PDISPLAY_DEVICEW lpDisplayDevice,
  61. DWORD dwFlags );
  62. typedef DWORD WINAPI T_GetNetworkParams( PFIXED_INFO pFixedInfo,
  63. PULONG pOutBufLen );
  64. typedef DWORD T_GetAdaptersInfo( PIP_ADAPTER_INFO pAdapterInfo,
  65. PULONG pOutBufLen );
  66. typedef DWORD T_GetPerAdapterInfo( ULONG IfIndex,
  67. PIP_PER_ADAPTER_INFO pPerAdapterInfo,
  68. PULONG pOutBufLen );
  69. extern
  70. NTSTATUS
  71. EtwpRegOpenKey(
  72. IN PCWSTR lpKeyName,
  73. OUT PHANDLE KeyHandle
  74. );
  75. extern
  76. NTSTATUS
  77. EtwpRegQueryValueKey(
  78. IN HANDLE KeyHandle,
  79. IN LPWSTR lpValueName,
  80. IN ULONG Length,
  81. OUT PVOID KeyValue,
  82. OUT PULONG ResultLength
  83. );
  84. NTSTATUS
  85. EtwpGetCpuSpeed(
  86. IN DWORD* CpuNum,
  87. OUT DWORD* CpuSpeed
  88. )
  89. {
  90. PWCHAR Buffer = NULL;
  91. NTSTATUS Status;
  92. ULONG DataLength;
  93. DWORD Size;
  94. HANDLE Handle = INVALID_HANDLE_VALUE;
  95. HRESULT hr;
  96. Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
  97. if (Buffer == NULL) {
  98. return STATUS_NO_MEMORY;
  99. }
  100. RtlZeroMemory(Buffer, DEFAULT_ALLOC_SIZE);
  101. hr = StringCchPrintf(Buffer, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), L"%ws\\%u", CPU_ROOT, *CpuNum);
  102. if(FAILED(hr)) {
  103. Status = STATUS_UNSUCCESSFUL;
  104. goto Cleanup;
  105. }
  106. Status = EtwpRegOpenKey(Buffer, &Handle);
  107. if(!NT_SUCCESS(Status)) {
  108. Handle = INVALID_HANDLE_VALUE;
  109. goto Cleanup;
  110. }
  111. hr = StringCchPrintf(Buffer, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), MHZ_VALUE_NAME);
  112. if(FAILED(hr)) {
  113. Status = STATUS_UNSUCCESSFUL;
  114. goto Cleanup;
  115. }
  116. Size = sizeof(DWORD);
  117. Status = EtwpRegQueryValueKey(Handle,
  118. (LPWSTR) Buffer,
  119. Size,
  120. CpuSpeed,
  121. &DataLength);
  122. Cleanup:
  123. if(!NT_SUCCESS(Status)) {
  124. *CpuSpeed = 0;
  125. }
  126. if(Handle != INVALID_HANDLE_VALUE) {
  127. NtClose(Handle);
  128. }
  129. if(Buffer) {
  130. RtlFreeHeap (RtlProcessHeap(),0,Buffer);
  131. }
  132. return Status;
  133. }
  134. ULONG
  135. EtwpGetCpuConfig(
  136. IN PWMI_LOGGER_CONTEXT LoggerContext
  137. )
  138. {
  139. PWCHAR Buffer = NULL;
  140. PWCHAR ComputerName = NULL;
  141. ULONG CpuNum;
  142. ULONG CpuSpeed;
  143. DWORD Size;
  144. SYSTEM_INFO SysInfo;
  145. MEMORYSTATUS MemStatus;
  146. NTSTATUS Status;
  147. HANDLE Handle;
  148. ULONG DataLength;
  149. ULONG StringSize;
  150. ULONG SizeNeeded;
  151. PCPU_CONFIG_RECORD CpuConfig = NULL;
  152. PFIXED_INFO pFixedInfo = NULL;
  153. DWORD ErrorCode;
  154. ULONG NetworkParamsSize;
  155. T_GetNetworkParams *pfnGetNetworkParams = NULL;
  156. HINSTANCE hIphlpapiDll = NULL;
  157. DWORD dwError;
  158. HRESULT hr;
  159. Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
  160. if (Buffer == NULL) {
  161. Status = STATUS_NO_MEMORY;
  162. goto CpuCleanup;
  163. }
  164. RtlZeroMemory(Buffer, DEFAULT_ALLOC_SIZE);
  165. Size = StringSize = (MAX_DEVICE_ID_LENGTH) * sizeof (WCHAR);
  166. ComputerName = RtlAllocateHeap (RtlProcessHeap(),0,Size);
  167. if(ComputerName == NULL) {
  168. Status = STATUS_NO_MEMORY;
  169. goto CpuCleanup;
  170. }
  171. RtlZeroMemory(ComputerName, Size);
  172. GlobalMemoryStatus(&MemStatus);
  173. hr = StringCchPrintf(Buffer, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), COMPUTERNAME_ROOT);
  174. if(FAILED(hr)) {
  175. Status = STATUS_UNSUCCESSFUL;
  176. goto CpuCleanup;
  177. }
  178. Status = EtwpRegOpenKey(Buffer, &Handle);
  179. if (!NT_SUCCESS(Status)) {
  180. goto CpuCleanup;
  181. }
  182. hr = StringCchPrintf(Buffer, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), COMPUTERNAME_VALUE_NAME);
  183. if(FAILED(hr)) {
  184. Status = STATUS_UNSUCCESSFUL;
  185. goto CpuCleanup;
  186. }
  187. CpuQuery:
  188. Status = EtwpRegQueryValueKey(Handle,
  189. (LPWSTR) Buffer,
  190. Size,
  191. ComputerName,
  192. &StringSize
  193. );
  194. if (!NT_SUCCESS(Status) ) {
  195. if (Status == STATUS_BUFFER_OVERFLOW) {
  196. RtlFreeHeap (RtlProcessHeap(),0,ComputerName);
  197. Size = StringSize;
  198. ComputerName = RtlAllocateHeap (RtlProcessHeap(),0,Size);
  199. if (ComputerName == NULL) {
  200. NtClose(Handle);
  201. Status = STATUS_NO_MEMORY;
  202. goto CpuCleanup;
  203. }
  204. RtlZeroMemory(ComputerName, Size);
  205. goto CpuQuery;
  206. }
  207. NtClose(Handle);
  208. goto CpuCleanup;
  209. }
  210. //
  211. // Get Architecture Type, Processor Type and Level Stepping...
  212. //
  213. CpuNum = 0;
  214. EtwpGetCpuSpeed(&CpuNum, &CpuSpeed);
  215. GetSystemInfo(&SysInfo);
  216. //
  217. // Get the Hostname and DomainName
  218. //
  219. // delay load iphlpapi.lib to Get network params
  220. hIphlpapiDll = LoadLibraryW(L"iphlpapi.dll");
  221. if (hIphlpapiDll == NULL) {
  222. Status = STATUS_DELAY_LOAD_FAILED;
  223. goto CpuCleanup;
  224. }
  225. pfnGetNetworkParams = (T_GetNetworkParams*) GetProcAddress(hIphlpapiDll, "GetNetworkParams");
  226. if(pfnGetNetworkParams == NULL) {
  227. Status = STATUS_PROCEDURE_NOT_FOUND;
  228. goto CpuCleanup;
  229. }
  230. ErrorCode = pfnGetNetworkParams(NULL, &NetworkParamsSize);
  231. if(ErrorCode != ERROR_BUFFER_OVERFLOW) {
  232. Status = STATUS_UNSUCCESSFUL;
  233. goto CpuCleanup;
  234. }
  235. pFixedInfo = (PFIXED_INFO)RtlAllocateHeap (RtlProcessHeap(),0,NetworkParamsSize);
  236. if(pFixedInfo == NULL) {
  237. Status = STATUS_NO_MEMORY;
  238. goto CpuCleanup;
  239. }
  240. RtlZeroMemory(pFixedInfo, NetworkParamsSize);
  241. ErrorCode = pfnGetNetworkParams(pFixedInfo, &NetworkParamsSize);
  242. if(ErrorCode != ERROR_SUCCESS) {
  243. Status = STATUS_UNSUCCESSFUL;
  244. goto CpuCleanup;
  245. }
  246. //
  247. // Create EventTrace record for CPU configuration and write it
  248. //
  249. SizeNeeded = sizeof(CPU_CONFIG_RECORD) + StringSize + (CONFIG_MAX_DOMAIN_NAME_LEN * sizeof(WCHAR));
  250. CpuConfig = (PCPU_CONFIG_RECORD) EtwpGetTraceBuffer(LoggerContext,
  251. NULL,
  252. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_CPU,
  253. SizeNeeded);
  254. if (CpuConfig == NULL) {
  255. Status = STATUS_NO_MEMORY;
  256. goto CpuCleanup;
  257. }
  258. CpuConfig->NumberOfProcessors = SysInfo.dwNumberOfProcessors;
  259. CpuConfig->ProcessorSpeed = CpuSpeed;
  260. CpuConfig->MemorySize = (ULONG)(((MemStatus.dwTotalPhys + 512) / 1024) + 512) / 1024;
  261. CpuConfig->PageSize = SysInfo.dwPageSize;
  262. CpuConfig->AllocationGranularity = SysInfo.dwAllocationGranularity;
  263. MultiByteToWideChar(CP_ACP,
  264. 0,
  265. pFixedInfo->DomainName,
  266. -1,
  267. CpuConfig->DomainName,
  268. CONFIG_MAX_DOMAIN_NAME_LEN);
  269. RtlCopyMemory(&CpuConfig->ComputerName, ComputerName, StringSize);
  270. CpuConfig->ComputerName[StringSize/2] = 0;
  271. CpuCleanup:
  272. if (Buffer != NULL) {
  273. RtlFreeHeap (RtlProcessHeap(),0,Buffer);
  274. }
  275. if (ComputerName != NULL) {
  276. RtlFreeHeap (RtlProcessHeap(),0,ComputerName);
  277. }
  278. if(pFixedInfo) {
  279. RtlFreeHeap (RtlProcessHeap(),0,pFixedInfo);
  280. }
  281. if(hIphlpapiDll) {
  282. FreeLibrary(hIphlpapiDll);
  283. }
  284. return Status;
  285. }
  286. // Function to get logical disk
  287. NTSTATUS
  288. GetIoFixedDrive(
  289. OUT PLOGICAL_DISK_EXTENTS* ppFdi,
  290. IN WCHAR* DriveLetterString
  291. )
  292. {
  293. DWORD i,dwLastError;
  294. WCHAR DeviceName[MAXSTR];
  295. BOOLEAN IsVolume = FALSE;
  296. PARTITION_INFORMATION_EX PartitionInfo;
  297. STORAGE_DEVICE_NUMBER StorageDeviceNum;
  298. HANDLE VolumeHandle;
  299. ULONG BytesTransferred;
  300. WCHAR DriveRootName[CONFIG_DRIVE_LETTER_LEN];
  301. PLOGICAL_DISK_EXTENTS pFdi = NULL;
  302. INT FixedDiskInfoSize;
  303. BOOL bRet;
  304. DWORD bytes;
  305. ULONG BufSize;
  306. CHAR* pBuf = NULL;
  307. CHAR* pNew = NULL;
  308. PVOLUME_DISK_EXTENTS pVolExt = NULL;
  309. PDISK_EXTENT pDiskExt = NULL;
  310. ULARGE_INTEGER TotalBytes;
  311. ULARGE_INTEGER TotalFreeBytes;
  312. ULARGE_INTEGER FreeBytesToCaller;
  313. ULONG TotalClusters;
  314. ULONG TotalFreeClusters;
  315. PUCHAR VolumeExtPtr = NULL;
  316. HRESULT hr;
  317. FixedDiskInfoSize = sizeof(LOGICAL_DISK_EXTENTS);
  318. //
  319. // First, we must calculate the size of FixedDiskInfo structure
  320. // non-partition logical drives have different size
  321. //
  322. hr = StringCchPrintf(DeviceName, MAXSTR, L"\\\\.\\%s",DriveLetterString);
  323. if(FAILED(hr)) {
  324. return STATUS_UNSUCCESSFUL;
  325. }
  326. VolumeHandle = CreateFileW(DeviceName,
  327. GENERIC_READ,
  328. FILE_SHARE_READ | FILE_SHARE_WRITE,
  329. NULL, // No child process should inherit the handle
  330. OPEN_EXISTING,
  331. FILE_ATTRIBUTE_NORMAL,
  332. INVALID_HANDLE_VALUE);
  333. if (VolumeHandle == INVALID_HANDLE_VALUE) {
  334. dwLastError = GetLastError();
  335. goto ErrorExit;
  336. }
  337. bRet = DeviceIoControl(VolumeHandle,
  338. IOCTL_STORAGE_GET_DEVICE_NUMBER,
  339. NULL,
  340. 0,
  341. &StorageDeviceNum,
  342. sizeof(StorageDeviceNum),
  343. &bytes,
  344. NULL);
  345. if (!bRet)
  346. {
  347. //
  348. // This is Volume
  349. //
  350. BufSize = 2048;
  351. pBuf = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
  352. if (pBuf == NULL) {
  353. dwLastError = GetLastError();
  354. goto ErrorExit;
  355. }
  356. //
  357. // Well, the drive letter is for a volume.
  358. //
  359. retry:
  360. RtlZeroMemory(pBuf, BufSize);
  361. bRet = DeviceIoControl(VolumeHandle,
  362. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
  363. NULL,
  364. 0,
  365. pBuf,
  366. BufSize,
  367. &bytes,
  368. NULL);
  369. dwLastError = GetLastError();
  370. if (!bRet && dwLastError == ERROR_INSUFFICIENT_BUFFER)
  371. {
  372. BufSize = bytes;
  373. if(pBuf) {
  374. RtlFreeHeap (RtlProcessHeap(),0,pBuf);
  375. pBuf = NULL;
  376. }
  377. pNew = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
  378. //
  379. // We can not reallocate memory, exit.
  380. //
  381. if (pNew == NULL){
  382. dwLastError = GetLastError();
  383. goto ErrorExit;
  384. }
  385. else {
  386. pBuf = pNew;
  387. }
  388. goto retry;
  389. }
  390. if (!bRet) {
  391. goto ErrorExit;
  392. }
  393. pVolExt = (PVOLUME_DISK_EXTENTS)pBuf;
  394. IsVolume=TRUE;
  395. FixedDiskInfoSize += sizeof(VOLUME_DISK_EXTENTS) + (pVolExt->NumberOfDiskExtents) * sizeof(DISK_EXTENT);
  396. }
  397. pFdi = (PLOGICAL_DISK_EXTENTS) RtlAllocateHeap (RtlProcessHeap(),0,FixedDiskInfoSize);
  398. if (pFdi == NULL) {
  399. goto ErrorExit;
  400. }
  401. RtlZeroMemory(pFdi, FixedDiskInfoSize);
  402. pFdi->VolumeExt = 0;
  403. pFdi->Size = FixedDiskInfoSize;
  404. if (IsVolume) {
  405. pFdi->DriveType = CONFIG_DRIVE_VOLUME;
  406. //
  407. // Volume can span multiple hard disks, so here we set the DriverNumber to -1
  408. //
  409. pFdi->DiskNumber = (ULONG)(-1);
  410. pFdi->PartitionNumber = 1;
  411. pFdi->VolumeExt= FIELD_OFFSET (LOGICAL_DISK_EXTENTS, VolumeExt);
  412. VolumeExtPtr = (PUCHAR) OffsetToPtr (pFdi, pFdi->VolumeExt);
  413. RtlCopyMemory(VolumeExtPtr,
  414. pVolExt,
  415. sizeof(VOLUME_DISK_EXTENTS) + (pVolExt->NumberOfDiskExtents) * sizeof(DISK_EXTENT));
  416. }
  417. else {
  418. pFdi->DriveType = CONFIG_DRIVE_PARTITION;
  419. pFdi->DiskNumber = StorageDeviceNum.DeviceNumber;
  420. pFdi->PartitionNumber = StorageDeviceNum.PartitionNumber;
  421. }
  422. pFdi->DriveLetterString[0] = DriveLetterString[0];
  423. pFdi->DriveLetterString[1] = DriveLetterString[1];
  424. pFdi->DriveLetterString[2] = DriveLetterString[2];
  425. DriveRootName[0] = pFdi->DriveLetterString[0];
  426. DriveRootName[1] = pFdi->DriveLetterString[1];
  427. DriveRootName[2] = L'\\';
  428. DriveRootName[3] = UNICODE_NULL;
  429. pFdi->SectorsPerCluster = 0;
  430. pFdi->BytesPerSector = 0;
  431. pFdi->NumberOfFreeClusters = 0;
  432. pFdi->TotalNumberOfClusters = 0;
  433. //
  434. // Get partition information.
  435. //
  436. if ( !DeviceIoControl(VolumeHandle,
  437. IOCTL_DISK_GET_PARTITION_INFO_EX,
  438. NULL,
  439. 0,
  440. &PartitionInfo,
  441. sizeof( PartitionInfo ),
  442. &BytesTransferred,
  443. NULL ) ) {
  444. dwLastError = GetLastError();
  445. goto ErrorExit;
  446. }
  447. CloseHandle(VolumeHandle);
  448. VolumeHandle = NULL;
  449. if (pBuf) {
  450. RtlFreeHeap (RtlProcessHeap(),0,pBuf);
  451. }
  452. pBuf = NULL;
  453. //
  454. // Get the information of the logical drive
  455. //
  456. if (!GetDiskFreeSpaceW(DriveRootName,
  457. &pFdi->SectorsPerCluster,
  458. &pFdi->BytesPerSector,
  459. &TotalFreeClusters,
  460. &TotalClusters)) {
  461. dwLastError = GetLastError();
  462. if(dwLastError == ERROR_UNRECOGNIZED_VOLUME) {
  463. //
  464. // This could be a partition that has been assigned drive letter but not yet formatted
  465. //
  466. pFdi->SectorsPerCluster = 0;
  467. pFdi->BytesPerSector = 0;
  468. goto SkipFreeSpace;
  469. }
  470. goto ErrorExit;
  471. }
  472. if (!GetDiskFreeSpaceExW(DriveRootName,
  473. &FreeBytesToCaller,
  474. &TotalBytes,
  475. &TotalFreeBytes)) {
  476. dwLastError = GetLastError();
  477. if(dwLastError == ERROR_UNRECOGNIZED_VOLUME) {
  478. //
  479. // This could be a partition that has been assigned drive letter but not yet formatted
  480. //
  481. goto SkipFreeSpace;
  482. }
  483. goto ErrorExit;
  484. }
  485. pFdi->NumberOfFreeClusters = TotalFreeBytes.QuadPart / (pFdi->BytesPerSector * pFdi->SectorsPerCluster);
  486. pFdi->TotalNumberOfClusters = TotalBytes.QuadPart / (pFdi->BytesPerSector * pFdi->SectorsPerCluster);
  487. SkipFreeSpace:
  488. pFdi->StartingOffset = PartitionInfo.StartingOffset.QuadPart;
  489. pFdi->PartitionSize = (ULONGLONG)(((ULONGLONG)pFdi->TotalNumberOfClusters) *
  490. ((ULONGLONG)pFdi->SectorsPerCluster) *
  491. ((ULONGLONG)pFdi->BytesPerSector));
  492. //
  493. // Get the file system type of the logical drive
  494. //
  495. if (!GetVolumeInformationW(DriveRootName,
  496. NULL,
  497. 0,
  498. NULL,
  499. NULL,
  500. NULL,
  501. pFdi->FileSystemType,
  502. CONFIG_FS_NAME_LEN
  503. ))
  504. {
  505. hr = StringCchCopy(pFdi->FileSystemType, CONFIG_FS_NAME_LEN, L"(unknown)");
  506. if(FAILED(hr)) {
  507. goto ErrorExit;
  508. }
  509. }
  510. *ppFdi = pFdi;
  511. if (VolumeHandle != INVALID_HANDLE_VALUE) {
  512. CloseHandle( VolumeHandle );
  513. }
  514. return STATUS_SUCCESS;
  515. ErrorExit:
  516. if (VolumeHandle != INVALID_HANDLE_VALUE) {
  517. CloseHandle( VolumeHandle );
  518. VolumeHandle = INVALID_HANDLE_VALUE;
  519. }
  520. if (pFdi) {
  521. RtlFreeHeap (RtlProcessHeap(),0,pFdi);
  522. }
  523. if (pBuf) {
  524. RtlFreeHeap (RtlProcessHeap(),0,pBuf);
  525. }
  526. return STATUS_UNSUCCESSFUL;
  527. }
  528. NTSTATUS
  529. EtwpGetDiskInfo(
  530. IN PWMI_LOGGER_CONTEXT LoggerContext
  531. )
  532. {
  533. PUCHAR Buffer = NULL;
  534. STORAGE_DEVICE_NUMBER Number;
  535. PMOUNTMGR_MOUNT_POINTS mountPoints = NULL;
  536. MOUNTMGR_MOUNT_POINT mountPoint;
  537. ULONG returnSize, success;
  538. SYSTEM_DEVICE_INFORMATION DevInfo;
  539. NTSTATUS Status = STATUS_SUCCESS;
  540. ULONG NumberOfDisks;
  541. PWCHAR deviceNameBuffer;
  542. ULONG i;
  543. OBJECT_ATTRIBUTES ObjectAttributes;
  544. IO_STATUS_BLOCK IoStatus;
  545. DISK_GEOMETRY_EX disk_geometryEx;
  546. PDISK_CACHE_INFORMATION disk_cache = NULL;
  547. PSCSI_ADDRESS scsi_address = NULL;
  548. HANDLE hDisk = INVALID_HANDLE_VALUE;
  549. UNICODE_STRING UnicodeName;
  550. PPHYSICAL_DISK_RECORD Disk = NULL;
  551. PLOGICAL_DISK_EXTENTS pLogicalDisk = NULL;
  552. PLOGICAL_DISK_EXTENTS pDiskExtents = NULL;
  553. ULONG SizeNeeded;
  554. PWCHAR LogicalDrives = NULL;
  555. DWORD LogicalDrivesSize = 0;
  556. LPWSTR Drive = NULL;
  557. DWORD Chars;
  558. ULONG BufferDataLength = 0;
  559. DWORD dwError;
  560. HRESULT hr;
  561. Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
  562. if (Buffer == NULL) {
  563. return STATUS_NO_MEMORY;
  564. }
  565. RtlZeroMemory(Buffer, DEFAULT_ALLOC_SIZE);
  566. //
  567. // Get the Number of Physical Disks
  568. //
  569. RtlZeroMemory(&DevInfo, sizeof(DevInfo));
  570. Status = NtQuerySystemInformation(
  571. SystemDeviceInformation,
  572. &DevInfo, sizeof (DevInfo), NULL);
  573. if (!NT_SUCCESS(Status)) {
  574. goto DiskCleanup;
  575. }
  576. NumberOfDisks = DevInfo.NumberOfDisks;
  577. //
  578. // Open Each Physical Disk and get Disk Layout information
  579. //
  580. for (i=0; i < NumberOfDisks; i++) {
  581. DISK_CACHE_INFORMATION cacheInfo;
  582. HANDLE PartitionHandle;
  583. HANDLE KeyHandle;
  584. ULONG DataLength;
  585. WCHAR BootDrive[MAX_PATH];
  586. WCHAR BootDriveLetter;
  587. WCHAR DriveBuffer[MAXSTR];
  588. PDRIVE_LAYOUT_INFORMATION_EX pDriveLayout = NULL;
  589. ULONG PartitionCount;
  590. ULONG j;
  591. BOOL bSuccess = FALSE;
  592. DWORD BufSize;
  593. ULONG Size = DEFAULT_ALLOC_SIZE;
  594. BOOL bValidDiskCacheInfo = FALSE;
  595. RtlZeroMemory(&disk_geometryEx, sizeof(DISK_GEOMETRY_EX));
  596. RtlZeroMemory(&cacheInfo, sizeof(DISK_CACHE_INFORMATION));
  597. PartitionCount = 0;
  598. BootDriveLetter = UNICODE_NULL;
  599. //
  600. // Get Boot Drive Letter
  601. //
  602. if(GetSystemDirectoryW(BootDrive, MAX_PATH)) {
  603. BootDriveLetter = BootDrive[0];
  604. }
  605. hr = StringCchPrintf(DriveBuffer, MAXSTR, L"\\\\.\\PhysicalDrive%d", i);
  606. if(FAILED(hr)) {
  607. Status = STATUS_UNSUCCESSFUL;
  608. goto DiskCleanup;
  609. }
  610. hDisk = CreateFileW(DriveBuffer,
  611. GENERIC_READ | GENERIC_WRITE,
  612. FILE_SHARE_READ | FILE_SHARE_WRITE,
  613. NULL, // No child process should inherit the handle
  614. OPEN_EXISTING,
  615. 0,
  616. NULL);
  617. if(hDisk == INVALID_HANDLE_VALUE) {
  618. goto DiskCleanup;
  619. }
  620. //
  621. // Get Partition0 handle to get the Disk layout
  622. //
  623. deviceNameBuffer = (PWCHAR) Buffer;
  624. hr = StringCchPrintf(deviceNameBuffer, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), L"\\Device\\Harddisk%d\\Partition0", i);
  625. if(FAILED(hr)) {
  626. Status = STATUS_UNSUCCESSFUL;
  627. goto DiskCleanup;
  628. }
  629. RtlInitUnicodeString(&UnicodeName, deviceNameBuffer);
  630. InitializeObjectAttributes(
  631. &ObjectAttributes,
  632. &UnicodeName,
  633. OBJ_CASE_INSENSITIVE,
  634. NULL,
  635. NULL
  636. );
  637. Status = NtOpenFile(
  638. &PartitionHandle,
  639. FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  640. &ObjectAttributes,
  641. &IoStatus,
  642. FILE_SHARE_READ | FILE_SHARE_WRITE,
  643. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
  644. );
  645. if (!NT_SUCCESS(Status)) {
  646. goto DiskCleanup;
  647. }
  648. //
  649. // Get geomerty information
  650. //
  651. Status = NtDeviceIoControlFile(PartitionHandle,
  652. 0,
  653. NULL,
  654. NULL,
  655. &IoStatus,
  656. IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
  657. NULL,
  658. 0,
  659. &disk_geometryEx,
  660. sizeof (DISK_GEOMETRY_EX)
  661. );
  662. if (!NT_SUCCESS(Status)) {
  663. RtlZeroMemory(&disk_geometryEx, sizeof(DISK_GEOMETRY_EX));
  664. NtClose(PartitionHandle);
  665. goto SkipPartition;
  666. }
  667. //
  668. // Get the scci information
  669. //
  670. scsi_address = (PSCSI_ADDRESS) Buffer;
  671. Status = NtDeviceIoControlFile(PartitionHandle,
  672. 0,
  673. NULL,
  674. NULL,
  675. &IoStatus,
  676. IOCTL_SCSI_GET_ADDRESS,
  677. NULL,
  678. 0,
  679. scsi_address,
  680. sizeof (SCSI_ADDRESS)
  681. );
  682. NtClose(PartitionHandle);
  683. if (!NT_SUCCESS(Status)) {
  684. goto DiskCleanup;
  685. }
  686. //
  687. // Get Manufacturer's name from Registry
  688. // We need to get the SCSI Address and then query the Registry with it.
  689. //
  690. hr = StringCchPrintf(DriveBuffer, MAXSTR,
  691. L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target ID %d\\Logical Unit Id %d",
  692. scsi_address->PortNumber, scsi_address->PathId, scsi_address->TargetId, scsi_address->Lun
  693. );
  694. if(FAILED(hr)) {
  695. Status = STATUS_UNSUCCESSFUL;
  696. goto DiskCleanup;
  697. }
  698. Status = EtwpRegOpenKey(DriveBuffer, &KeyHandle);
  699. if (!NT_SUCCESS(Status)) {
  700. goto DiskCleanup;
  701. }
  702. Size = DEFAULT_ALLOC_SIZE;
  703. RtlZeroMemory(Buffer, Size);
  704. DiskQuery:
  705. Status = EtwpRegQueryValueKey(KeyHandle,
  706. L"Identifier",
  707. Size,
  708. Buffer,
  709. &BufferDataLength);
  710. if (Status == STATUS_BUFFER_OVERFLOW) {
  711. RtlFreeHeap (RtlProcessHeap(),0,Buffer);
  712. Buffer = RtlAllocateHeap (RtlProcessHeap(),0,BufferDataLength);
  713. if (Buffer == NULL) {
  714. NtClose(KeyHandle);
  715. Status = STATUS_NO_MEMORY;
  716. goto DiskCleanup;
  717. }
  718. RtlZeroMemory(Buffer, BufferDataLength);
  719. goto DiskQuery;
  720. }
  721. NtClose(KeyHandle);
  722. if (!NT_SUCCESS(Status) ) {
  723. goto DiskCleanup;
  724. }
  725. //
  726. // Get the total partitions on the drive
  727. //
  728. BufSize = 2048;
  729. pDriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
  730. if(pDriveLayout == NULL) {
  731. goto DiskCleanup;
  732. }
  733. RtlZeroMemory(pDriveLayout, BufSize);
  734. bSuccess = DeviceIoControl (
  735. hDisk,
  736. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
  737. NULL,
  738. 0,
  739. pDriveLayout,
  740. BufSize,
  741. &DataLength,
  742. NULL
  743. );
  744. if(bSuccess == FALSE && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  745. BufSize = DataLength;
  746. if(pDriveLayout) {
  747. RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
  748. }
  749. pDriveLayout = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
  750. if(pDriveLayout == NULL) {
  751. Status = STATUS_NO_MEMORY;
  752. goto DiskCleanup;
  753. }
  754. else {
  755. RtlZeroMemory(pDriveLayout, BufSize);
  756. bSuccess = DeviceIoControl (
  757. hDisk,
  758. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
  759. NULL,
  760. 0,
  761. pDriveLayout,
  762. BufSize,
  763. &DataLength,
  764. NULL
  765. );
  766. }
  767. }
  768. if(bSuccess == FALSE) {
  769. //
  770. // If media type is not fixed media and device is not ready then dont query partition info.
  771. //
  772. if(disk_geometryEx.Geometry.MediaType != FixedMedia && GetLastError() == ERROR_NOT_READY) {
  773. goto SkipPartition;
  774. }
  775. if(pDriveLayout) {
  776. RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
  777. pDriveLayout = NULL;
  778. }
  779. continue;
  780. }
  781. //
  782. // Get Partition count for the current disk
  783. //
  784. PartitionCount = 0;
  785. j = 0;
  786. while (j < pDriveLayout->PartitionCount) {
  787. if (pDriveLayout->PartitionEntry[j].PartitionNumber != 0) {
  788. PartitionCount++;
  789. }
  790. j++;
  791. }
  792. //
  793. // Get cache info - IOCTL_DISK_GET_CACHE_INFORMATION
  794. //
  795. bValidDiskCacheInfo = DeviceIoControl(hDisk,
  796. IOCTL_DISK_GET_CACHE_INFORMATION,
  797. NULL,
  798. 0,
  799. &cacheInfo,
  800. sizeof(DISK_CACHE_INFORMATION),
  801. &DataLength,
  802. NULL);
  803. NtClose(hDisk);
  804. hDisk = INVALID_HANDLE_VALUE;
  805. //
  806. // Free drivelayout structure
  807. //
  808. if(pDriveLayout) {
  809. RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
  810. pDriveLayout = NULL;
  811. }
  812. SkipPartition:
  813. //
  814. // Package all information about this disk and write an event record
  815. //
  816. SizeNeeded = sizeof(PHYSICAL_DISK_RECORD) + BufferDataLength;
  817. Disk = (PPHYSICAL_DISK_RECORD) EtwpGetTraceBuffer( LoggerContext,
  818. NULL,
  819. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_PHYSICALDISK,
  820. SizeNeeded);
  821. if (Disk == NULL) {
  822. Status = STATUS_NO_MEMORY;
  823. goto DiskCleanup;
  824. }
  825. Disk->DiskNumber = i;
  826. Disk->BytesPerSector = disk_geometryEx.Geometry.BytesPerSector;
  827. Disk->SectorsPerTrack = disk_geometryEx.Geometry.SectorsPerTrack;
  828. Disk->TracksPerCylinder = disk_geometryEx.Geometry.TracksPerCylinder;
  829. Disk->Cylinders = disk_geometryEx.Geometry.Cylinders.QuadPart;
  830. if(scsi_address) {
  831. Disk->SCSIPortNumber = scsi_address->PortNumber;
  832. Disk->SCSIPathId = scsi_address->PathId;
  833. Disk->SCSITargetId = scsi_address->TargetId;
  834. Disk->SCSILun = scsi_address->Lun;
  835. }
  836. else {
  837. Disk->SCSIPortNumber = 0;
  838. Disk->SCSIPathId = 0;
  839. Disk->SCSITargetId = 0;
  840. Disk->SCSILun = 0;
  841. }
  842. Disk->BootDriveLetter[0] = BootDriveLetter;
  843. if (bValidDiskCacheInfo && cacheInfo.WriteCacheEnabled) {
  844. Disk->WriteCacheEnabled = TRUE;
  845. }
  846. Disk->PartitionCount = PartitionCount;
  847. if(BufferDataLength > MAX_DEVICE_ID_LENGTH*sizeof(WCHAR)) BufferDataLength = MAX_DEVICE_ID_LENGTH * sizeof(WCHAR);
  848. RtlCopyMemory(Disk->Manufacturer, Buffer, BufferDataLength);
  849. Disk->Manufacturer[BufferDataLength/2] = 0;
  850. }
  851. //
  852. // Retrieve the logical drive strings from the system.
  853. //
  854. LogicalDrivesSize = MAX_PATH * sizeof(WCHAR);
  855. DriveTry:
  856. LogicalDrives = RtlAllocateHeap (RtlProcessHeap(),0,LogicalDrivesSize);
  857. if(LogicalDrives == NULL) {
  858. Status = STATUS_NO_MEMORY;
  859. goto DiskCleanup;
  860. }
  861. RtlZeroMemory(LogicalDrives, LogicalDrivesSize);
  862. Chars = GetLogicalDriveStringsW(LogicalDrivesSize / sizeof(WCHAR), LogicalDrives);
  863. if(Chars > LogicalDrivesSize) {
  864. RtlFreeHeap (RtlProcessHeap(),0,LogicalDrives);
  865. LogicalDrivesSize = Chars;
  866. goto DriveTry;
  867. }
  868. else if(Chars == 0) {
  869. RtlFreeHeap (RtlProcessHeap(),0,LogicalDrives);
  870. Status = STATUS_UNSUCCESSFUL;
  871. goto DiskCleanup;
  872. }
  873. Drive = LogicalDrives;
  874. //
  875. // How many logical drives in physical disks exist?
  876. //
  877. while ( *Drive ) {
  878. WCHAR DriveLetter[CONFIG_BOOT_DRIVE_LEN];
  879. size_t DriveTypeLength;
  880. DriveLetter[ 0 ] = Drive [ 0 ];
  881. DriveLetter[ 1 ] = Drive [ 1 ];
  882. DriveLetter[ 2 ] = UNICODE_NULL;
  883. if(GetDriveTypeW( Drive ) == DRIVE_FIXED) {
  884. //
  885. // If this is a logical drive which resides in a hard disk
  886. // we need to allocate a FixedDiskInfo structure for it.
  887. //
  888. if(GetIoFixedDrive(&pLogicalDisk, DriveLetter) == STATUS_SUCCESS) {
  889. SizeNeeded = pLogicalDisk->Size;
  890. //
  891. // Package all information about this disk and write an event record
  892. //
  893. pDiskExtents = (PLOGICAL_DISK_EXTENTS) EtwpGetTraceBuffer( LoggerContext,
  894. NULL,
  895. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_LOGICALDISK,
  896. SizeNeeded);
  897. if(pDiskExtents == NULL) {
  898. RtlFreeHeap (RtlProcessHeap(),0,pLogicalDisk);
  899. pLogicalDisk = NULL;
  900. Status = STATUS_NO_MEMORY;
  901. goto DiskCleanup;
  902. }
  903. RtlCopyMemory(pDiskExtents, pLogicalDisk, SizeNeeded);
  904. RtlFreeHeap (RtlProcessHeap(),0,pLogicalDisk);
  905. pLogicalDisk = NULL;
  906. }
  907. }
  908. hr = StringCchLength(Drive, LogicalDrivesSize/sizeof(WCHAR), &DriveTypeLength);
  909. if(FAILED(hr)) {
  910. Status = STATUS_UNSUCCESSFUL;
  911. goto DiskCleanup;
  912. }
  913. Drive += (DriveTypeLength + 1);
  914. LogicalDrivesSize -= (DriveTypeLength+1) * sizeof(WCHAR);
  915. }
  916. DiskCleanup:
  917. if (Buffer != NULL) {
  918. RtlFreeHeap (RtlProcessHeap(),0,Buffer);
  919. }
  920. if(hDisk != INVALID_HANDLE_VALUE) {
  921. NtClose(hDisk);
  922. }
  923. return Status;
  924. }
  925. NTSTATUS
  926. EtwpGetVideoAdapters(
  927. IN PWMI_LOGGER_CONTEXT LoggerContext
  928. )
  929. {
  930. PVIDEO_RECORD Video = NULL;
  931. VIDEO_RECORD VideoRecord;
  932. HANDLE hVideoDeviceMap;
  933. HANDLE hVideoDriver;
  934. HANDLE hHardwareProfile;
  935. ULONG DeviceId = 0;
  936. PWCHAR Device = NULL;
  937. PWCHAR HardwareProfile = NULL;
  938. PWCHAR Driver = NULL;
  939. PWCHAR Buffer = NULL;
  940. PWCHAR DriverRegistryPath = NULL;
  941. ULONG ResultLength;
  942. PCHAR ValueBuffer = NULL;
  943. ULONG Length;
  944. BOOLEAN IsAdapter;
  945. ULONG SizeNeeded;
  946. NTSTATUS Status;
  947. INT i;
  948. DWORD iDevice = 0;
  949. DISPLAY_DEVICEW dd;
  950. HINSTANCE hUser32Dll = NULL;
  951. T_EnumDisplayDevicesW *pfnEnumDisplayDevicesW = NULL;
  952. LPWSTR ChipsetInfo[6] = {
  953. L"HardwareInformation.MemorySize",
  954. L"HardwareInformation.ChipType",
  955. L"HardwareInformation.DacType",
  956. L"HardwareInformation.AdapterString",
  957. L"HardwareInformation.BiosString",
  958. L"Device Description"
  959. };
  960. LPWSTR SettingInfo[4] = {
  961. L"DefaultSettings.BitsPerPel",
  962. L"DefaultSettings.VRefresh",
  963. L"DefaultSettings.XResolution",
  964. L"DefaultSettings.YResolution",
  965. };
  966. HRESULT hr;
  967. //
  968. // delay load user32.lib to enum display devices function
  969. //
  970. hUser32Dll = LoadLibraryW(L"user32.dll");
  971. if (hUser32Dll == NULL) {
  972. return STATUS_DELAY_LOAD_FAILED;
  973. }
  974. RtlZeroMemory(&dd, sizeof(dd));
  975. dd.cb = sizeof(dd);
  976. //
  977. // Enumerate all the video devices in the system
  978. //
  979. Status = EtwpRegOpenKey(REG_PATH_VIDEO_DEVICE_MAP, &hVideoDeviceMap);
  980. if (!NT_SUCCESS(Status)) {
  981. return Status;
  982. }
  983. //
  984. // Allocate memory for local variables on heap
  985. //
  986. Device = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
  987. if(Device == NULL) {
  988. Status = STATUS_NO_MEMORY;
  989. goto VideoCleanup;
  990. }
  991. RtlZeroMemory(Device, DEFAULT_ALLOC_SIZE);
  992. HardwareProfile = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
  993. if(HardwareProfile == NULL) {
  994. Status = STATUS_NO_MEMORY;
  995. goto VideoCleanup;
  996. }
  997. RtlZeroMemory(HardwareProfile, DEFAULT_ALLOC_SIZE);
  998. Driver = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
  999. if(Driver == NULL) {
  1000. Status = STATUS_NO_MEMORY;
  1001. goto VideoCleanup;
  1002. }
  1003. RtlZeroMemory(Driver, DEFAULT_ALLOC_SIZE);
  1004. Buffer = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
  1005. if(Buffer == NULL) {
  1006. Status = STATUS_NO_MEMORY;
  1007. goto VideoCleanup;
  1008. }
  1009. RtlZeroMemory(Buffer, DEFAULT_ALLOC_SIZE);
  1010. while (TRUE) {
  1011. RtlZeroMemory(&VideoRecord, sizeof(VideoRecord));
  1012. //
  1013. // Open video device
  1014. //
  1015. hr = StringCchPrintf(Device, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), L"\\Device\\Video%d", DeviceId++);
  1016. if(FAILED(hr)) {
  1017. Status = STATUS_UNSUCCESSFUL;
  1018. break;
  1019. }
  1020. Status = EtwpRegQueryValueKey(hVideoDeviceMap,
  1021. Device,
  1022. DEFAULT_ALLOC_SIZE,
  1023. Buffer,
  1024. &ResultLength
  1025. );
  1026. if (!NT_SUCCESS(Status)) {
  1027. Status = STATUS_SUCCESS;
  1028. break;
  1029. }
  1030. //
  1031. // Open the driver registry key
  1032. //
  1033. Status = EtwpRegOpenKey(Buffer, &hVideoDriver);
  1034. if (!NT_SUCCESS(Status)) {
  1035. continue;
  1036. }
  1037. //
  1038. // Get Video adapter information.
  1039. //
  1040. IsAdapter = TRUE;
  1041. for (i = 0; i < 6; i++) {
  1042. switch (i ) {
  1043. case 0:
  1044. ValueBuffer = (PCHAR)&VideoRecord.MemorySize;
  1045. Length = sizeof(VideoRecord.MemorySize);
  1046. break;
  1047. case 1:
  1048. ValueBuffer = (PCHAR)&VideoRecord.ChipType;
  1049. Length = sizeof(VideoRecord.ChipType);
  1050. break;
  1051. case 2:
  1052. ValueBuffer = (PCHAR)&VideoRecord.DACType;
  1053. Length = sizeof(VideoRecord.DACType);
  1054. break;
  1055. case 3:
  1056. ValueBuffer = (PCHAR)&VideoRecord.AdapterString;
  1057. Length = sizeof(VideoRecord.AdapterString);
  1058. break;
  1059. case 4:
  1060. ValueBuffer = (PCHAR)&VideoRecord.BiosString;
  1061. Length = sizeof(VideoRecord.BiosString);
  1062. break;
  1063. case 5:
  1064. ValueBuffer = (PCHAR)&VideoRecord.DeviceId;
  1065. Length = sizeof(VideoRecord.DeviceId);
  1066. break;
  1067. }
  1068. //
  1069. // Query the size of the data
  1070. //
  1071. Status = EtwpRegQueryValueKey(hVideoDriver,
  1072. ChipsetInfo[i],
  1073. Length,
  1074. ValueBuffer,
  1075. &ResultLength);
  1076. //
  1077. // If we can not get the hardware information, this
  1078. // is not adapter
  1079. //
  1080. if (!NT_SUCCESS(Status)) {
  1081. IsAdapter = FALSE;
  1082. break;
  1083. }
  1084. }
  1085. NtClose(hVideoDriver);
  1086. if (IsAdapter == FALSE) {
  1087. continue;
  1088. }
  1089. DriverRegistryPath = wcsstr(Buffer, L"{");
  1090. if(DriverRegistryPath == NULL) {
  1091. continue;
  1092. }
  1093. hr = StringCchPrintf(HardwareProfile, DEFAULT_ALLOC_SIZE/sizeof(WCHAR), L"%s\\%s", REG_PATH_VIDEO_HARDWARE_PROFILE, DriverRegistryPath);
  1094. if(FAILED(hr)) {
  1095. continue;
  1096. }
  1097. Status = EtwpRegOpenKey(HardwareProfile, &hHardwareProfile);
  1098. if (!NT_SUCCESS(Status)) {
  1099. continue;
  1100. }
  1101. for (i = 0; i < 4; i++) {
  1102. switch (i ) {
  1103. case 0:
  1104. ValueBuffer = (PCHAR)&VideoRecord.BitsPerPixel;
  1105. Length = sizeof(VideoRecord.BitsPerPixel);
  1106. break;
  1107. case 1:
  1108. ValueBuffer = (PCHAR)&VideoRecord.VRefresh;
  1109. Length = sizeof(VideoRecord.VRefresh);
  1110. break;
  1111. case 2:
  1112. ValueBuffer = (PCHAR)&VideoRecord.XResolution;
  1113. Length = sizeof(VideoRecord.XResolution);
  1114. break;
  1115. case 3:
  1116. ValueBuffer = (PCHAR)&VideoRecord.YResolution;
  1117. Length = sizeof(VideoRecord.YResolution);
  1118. break;
  1119. }
  1120. //
  1121. // Query the size of the data
  1122. //
  1123. Status = EtwpRegQueryValueKey(hHardwareProfile,
  1124. SettingInfo[i],
  1125. Length,
  1126. ValueBuffer,
  1127. &ResultLength);
  1128. }
  1129. NtClose(hHardwareProfile);
  1130. //
  1131. // Enum display devices
  1132. //
  1133. pfnEnumDisplayDevicesW = (T_EnumDisplayDevicesW *) GetProcAddress(hUser32Dll, "EnumDisplayDevicesW");
  1134. if(pfnEnumDisplayDevicesW == NULL) {
  1135. Status = STATUS_PROCEDURE_NOT_FOUND;
  1136. break;
  1137. }
  1138. while (pfnEnumDisplayDevicesW(NULL, iDevice++, &dd, 0)) {
  1139. if (_wcsicmp(VideoRecord.DeviceId, dd.DeviceString) == 0) {
  1140. if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
  1141. VideoRecord.StateFlags = (ULONG)dd.StateFlags;
  1142. }
  1143. break;
  1144. iDevice = 0;
  1145. }
  1146. }
  1147. //
  1148. // Package all information about this disk and write an event record
  1149. //
  1150. SizeNeeded = sizeof(VIDEO_RECORD);
  1151. Video = (PVIDEO_RECORD) EtwpGetTraceBuffer( LoggerContext,
  1152. NULL,
  1153. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_VIDEO,
  1154. SizeNeeded);
  1155. if (Video == NULL) {
  1156. Status = STATUS_NO_MEMORY;
  1157. break;
  1158. }
  1159. RtlCopyMemory(Video, &VideoRecord, sizeof(VIDEO_RECORD));
  1160. }
  1161. VideoCleanup:
  1162. NtClose(hVideoDeviceMap);
  1163. if (hUser32Dll) {
  1164. FreeLibrary(hUser32Dll);
  1165. }
  1166. //
  1167. // Free local variables allocated on heap
  1168. //
  1169. if(Device) {
  1170. RtlFreeHeap (RtlProcessHeap(), 0, Device);
  1171. }
  1172. if(HardwareProfile) {
  1173. RtlFreeHeap (RtlProcessHeap(), 0, HardwareProfile);
  1174. }
  1175. if(Driver) {
  1176. RtlFreeHeap (RtlProcessHeap(), 0, Driver);
  1177. }
  1178. if(Buffer) {
  1179. RtlFreeHeap (RtlProcessHeap(), 0, Buffer);
  1180. }
  1181. return Status;
  1182. }
  1183. NTSTATUS
  1184. EtwpGetNetworkAdapters(
  1185. IN PWMI_LOGGER_CONTEXT LoggerContext
  1186. )
  1187. {
  1188. DWORD IfNum;
  1189. DWORD Ret;
  1190. PIP_ADAPTER_INFO pAdapterList = NULL, pAdapterListHead = NULL;
  1191. PIP_PER_ADAPTER_INFO pPerAdapterInfo = NULL;
  1192. PFIXED_INFO pFixedInfo = NULL;
  1193. PIP_ADDR_STRING pIpAddressList = NULL;
  1194. ULONG OutBufLen = 0;
  1195. INT i;
  1196. NIC_RECORD AdapterInfo;
  1197. PNIC_RECORD pAdapterInfo = NULL;
  1198. NTSTATUS Status = STATUS_SUCCESS;
  1199. INT IpAddrLen = 0;
  1200. T_GetAdaptersInfo *pfnGetAdaptersInfo = NULL;
  1201. T_GetPerAdapterInfo *pfnGetPerAdapterInfo = NULL;
  1202. HINSTANCE hIphlpapiDll = NULL;
  1203. PUCHAR IpDataPtr = NULL;
  1204. // delay load iphlpapi.lib to Get network params
  1205. hIphlpapiDll = LoadLibraryW(L"iphlpapi.dll");
  1206. if (hIphlpapiDll == NULL) {
  1207. Status = STATUS_DELAY_LOAD_FAILED;
  1208. goto IpCleanup;
  1209. }
  1210. pfnGetAdaptersInfo = (T_GetAdaptersInfo*) GetProcAddress(hIphlpapiDll, "GetAdaptersInfo");
  1211. if(pfnGetAdaptersInfo == NULL) {
  1212. Status = STATUS_PROCEDURE_NOT_FOUND;
  1213. goto IpCleanup;
  1214. }
  1215. pfnGetPerAdapterInfo = (T_GetPerAdapterInfo*) GetProcAddress(hIphlpapiDll, "GetPerAdapterInfo");
  1216. if(pfnGetPerAdapterInfo == NULL) {
  1217. Status = STATUS_PROCEDURE_NOT_FOUND;
  1218. goto IpCleanup;
  1219. }
  1220. //
  1221. // Get number of adapters
  1222. //
  1223. Ret = pfnGetAdaptersInfo(NULL, &OutBufLen);
  1224. if(Ret != ERROR_BUFFER_OVERFLOW) {
  1225. Status = STATUS_UNSUCCESSFUL;
  1226. goto IpCleanup;
  1227. }
  1228. TryAgain:
  1229. pAdapterList = (PIP_ADAPTER_INFO)RtlAllocateHeap (RtlProcessHeap(),0,OutBufLen);
  1230. if (pAdapterList == NULL) {
  1231. Status = STATUS_NO_MEMORY;
  1232. goto IpCleanup;
  1233. }
  1234. RtlZeroMemory(pAdapterList, OutBufLen);
  1235. Ret = pfnGetAdaptersInfo(pAdapterList, &OutBufLen);
  1236. if(Ret != ERROR_SUCCESS) {
  1237. if (Ret == ERROR_BUFFER_OVERFLOW) {
  1238. RtlFreeHeap (RtlProcessHeap(),0,pAdapterList);
  1239. goto TryAgain;
  1240. }
  1241. if (pAdapterList != NULL) {
  1242. RtlFreeHeap (RtlProcessHeap(),0,pAdapterList);
  1243. }
  1244. Status = STATUS_UNSUCCESSFUL;
  1245. goto IpCleanup;
  1246. }
  1247. //
  1248. // Calculate the total length for all the IP Addresses
  1249. //
  1250. IpAddrLen = sizeof(IP_ADDRESS_STRING) * CONFIG_MAX_DNS_SERVER; // Length of 4 DNS Server IP Address
  1251. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of IP Address
  1252. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of IP Mask
  1253. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of DHCP Server IP Address
  1254. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Gateway IP Address
  1255. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Primary Wins Server IP Address
  1256. IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Secondary Wins Server IP Address
  1257. //
  1258. // Allocate memory for NIC_RECORD
  1259. //
  1260. RtlZeroMemory(&AdapterInfo, sizeof(AdapterInfo));
  1261. //
  1262. // Fill out the information per adapter
  1263. //
  1264. pAdapterListHead = pAdapterList;
  1265. while (pAdapterList ) {
  1266. MultiByteToWideChar(CP_ACP,
  1267. 0,
  1268. (LPCSTR)pAdapterList->Description,
  1269. -1,
  1270. (LPWSTR)AdapterInfo.NICName,
  1271. MAX_DEVICE_ID_LENGTH);
  1272. AdapterInfo.Index = (ULONG)pAdapterList->Index;
  1273. //
  1274. // Copy the Physical address of NIC
  1275. //
  1276. AdapterInfo.PhysicalAddrLen = pAdapterList->AddressLength;
  1277. RtlCopyMemory(AdapterInfo.PhysicalAddr, pAdapterList->Address, pAdapterList->AddressLength);
  1278. //
  1279. // Set the size of the Data
  1280. //
  1281. AdapterInfo.Size = IpAddrLen;
  1282. //
  1283. // Get DNS server list for this adapter
  1284. //
  1285. Ret = pfnGetPerAdapterInfo(pAdapterList->Index, NULL, &OutBufLen);
  1286. if(Ret != ERROR_BUFFER_OVERFLOW) {
  1287. Status = STATUS_UNSUCCESSFUL;
  1288. goto IpCleanup;
  1289. }
  1290. pPerAdapterInfo = (PIP_PER_ADAPTER_INFO)RtlAllocateHeap (RtlProcessHeap(),0,OutBufLen);
  1291. if (!pPerAdapterInfo) {
  1292. Status = STATUS_NO_MEMORY;
  1293. goto IpCleanup;
  1294. }
  1295. RtlZeroMemory(pPerAdapterInfo, OutBufLen);
  1296. Ret = pfnGetPerAdapterInfo(pAdapterList->Index, pPerAdapterInfo, &OutBufLen);
  1297. if(Ret != ERROR_SUCCESS) {
  1298. Status = STATUS_UNSUCCESSFUL;
  1299. goto IpCleanup;
  1300. }
  1301. //
  1302. // Package all information about this NIC and write an event record
  1303. //
  1304. pAdapterInfo = (PNIC_RECORD) EtwpGetTraceBuffer( LoggerContext,
  1305. NULL,
  1306. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_NIC,
  1307. sizeof(NIC_RECORD) + IpAddrLen);
  1308. if(!pAdapterInfo) {
  1309. Status = STATUS_NO_MEMORY;
  1310. goto IpCleanup;
  1311. }
  1312. RtlCopyMemory(pAdapterInfo,
  1313. &AdapterInfo,
  1314. sizeof(NIC_RECORD));
  1315. //
  1316. // Copy the IP Address and Subnet mask
  1317. //
  1318. if (pAdapterList->CurrentIpAddress) {
  1319. pAdapterInfo->IpAddress = FIELD_OFFSET(NIC_RECORD, Data);
  1320. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->IpAddress),
  1321. &(pAdapterList->CurrentIpAddress->IpAddress),
  1322. sizeof(IP_ADDRESS_STRING));
  1323. pAdapterInfo->SubnetMask = pAdapterInfo->IpAddress + sizeof(IP_ADDRESS_STRING);
  1324. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SubnetMask),
  1325. &(pAdapterList->CurrentIpAddress->IpMask),
  1326. sizeof(IP_ADDRESS_STRING));
  1327. }
  1328. else {
  1329. pAdapterInfo->IpAddress = FIELD_OFFSET(NIC_RECORD, Data);
  1330. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->IpAddress),
  1331. &(pAdapterList->IpAddressList.IpAddress),
  1332. sizeof(IP_ADDRESS_STRING));
  1333. pAdapterInfo->SubnetMask = pAdapterInfo->IpAddress + sizeof(IP_ADDRESS_STRING);
  1334. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SubnetMask),
  1335. &(pAdapterList->IpAddressList.IpMask),
  1336. sizeof(IP_ADDRESS_STRING));
  1337. }
  1338. //
  1339. // Copy the Dhcp Server IP Address
  1340. //
  1341. pAdapterInfo->DhcpServer = pAdapterInfo->SubnetMask + sizeof(IP_ADDRESS_STRING);
  1342. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->DhcpServer),
  1343. &(pAdapterList->DhcpServer.IpAddress),
  1344. sizeof(IP_ADDRESS_STRING));
  1345. //
  1346. // Copy the Gateway IP Address
  1347. //
  1348. pAdapterInfo->Gateway = pAdapterInfo->DhcpServer + sizeof(IP_ADDRESS_STRING);
  1349. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->Gateway),
  1350. &(pAdapterList->GatewayList.IpAddress),
  1351. sizeof(IP_ADDRESS_STRING));
  1352. //
  1353. // Copy the Primary Wins Server IP Address
  1354. //
  1355. pAdapterInfo->PrimaryWinsServer = pAdapterInfo->Gateway + sizeof(IP_ADDRESS_STRING);
  1356. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->PrimaryWinsServer),
  1357. &(pAdapterList->PrimaryWinsServer.IpAddress),
  1358. sizeof(IP_ADDRESS_STRING));
  1359. //
  1360. // Copy the Secondary Wins Server IP Address
  1361. //
  1362. pAdapterInfo->SecondaryWinsServer = pAdapterInfo->PrimaryWinsServer + sizeof(IP_ADDRESS_STRING);
  1363. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SecondaryWinsServer),
  1364. &(pAdapterList->SecondaryWinsServer.IpAddress),
  1365. sizeof(IP_ADDRESS_STRING));
  1366. //
  1367. // Hardcoded entries for DNS server(limited upto 4);
  1368. //
  1369. pIpAddressList = &pPerAdapterInfo->DnsServerList;
  1370. pAdapterInfo->DnsServer[0] = pAdapterInfo->SecondaryWinsServer + sizeof(IP_ADDRESS_STRING);
  1371. for (i = 0; pIpAddressList && i < CONFIG_MAX_DNS_SERVER; i++) {
  1372. RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->DnsServer[i]),
  1373. &(pIpAddressList->IpAddress),
  1374. sizeof(IP_ADDRESS_STRING));
  1375. if(i < CONFIG_MAX_DNS_SERVER - 1) {
  1376. pAdapterInfo->DnsServer[i + 1] = pAdapterInfo->DnsServer[i] + sizeof(IP_ADDRESS_STRING);
  1377. }
  1378. pIpAddressList = pIpAddressList->Next;
  1379. }
  1380. //
  1381. // Free the DNS server list
  1382. //
  1383. RtlFreeHeap (RtlProcessHeap(),0,pPerAdapterInfo);
  1384. pPerAdapterInfo = NULL;
  1385. //
  1386. // increment the AdapterInfo buffer position for next record
  1387. //
  1388. pAdapterList = pAdapterList->Next;
  1389. }
  1390. IpCleanup:
  1391. if (pAdapterListHead) {
  1392. RtlFreeHeap (RtlProcessHeap(),0,pAdapterListHead);
  1393. }
  1394. if(pPerAdapterInfo) {
  1395. RtlFreeHeap(RtlProcessHeap(),0,pPerAdapterInfo);
  1396. }
  1397. if(hIphlpapiDll) {
  1398. FreeLibrary(hIphlpapiDll);
  1399. }
  1400. return Status;
  1401. }
  1402. NTSTATUS
  1403. EtwpGetServiceInfo(
  1404. IN PWMI_LOGGER_CONTEXT LoggerContext
  1405. )
  1406. {
  1407. DWORD dwServicesNum = 0;
  1408. SC_HANDLE hScm = NULL;
  1409. NTSTATUS Status = STATUS_UNSUCCESSFUL;
  1410. PSYSTEM_PROCESS_INFORMATION pProcInfo = NULL;
  1411. PSYSTEM_PROCESS_INFORMATION ppProcInfo = NULL;
  1412. PUCHAR pBuffer = NULL;
  1413. ULONG ulBufferSize = 16 * DEFAULT_ALLOC_SIZE;
  1414. ULONG TotalOffset;
  1415. ULONG TotalTasks = 0;
  1416. ULONG j;
  1417. ULONG ulReturnedLength = 0;
  1418. HRESULT hr;
  1419. //
  1420. // Allocate memory for process Info
  1421. //
  1422. retry:
  1423. pBuffer = RtlAllocateHeap (RtlProcessHeap(),0,ulBufferSize);
  1424. if(pBuffer == NULL) {
  1425. return STATUS_NO_MEMORY;
  1426. }
  1427. RtlZeroMemory(pBuffer, ulBufferSize);
  1428. //
  1429. // Query process Info
  1430. //
  1431. Status = NtQuerySystemInformation(
  1432. SystemProcessInformation,
  1433. pBuffer,
  1434. ulBufferSize,
  1435. &ulReturnedLength
  1436. );
  1437. if(!NT_SUCCESS(Status)) {
  1438. if (Status == STATUS_INFO_LENGTH_MISMATCH) {
  1439. ulBufferSize = ulReturnedLength;
  1440. RtlFreeHeap (RtlProcessHeap(),0,pBuffer);
  1441. pBuffer = NULL;
  1442. goto retry;
  1443. }
  1444. goto ServiceCleanup;
  1445. }
  1446. pProcInfo = (PSYSTEM_PROCESS_INFORMATION) pBuffer;
  1447. //
  1448. // Connect to the service controller.
  1449. //
  1450. hScm = OpenSCManager(
  1451. NULL,
  1452. NULL,
  1453. SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE
  1454. );
  1455. if (hScm) {
  1456. LPENUM_SERVICE_STATUS_PROCESSW pInfo = NULL;
  1457. LPENUM_SERVICE_STATUS_PROCESSW ppInfo = NULL;
  1458. DWORD cbInfo = DEFAULT_ALLOC_SIZE;
  1459. DWORD dwErr = ERROR_SUCCESS;
  1460. DWORD dwResume = 0;
  1461. DWORD cLoop = 0;
  1462. const DWORD cLoopMax = 2;
  1463. WMI_SERVICE_INFO ServiceInfo;
  1464. PWMI_SERVICE_INFO pServiceInfo = NULL;
  1465. SERVICE_STATUS_PROCESS ServiceProcess;
  1466. PWCHAR p = NULL;
  1467. DWORD dwRemainBytes;
  1468. //
  1469. // First pass through the loop allocates from an initial guess. (4K)
  1470. // If that isn't sufficient, we make another pass and allocate
  1471. // what is actually needed. (We only go through the loop a
  1472. // maximum of two times.)
  1473. //
  1474. do {
  1475. if (pInfo) {
  1476. RtlFreeHeap (RtlProcessHeap(),0,pInfo);
  1477. }
  1478. pInfo = (LPENUM_SERVICE_STATUS_PROCESSW)RtlAllocateHeap (RtlProcessHeap(),0,cbInfo);
  1479. if (!pInfo) {
  1480. dwErr = ERROR_OUTOFMEMORY;
  1481. break;
  1482. }
  1483. RtlZeroMemory(pInfo, cbInfo);
  1484. dwErr = ERROR_SUCCESS;
  1485. if (!EnumServicesStatusExW(
  1486. hScm,
  1487. SC_ENUM_PROCESS_INFO,
  1488. SERVICE_WIN32,
  1489. SERVICE_ACTIVE,
  1490. (PBYTE)pInfo,
  1491. cbInfo,
  1492. &dwRemainBytes,
  1493. &dwServicesNum,
  1494. &dwResume,
  1495. NULL))
  1496. {
  1497. dwErr = GetLastError();
  1498. cbInfo += dwRemainBytes;
  1499. dwResume = 0;
  1500. }
  1501. } while ((ERROR_MORE_DATA == dwErr) && (++cLoop < cLoopMax));
  1502. if ((ERROR_SUCCESS == dwErr) && dwServicesNum) {
  1503. //
  1504. // Process each service and send an event
  1505. //
  1506. ppInfo = pInfo;
  1507. Status = STATUS_SUCCESS;
  1508. while(dwServicesNum) {
  1509. RtlZeroMemory(&ServiceInfo, sizeof(WMI_SERVICE_INFO));
  1510. hr = StringCchCopy(ServiceInfo.ServiceName, CONFIG_MAX_NAME_LENGTH, ppInfo->lpServiceName);
  1511. if(FAILED(hr)) {
  1512. Status = STATUS_UNSUCCESSFUL;
  1513. goto ServiceCleanup;
  1514. }
  1515. hr = StringCchCopy(ServiceInfo.DisplayName, CONFIG_MAX_DISPLAY_NAME, ppInfo->lpDisplayName);
  1516. if(FAILED(hr)) {
  1517. Status = STATUS_UNSUCCESSFUL;
  1518. goto ServiceCleanup;
  1519. }
  1520. ServiceInfo.ProcessId = ppInfo->ServiceStatusProcess.dwProcessId;
  1521. //
  1522. // Get the process name
  1523. //
  1524. ppProcInfo = pProcInfo;
  1525. TotalOffset = 0;
  1526. while(TRUE) {
  1527. if((DWORD)(DWORD_PTR)ppProcInfo->UniqueProcessId == ServiceInfo.ProcessId) {
  1528. if(ppProcInfo->ImageName.Buffer) {
  1529. p = wcschr(ppProcInfo->ImageName.Buffer, L'\\');
  1530. if ( p ) {
  1531. p++;
  1532. } else {
  1533. p = ppProcInfo->ImageName.Buffer;
  1534. }
  1535. }
  1536. else {
  1537. p = L"System Process";
  1538. }
  1539. hr = StringCchCopy(ServiceInfo.ProcessName, CONFIG_MAX_NAME_LENGTH, p);
  1540. if(FAILED(hr)) {
  1541. Status = STATUS_UNSUCCESSFUL;
  1542. goto ServiceCleanup;
  1543. }
  1544. }
  1545. if (ppProcInfo->NextEntryOffset == 0) {
  1546. break;
  1547. }
  1548. TotalOffset += ppProcInfo->NextEntryOffset;
  1549. ppProcInfo = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)pProcInfo+TotalOffset);
  1550. }
  1551. //
  1552. // Package all information about this NIC and write an event record
  1553. //
  1554. pServiceInfo = NULL;
  1555. pServiceInfo = (PWMI_SERVICE_INFO) EtwpGetTraceBuffer( LoggerContext,
  1556. NULL,
  1557. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_SERVICES,
  1558. sizeof(WMI_SERVICE_INFO));
  1559. if(pServiceInfo == NULL) {
  1560. Status = STATUS_UNSUCCESSFUL;
  1561. break;
  1562. }
  1563. RtlCopyMemory(pServiceInfo, &ServiceInfo, sizeof(WMI_SERVICE_INFO));
  1564. dwServicesNum--;
  1565. ppInfo++;
  1566. }
  1567. }
  1568. if (pInfo) {
  1569. RtlFreeHeap (RtlProcessHeap(),0,pInfo);
  1570. }
  1571. CloseServiceHandle(hScm);
  1572. }
  1573. ServiceCleanup:
  1574. if(pBuffer) {
  1575. RtlFreeHeap (RtlProcessHeap(),0,pBuffer);
  1576. }
  1577. return Status;
  1578. }
  1579. NTSTATUS
  1580. EtwpGetPowerInfo(
  1581. IN PWMI_LOGGER_CONTEXT LoggerContext
  1582. )
  1583. {
  1584. NTSTATUS Status;
  1585. SYSTEM_POWER_CAPABILITIES Cap;
  1586. WMI_POWER_RECORD Power;
  1587. PWMI_POWER_RECORD pPower = NULL;
  1588. RtlZeroMemory(&Power, sizeof(WMI_POWER_RECORD));
  1589. Status = NtPowerInformation (SystemPowerCapabilities,
  1590. NULL,
  1591. 0,
  1592. &Cap,
  1593. sizeof (Cap));
  1594. if(!NT_SUCCESS(Status)) {
  1595. Status = STATUS_UNSUCCESSFUL;
  1596. goto PowerCleanup;
  1597. }
  1598. Power.SystemS1 = Cap.SystemS1;
  1599. Power.SystemS2 = Cap.SystemS2;
  1600. Power.SystemS3 = Cap.SystemS3;
  1601. Power.SystemS4 = Cap.SystemS4;
  1602. Power.SystemS5 = Cap.SystemS5;
  1603. //
  1604. // Package all Power information and write an event record
  1605. //
  1606. pPower = (PWMI_POWER_RECORD) EtwpGetTraceBuffer(LoggerContext,
  1607. NULL,
  1608. EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_POWER,
  1609. sizeof(WMI_POWER_RECORD));
  1610. if(!pPower) {
  1611. Status = STATUS_NO_MEMORY;
  1612. goto PowerCleanup;
  1613. }
  1614. RtlCopyMemory(pPower,
  1615. &Power,
  1616. sizeof(WMI_POWER_RECORD));
  1617. PowerCleanup:
  1618. return Status;
  1619. }
  1620. //
  1621. // This routine records the hardware configuration in the
  1622. // logfile during RunDown
  1623. //
  1624. ULONG
  1625. EtwpDumpHardwareConfig(
  1626. IN PWMI_LOGGER_CONTEXT LoggerContext
  1627. )
  1628. {
  1629. NTSTATUS Status = STATUS_UNSUCCESSFUL;
  1630. Status = EtwpGetCpuConfig(LoggerContext);
  1631. if (!NT_SUCCESS(Status) )
  1632. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1633. Status = EtwpGetVideoAdapters(LoggerContext);
  1634. if (!NT_SUCCESS(Status) )
  1635. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1636. Status = EtwpGetDiskInfo(LoggerContext);
  1637. if (!NT_SUCCESS(Status) )
  1638. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1639. Status = EtwpGetNetworkAdapters(LoggerContext);
  1640. if (!NT_SUCCESS(Status) )
  1641. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1642. Status = EtwpGetServiceInfo(LoggerContext);
  1643. if (!NT_SUCCESS(Status) )
  1644. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1645. Status = EtwpGetPowerInfo(LoggerContext);
  1646. if (!NT_SUCCESS(Status) )
  1647. return EtwpSetDosError(EtwpNtStatusToDosError(Status));
  1648. return ERROR_SUCCESS;
  1649. }
  1650. void EtwpCallHWConfig(ULONG Reason) {
  1651. EtwpSetHWConfigFunction(EtwpDumpHardwareConfig, Reason);
  1652. }