1813 lines
54 KiB
C
1813 lines
54 KiB
C
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tracehw.c
|
|
|
|
Abstract:
|
|
|
|
This routine dumps the hardware configuration of the machine to the
|
|
logfile.
|
|
|
|
Author:
|
|
|
|
04-Jul-2000 Melur Raghuraman
|
|
09-Sep-2001 Nitin Choubey
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h> // for ntutrl.h
|
|
#include <nturtl.h> // for RTL_CRITICAL_SECTION in winbase.h/wtypes.h
|
|
#include <wtypes.h> // for LPGUID in wmium.h
|
|
#include <mountmgr.h>
|
|
#include <winioctl.h>
|
|
#include <ntddvol.h>
|
|
#include <ntddscsi.h>
|
|
#include <regstr.h>
|
|
#include <iptypes.h>
|
|
|
|
#include "wmiump.h"
|
|
#include "evntrace.h"
|
|
#include "traceump.h"
|
|
|
|
#define DEFAULT_ALLOC_SIZE 4096
|
|
|
|
extern
|
|
PVOID
|
|
WmipGetTraceBuffer(
|
|
IN PWMI_LOGGER_CONTEXT Logger,
|
|
IN PSYSTEM_THREAD_INFORMATION pThread,
|
|
IN ULONG GroupType,
|
|
IN ULONG RequiredSize
|
|
);
|
|
|
|
__inline ULONG WmipSetDosError(IN ULONG DosError);
|
|
|
|
#define WmipNtStatusToDosError(Status) \
|
|
((ULONG)((Status == STATUS_SUCCESS)?ERROR_SUCCESS:RtlNtStatusToDosError(Status)))
|
|
|
|
#define COMPUTERNAME_ROOT \
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName"
|
|
|
|
#define CPU_ROOT \
|
|
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"
|
|
|
|
#define COMPUTERNAME_VALUE_NAME \
|
|
L"ComputerName"
|
|
|
|
#define NETWORKCARDS_ROOT \
|
|
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"
|
|
|
|
#define MHZ_VALUE_NAME \
|
|
L"~MHz"
|
|
|
|
#define NIC_VALUE_NAME \
|
|
L"Description"
|
|
|
|
#define REG_PATH_VIDEO_DEVICE_MAP \
|
|
L"\\Registry\\Machine\\Hardware\\DeviceMap\\Video"
|
|
|
|
#define REG_PATH_VIDEO_HARDWARE_PROFILE \
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\Video"
|
|
|
|
#define REG_PATH_SERVICES \
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video"
|
|
|
|
typedef BOOL WINAPI T_EnumDisplayDevicesW( LPWSTR lpDevice,
|
|
DWORD iDevNum,
|
|
PDISPLAY_DEVICEW lpDisplayDevice,
|
|
DWORD dwFlags );
|
|
|
|
typedef DWORD WINAPI T_GetNetworkParams( PFIXED_INFO pFixedInfo,
|
|
PULONG pOutBufLen );
|
|
|
|
typedef DWORD T_GetAdaptersInfo( PIP_ADAPTER_INFO pAdapterInfo,
|
|
PULONG pOutBufLen );
|
|
|
|
typedef DWORD T_GetPerAdapterInfo( ULONG IfIndex,
|
|
PIP_PER_ADAPTER_INFO pPerAdapterInfo,
|
|
PULONG pOutBufLen );
|
|
|
|
NTSTATUS
|
|
WmipRegOpenKey(
|
|
IN LPWSTR lpKeyName,
|
|
OUT PHANDLE KeyHandle
|
|
)
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING KeyName;
|
|
RtlInitUnicodeString( &KeyName, lpKeyName );
|
|
RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&KeyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
return NtOpenKey( KeyHandle, KEY_READ, &ObjectAttributes );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
WmipRegQueryValueKey(
|
|
IN HANDLE KeyHandle,
|
|
IN LPWSTR lpValueName,
|
|
IN ULONG Length,
|
|
OUT PVOID KeyValue,
|
|
OUT PULONG ResultLength
|
|
)
|
|
{
|
|
UNICODE_STRING ValueName;
|
|
ULONG BufferLength;
|
|
NTSTATUS Status;
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
|
|
RtlInitUnicodeString( &ValueName, lpValueName );
|
|
|
|
BufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + Length;
|
|
KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
|
|
RtlAllocateHeap (RtlProcessHeap(),0,BufferLength);
|
|
if (KeyValueInformation == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
Status = NtQueryValueKey(
|
|
KeyHandle,
|
|
|
|
&ValueName,
|
|
KeyValuePartialInformation,
|
|
KeyValueInformation,
|
|
BufferLength,
|
|
ResultLength
|
|
);
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
RtlCopyMemory(KeyValue,
|
|
KeyValueInformation->Data,
|
|
KeyValueInformation->DataLength
|
|
);
|
|
|
|
*ResultLength = KeyValueInformation->DataLength;
|
|
if (KeyValueInformation->Type == REG_SZ) {
|
|
if (KeyValueInformation->DataLength + sizeof(WCHAR) > Length) {
|
|
KeyValueInformation->DataLength -= sizeof(WCHAR);
|
|
}
|
|
((PUCHAR)KeyValue)[KeyValueInformation->DataLength++] = 0;
|
|
((PUCHAR)KeyValue)[KeyValueInformation->DataLength] = 0;
|
|
*ResultLength = KeyValueInformation->DataLength + sizeof(WCHAR);
|
|
}
|
|
}
|
|
RtlFreeHeap(RtlProcessHeap(),0,KeyValueInformation);
|
|
return Status;
|
|
}
|
|
|
|
|
|
BOOL
|
|
WmipIsVolumeName(
|
|
LPWSTR Name
|
|
)
|
|
{
|
|
if (Name[0] == '\\' &&
|
|
(Name[1] == '?' || Name[1] == '\\') &&
|
|
Name[2] == '?' &&
|
|
Name[3] == '\\' &&
|
|
Name[4] == 'V' &&
|
|
Name[5] == 'o' &&
|
|
Name[6] == 'l' &&
|
|
Name[7] == 'u' &&
|
|
Name[8] == 'm' &&
|
|
Name[9] == 'e' &&
|
|
Name[10] == '{' &&
|
|
Name[19] == '-' &&
|
|
Name[24] == '-' &&
|
|
Name[29] == '-' &&
|
|
Name[34] == '-' &&
|
|
Name[47] == '}' ) {
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
NTSTATUS
|
|
WmipGetCpuSpeed(
|
|
OUT DWORD* CpuNum,
|
|
OUT DWORD* CpuSpeed
|
|
)
|
|
{
|
|
PWCHAR Buffer = NULL;
|
|
NTSTATUS Status;
|
|
ULONG DataLength;
|
|
DWORD Size = MAXSTR;
|
|
HANDLE Handle = INVALID_HANDLE_VALUE;
|
|
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
|
|
if (Buffer == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
swprintf(Buffer, L"%ws\\%u", CPU_ROOT, *CpuNum);
|
|
Status = WmipRegOpenKey((LPWSTR)Buffer, &Handle);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
swprintf(Buffer, MHZ_VALUE_NAME);
|
|
Size = sizeof(DWORD);
|
|
Status = WmipRegQueryValueKey(Handle,
|
|
(LPWSTR) Buffer,
|
|
Size,
|
|
CpuSpeed,
|
|
&DataLength
|
|
);
|
|
NtClose(Handle);
|
|
if(Buffer) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
*CpuSpeed = 0;
|
|
if(Buffer) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
}
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
ULONG
|
|
WmipGetCpuConfig(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
PWCHAR Buffer = NULL;
|
|
WCHAR ComputerName[MAXSTR];
|
|
ULONG CpuNum;
|
|
ULONG CpuSpeed;
|
|
DWORD Size = MAXSTR;
|
|
SYSTEM_INFO SysInfo;
|
|
MEMORYSTATUS MemStatus;
|
|
NTSTATUS Status;
|
|
HANDLE Handle;
|
|
ULONG DataLength;
|
|
ULONG StringSize;
|
|
ULONG SizeNeeded;
|
|
PCPU_CONFIG_RECORD CpuConfig = NULL;
|
|
PFIXED_INFO pFixedInfo = NULL;
|
|
DWORD ErrorCode;
|
|
ULONG NetworkParamsSize;
|
|
T_GetNetworkParams *pfnGetNetworkParams = NULL;
|
|
HINSTANCE hIphlpapiDll = NULL;
|
|
|
|
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
|
|
if (Buffer == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
GlobalMemoryStatus(&MemStatus);
|
|
|
|
|
|
swprintf(Buffer, COMPUTERNAME_ROOT);
|
|
|
|
Status = WmipRegOpenKey((LPWSTR)Buffer, &Handle);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
swprintf(Buffer, COMPUTERNAME_VALUE_NAME);
|
|
Size = (MAX_DEVICE_ID_LENGTH) * sizeof (WCHAR);
|
|
|
|
CpuQuery:
|
|
Status = WmipRegQueryValueKey(Handle,
|
|
(LPWSTR) Buffer,
|
|
Size,
|
|
ComputerName,
|
|
&StringSize
|
|
);
|
|
|
|
if (Status == STATUS_BUFFER_OVERFLOW) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(),0,StringSize);
|
|
if (Buffer == NULL) {
|
|
NtClose(Handle);
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
goto CpuQuery;
|
|
}
|
|
|
|
NtClose(Handle);
|
|
if (!NT_SUCCESS(Status) ) {
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
//
|
|
// Get Architecture Type, Processor Type and Level Stepping...
|
|
//
|
|
CpuNum = 0;
|
|
WmipGetCpuSpeed(&CpuNum, &CpuSpeed);
|
|
|
|
GetSystemInfo(&SysInfo);
|
|
|
|
//
|
|
// Get the Hostname and DomainName
|
|
//
|
|
|
|
// delay load iphlpapi.lib to Get network params
|
|
hIphlpapiDll = LoadLibraryW(L"iphlpapi.dll");
|
|
if (hIphlpapiDll == NULL) {
|
|
goto CpuCleanup;
|
|
}
|
|
pfnGetNetworkParams = (T_GetNetworkParams*) GetProcAddress(hIphlpapiDll, "GetNetworkParams");
|
|
if(pfnGetNetworkParams == NULL) {
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
pfnGetNetworkParams(NULL, &NetworkParamsSize);
|
|
pFixedInfo = (PFIXED_INFO)RtlAllocateHeap (RtlProcessHeap(),0,NetworkParamsSize);
|
|
if(pFixedInfo == NULL) {
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
ErrorCode = pfnGetNetworkParams(pFixedInfo, &NetworkParamsSize);
|
|
|
|
if(ErrorCode != ERROR_SUCCESS) {
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
//
|
|
// Create EventTrace record for CPU configuration and write it
|
|
//
|
|
|
|
SizeNeeded = sizeof(CPU_CONFIG_RECORD) + StringSize + (CONFIG_MAX_DOMAIN_NAME_LEN);
|
|
|
|
CpuConfig = (PCPU_CONFIG_RECORD) WmipGetTraceBuffer(LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_CPU,
|
|
SizeNeeded);
|
|
if (CpuConfig == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto CpuCleanup;
|
|
}
|
|
|
|
CpuConfig->NumberOfProcessors = SysInfo.dwNumberOfProcessors;
|
|
CpuConfig->ProcessorSpeed = CpuSpeed;
|
|
CpuConfig->MemorySize = (ULONG)(((MemStatus.dwTotalPhys + 512) / 1024) + 512) / 1024;
|
|
CpuConfig->PageSize = SysInfo.dwPageSize;
|
|
CpuConfig->AllocationGranularity = SysInfo.dwAllocationGranularity;
|
|
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
pFixedInfo->DomainName,
|
|
-1,
|
|
CpuConfig->DomainName,
|
|
CONFIG_MAX_DOMAIN_NAME_LEN);
|
|
|
|
RtlCopyMemory(&CpuConfig->ComputerName, ComputerName, StringSize);
|
|
CpuConfig->ComputerName[StringSize/2] = 0;
|
|
|
|
CpuCleanup:
|
|
if (Buffer != NULL) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
}
|
|
if(pFixedInfo) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pFixedInfo);
|
|
}
|
|
if(hIphlpapiDll) {
|
|
FreeLibrary(hIphlpapiDll);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
// Function to get logical disk
|
|
NTSTATUS
|
|
GetIoFixedDrive(
|
|
OUT PLOGICAL_DISK_EXTENTS* ppFdi,
|
|
IN WCHAR* DriveLetterString
|
|
)
|
|
{
|
|
DWORD i,dwLastError;
|
|
WCHAR DeviceName[MAXSTR];
|
|
BOOLEAN IsVolume = FALSE;
|
|
PARTITION_INFORMATION PartitionInfo;
|
|
STORAGE_DEVICE_NUMBER StorageDeviceNum;
|
|
HANDLE VolumeHandle;
|
|
ULONG BytesTransferred;
|
|
WCHAR DriveRootName[CONFIG_DRIVE_LETTER_LEN];
|
|
PLOGICAL_DISK_EXTENTS pFdi = NULL;
|
|
INT FixedDiskInfoSize;
|
|
BOOL bRet;
|
|
DWORD bytes;
|
|
ULONG BufSize;
|
|
CHAR* pBuf = NULL;
|
|
CHAR* pNew = NULL;
|
|
PVOLUME_DISK_EXTENTS pVolExt = NULL;
|
|
PDISK_EXTENT pDiskExt = NULL;
|
|
ULARGE_INTEGER TotalBytes;
|
|
ULARGE_INTEGER TotalFreeBytes;
|
|
ULARGE_INTEGER FreeBytesToCaller;
|
|
ULONG TotalClusters;
|
|
ULONG TotalFreeClusters;
|
|
PUCHAR VolumeExtPtr = NULL;
|
|
|
|
FixedDiskInfoSize = sizeof(LOGICAL_DISK_EXTENTS);
|
|
//
|
|
// First, we must calculate the size of FixedDiskInfo structure
|
|
// non-partition logical drives have different size
|
|
//
|
|
swprintf(DeviceName, L"\\\\.\\%s",DriveLetterString);
|
|
VolumeHandle = CreateFileW(DeviceName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
INVALID_HANDLE_VALUE);
|
|
|
|
if (VolumeHandle == INVALID_HANDLE_VALUE) {
|
|
dwLastError = GetLastError();
|
|
goto ErrorExit;
|
|
}
|
|
|
|
bRet = DeviceIoControl(VolumeHandle,
|
|
IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
|
NULL,
|
|
0,
|
|
&StorageDeviceNum,
|
|
sizeof(StorageDeviceNum),
|
|
&bytes,
|
|
NULL);
|
|
if (!bRet)
|
|
{
|
|
//
|
|
// This is Volume
|
|
//
|
|
BufSize = 2048;
|
|
pBuf = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
|
|
if (pBuf == NULL) {
|
|
dwLastError = GetLastError();
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Well, the drive letter is for a volume.
|
|
//
|
|
retry:
|
|
bRet = DeviceIoControl(VolumeHandle,
|
|
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
|
NULL,
|
|
0,
|
|
pBuf,
|
|
BufSize,
|
|
&bytes,
|
|
NULL);
|
|
|
|
dwLastError = GetLastError();
|
|
if (!bRet && dwLastError == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
BufSize = bytes;
|
|
if(pBuf) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pBuf);
|
|
}
|
|
pNew = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
|
|
//
|
|
// We can not reallocate memory, exit.
|
|
//
|
|
if (pNew == NULL){
|
|
dwLastError = GetLastError();
|
|
goto ErrorExit;
|
|
}
|
|
else
|
|
pBuf = pNew;
|
|
|
|
goto retry;
|
|
}
|
|
|
|
if (!bRet) {
|
|
goto ErrorExit;
|
|
}
|
|
pVolExt = (PVOLUME_DISK_EXTENTS)pBuf;
|
|
IsVolume=TRUE;
|
|
FixedDiskInfoSize += sizeof(VOLUME_DISK_EXTENTS) + (pVolExt->NumberOfDiskExtents) * sizeof(DISK_EXTENT);
|
|
}
|
|
|
|
pFdi = (PLOGICAL_DISK_EXTENTS) RtlAllocateHeap (RtlProcessHeap(),0,FixedDiskInfoSize);
|
|
if (pFdi == NULL) {
|
|
goto ErrorExit;
|
|
}
|
|
pFdi->VolumeExt = 0;
|
|
pFdi->Size = FixedDiskInfoSize;
|
|
|
|
if (IsVolume) {
|
|
pFdi->DriveType = CONFIG_DRIVE_VOLUME;
|
|
//
|
|
// Volume can span multiple hard disks, so here we set the DriverNumber to -1
|
|
//
|
|
pFdi->DiskNumber = (ULONG)(-1);
|
|
pFdi->PartitionNumber = 1;
|
|
|
|
pFdi->VolumeExt = FIELD_OFFSET (LOGICAL_DISK_EXTENTS, VolumeExt);
|
|
VolumeExtPtr = (PUCHAR) OffsetToPtr (pFdi, pFdi->VolumeExt);
|
|
RtlCopyMemory(VolumeExtPtr,
|
|
pVolExt,
|
|
sizeof(VOLUME_DISK_EXTENTS) + (pVolExt->NumberOfDiskExtents) * sizeof(DISK_EXTENT));
|
|
}
|
|
else {
|
|
pFdi->DriveType = CONFIG_DRIVE_PARTITION;
|
|
pFdi->DiskNumber = StorageDeviceNum.DeviceNumber;
|
|
pFdi->PartitionNumber = StorageDeviceNum.PartitionNumber;
|
|
}
|
|
|
|
pFdi->DriveLetterString[0] = DriveLetterString[0];
|
|
pFdi->DriveLetterString[1] = DriveLetterString[1];
|
|
pFdi->DriveLetterString[2] = DriveLetterString[2];
|
|
|
|
DriveRootName[0] = pFdi->DriveLetterString[0];
|
|
DriveRootName[1] = pFdi->DriveLetterString[1];
|
|
DriveRootName[2] = L'\\';
|
|
DriveRootName[3] = UNICODE_NULL;
|
|
|
|
pFdi->SectorsPerCluster = 0;
|
|
pFdi->BytesPerSector = 0;
|
|
pFdi->NumberOfFreeClusters = 0;
|
|
pFdi->TotalNumberOfClusters = 0;
|
|
|
|
//
|
|
// Get partition information.
|
|
//
|
|
if ( !DeviceIoControl(VolumeHandle,
|
|
IOCTL_DISK_GET_PARTITION_INFO,
|
|
NULL,
|
|
0,
|
|
&PartitionInfo,
|
|
sizeof( PartitionInfo ),
|
|
&BytesTransferred,
|
|
NULL ) ) {
|
|
|
|
dwLastError = GetLastError();
|
|
goto ErrorExit;
|
|
}
|
|
CloseHandle(VolumeHandle);
|
|
VolumeHandle = NULL;
|
|
if (pBuf) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pBuf);
|
|
}
|
|
pBuf = NULL;
|
|
|
|
//
|
|
// Get the information of the logical drive
|
|
//
|
|
if (!GetDiskFreeSpaceW(DriveRootName,
|
|
&pFdi->SectorsPerCluster,
|
|
&pFdi->BytesPerSector,
|
|
&TotalFreeClusters,
|
|
&TotalClusters)) {
|
|
|
|
dwLastError = GetLastError();
|
|
if(dwLastError == ERROR_UNRECOGNIZED_VOLUME) {
|
|
//
|
|
// This could be a partition that has been assigned drive letter but not yet formatted
|
|
//
|
|
goto SkipFreeSpace;
|
|
}
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (!GetDiskFreeSpaceExW(DriveRootName,
|
|
&FreeBytesToCaller,
|
|
&TotalBytes,
|
|
&TotalFreeBytes)) {
|
|
|
|
dwLastError = GetLastError();
|
|
if(dwLastError == ERROR_UNRECOGNIZED_VOLUME) {
|
|
//
|
|
// This could be a partition that has been assigned drive letter but not yet formatted
|
|
//
|
|
goto SkipFreeSpace;
|
|
}
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pFdi->NumberOfFreeClusters = TotalFreeBytes.QuadPart / (pFdi->BytesPerSector * pFdi->SectorsPerCluster);
|
|
pFdi->TotalNumberOfClusters = TotalBytes.QuadPart / (pFdi->BytesPerSector * pFdi->SectorsPerCluster);
|
|
|
|
SkipFreeSpace:
|
|
pFdi->StartingOffset = PartitionInfo.StartingOffset.QuadPart;
|
|
pFdi->PartitionSize = (ULONGLONG)(((ULONGLONG)pFdi->TotalNumberOfClusters) *
|
|
((ULONGLONG)pFdi->SectorsPerCluster) *
|
|
((ULONGLONG)pFdi->BytesPerSector));
|
|
|
|
//
|
|
// Get the file system type of the logical drive
|
|
//
|
|
if (!GetVolumeInformationW(DriveRootName,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
pFdi->FileSystemType,
|
|
sizeof(pFdi->FileSystemType))
|
|
)
|
|
{
|
|
wcscpy(pFdi->FileSystemType, L"(unknown)");
|
|
}
|
|
|
|
*ppFdi = pFdi;
|
|
|
|
if (VolumeHandle != INVALID_HANDLE_VALUE) {
|
|
CloseHandle( VolumeHandle );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
ErrorExit:
|
|
|
|
if (VolumeHandle != INVALID_HANDLE_VALUE) {
|
|
CloseHandle( VolumeHandle );
|
|
VolumeHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
if (pFdi) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pFdi);
|
|
}
|
|
if (pBuf) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pBuf);
|
|
}
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
WmipGetDiskInfo(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
PUCHAR Buffer = NULL;
|
|
STORAGE_DEVICE_NUMBER Number;
|
|
PMOUNTMGR_MOUNT_POINTS mountPoints = NULL;
|
|
MOUNTMGR_MOUNT_POINT mountPoint;
|
|
ULONG returnSize, success;
|
|
SYSTEM_DEVICE_INFORMATION DevInfo;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
ULONG NumberOfDisks;
|
|
PWCHAR deviceNameBuffer;
|
|
ULONG i;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
IO_STATUS_BLOCK IoStatus;
|
|
|
|
DISK_GEOMETRY disk_geometry;
|
|
PDISK_CACHE_INFORMATION disk_cache = NULL;
|
|
PSCSI_ADDRESS scsi_address = NULL;
|
|
PWCHAR KeyName = NULL;
|
|
HANDLE hDisk = INVALID_HANDLE_VALUE;
|
|
UNICODE_STRING UnicodeName;
|
|
|
|
PPHYSICAL_DISK_RECORD Disk = NULL;
|
|
PLOGICAL_DISK_EXTENTS pLogicalDisk = NULL;
|
|
PLOGICAL_DISK_EXTENTS pDiskExtents = NULL;
|
|
ULONG SizeNeeded;
|
|
WCHAR LogicalDrives[MAXSTR];
|
|
LPWSTR Drive = NULL;
|
|
DWORD Chars;
|
|
ULONG BufferDataLength;
|
|
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(),0,DEFAULT_ALLOC_SIZE);
|
|
if (Buffer == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
//
|
|
// Get the Number of Physical Disks
|
|
//
|
|
|
|
RtlZeroMemory(&DevInfo, sizeof(DevInfo));
|
|
|
|
Status = NtQuerySystemInformation(
|
|
SystemDeviceInformation,
|
|
&DevInfo, sizeof (DevInfo), NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
NumberOfDisks = DevInfo.NumberOfDisks;
|
|
|
|
//
|
|
// Open Each Physical Disk and get Disk Layout information
|
|
//
|
|
for (i=0; i < NumberOfDisks; i++) {
|
|
|
|
DISK_CACHE_INFORMATION cacheInfo;
|
|
HANDLE PartitionHandle;
|
|
HANDLE KeyHandle;
|
|
ULONG DataLength;
|
|
WCHAR BootDrive[MAX_PATH];
|
|
WCHAR BootDriveLetter;
|
|
WCHAR DriveBuffer[MAXSTR];
|
|
PDRIVE_LAYOUT_INFORMATION pDriveLayout = NULL;
|
|
ULONG PartitionCount;
|
|
ULONG j;
|
|
BOOL bSuccess = FALSE;
|
|
DWORD BufSize;
|
|
ULONG Size = DEFAULT_ALLOC_SIZE;
|
|
BOOL bValidDiskCacheInfo = FALSE;
|
|
|
|
RtlZeroMemory(&disk_geometry, sizeof(DISK_GEOMETRY));
|
|
RtlZeroMemory(&cacheInfo, sizeof(DISK_CACHE_INFORMATION));
|
|
PartitionCount = 0;
|
|
BootDriveLetter = UNICODE_NULL;
|
|
|
|
//
|
|
// Get Boot Drive Letter
|
|
//
|
|
if(GetSystemDirectoryW(BootDrive, MAX_PATH)) {
|
|
BootDriveLetter = BootDrive[0];
|
|
}
|
|
|
|
swprintf(DriveBuffer, L"\\\\.\\PhysicalDrive%d", i);
|
|
|
|
hDisk = CreateFileW(DriveBuffer,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
if(hDisk == INVALID_HANDLE_VALUE) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
//
|
|
// Get Partition0 handle to get the Disk layout
|
|
//
|
|
deviceNameBuffer = (PWCHAR) Buffer;
|
|
swprintf(deviceNameBuffer, L"\\Device\\Harddisk%d\\Partition0", i);
|
|
|
|
RtlInitUnicodeString(&UnicodeName, deviceNameBuffer);
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&UnicodeName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
Status = NtOpenFile(
|
|
&PartitionHandle,
|
|
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatus,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
//
|
|
// Get geomerty information
|
|
//
|
|
Status = NtDeviceIoControlFile(PartitionHandle,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&IoStatus,
|
|
IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
|
NULL,
|
|
0,
|
|
&disk_geometry,
|
|
sizeof (DISK_GEOMETRY)
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
NtClose(PartitionHandle);
|
|
goto SkipPartition;
|
|
}
|
|
|
|
//
|
|
// Get the scci information
|
|
//
|
|
scsi_address = (PSCSI_ADDRESS) Buffer;
|
|
Status = NtDeviceIoControlFile(PartitionHandle,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&IoStatus,
|
|
IOCTL_SCSI_GET_ADDRESS,
|
|
NULL,
|
|
0,
|
|
scsi_address,
|
|
sizeof (SCSI_ADDRESS)
|
|
);
|
|
NtClose(PartitionHandle);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
//
|
|
// Get Manufacturer's name from Registry
|
|
// We need to get the SCSI Address and then query the Registry with it.
|
|
//
|
|
KeyName = (PWCHAR) Buffer;
|
|
swprintf(KeyName,
|
|
L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target ID %d\\Logical Unit Id %d",
|
|
scsi_address->PortNumber, scsi_address->PathId, scsi_address->TargetId, scsi_address->Lun
|
|
);
|
|
Status = WmipRegOpenKey(KeyName, &KeyHandle);
|
|
if (!NT_SUCCESS(Status)) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
Size = DEFAULT_ALLOC_SIZE;
|
|
RtlZeroMemory(Buffer, Size);
|
|
DiskQuery:
|
|
Status = WmipRegQueryValueKey(KeyHandle,
|
|
L"Identifier",
|
|
Size,
|
|
Buffer, &BufferDataLength);
|
|
if (Status == STATUS_BUFFER_OVERFLOW) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(),0,BufferDataLength);
|
|
if (Buffer == NULL) {
|
|
NtClose(KeyHandle);
|
|
Status = STATUS_NO_MEMORY;
|
|
goto DiskCleanup;
|
|
}
|
|
goto DiskQuery;
|
|
}
|
|
|
|
NtClose(KeyHandle);
|
|
if (!NT_SUCCESS(Status) ) {
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
//
|
|
// Get the total partitions on the drive
|
|
//
|
|
BufSize = 2048;
|
|
pDriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
|
|
if(pDriveLayout == NULL) {
|
|
goto DiskCleanup;
|
|
}
|
|
RtlZeroMemory(pDriveLayout, BufSize);
|
|
bSuccess = DeviceIoControl (
|
|
hDisk,
|
|
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|
NULL,
|
|
0,
|
|
pDriveLayout,
|
|
BufSize,
|
|
&DataLength,
|
|
NULL
|
|
);
|
|
if(bSuccess == FALSE && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
|
BufSize = DataLength;
|
|
if(pDriveLayout) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
|
|
}
|
|
pDriveLayout = RtlAllocateHeap (RtlProcessHeap(),0,BufSize);
|
|
if(pDriveLayout == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto DiskCleanup;
|
|
}
|
|
else {
|
|
bSuccess = DeviceIoControl (
|
|
hDisk,
|
|
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|
NULL,
|
|
0,
|
|
pDriveLayout,
|
|
BufSize,
|
|
&DataLength,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
if(bSuccess == FALSE) {
|
|
//
|
|
// If media type is not fixed media and device is not ready then dont query partition info.
|
|
//
|
|
if(disk_geometry.MediaType != FixedMedia && GetLastError() == ERROR_NOT_READY) {
|
|
goto SkipPartition;
|
|
}
|
|
|
|
if(pDriveLayout) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
|
|
pDriveLayout = NULL;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Get Partition count for the current disk
|
|
//
|
|
PartitionCount = 0;
|
|
j = 0;
|
|
while (j < pDriveLayout->PartitionCount) {
|
|
if (pDriveLayout->PartitionEntry[j].PartitionNumber != 0) {
|
|
PartitionCount++;
|
|
}
|
|
j++;
|
|
}
|
|
|
|
//
|
|
// Get cache info - IOCTL_DISK_GET_CACHE_INFORMATION
|
|
//
|
|
bValidDiskCacheInfo = DeviceIoControl(hDisk,
|
|
IOCTL_DISK_GET_CACHE_INFORMATION,
|
|
NULL,
|
|
0,
|
|
&cacheInfo,
|
|
sizeof(DISK_CACHE_INFORMATION),
|
|
&DataLength,
|
|
NULL);
|
|
|
|
NtClose(hDisk);
|
|
hDisk = INVALID_HANDLE_VALUE;
|
|
|
|
//
|
|
// Free drivelayout structure
|
|
//
|
|
if(pDriveLayout) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pDriveLayout);
|
|
pDriveLayout = NULL;
|
|
}
|
|
|
|
SkipPartition:
|
|
|
|
//
|
|
// Package all information about this disk and write an event record
|
|
//
|
|
|
|
SizeNeeded = sizeof(PHYSICAL_DISK_RECORD) + BufferDataLength;
|
|
|
|
Disk = (PPHYSICAL_DISK_RECORD) WmipGetTraceBuffer( LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_PHYSICALDISK,
|
|
SizeNeeded);
|
|
|
|
if (Disk == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
Disk->DiskNumber = i;
|
|
Disk->BytesPerSector = disk_geometry.BytesPerSector;
|
|
Disk->SectorsPerTrack = disk_geometry.SectorsPerTrack;
|
|
Disk->TracksPerCylinder = disk_geometry.TracksPerCylinder;
|
|
Disk->Cylinders = disk_geometry.Cylinders.QuadPart;
|
|
Disk->SCSIPortNumber = scsi_address->PortNumber;
|
|
Disk->SCSIPathId = scsi_address->PathId;
|
|
Disk->SCSITargetId = scsi_address->TargetId;
|
|
Disk->SCSILun = scsi_address->Lun;
|
|
Disk->BootDriveLetter[0] = BootDriveLetter;
|
|
if (bValidDiskCacheInfo && cacheInfo.WriteCacheEnabled) {
|
|
Disk->WriteCacheEnabled = TRUE;
|
|
}
|
|
Disk->PartitionCount = PartitionCount;
|
|
if(BufferDataLength > MAX_DEVICE_ID_LENGTH) BufferDataLength = MAX_DEVICE_ID_LENGTH;
|
|
RtlCopyMemory(Disk->Manufacturer, Buffer, BufferDataLength);
|
|
Disk->Manufacturer[BufferDataLength/2] = 0;
|
|
}
|
|
|
|
//
|
|
// Retrieve the logical drive strings from the system.
|
|
//
|
|
Chars = GetLogicalDriveStringsW(MAXSTR, LogicalDrives);
|
|
Drive = LogicalDrives;
|
|
|
|
//
|
|
// How many logical drives in physical disks exist?
|
|
//
|
|
while ( *Drive ) {
|
|
WCHAR DriveLetter[CONFIG_BOOT_DRIVE_LEN];
|
|
|
|
DriveLetter[ 0 ] = Drive [ 0 ];
|
|
DriveLetter[ 1 ] = Drive [ 1 ];
|
|
DriveLetter[ 2 ] = UNICODE_NULL;
|
|
|
|
if(GetDriveTypeW( Drive ) == DRIVE_FIXED) {
|
|
//
|
|
// If this is a logical drive which resides in a hard disk
|
|
// we need to allocate a FixedDiskInfo structure for it.
|
|
//
|
|
if(GetIoFixedDrive(&pLogicalDisk, DriveLetter) == STATUS_SUCCESS) {
|
|
SizeNeeded = pLogicalDisk->Size;
|
|
|
|
//
|
|
// Package all information about this disk and write an event record
|
|
//
|
|
pDiskExtents = (PLOGICAL_DISK_EXTENTS) WmipGetTraceBuffer( LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_LOGICALDISK,
|
|
SizeNeeded);
|
|
if(pDiskExtents == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto DiskCleanup;
|
|
}
|
|
|
|
RtlCopyMemory(pDiskExtents, pLogicalDisk, SizeNeeded);
|
|
RtlFreeHeap (RtlProcessHeap(),0,pLogicalDisk);
|
|
pLogicalDisk = NULL;
|
|
}
|
|
}
|
|
|
|
Drive += wcslen( Drive ) + 1;
|
|
}
|
|
|
|
DiskCleanup:
|
|
if (Buffer != NULL) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,Buffer);
|
|
}
|
|
if(hDisk != INVALID_HANDLE_VALUE) {
|
|
NtClose(hDisk);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
WmipGetVideoAdapters(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
PVIDEO_RECORD Video = NULL;
|
|
VIDEO_RECORD VideoRecord;
|
|
HANDLE hVideoDeviceMap;
|
|
HANDLE hVideoDriver;
|
|
HANDLE hHardwareProfile;
|
|
ULONG DeviceId = 0;
|
|
PWCHAR Device = NULL;
|
|
PWCHAR HardwareProfile = NULL;
|
|
PWCHAR Driver = NULL;
|
|
PWCHAR Buffer = NULL;
|
|
PWCHAR DriverRegistryPath = NULL;
|
|
|
|
ULONG ResultLength;
|
|
PCHAR ValueBuffer = NULL;
|
|
ULONG Length;
|
|
BOOLEAN IsAdapter;
|
|
ULONG SizeNeeded;
|
|
NTSTATUS Status;
|
|
INT i;
|
|
|
|
DWORD iDevice = 0;
|
|
DISPLAY_DEVICEW dd;
|
|
HINSTANCE hUser32Dll = NULL;
|
|
T_EnumDisplayDevicesW *pfnEnumDisplayDevicesW = NULL;
|
|
|
|
LPWSTR ChipsetInfo[6] = {
|
|
L"HardwareInformation.MemorySize",
|
|
L"HardwareInformation.ChipType",
|
|
L"HardwareInformation.DacType",
|
|
L"HardwareInformation.AdapterString",
|
|
L"HardwareInformation.BiosString",
|
|
L"Device Description"
|
|
};
|
|
|
|
LPWSTR SettingInfo[4] = {
|
|
L"DefaultSettings.BitsPerPel",
|
|
L"DefaultSettings.VRefresh",
|
|
L"DefaultSettings.XResolution",
|
|
L"DefaultSettings.YResolution",
|
|
};
|
|
|
|
|
|
RtlZeroMemory(&dd, sizeof(dd));
|
|
dd.cb = sizeof(dd);
|
|
|
|
//
|
|
// Enumerate all the video devices in the system
|
|
//
|
|
Status = WmipRegOpenKey(REG_PATH_VIDEO_DEVICE_MAP, &hVideoDeviceMap);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Allocate memory for local variables on heap
|
|
//
|
|
Device = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
|
|
HardwareProfile = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
|
|
Driver = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
|
|
Buffer = RtlAllocateHeap (RtlProcessHeap(), 0, DEFAULT_ALLOC_SIZE);
|
|
|
|
while (TRUE) {
|
|
RtlZeroMemory(&VideoRecord, sizeof(VideoRecord));
|
|
|
|
//
|
|
// Open video device
|
|
//
|
|
swprintf(Device, L"\\Device\\Video%d", DeviceId++);
|
|
|
|
Status = WmipRegQueryValueKey(hVideoDeviceMap,
|
|
Device,
|
|
DEFAULT_ALLOC_SIZE * sizeof(WCHAR),
|
|
Buffer,
|
|
&ResultLength
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Open the driver registry key
|
|
//
|
|
Status = WmipRegOpenKey(Buffer, &hVideoDriver);
|
|
if (!NT_SUCCESS(Status)) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Get Video adapter information.
|
|
//
|
|
IsAdapter = TRUE;
|
|
for (i = 0; i < 6; i++) {
|
|
switch (i ) {
|
|
case 0:
|
|
ValueBuffer = (PCHAR)&VideoRecord.MemorySize;
|
|
Length = sizeof(VideoRecord.MemorySize);
|
|
break;
|
|
|
|
case 1:
|
|
ValueBuffer = (PCHAR)&VideoRecord.ChipType;
|
|
Length = sizeof(VideoRecord.ChipType);
|
|
break;
|
|
|
|
case 2:
|
|
ValueBuffer = (PCHAR)&VideoRecord.DACType;
|
|
Length = sizeof(VideoRecord.DACType);
|
|
break;
|
|
|
|
case 3:
|
|
ValueBuffer = (PCHAR)&VideoRecord.AdapterString;
|
|
Length = sizeof(VideoRecord.AdapterString);
|
|
break;
|
|
|
|
case 4:
|
|
ValueBuffer = (PCHAR)&VideoRecord.BiosString;
|
|
Length = sizeof(VideoRecord.BiosString);
|
|
break;
|
|
|
|
case 5:
|
|
ValueBuffer = (PCHAR)&VideoRecord.DeviceId;
|
|
Length = sizeof(VideoRecord.DeviceId);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Query the size of the data
|
|
//
|
|
Status = WmipRegQueryValueKey(hVideoDriver,
|
|
ChipsetInfo[i],
|
|
Length,
|
|
ValueBuffer,
|
|
&ResultLength);
|
|
//
|
|
// If we can not get the hardware information, this
|
|
// is not adapter
|
|
//
|
|
if (!NT_SUCCESS(Status)) {
|
|
IsAdapter = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
NtClose(hVideoDriver);
|
|
if (IsAdapter == FALSE) {
|
|
continue;
|
|
}
|
|
|
|
DriverRegistryPath = wcsstr(Buffer, L"{");
|
|
if(DriverRegistryPath == NULL) {
|
|
continue;
|
|
}
|
|
|
|
swprintf(HardwareProfile, L"%s\\%s", REG_PATH_VIDEO_HARDWARE_PROFILE, DriverRegistryPath);
|
|
Status = WmipRegOpenKey(HardwareProfile, &hHardwareProfile);
|
|
if (!NT_SUCCESS(Status)) {
|
|
continue;
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
switch (i ) {
|
|
case 0:
|
|
ValueBuffer = (PCHAR)&VideoRecord.BitsPerPixel;
|
|
Length = sizeof(VideoRecord.BitsPerPixel);
|
|
break;
|
|
|
|
case 1:
|
|
ValueBuffer = (PCHAR)&VideoRecord.VRefresh;
|
|
Length = sizeof(VideoRecord.VRefresh);
|
|
break;
|
|
|
|
case 2:
|
|
ValueBuffer = (PCHAR)&VideoRecord.XResolution;
|
|
Length = sizeof(VideoRecord.XResolution);
|
|
break;
|
|
|
|
case 3:
|
|
ValueBuffer = (PCHAR)&VideoRecord.YResolution;
|
|
Length = sizeof(VideoRecord.YResolution);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Query the size of the data
|
|
//
|
|
Status = WmipRegQueryValueKey(hHardwareProfile,
|
|
SettingInfo[i],
|
|
Length,
|
|
ValueBuffer,
|
|
&ResultLength);
|
|
}
|
|
|
|
NtClose(hHardwareProfile);
|
|
|
|
//
|
|
// delay load user32.lib to enum display devices function
|
|
//
|
|
hUser32Dll = LoadLibraryW(L"user32.dll");
|
|
if (hUser32Dll == NULL) {
|
|
break;
|
|
}
|
|
pfnEnumDisplayDevicesW = (T_EnumDisplayDevicesW *) GetProcAddress(hUser32Dll, "EnumDisplayDevicesW");
|
|
if(pfnEnumDisplayDevicesW == NULL) {
|
|
break;
|
|
}
|
|
|
|
while (pfnEnumDisplayDevicesW(NULL, iDevice++, &dd, 0)) {
|
|
if (_wcsicmp(VideoRecord.DeviceId, dd.DeviceString) == 0) {
|
|
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
|
|
VideoRecord.StateFlags = (ULONG)dd.StateFlags;
|
|
}
|
|
break;
|
|
iDevice = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Package all information about this disk and write an event record
|
|
//
|
|
|
|
SizeNeeded = sizeof(VIDEO_RECORD);
|
|
|
|
Video = (PVIDEO_RECORD) WmipGetTraceBuffer( LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_VIDEO,
|
|
SizeNeeded);
|
|
|
|
if (Video == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
break;
|
|
}
|
|
RtlCopyMemory(Video, &VideoRecord, sizeof(VIDEO_RECORD));
|
|
}
|
|
|
|
NtClose(hVideoDeviceMap);
|
|
if (hUser32Dll) {
|
|
FreeLibrary(hUser32Dll);
|
|
}
|
|
|
|
//
|
|
// Free local variables allocated on heap
|
|
//
|
|
if(Device) {
|
|
RtlFreeHeap (RtlProcessHeap(), 0, Device);
|
|
}
|
|
|
|
if(HardwareProfile) {
|
|
RtlFreeHeap (RtlProcessHeap(), 0, HardwareProfile);
|
|
}
|
|
|
|
if(Driver) {
|
|
RtlFreeHeap (RtlProcessHeap(), 0, Driver);
|
|
}
|
|
|
|
if(Buffer) {
|
|
RtlFreeHeap (RtlProcessHeap(), 0, Buffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
WmipGetNetworkAdapters(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
DWORD IfNum;
|
|
DWORD Ret;
|
|
PIP_ADAPTER_INFO pAdapterList = NULL, pAdapterListHead = NULL;
|
|
PIP_PER_ADAPTER_INFO pPerAdapterInfo = NULL;
|
|
PFIXED_INFO pFixedInfo = NULL;
|
|
PIP_ADDR_STRING pIpAddressList = NULL;
|
|
ULONG OutBufLen = 0;
|
|
INT i;
|
|
NIC_RECORD AdapterInfo;
|
|
PNIC_RECORD pAdapterInfo = NULL;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
INT IpAddrLen = 0;
|
|
T_GetAdaptersInfo *pfnGetAdaptersInfo = NULL;
|
|
T_GetPerAdapterInfo *pfnGetPerAdapterInfo = NULL;
|
|
HINSTANCE hIphlpapiDll = NULL;
|
|
PUCHAR IpDataPtr = NULL;
|
|
|
|
// delay load iphlpapi.lib to Get network params
|
|
hIphlpapiDll = LoadLibraryW(L"iphlpapi.dll");
|
|
if (hIphlpapiDll == NULL) {
|
|
goto IpCleanup;
|
|
}
|
|
pfnGetAdaptersInfo = (T_GetAdaptersInfo*) GetProcAddress(hIphlpapiDll, "GetAdaptersInfo");
|
|
if(pfnGetAdaptersInfo == NULL) {
|
|
goto IpCleanup;
|
|
}
|
|
|
|
pfnGetPerAdapterInfo = (T_GetPerAdapterInfo*) GetProcAddress(hIphlpapiDll, "GetPerAdapterInfo");
|
|
if(pfnGetPerAdapterInfo == NULL) {
|
|
goto IpCleanup;
|
|
}
|
|
|
|
//
|
|
// Get number of adapters
|
|
//
|
|
pfnGetAdaptersInfo(NULL, &OutBufLen);
|
|
|
|
TryAgain:
|
|
pAdapterList = (PIP_ADAPTER_INFO)RtlAllocateHeap (RtlProcessHeap(),0,OutBufLen);
|
|
if (pAdapterList == NULL) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto IpCleanup;
|
|
}
|
|
|
|
Ret = pfnGetAdaptersInfo(pAdapterList, &OutBufLen);
|
|
if (Ret == ERROR_BUFFER_OVERFLOW) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pAdapterList);
|
|
Status = !STATUS_SUCCESS;
|
|
goto TryAgain;
|
|
}
|
|
else if (Ret != ERROR_SUCCESS) {
|
|
if (pAdapterList != NULL) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pAdapterList);
|
|
}
|
|
Status = !STATUS_SUCCESS;
|
|
goto IpCleanup;
|
|
}
|
|
|
|
//
|
|
// Calculate the total length for all the IP Addresses
|
|
//
|
|
IpAddrLen = sizeof(IP_ADDRESS_STRING) * CONFIG_MAX_DNS_SERVER; // Length of 4 DNS Server IP Address
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of IP Address
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of IP Mask
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of DHCP Server IP Address
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Gateway IP Address
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Primary Wins Server IP Address
|
|
IpAddrLen += sizeof(IP_ADDRESS_STRING); // Length of Secondary Wins Server IP Address
|
|
|
|
//
|
|
// Allocate memory for NIC_RECORD
|
|
//
|
|
RtlZeroMemory(&AdapterInfo, sizeof(AdapterInfo));
|
|
|
|
//
|
|
// Fill out the information per adapter
|
|
//
|
|
pAdapterListHead = pAdapterList;
|
|
while (pAdapterList ) {
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
(LPCSTR)pAdapterList->Description,
|
|
-1,
|
|
(LPWSTR)AdapterInfo.NICName,
|
|
MAX_DEVICE_ID_LENGTH);
|
|
|
|
AdapterInfo.Index = (ULONG)pAdapterList->Index;
|
|
|
|
//
|
|
// Copy the Physical address of NIC
|
|
//
|
|
AdapterInfo.PhysicalAddrLen = pAdapterList->AddressLength;
|
|
RtlCopyMemory(AdapterInfo.PhysicalAddr, pAdapterList->Address, pAdapterList->AddressLength);
|
|
|
|
//
|
|
// Set the size of the Data
|
|
//
|
|
AdapterInfo.Size = IpAddrLen;
|
|
|
|
//
|
|
// Get DNS server list for this adapter
|
|
//
|
|
pfnGetPerAdapterInfo(pAdapterList->Index, NULL, &OutBufLen);
|
|
|
|
pPerAdapterInfo = (PIP_PER_ADAPTER_INFO)RtlAllocateHeap (RtlProcessHeap(),0,OutBufLen);
|
|
if (!pPerAdapterInfo) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto IpCleanup;
|
|
}
|
|
|
|
pfnGetPerAdapterInfo(pAdapterList->Index, pPerAdapterInfo, &OutBufLen);
|
|
|
|
//
|
|
// Package all information about this NIC and write an event record
|
|
//
|
|
pAdapterInfo = (PNIC_RECORD) WmipGetTraceBuffer( LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_NIC,
|
|
sizeof(NIC_RECORD) + IpAddrLen);
|
|
|
|
|
|
if(!pAdapterInfo) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto IpCleanup;
|
|
}
|
|
|
|
RtlCopyMemory(pAdapterInfo,
|
|
&AdapterInfo,
|
|
sizeof(NIC_RECORD) + IpAddrLen);
|
|
|
|
//
|
|
// Copy the IP Address and Subnet mask
|
|
//
|
|
if (pAdapterList->CurrentIpAddress) {
|
|
pAdapterInfo->IpAddress = FIELD_OFFSET(NIC_RECORD, Data);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->IpAddress),
|
|
&(pAdapterList->CurrentIpAddress->IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
pAdapterInfo->SubnetMask = pAdapterInfo->IpAddress + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SubnetMask),
|
|
&(pAdapterList->CurrentIpAddress->IpMask),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
}
|
|
else {
|
|
pAdapterInfo->IpAddress = FIELD_OFFSET(NIC_RECORD, Data);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->IpAddress),
|
|
&(pAdapterList->IpAddressList.IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
pAdapterInfo->SubnetMask = pAdapterInfo->IpAddress + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SubnetMask),
|
|
&(pAdapterList->IpAddressList.IpMask),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
}
|
|
|
|
//
|
|
// Copy the Dhcp Server IP Address
|
|
//
|
|
pAdapterInfo->DhcpServer = pAdapterInfo->SubnetMask + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->DhcpServer),
|
|
&(pAdapterList->DhcpServer.IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
//
|
|
// Copy the Gateway IP Address
|
|
//
|
|
pAdapterInfo->Gateway = pAdapterInfo->DhcpServer + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->Gateway),
|
|
&(pAdapterList->GatewayList.IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
//
|
|
// Copy the Primary Wins Server IP Address
|
|
//
|
|
pAdapterInfo->PrimaryWinsServer = pAdapterInfo->Gateway + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->PrimaryWinsServer),
|
|
&(pAdapterList->PrimaryWinsServer.IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
//
|
|
// Copy the Secondary Wins Server IP Address
|
|
//
|
|
pAdapterInfo->SecondaryWinsServer = pAdapterInfo->PrimaryWinsServer + sizeof(IP_ADDRESS_STRING);
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->SecondaryWinsServer),
|
|
&(pAdapterList->SecondaryWinsServer.IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
//
|
|
// Hardcoded entries for DNS server(limited upto 4);
|
|
//
|
|
pIpAddressList = &pPerAdapterInfo->DnsServerList;
|
|
pAdapterInfo->DnsServer[0] = pAdapterInfo->SecondaryWinsServer + sizeof(IP_ADDRESS_STRING);
|
|
for (i = 0; pIpAddressList && i < CONFIG_MAX_DNS_SERVER; i++) {
|
|
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)pAdapterInfo + pAdapterInfo->DnsServer[i]),
|
|
&(pIpAddressList->IpAddress),
|
|
sizeof(IP_ADDRESS_STRING));
|
|
|
|
if(i < CONFIG_MAX_DNS_SERVER - 1) {
|
|
pAdapterInfo->DnsServer[i + 1] = pAdapterInfo->DnsServer[i] + sizeof(IP_ADDRESS_STRING);
|
|
}
|
|
|
|
pIpAddressList = pIpAddressList->Next;
|
|
}
|
|
|
|
//
|
|
// Free the DNS server list
|
|
//
|
|
RtlFreeHeap (RtlProcessHeap(),0,pPerAdapterInfo);
|
|
|
|
//
|
|
// increment the AdapterInfo buffer position for next record
|
|
//
|
|
pAdapterList = pAdapterList->Next;
|
|
}
|
|
|
|
IpCleanup:
|
|
if (pAdapterListHead) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pAdapterListHead);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
WmipGetServiceInfo(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
DWORD dwServicesNum = 0;
|
|
SC_HANDLE hScm = NULL;
|
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
|
PSYSTEM_PROCESS_INFORMATION pProcInfo = NULL;
|
|
PSYSTEM_PROCESS_INFORMATION ppProcInfo = NULL;
|
|
PUCHAR pBuffer = NULL;
|
|
ULONG ulBufferSize = 64*1024;
|
|
ULONG TotalOffset;
|
|
ULONG TotalTasks = 0;
|
|
ULONG j;
|
|
|
|
//
|
|
// Get the process Info
|
|
//
|
|
retry:
|
|
|
|
if(pBuffer == NULL) {
|
|
pBuffer = RtlAllocateHeap (RtlProcessHeap(),0,ulBufferSize);
|
|
}
|
|
if(pBuffer == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
Status = NtQuerySystemInformation(
|
|
SystemProcessInformation,
|
|
pBuffer,
|
|
ulBufferSize,
|
|
NULL
|
|
);
|
|
|
|
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
|
|
ulBufferSize += 8192;
|
|
RtlFreeHeap (RtlProcessHeap(),0,pBuffer);
|
|
pBuffer = NULL;
|
|
goto retry;
|
|
}
|
|
|
|
pProcInfo = (PSYSTEM_PROCESS_INFORMATION) pBuffer;
|
|
|
|
//
|
|
// Connect to the service controller.
|
|
//
|
|
hScm = OpenSCManager(
|
|
NULL,
|
|
NULL,
|
|
SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE
|
|
);
|
|
|
|
if (hScm) {
|
|
LPENUM_SERVICE_STATUS_PROCESSW pInfo = NULL;
|
|
LPENUM_SERVICE_STATUS_PROCESSW ppInfo = NULL;
|
|
DWORD cbInfo = 4 * 1024;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD dwResume = 0;
|
|
DWORD cLoop = 0;
|
|
const DWORD cLoopMax = 2;
|
|
WMI_SERVICE_INFO ServiceInfo;
|
|
PWMI_SERVICE_INFO pServiceInfo = NULL;
|
|
SERVICE_STATUS_PROCESS ServiceProcess;
|
|
PWCHAR p = NULL;
|
|
DWORD dwRemainBytes;
|
|
|
|
//
|
|
// First pass through the loop allocates from an initial guess. (4K)
|
|
// If that isn't sufficient, we make another pass and allocate
|
|
// what is actually needed. (We only go through the loop a
|
|
// maximum of two times.)
|
|
//
|
|
do {
|
|
if (pInfo) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pInfo);
|
|
}
|
|
pInfo = (LPENUM_SERVICE_STATUS_PROCESSW)RtlAllocateHeap (RtlProcessHeap(),0,cbInfo);
|
|
if (!pInfo) {
|
|
dwErr = ERROR_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
dwErr = ERROR_SUCCESS;
|
|
if (!EnumServicesStatusExW(
|
|
hScm,
|
|
SC_ENUM_PROCESS_INFO,
|
|
SERVICE_WIN32,
|
|
SERVICE_ACTIVE,
|
|
(PBYTE)pInfo,
|
|
cbInfo,
|
|
&dwRemainBytes,
|
|
&dwServicesNum,
|
|
&dwResume,
|
|
NULL))
|
|
{
|
|
dwErr = GetLastError();
|
|
cbInfo += dwRemainBytes;
|
|
dwResume = 0;
|
|
}
|
|
} while ((ERROR_MORE_DATA == dwErr) && (++cLoop < cLoopMax));
|
|
|
|
if ((ERROR_SUCCESS == dwErr) && dwServicesNum) {
|
|
//
|
|
// Process each service and send an event
|
|
//
|
|
ppInfo = pInfo;
|
|
Status = STATUS_SUCCESS;
|
|
while(dwServicesNum) {
|
|
|
|
RtlZeroMemory(&ServiceInfo, sizeof(WMI_SERVICE_INFO));
|
|
|
|
wcscpy(ServiceInfo.ServiceName, ppInfo->lpServiceName);
|
|
|
|
wcscpy(ServiceInfo.DisplayName, ppInfo->lpDisplayName);
|
|
|
|
ServiceInfo.ProcessId = ppInfo->ServiceStatusProcess.dwProcessId;
|
|
|
|
//
|
|
// Get the process name
|
|
//
|
|
ppProcInfo = pProcInfo;
|
|
TotalOffset = 0;
|
|
while(TRUE) {
|
|
if((DWORD)(DWORD_PTR)ppProcInfo->UniqueProcessId == ServiceInfo.ProcessId) {
|
|
if(ppProcInfo->ImageName.Buffer) {
|
|
p = wcschr(ppProcInfo->ImageName.Buffer, L'\\');
|
|
if ( p ) {
|
|
p++;
|
|
} else {
|
|
p = ppProcInfo->ImageName.Buffer;
|
|
}
|
|
}
|
|
else {
|
|
p = L"System Process";
|
|
}
|
|
wcscpy(ServiceInfo.ProcessName, p);
|
|
}
|
|
if (ppProcInfo->NextEntryOffset == 0) {
|
|
break;
|
|
}
|
|
TotalOffset += ppProcInfo->NextEntryOffset;
|
|
ppProcInfo = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)pProcInfo+TotalOffset);
|
|
}
|
|
|
|
//
|
|
// Package all information about this NIC and write an event record
|
|
//
|
|
pServiceInfo = NULL;
|
|
pServiceInfo = (PWMI_SERVICE_INFO) WmipGetTraceBuffer( LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_SERVICES,
|
|
sizeof(WMI_SERVICE_INFO));
|
|
if(pServiceInfo == NULL) {
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
break;
|
|
}
|
|
|
|
RtlCopyMemory(pServiceInfo, &ServiceInfo, sizeof(WMI_SERVICE_INFO));
|
|
|
|
dwServicesNum--;
|
|
ppInfo++;
|
|
}
|
|
}
|
|
|
|
if (pInfo) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pInfo);
|
|
}
|
|
|
|
CloseServiceHandle(hScm);
|
|
}
|
|
|
|
if(pBuffer) {
|
|
RtlFreeHeap (RtlProcessHeap(),0,pBuffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
WmipGetPowerInfo(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
SYSTEM_POWER_CAPABILITIES Cap;
|
|
WMI_POWER_RECORD Power;
|
|
PWMI_POWER_RECORD pPower = NULL;
|
|
|
|
RtlZeroMemory(&Power, sizeof(WMI_POWER_RECORD));
|
|
|
|
Status = NtPowerInformation (SystemPowerCapabilities,
|
|
NULL,
|
|
0,
|
|
&Cap,
|
|
sizeof (Cap));
|
|
if(!NT_SUCCESS(Status)) {
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
goto PowerCleanup;
|
|
}
|
|
|
|
Power.SystemS1 = Cap.SystemS1;
|
|
Power.SystemS2 = Cap.SystemS2;
|
|
Power.SystemS3 = Cap.SystemS3;
|
|
Power.SystemS4 = Cap.SystemS4;
|
|
Power.SystemS5 = Cap.SystemS5;
|
|
|
|
//
|
|
// Package all Power information and write an event record
|
|
//
|
|
pPower = (PWMI_POWER_RECORD) WmipGetTraceBuffer(LoggerContext,
|
|
NULL,
|
|
EVENT_TRACE_GROUP_CONFIG + EVENT_TRACE_TYPE_CONFIG_POWER,
|
|
sizeof(WMI_POWER_RECORD));
|
|
|
|
|
|
if(!pPower) {
|
|
Status = STATUS_NO_MEMORY;
|
|
goto PowerCleanup;
|
|
}
|
|
|
|
RtlCopyMemory(pPower,
|
|
&Power,
|
|
sizeof(WMI_POWER_RECORD));
|
|
|
|
PowerCleanup:
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// This routine records the hardware configuration in the
|
|
// logfile during RunDown
|
|
//
|
|
|
|
ULONG
|
|
WmipDumpHardwareConfig(
|
|
IN PWMI_LOGGER_CONTEXT LoggerContext
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
|
|
|
Status = WmipGetCpuConfig(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
Status = WmipGetVideoAdapters(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
Status = WmipGetDiskInfo(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
Status = WmipGetNetworkAdapters(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
Status = WmipGetServiceInfo(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
Status = WmipGetPowerInfo(LoggerContext);
|
|
|
|
if (!NT_SUCCESS(Status) )
|
|
return WmipSetDosError(WmipNtStatusToDosError(Status));
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|