Author: tkreuzer Date: Sun Feb 23 14:56:48 2014 New Revision: 62302 URL: http://svn.reactos.org/svn/reactos?rev=62302&view=rev Log: [NTOSKRNL] Implement WmipFastIoDeviceControl, start implementing WmipIoControl
Added: branches/kernel-fun/reactos/include/reactos/wmiioctl.h - copied unchanged from r62291, branches/kernel-fun/reactos/include/reactos/wmiguid.h Removed: branches/kernel-fun/reactos/include/reactos/wmiguid.h Modified: branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c Removed: branches/kernel-fun/reactos/include/reactos/wmiguid.h URL: http://svn.reactos.org/svn/reactos/branches/kernel-fun/reactos/include/reactos/wmiguid.h?rev=62301 ============================================================================== --- branches/kernel-fun/reactos/include/reactos/wmiguid.h [iso-8859-1] (original) +++ branches/kernel-fun/reactos/include/reactos/wmiguid.h (removed) @@ -1,37 +0,0 @@ - -#pragma once - -#define IOCTL_WMI_QUERY_ALL_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224000 -#define IOCTL_WMI_SINGLE_INSTANCE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x01, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224004 -#define IOCTL_WMI_SET_SINGLE_INSTANCE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x02, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x228008 -#define IOCTL_WMI_SET_SINGLE_ITEM CTL_CODE(FILE_DEVICE_UNKNOWN, 0x03, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x22800C -#define IOCTL_WMI_09 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x09, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x228024 -#define IOCTL_WMI_20 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x220080 -#define IOCTL_WMI_21 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x21, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x220084 -#define IOCTL_WMI_22 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x22, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x220088 -#define IOCTL_WMI_TRACE_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x23, METHOD_NEITHER, FILE_WRITE_ACCESS) // 0x22808F -#define IOCTL_WMI_24 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x24, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x220090 -#define IOCTL_WMI_25 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x25, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x220094 -#define IOCTL_WMI_TRACE_USER_MESSAGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x28, METHOD_NEITHER, FILE_WRITE_ACCESS) // 0x2280A3 -#define IOCTL_WMI_29 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x29, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x2200A4 -#define IOCTL_WMI_2a CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2a, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x2200A8 -#define IOCTL_WMI_2b CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2b, METHOD_BUFFERED, FILE_ANY_ACCESS) // 0x2200AC -#define IOCTL_WMI_42 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x42, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224108 -#define IOCTL_WMI_47 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x47, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x22811C -#define IOCTL_WMI_49 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x49, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224124 -#define IOCTL_WMI_4b CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4b, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x22812C -#define IOCTL_WMI_4c CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4c, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x228130 -#define IOCTL_WMI_4d CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4d, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224134 -#define IOCTL_WMI_4e CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4e, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224138 -#define IOCTL_WMI_4f CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4f, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x22413C -#define IOCTL_WMI_OPEN_GUID_FOR_EVENTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x50, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224140 -#define IOCTL_WMI_51 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x51, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x228144 -#define IOCTL_WMI_52 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x52, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224148 -#define IOCTL_WMI_REGISTER_GUIDS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x53, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x22414C, called from ntdll!EtwpRegisterGuids -#define IOCTL_WMI_54 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x54, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224150 -#define IOCTL_WMI_55 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x55, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224154 -#define IOCTL_WMI_56 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x56, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224158 -#define IOCTL_WMI_57 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x57, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x22415C -#define IOCTL_WMI_58 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x58, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224160 -#define IOCTL_WMI_59 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x59, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x224164 -#define IOCTL_WMI_5a CTL_CODE(FILE_DEVICE_UNKNOWN, 0x5a, METHOD_BUFFERED, FILE_WRITE_ACCESS) // 0x228168 Modified: branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c URL: http://svn.reactos.org/svn/reactos/branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c?rev=62302&r1=62301&r2=62302&view=diff ============================================================================== --- branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] (original) +++ branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] Sun Feb 23 14:56:48 2014 @@ -10,10 +10,34 @@ #include <ntoskrnl.h> #include <wmistr.h> -#include <wmiguid.h> +#include <wmiioctl.h> +#include "wmip.h" #define NDEBUG #include <debug.h> + +// FIXME: these should go to a shared header +typedef struct _WMIP_REGISTER_GUIDS +{ + POBJECT_ATTRIBUTES ObjectAttributes; + ULONG Unknown04; + ULONG Unknown08; + ULONG Unknown0C; + ULONG Unknown10; + ULONG Unknown14; + + WMIREGINFOW RegInfo; +} WMIP_REGISTER_GUIDS, *PWMIP_REGISTER_GUIDS; + +typedef struct _WMIP_RESULT +{ + HANDLE Handle; + ULONG Unknown04; + ULONG Unknown08; + ULONG Unknown0C; + BOOLEAN Unknown10; +} WMIP_RESULT, *PWMIP_RESULT; + PDEVICE_OBJECT WmipServiceDeviceObject; PDEVICE_OBJECT WmipAdminDeviceObject; @@ -42,14 +66,167 @@ return STATUS_SUCCESS; } +static +NTSTATUS +WmiTraceEvent( + PVOID InputBuffer, + KPROCESSOR_MODE PreviousMode) +{ + UNIMPLEMENTED_DBGBREAK(); + return STATUS_SUCCESS; +} + +static +NTSTATUS +WmiTraceUserMessage( + PVOID InputBuffer, + ULONG InputBufferLength) +{ + UNIMPLEMENTED_DBGBREAK(); + return STATUS_SUCCESS; +} + +static +NTSTATUS +WmipRegisterGuids( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PVOID Buffer, + _In_ ULONG InputLength, + _Inout_ PULONG OutputLength) +{ + PWMIP_REGISTER_GUIDS RegisterGuids = (PWMIP_REGISTER_GUIDS)Buffer; + PWMIP_RESULT Result = (PWMIP_RESULT)Buffer; + OBJECT_ATTRIBUTES LocalObjectAttributes; + UNICODE_STRING LocalObjectName; + WCHAR LocalObjectNameBuffer[45 + 1]; + KPROCESSOR_MODE PreviousMode; + HANDLE GuidObjectHandle; + PVOID GuidObject; + NTSTATUS Status; + + /* Make sure the input buffer is large enough */ + if ((InputLength < sizeof(WMIP_REGISTER_GUIDS)) || + (RegisterGuids->RegInfo.BufferSize > + (InputLength - FIELD_OFFSET(WMIP_REGISTER_GUIDS, RegInfo)))) + { + return STATUS_UNSUCCESSFUL; + } + + /* Make sure we have a resonable GUID count */ + if ((RegisterGuids->RegInfo.GuidCount == 0) || + (RegisterGuids->RegInfo.GuidCount > 0x10000)) + { + return STATUS_UNSUCCESSFUL; + } + + _SEH2_TRY + { + /* Probe and copy the object attributes structure */ + ProbeForRead(RegisterGuids->ObjectAttributes, + sizeof(OBJECT_ATTRIBUTES), + sizeof(PVOID)); + LocalObjectAttributes = *RegisterGuids->ObjectAttributes; + + /* Probe and copy the object name UNICODE_STRING */ + ProbeForRead(LocalObjectAttributes.ObjectName, + sizeof(UNICODE_STRING), + sizeof(PVOID)); + LocalObjectName = *LocalObjectAttributes.ObjectName; + + /* Check if the object name has the expected length */ + if (LocalObjectName.Length != 45 * sizeof(WCHAR)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Probe and copy the object name buffer */ + ProbeForRead(LocalObjectName.Buffer, LocalObjectName.Length, sizeof(WCHAR)); + RtlCopyMemory(LocalObjectNameBuffer, + LocalObjectName.Buffer, + LocalObjectName.Length); + + /* Fix pointers */ + LocalObjectName.Buffer = LocalObjectNameBuffer; + LocalObjectAttributes.ObjectName = &LocalObjectName; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DPRINT1("Got exception!\n"); + return _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* Open a new GUID object */ + PreviousMode = ExGetPreviousMode(); + Status = WmipOpenGuidObject(&LocalObjectAttributes, + SPECIFIC_RIGHTS_ALL, + PreviousMode, + &GuidObjectHandle, + &GuidObject); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Derefernce the GUID object */ + ObDereferenceObject(GuidObject); + + /* Return the handle */ + Result->Handle = GuidObjectHandle; + *OutputLength = 24; + + return STATUS_SUCCESS; +} + NTSTATUS NTAPI WmipIoControl( - _Inout_ PDEVICE_OBJECT DeviceObject, - _Inout_ PIRP Irp) -{ - UNIMPLEMENTED_DBGBREAK(); - return STATUS_NOT_IMPLEMENTED; + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PIO_STACK_LOCATION IoStackLocation; + ULONG IoControlCode; + PVOID Buffer; + ULONG InputLength, OutputLength; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the current stack location */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + + /* Get the io control parameters */ + IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; + Buffer = Irp->AssociatedIrp.SystemBuffer; + InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; + OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; + + switch (IoControlCode) + { + + case IOCTL_WMI_REGISTER_GUIDS: + { + Status = WmipRegisterGuids(DeviceObject, + Buffer, + InputLength, + &OutputLength); + break; + } + + default: + DPRINT1("Unsupported yet IOCTL: 0x%lx\n", IoControlCode); + Status = STATUS_INVALID_DEVICE_REQUEST; + __debugbreak(); + break; + } + + if (Status == STATUS_PENDING) + return Status; + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = NT_SUCCESS(Status) ? OutputLength : 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } NTSTATUS @@ -87,7 +264,32 @@ _Out_ PIO_STATUS_BLOCK IoStatus, _In_ PDEVICE_OBJECT DeviceObject) { - UNIMPLEMENTED_DBGBREAK(); + PAGED_CODE(); + + if (IoControlCode == IOCTL_WMI_TRACE_EVENT) + { + if (InputBufferLength < 0x30) + { + DPRINT1("Buffer too small\n"); + return FALSE; + } + + IoStatus->Status = WmiTraceEvent(InputBuffer, ExGetPreviousMode()); + return TRUE; + } + else if (IoControlCode == IOCTL_WMI_TRACE_USER_MESSAGE) + { + if (InputBufferLength < 0x30) + { + DPRINT1("Buffer too small\n"); + return FALSE; + } + + IoStatus->Status = WmiTraceUserMessage(InputBuffer, InputBufferLength); + return TRUE; + } + + DPRINT1("Invalid io control code for fast dispatch: 0x%lx\n", IoControlCode); return FALSE; }