Author: tkreuzer Date: Thu Mar 19 21:31:20 2015 New Revision: 66822
URL: http://svn.reactos.org/svn/reactos?rev=66822&view=rev Log: [NTOSKRNL] Hackplement IoWMIOpenBlock and IoWMIQueryAllData. Just enough to query the SMBIOS tables.
Added: trunk/reactos/ntoskrnl/wmi/smbios.c (with props) Modified: trunk/reactos/ntoskrnl/ntos.cmake trunk/reactos/ntoskrnl/wmi/guidobj.c trunk/reactos/ntoskrnl/wmi/wmi.c trunk/reactos/ntoskrnl/wmi/wmidrv.c trunk/reactos/ntoskrnl/wmi/wmip.h
Modified: trunk/reactos/ntoskrnl/ntos.cmake URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntos.cmake?rev=668... ============================================================================== --- trunk/reactos/ntoskrnl/ntos.cmake [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ntos.cmake [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -270,6 +270,7 @@ ${REACTOS_SOURCE_DIR}/ntoskrnl/se/token.c ${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/guidobj.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/smbios.c ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmi.c ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmidrv.c)
Modified: trunk/reactos/ntoskrnl/wmi/guidobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/guidobj.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/wmi/guidobj.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/wmi/guidobj.c [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -167,21 +167,12 @@ static NTSTATUS WmipCreateGuidObject( - _In_ PUNICODE_STRING GuidString, + _In_ const GUID *Guid, _Out_ PWMIP_GUID_OBJECT *OutGuidObject) { OBJECT_ATTRIBUTES ObjectAttributes; - GUID Guid; PWMIP_GUID_OBJECT GuidObject; NTSTATUS Status; - - /* Convert the string into a GUID structure */ - Status = WmipGUIDFromString(GuidString, &Guid); - if (!NT_SUCCESS(Status)) - { - DPRINT1("WMI: Invalid uuid format for guid '%wZ'\n", GuidString); - return Status; - }
/* Initialize object attributes for an unnamed object */ InitializeObjectAttributes(&ObjectAttributes, @@ -207,7 +198,7 @@ }
RtlZeroMemory(GuidObject, sizeof(*GuidObject)); - GuidObject->Guid = Guid; + GuidObject->Guid = *Guid;
*OutGuidObject = GuidObject;
@@ -217,37 +208,22 @@ NTSTATUS NTAPI WmipOpenGuidObject( - POBJECT_ATTRIBUTES ObjectAttributes, - ACCESS_MASK DesiredAccess, - KPROCESSOR_MODE AccessMode, - PHANDLE OutGuidObjectHandle, - PVOID *OutGuidObject) -{ - static UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\WmiGuid\"); - UNICODE_STRING GuidString; + _In_ LPCGUID Guid, + _In_ ACCESS_MASK DesiredAccess, + _In_ KPROCESSOR_MODE AccessMode, + _Out_ PHANDLE OutGuidObjectHandle, + _Outptr_ PVOID *OutGuidObject) +{ + PWMIP_GUID_OBJECT GuidObject; ULONG HandleAttributes; - PWMIP_GUID_OBJECT GuidObject; - NTSTATUS Status; - PAGED_CODE(); - - /* Check if we have the expected prefix */ - if (!RtlPrefixUnicodeString(&Prefix, ObjectAttributes->ObjectName, FALSE)) - { - DPRINT1("WMI: Invalid prefix for guid object '%wZ'\n", - ObjectAttributes->ObjectName); - return STATUS_INVALID_PARAMETER; - } - - /* Extract the GUID string */ - GuidString = *ObjectAttributes->ObjectName; - GuidString.Buffer += Prefix.Length / sizeof(WCHAR); - GuidString.Length -= Prefix.Length; + NTSTATUS Status;
/* Create the GUID object */ - Status = WmipCreateGuidObject(&GuidString, &GuidObject); + Status = WmipCreateGuidObject(Guid, &GuidObject); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create GUID object: 0x%lx\n", Status); + *OutGuidObject = NULL; return Status; }
@@ -266,6 +242,7 @@ { DPRINT1("ObOpenObjectByPointer failed: 0x%lx\n", Status); ObfDereferenceObject(GuidObject); + GuidObject = NULL; }
*OutGuidObject = GuidObject; @@ -273,3 +250,46 @@ return Status; }
+NTSTATUS +NTAPI +WmipOpenGuidObjectByName( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ACCESS_MASK DesiredAccess, + _In_ KPROCESSOR_MODE AccessMode, + _Out_ PHANDLE OutGuidObjectHandle, + _Outptr_ PVOID *OutGuidObject) +{ + static UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\WmiGuid\"); + UNICODE_STRING GuidString; + NTSTATUS Status; + GUID Guid; + PAGED_CODE(); + + /* Check if we have the expected prefix */ + if (!RtlPrefixUnicodeString(&Prefix, ObjectAttributes->ObjectName, FALSE)) + { + DPRINT1("WMI: Invalid prefix for guid object '%wZ'\n", + ObjectAttributes->ObjectName); + return STATUS_INVALID_PARAMETER; + } + + /* Extract the GUID string */ + GuidString = *ObjectAttributes->ObjectName; + GuidString.Buffer += Prefix.Length / sizeof(WCHAR); + GuidString.Length -= Prefix.Length; + + /* Convert the string into a GUID structure */ + Status = WmipGUIDFromString(&GuidString, &Guid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WMI: Invalid uuid format for guid '%wZ'\n", GuidString); + return Status; + } + + return WmipOpenGuidObject(&Guid, + DesiredAccess, + AccessMode, + OutGuidObjectHandle, + OutGuidObject); +} +
Added: trunk/reactos/ntoskrnl/wmi/smbios.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/smbios.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/wmi/smbios.c (added) +++ trunk/reactos/ntoskrnl/wmi/smbios.c [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -0,0 +1,279 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/io/wmi.c + * PURPOSE: I/O Windows Management Instrumentation (WMI) Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include <ntoskrnl.h> +#include <wmiguid.h> +#include <wmidata.h> +#include <wmistr.h> + +#include "wmip.h" + +#define NDEBUG +#include <debug.h> + + +/* FUNCTIONS *****************************************************************/ + +typedef struct _SMBIOS21_ENTRY_POINT +{ + CHAR AnchorString[4]; + UCHAR Checksum; + UCHAR Length; + UCHAR MajorVersion; + UCHAR MinorVersion; + USHORT MaxStructureSize; + UCHAR EntryPointRevision; + CHAR FormattedArea[5]; + CHAR AnchorString2[5]; + UCHAR Checksum2; + USHORT TableLength; + ULONG TableAddress; + USHORT NumberOfStructures; + UCHAR BCDRevision; +} SMBIOS21_ENTRY_POINT, *PSMBIOS21_ENTRY_POINT; + +typedef struct _SMBIOS30_ENTRY_POINT +{ + CHAR AnchorString[5]; + UCHAR Checksum; + UCHAR Length; + UCHAR MajorVersion; + UCHAR MinorVersion; + UCHAR Docref; + UCHAR Revision; + UCHAR Reserved; + ULONG TableMaxSize; + ULONG64 TableAddress; +} SMBIOS30_ENTRY_POINT, *PSMBIOS30_ENTRY_POINT; + +static +BOOLEAN +GetEntryPointData( + _In_ const UCHAR *EntryPointAddress, + _Out_ PULONG64 TableAddress, + _Out_ PULONG TableSize, + _Out_ PMSSmBios_RawSMBiosTables BiosTablesHeader) +{ + PSMBIOS21_ENTRY_POINT EntryPoint21; + PSMBIOS30_ENTRY_POINT EntryPoint30; + UCHAR Checksum; + ULONG i; + + /* Check for SMBIOS 2.1 entry point */ + EntryPoint21 = (PSMBIOS21_ENTRY_POINT)EntryPointAddress; + if (RtlEqualMemory(EntryPoint21->AnchorString, "_SM_", 4)) + { + if (EntryPoint21->Length > 32) + return FALSE; + + /* Calculate the checksum */ + Checksum = 0; + for (i = 0; i < EntryPoint21->Length; i++) + { + Checksum += EntryPointAddress[i]; + } + + if (Checksum != 0) + return FALSE; + + *TableAddress = EntryPoint21->TableAddress; + *TableSize = EntryPoint21->TableLength; + BiosTablesHeader->Used20CallingMethod = 0; + BiosTablesHeader->SmbiosMajorVersion = EntryPoint21->MajorVersion; + BiosTablesHeader->SmbiosMinorVersion = EntryPoint21->MinorVersion; + BiosTablesHeader->DmiRevision = 2; + BiosTablesHeader->Size = EntryPoint21->TableLength; + return TRUE; + } + + /* Check for SMBIOS 3.0 entry point */ + EntryPoint30 = (PSMBIOS30_ENTRY_POINT)EntryPointAddress; + if (RtlEqualMemory(EntryPoint30->AnchorString, "_SM3_", 5)) + { + if (EntryPoint30->Length > 32) + return FALSE; + + /* Calculate the checksum */ + Checksum = 0; + for (i = 0; i < EntryPoint30->Length; i++) + { + Checksum += EntryPointAddress[i]; + } + + if (Checksum != 0) + return FALSE; + + *TableAddress = EntryPoint30->TableAddress; + *TableSize = EntryPoint30->TableMaxSize; + BiosTablesHeader->Used20CallingMethod = 0; + BiosTablesHeader->SmbiosMajorVersion = EntryPoint30->MajorVersion; + BiosTablesHeader->SmbiosMinorVersion = EntryPoint30->MinorVersion; + BiosTablesHeader->DmiRevision = 3; + BiosTablesHeader->Size = EntryPoint30->TableMaxSize; + return TRUE; + } + + return FALSE; +} + +_At_(*OutTableData, __drv_allocatesMem(Mem)) +NTSTATUS +NTAPI +WmipGetRawSMBiosTableData( + _Outptr_opt_result_buffer_(*OutDataSize) PVOID *OutTableData, + _Out_ PULONG OutDataSize) +{ + static const SIZE_T SearchSize = 0x10000; + static const ULONG HeaderSize = FIELD_OFFSET(MSSmBios_RawSMBiosTables, SMBiosData); + PHYSICAL_ADDRESS PhysicalAddress; + PUCHAR EntryPointMapping; + MSSmBios_RawSMBiosTables BiosTablesHeader; + PVOID BiosTables, TableMapping; + ULONG Offset, TableSize; + ULONG64 TableAddress = 0; + + /* This is where the range for the entry point starts */ + PhysicalAddress.QuadPart = 0xF0000; + + /* Map the range into the system address space */ + EntryPointMapping = MmMapIoSpace(PhysicalAddress, SearchSize, MmCached); + if (EntryPointMapping == NULL) + { + DPRINT1("Failed to map range for SMBIOS entry point\n"); + return STATUS_UNSUCCESSFUL; + } + + /* Loop the table memory in 16 byte steps */ + for (Offset = 0; Offset <= (0x10000 - 32); Offset += 16) + { + /* Check if we have an entry point here and get it's data */ + if (GetEntryPointData(EntryPointMapping + Offset, + &TableAddress, + &TableSize, + &BiosTablesHeader)) + { + break; + } + } + + /* Unmap the entry point */ + MmUnmapIoSpace(EntryPointMapping, SearchSize); + + /* Did we find anything */ + if (TableAddress == 0) + { + DPRINT1("Could not find the SMBIOS entry point\n"); + return STATUS_NOT_FOUND; + } + + /* Check if the caller asked for the buffer */ + if (OutTableData != NULL) + { + /* Allocate a buffer for the result */ + BiosTables = ExAllocatePoolWithTag(PagedPool, + HeaderSize + TableSize, + 'BTMS'); + if (BiosTables == NULL) + { + DPRINT1("Failed to allocate %lu bytes for the SMBIOS table\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy the header */ + RtlCopyMemory(BiosTables, &BiosTablesHeader, HeaderSize); + + /* This is where the table is */ + PhysicalAddress.QuadPart = TableAddress; + + /* Map the table into the system address space */ + TableMapping = MmMapIoSpace(PhysicalAddress, TableSize, MmCached); + if (TableMapping == NULL) + { + return STATUS_UNSUCCESSFUL; + } + + /* Copy the table */ + RtlCopyMemory((PUCHAR)BiosTables + HeaderSize, TableMapping, TableSize); + + /* Unmap the table */ + MmUnmapIoSpace(TableMapping, TableSize); + + *OutTableData = BiosTables; + } + + *OutDataSize = HeaderSize + TableSize; + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +WmipQueryRawSMBiosTables( + _Inout_ ULONG *InOutBufferSize, + _Out_opt_ PVOID OutBuffer) +{ + NTSTATUS Status; + PVOID TableData = NULL; + ULONG TableSize, ResultSize; + PWNODE_ALL_DATA AllData; + + /* Get the table data */ + Status = WmipGetRawSMBiosTableData(OutBuffer ? &TableData : NULL, &TableSize); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WmipGetRawSMBiosTableData failed: 0x08lx\n", Status); + return Status; + } + + ResultSize = sizeof(WNODE_ALL_DATA) + TableSize; + + /* Check if the caller provided a buffer */ + if ((OutBuffer != NULL) && (*InOutBufferSize != 0)) + { + /* Check if the buffer is large enough */ + if (*InOutBufferSize < ResultSize) + { + DPRINT1("Buffer too small. Got %lu, need %lu\n", + *InOutBufferSize, ResultSize); + return STATUS_BUFFER_TOO_SMALL; + } + + /// FIXME: most of this is fubar + AllData = OutBuffer; + AllData->WnodeHeader.BufferSize = ResultSize; + AllData->WnodeHeader.ProviderId = 0; + AllData->WnodeHeader.Version = 0; + AllData->WnodeHeader.Linkage = 0; // last entry + //AllData->WnodeHeader.CountLost; + AllData->WnodeHeader.KernelHandle = NULL; + //AllData->WnodeHeader.TimeStamp; + AllData->WnodeHeader.Guid = MSSmBios_RawSMBiosTables_GUID; + AllData->WnodeHeader.ClientContext; + AllData->WnodeHeader.Flags = WNODE_FLAG_FIXED_INSTANCE_SIZE; + AllData->DataBlockOffset = sizeof(WNODE_ALL_DATA); + AllData->InstanceCount = 1; + AllData->OffsetInstanceNameOffsets; + AllData->FixedInstanceSize = TableSize; + + RtlCopyMemory(AllData + 1, TableData, TableSize); + } + + /* Set the size */ + *InOutBufferSize = ResultSize; + + /* Free the table buffer */ + if (TableData != NULL) + { + ExFreePoolWithTag(TableData, 'BTMS'); + } + + return STATUS_SUCCESS; +} +
Propchange: trunk/reactos/ntoskrnl/wmi/smbios.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/ntoskrnl/wmi/wmi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmi.c?rev=6682... ============================================================================== --- trunk/reactos/ntoskrnl/wmi/wmi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/wmi/wmi.c [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -9,6 +9,11 @@ /* INCLUDES *****************************************************************/
#include <ntoskrnl.h> +#define INITGUID +#include <wmiguid.h> +#include <wmidata.h> +#include <wmistr.h> + #include "wmip.h"
#define NDEBUG @@ -106,25 +111,68 @@ */ NTSTATUS NTAPI -IoWMIOpenBlock(IN LPCGUID DataBlockGuid, - IN ULONG DesiredAccess, - OUT PVOID *DataBlockObject) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IoWMIQueryAllData(IN PVOID DataBlockObject, - IN OUT ULONG *InOutBufferSize, - OUT PVOID OutBuffer) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; +IoWMIOpenBlock( + _In_ LPCGUID DataBlockGuid, + _In_ ULONG DesiredAccess, + _Out_ PVOID *DataBlockObject) +{ + HANDLE GuidObjectHandle; + NTSTATUS Status; + + /* Open the GIOD object */ + Status = WmipOpenGuidObject(DataBlockGuid, + DesiredAccess, + KernelMode, + &GuidObjectHandle, + DataBlockObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WmipOpenGuidObject failed: 0x%lx\n", Status); + return Status; + } + + + return STATUS_SUCCESS; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IoWMIQueryAllData( + IN PVOID DataBlockObject, + IN OUT ULONG *InOutBufferSize, + OUT PVOID OutBuffer) +{ + PWMIP_GUID_OBJECT GuidObject; + NTSTATUS Status; + + + Status = ObReferenceObjectByPointer(DataBlockObject, + WMIGUID_QUERY, + WmipGuidObjectType, + KernelMode); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + GuidObject = DataBlockObject; + + /* Huge HACK! */ + if (IsEqualGUID(&GuidObject->Guid, &MSSmBios_RawSMBiosTables_GUID)) + { + Status = WmipQueryRawSMBiosTables(InOutBufferSize, OutBuffer); + } + else + { + Status = STATUS_NOT_SUPPORTED; + } + + ObDereferenceObject(DataBlockObject); + + return Status; }
/*
Modified: trunk/reactos/ntoskrnl/wmi/wmidrv.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmidrv.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -210,14 +210,14 @@ }
/* Open a new GUID object */ - Status = WmipOpenGuidObject(&LocalObjectAttributes, - SPECIFIC_RIGHTS_ALL, - PreviousMode, - &GuidObjectHandle, - &GuidObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("WmipOpenGuidObject failed: 0x%lx\n", Status); + Status = WmipOpenGuidObjectByName(&LocalObjectAttributes, + SPECIFIC_RIGHTS_ALL, + PreviousMode, + &GuidObjectHandle, + &GuidObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WmipOpenGuidObjectByName failed: 0x%lx\n", Status); return Status; }
@@ -409,14 +409,14 @@ }
/* Open a new GUID object */ - Status = WmipOpenGuidObject(&LocalObjectAttributes, - OpenGuidForEvents->DesiredAccess, - PreviousMode, - &GuidObjectHandle, - &GuidObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("WmipOpenGuidObject failed: 0x%lx\n", Status); + Status = WmipOpenGuidObjectByName(&LocalObjectAttributes, + OpenGuidForEvents->DesiredAccess, + PreviousMode, + &GuidObjectHandle, + &GuidObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WmipOpenGuidObjectByName failed: 0x%lx\n", Status); return Status; }
Modified: trunk/reactos/ntoskrnl/wmi/wmip.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmip.h?rev=668... ============================================================================== --- trunk/reactos/ntoskrnl/wmi/wmip.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/wmi/wmip.h [iso-8859-1] Thu Mar 19 21:31:20 2015 @@ -1,5 +1,7 @@
#pragma once + +extern POBJECT_TYPE WmipGuidObjectType;
#define GUID_STRING_LENGTH 36
@@ -32,8 +34,24 @@ NTSTATUS NTAPI WmipOpenGuidObject( - POBJECT_ATTRIBUTES ObjectAttributes, - ACCESS_MASK DesiredAccess, - KPROCESSOR_MODE AccessMode, - PHANDLE OutGuidObjectHandle, - PVOID *OutGuidObject); + _In_ LPCGUID Guid, + _In_ ACCESS_MASK DesiredAccess, + _In_ KPROCESSOR_MODE AccessMode, + _Out_ PHANDLE OutGuidObjectHandle, + _Outptr_ PVOID *OutGuidObject); + +NTSTATUS +NTAPI +WmipOpenGuidObjectByName( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ACCESS_MASK DesiredAccess, + _In_ KPROCESSOR_MODE AccessMode, + _Out_ PHANDLE OutGuidObjectHandle, + _Outptr_ PVOID *OutGuidObject); + +NTSTATUS +NTAPI +WmipQueryRawSMBiosTables( + _Inout_ ULONG *InOutBufferSize, + _Out_opt_ PVOID OutBuffer); +