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.

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