Author: tkreuzer
Date: Thu Mar 19 10:47:36 2015
New Revision: 66797
URL:
http://svn.reactos.org/svn/reactos?rev=66797&view=rev
Log:
Merge the following revisions from kernel-fun branch:
r62291
[NTOSKRNL]
Start implementing the built-in WMI driver
r62294
[NTOSKRNL]
Add basic code for the WMI GUID object
r62301
[NTOSKRNK]
Halfplement WmipSecurityMethod, implement WmipGUIDFromString as a wrapper around
RtlGUIDFromString due to different format requirements, fix usage of
RtlPrefixUnicodeString.
r62302
[NTOSKRNL]
Implement WmipFastIoDeviceControl, start implementing WmipIoControl
r62321
[NTOSKRNL]
Stubplement IOCTL_WMI_UNREGISTER_GUIDS and IOCTL_WMI_RECEIVE_NOTIFICATIONS, just enough
that the callers don't error out.
r62322
[NTOSKRNL]
Zero out the guid object, remove debug breakpoints in WmipDeleteMethod and WmipCloseMethod
(for now there's nothing to do), factor out the code to capture the guid object
attributes into WmipCaptureGuidObjectAttributes, ignore ioctl 0x228168 for now and
stubplement IOCTL_WMI_OPEN_GUID_FOR_EVENTS
Added:
trunk/reactos/include/reactos/wmiioctl.h
- copied, changed from r62302,
branches/kernel-fun/reactos/include/reactos/wmiioctl.h
trunk/reactos/ntoskrnl/wmi/guidobj.c
- copied, changed from r62294, branches/kernel-fun/reactos/ntoskrnl/wmi/guidobj.c
trunk/reactos/ntoskrnl/wmi/wmidrv.c
- copied, changed from r62291, branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c
trunk/reactos/ntoskrnl/wmi/wmip.h
- copied, changed from r62291, branches/kernel-fun/reactos/ntoskrnl/wmi/wmip.h
Modified:
trunk/reactos/ (props changed)
trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
trunk/reactos/ntoskrnl/ntos.cmake
trunk/reactos/ntoskrnl/wmi/wmi.c
Propchange: trunk/reactos/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Mar 19 10:47:36 2015
@@ -6,7 +6,7 @@
/branches/condrv_restructure:63104-65657
/branches/header-work:45691-47721
/branches/kd++:58883-58973
-/branches/kernel-fun/reactos:62304,62353,62531-62532,62853,64152,64173-64174,65253
+/branches/kernel-fun/reactos:62291,62294,62301-62302,62304,62321-62322,62353,62531-62532,62853,64152,64173-64174,65253
/branches/ntvdm:59241-63176
/branches/reactos-yarotows:45219-46371,46373-48025,48027-49273
/branches/reactx/reactos:49994-49995
Copied: trunk/reactos/include/reactos/wmiioctl.h (from r62302,
branches/kernel-fun/reactos/include/reactos/wmiioctl.h)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/wmiioctl.h…
==============================================================================
--- branches/kernel-fun/reactos/include/reactos/wmiioctl.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/wmiioctl.h [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -25,13 +25,13 @@
#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_RECEIVE_NOTIFICATIONS 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_UNREGISTER_GUIDS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x57, METHOD_BUFFERED,
FILE_READ_ACCESS) // 0x22415C, called from ntdll!WmiUnregisterGuids
#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: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -24,6 +24,11 @@
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
+
+BOOLEAN
+NTAPI
+WmiInitialize(
+ VOID);
/* DATA ********************************************************************/
@@ -526,6 +531,9 @@
/* Initialize PnP manager */
IopInitializePlugPlayServices();
+ /* Initialize WMI */
+ WmiInitialize();
+
/* Initialize HAL Root Bus Driver */
HalInitPnpDriver();
Modified: trunk/reactos/ntoskrnl/ntos.cmake
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntos.cmake?rev=66…
==============================================================================
--- trunk/reactos/ntoskrnl/ntos.cmake [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntos.cmake [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -269,7 +269,9 @@
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sid.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/token.c
${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c
- ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmi.c)
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/guidobj.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmi.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmidrv.c)
list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/ex/zw.S)
Copied: trunk/reactos/ntoskrnl/wmi/guidobj.c (from r62294,
branches/kernel-fun/reactos/ntoskrnl/wmi/guidobj.c)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/guidobj.c?p2=…
==============================================================================
--- branches/kernel-fun/reactos/ntoskrnl/wmi/guidobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/wmi/guidobj.c [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -10,7 +10,6 @@
#include <ntoskrnl.h>
#include <wmistr.h>
-#include <wmiguid.h>
#include "wmip.h"
#define NDEBUG
@@ -37,8 +36,43 @@
_In_ POOL_TYPE PoolType,
_In_ PGENERIC_MAPPING GenericMapping)
{
- UNIMPLEMENTED_DBGBREAK();
- return STATUS_NOT_IMPLEMENTED;
+ PAGED_CODE();
+
+ ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
+ ASSERT((OperationType == QuerySecurityDescriptor) ||
+ (OperationType == SetSecurityDescriptor) ||
+ (OperationType == AssignSecurityDescriptor) ||
+ (OperationType == DeleteSecurityDescriptor));
+
+ if (OperationType == QuerySecurityDescriptor)
+ {
+ return ObQuerySecurityDescriptorInfo(Object,
+ SecurityInformation,
+ SecurityDescriptor,
+ CapturedLength,
+ ObjectSecurityDescriptor);
+ }
+ else if (OperationType == SetSecurityDescriptor)
+ {
+ return ObSetSecurityDescriptorInfo(Object,
+ SecurityInformation,
+ SecurityDescriptor,
+ ObjectSecurityDescriptor,
+ PoolType,
+ GenericMapping);
+ }
+ else if (OperationType == AssignSecurityDescriptor)
+ {
+ ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
+ return STATUS_SUCCESS;
+ }
+ else if (OperationType == DeleteSecurityDescriptor)
+ {
+ return ObDeassignSecurity(ObjectSecurityDescriptor);
+ }
+
+ ASSERT(FALSE);
+ return STATUS_INVALID_PARAMETER;
}
VOID
@@ -46,7 +80,14 @@
WmipDeleteMethod(
_In_ PVOID Object)
{
- UNIMPLEMENTED_DBGBREAK();
+ PWMIP_GUID_OBJECT GuidObject = Object;
+
+ /* Check if the object is attached to an IRP */
+ if (GuidObject->Irp != NULL)
+ {
+ /* This is not supported yet */
+ ASSERT(FALSE);
+ }
}
VOID
@@ -58,7 +99,7 @@
_In_ ULONG ProcessHandleCount,
_In_ ULONG SystemHandleCount)
{
- UNIMPLEMENTED_DBGBREAK();
+ /* For now nothing */
}
NTSTATUS
@@ -99,6 +140,32 @@
static
NTSTATUS
+WmipGUIDFromString(
+ _In_ PUNICODE_STRING GuidString,
+ _Out_ PGUID Guid)
+{
+ WCHAR Buffer[GUID_STRING_LENGTH + 2];
+ UNICODE_STRING String;
+
+ /* Validate string length */
+ if (GuidString->Length != GUID_STRING_LENGTH * sizeof(WCHAR))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Copy the string and wrap it in {} */
+ RtlCopyMemory(&Buffer[1], GuidString->Buffer, GuidString->Length);
+ Buffer[0] = L'{';
+ Buffer[GUID_STRING_LENGTH + 1] = L'}';
+
+ String.Buffer = Buffer;
+ String.Length = String.MaximumLength = sizeof(Buffer);
+
+ return RtlGUIDFromString(&String, Guid);
+}
+
+static
+NTSTATUS
WmipCreateGuidObject(
_In_ PUNICODE_STRING GuidString,
_Out_ PWMIP_GUID_OBJECT *OutGuidObject)
@@ -109,7 +176,7 @@
NTSTATUS Status;
/* Convert the string into a GUID structure */
- Status = RtlGUIDFromString(GuidString, &Guid);
+ Status = WmipGUIDFromString(GuidString, &Guid);
if (!NT_SUCCESS(Status))
{
DPRINT1("WMI: Invalid uuid format for guid '%wZ'\n",
GuidString);
@@ -139,6 +206,7 @@
return Status;
}
+ RtlZeroMemory(GuidObject, sizeof(*GuidObject));
GuidObject->Guid = Guid;
*OutGuidObject = GuidObject;
@@ -163,7 +231,7 @@
PAGED_CODE();
/* Check if we have the expected prefix */
- if (!RtlPrefixUnicodeString(ObjectAttributes->ObjectName, &Prefix, FALSE))
+ if (!RtlPrefixUnicodeString(&Prefix, ObjectAttributes->ObjectName, FALSE))
{
DPRINT1("WMI: Invalid prefix for guid object '%wZ'\n",
ObjectAttributes->ObjectName);
Modified: trunk/reactos/ntoskrnl/wmi/wmi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmi.c?rev=667…
==============================================================================
--- trunk/reactos/ntoskrnl/wmi/wmi.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/wmi/wmi.c [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -9,10 +9,39 @@
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
+#include "wmip.h"
+
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+WmiInitialize(
+ VOID)
+{
+ UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\WMIxWDM");
+ NTSTATUS Status;
+
+ /* Initialize the GUID object type */
+ Status = WmipInitializeGuidObjectType();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("WmipInitializeGuidObjectType() failed: 0x%lx\n", Status);
+ return FALSE;
+ }
+
+ /* Create the WMI driver */
+ Status = IoCreateDriver(&DriverName, WmipDriverEntry);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create WMI driver: 0x%lx\n", Status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
/*
* @unimplemented
Copied: trunk/reactos/ntoskrnl/wmi/wmidrv.c (from r62291,
branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmidrv.c?p2=t…
==============================================================================
--- branches/kernel-fun/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/wmi/wmidrv.c [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -10,10 +10,58 @@
#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;
+ TRACEHANDLE TraceHandle;
+ BOOLEAN Unknown10;
+} WMIP_RESULT, *PWMIP_RESULT;
+
+typedef struct _WMI_UNREGISTER_GUID
+{
+ GUID Guid;
+ ULONG Unknown10;
+ ULONG Unknown14;
+ ULONG Unknown18;
+ ULONG Unknown1C;
+} WMI_UNREGISTER_GUID, *PWMI_UNREGISTER_GUID;
+
+typedef struct _WMI_GUID_OBJECT_ENTRY
+{
+ HANDLE Handle;
+ ULONG Unknown04;
+} WMI_GUID_OBJECT_ENTRY, *PWMI_GUID_OBJECT_ENTRY;
+
+typedef struct _WMI_NOTIFICATION
+{
+ ULONG NumberOfGuidObjects;
+ ULONG Unknown04;
+ ULONG Unknown08;
+ ULONG Unknown0C;
+ ULONG Unknown10;
+ ULONG Unknown14;
+ WMI_GUID_OBJECT_ENTRY GuidObjects[0];
+} WMI_NOTIFICATION, *PWMI_NOTIFICATION;
PDEVICE_OBJECT WmipServiceDeviceObject;
PDEVICE_OBJECT WmipAdminDeviceObject;
@@ -42,14 +90,422 @@
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
+WmipCaptureGuidObjectAttributes(
+ _In_ POBJECT_ATTRIBUTES GuidObjectAttributes,
+ _Out_ POBJECT_ATTRIBUTES CapuredObjectAttributes,
+ _Out_ PUNICODE_STRING CapturedObjectName,
+ _Out_ PWSTR ObjectNameBuffer,
+ _In_ KPROCESSOR_MODE AccessMode)
+{
+ NT_ASSERT(AccessMode != KernelMode);
+
+ _SEH2_TRY
+ {
+ /* Probe and copy the object attributes structure */
+ ProbeForRead(GuidObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES),
+ sizeof(PVOID));
+ *CapuredObjectAttributes = *GuidObjectAttributes;
+
+ /* Probe and copy the object name UNICODE_STRING */
+ ProbeForRead(CapuredObjectAttributes->ObjectName,
+ sizeof(UNICODE_STRING),
+ sizeof(PVOID));
+ *CapturedObjectName = *CapuredObjectAttributes->ObjectName;
+
+ /* Check if the object name has the expected length */
+ if (CapturedObjectName->Length != 45 * sizeof(WCHAR))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Probe and copy the object name buffer */
+ ProbeForRead(CapturedObjectName->Buffer,
+ CapturedObjectName->Length,
+ sizeof(WCHAR));
+ RtlCopyMemory(ObjectNameBuffer,
+ CapturedObjectName->Buffer,
+ CapturedObjectName->Length);
+
+ /* Fix pointers */
+ CapturedObjectName->Buffer = ObjectNameBuffer;
+ GuidObjectAttributes->ObjectName = CapturedObjectName;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Got exception!\n");
+ return _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ 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;
+ }
+
+ /* Capture object attributes */
+ PreviousMode = ExGetPreviousMode();
+ Status = WmipCaptureGuidObjectAttributes(RegisterGuids->ObjectAttributes,
+ &LocalObjectAttributes,
+ &LocalObjectName,
+ LocalObjectNameBuffer,
+ PreviousMode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("WmipCaptureGuidObjectAttributes failed: 0x%lx\n", Status);
+ return Status;
+ }
+
+ /* 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);
+ return Status;
+ }
+
+ /* Dereference the GUID object */
+ ObDereferenceObject(GuidObject);
+
+ /* Return the handle (user mode will close it) */
+ Result->Handle = GuidObjectHandle;
+ Result->TraceHandle = 0;
+ *OutputLength = 24;
+
+ return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+WmipUnregisterGuids(
+ _In_ PVOID Buffer,
+ _In_ ULONG InputLength,
+ _Inout_ PULONG OutputLength)
+{
+ /* For now we have nothing to do */
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+WmipClearIrpObjectList(
+ _In_ PIRP Irp)
+{
+ PWMIP_IRP_CONTEXT IrpContext;
+ PLIST_ENTRY ListEntry;
+ PWMIP_GUID_OBJECT GuidObject;
+
+ /* Get the IRP context */
+ IrpContext = (PWMIP_IRP_CONTEXT)Irp->Tail.Overlay.DriverContext;
+
+ /* Loop all GUID objects attached to this IRP */
+ for (ListEntry = IrpContext->GuidObjectListHead.Flink;
+ ListEntry != &IrpContext->GuidObjectListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ /* Get the GUID object */
+ GuidObject = CONTAINING_RECORD(ListEntry, WMIP_GUID_OBJECT, IrpLink);
+
+ /* Make sure the IRP matches and clear it */
+ ASSERT(GuidObject->Irp == Irp);
+ GuidObject->Irp = NULL;
+
+ /* Remove the entry */
+ RemoveEntryList(ListEntry);
+ }
+}
+
+VOID
+NTAPI
+WmipNotificationIrpCancel(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _Inout_ PIRP Irp)
+{
+ /* Clear the list */
+ WmipClearIrpObjectList(Irp);
+
+ /* Release the cancel spin lock */
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+ /* Set the status to cancelled and complete the IRP */
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+static
+VOID
+WmipInitializeIrpContext(
+ PWMIP_IRP_CONTEXT IrpContext)
+{
+ /* Initialize the list head for GUID objects */
+ InitializeListHead(&IrpContext->GuidObjectListHead);
+}
+
+static
+NTSTATUS
+WmipReceiveNotifications(
+ _Inout_ PIRP Irp,
+ _In_ PVOID Buffer,
+ _In_ ULONG InputLength,
+ _Inout_ PULONG OutputLength)
+{
+ PWMI_NOTIFICATION Notification;
+ PWMIP_IRP_CONTEXT IrpContext;
+ NTSTATUS Status;
+
+ //__debugbreak();
+ if ((InputLength < sizeof(WMI_NOTIFICATION)) || (*OutputLength < 0x38))
+ {
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /// FIXME: For now we don't do any actual work, but simply pretend we are
+ /// waiting for notifications. We won't ever deliver any though.
+ Notification = (PWMI_NOTIFICATION)Buffer;
+ DBG_UNREFERENCED_LOCAL_VARIABLE(Notification);
+
+ // loop all objects
+ // reference the object
+ // on failure, fail the whole request
+
+ // loop all objects
+ // update the irp (synchronization!)
+ // if we had one before complete the old irp with an error
+
+ /* Get the IRP context and initialize it */
+ IrpContext = (PWMIP_IRP_CONTEXT)Irp->Tail.Overlay.DriverContext;
+ WmipInitializeIrpContext(IrpContext);
+
+ // loop all objects
+ // insert the objects into the IRP list
+
+ /* Set our cancel routine for cleanup */
+ IoSetCancelRoutine(Irp, WmipNotificationIrpCancel);
+
+ /* Check if the IRP is already being cancelled */
+ if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
+ {
+ Status = STATUS_CANCELLED;
+ }
+ else
+ {
+ /* Mark the IRP as pending */
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+ }
+
+ return Status;
+}
+
+typedef struct _WMI_OPEN_GUID_FOR_EVENTS
+{
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess;
+ ULONG Unknown08;
+ ULONG Unknown0C;
+} WMI_OPEN_GUID_FOR_EVENTS, *PWMI_OPEN_GUID_FOR_EVENTS;
+
+typedef struct _WMIP_RESULT2
+{
+ ULONG Unknown00;
+ ULONG Unknown04;
+ HANDLE Handle;
+ ULONG Unknown0C;
+} WMIP_RESULT2, *PWMIP_RESULT2;
+
+static
+NTSTATUS
+WmipOpenGuidForEvents(
+ PVOID Buffer,
+ ULONG InputLength,
+ PULONG OutputLength)
+{
+ PWMI_OPEN_GUID_FOR_EVENTS OpenGuidForEvents = Buffer;
+ PWMIP_RESULT2 Result = (PWMIP_RESULT2)Buffer;
+ OBJECT_ATTRIBUTES LocalObjectAttributes;
+ UNICODE_STRING LocalObjectName;
+ WCHAR LocalObjectNameBuffer[45 + 1];
+ KPROCESSOR_MODE PreviousMode;
+ HANDLE GuidObjectHandle;
+ PVOID GuidObject;
+ NTSTATUS Status;
+
+ if ((InputLength != sizeof(WMI_OPEN_GUID_FOR_EVENTS)) ||
+ (*OutputLength != sizeof(WMIP_RESULT2)))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Capture object attributes */
+ PreviousMode = ExGetPreviousMode();
+ Status = WmipCaptureGuidObjectAttributes(OpenGuidForEvents->ObjectAttributes,
+ &LocalObjectAttributes,
+ &LocalObjectName,
+ LocalObjectNameBuffer,
+ PreviousMode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ProbeAndCaptureGuidObjectAttributes failed: 0x%lx\n",
Status);
+ return Status;
+ }
+
+ /* Open a new GUID object */
+ Status = WmipOpenGuidObject(&LocalObjectAttributes,
+ OpenGuidForEvents->DesiredAccess,
+ PreviousMode,
+ &GuidObjectHandle,
+ &GuidObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("WmipOpenGuidObject failed: 0x%lx\n", Status);
+ return Status;
+ }
+
+ Result->Handle = GuidObjectHandle;
+
+ ObDereferenceObject(GuidObject);
+
+ 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;
+ }
+
+ case IOCTL_WMI_UNREGISTER_GUIDS:
+ {
+ Status = WmipUnregisterGuids(Buffer,
+ InputLength,
+ &OutputLength);
+ break;
+ }
+
+ case IOCTL_WMI_RECEIVE_NOTIFICATIONS:
+ {
+ Status = WmipReceiveNotifications(Irp,
+ Buffer,
+ InputLength,
+ &OutputLength);
+ break;
+ }
+
+ case 0x228168:
+ {
+ DPRINT1("IOCTL 0x228168 is unimplemented, ignoring\n");
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case IOCTL_WMI_OPEN_GUID_FOR_EVENTS:
+ {
+ Status = WmipOpenGuidForEvents(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 +543,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;
}
Copied: trunk/reactos/ntoskrnl/wmi/wmip.h (from r62291,
branches/kernel-fun/reactos/ntoskrnl/wmi/wmip.h)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/wmi/wmip.h?p2=tru…
==============================================================================
--- branches/kernel-fun/reactos/ntoskrnl/wmi/wmip.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/wmi/wmip.h [iso-8859-1] Thu Mar 19 10:47:36 2015
@@ -1,5 +1,19 @@
#pragma once
+
+#define GUID_STRING_LENGTH 36
+
+typedef struct _WMIP_IRP_CONTEXT
+{
+ LIST_ENTRY GuidObjectListHead;
+} WMIP_IRP_CONTEXT, *PWMIP_IRP_CONTEXT;
+
+typedef struct _WMIP_GUID_OBJECT
+{
+ GUID Guid;
+ PIRP Irp;
+ LIST_ENTRY IrpLink;
+} WMIP_GUID_OBJECT, *PWMIP_GUID_OBJECT;
_Function_class_(DRIVER_INITIALIZE)
@@ -10,3 +24,16 @@
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath);
+NTSTATUS
+NTAPI
+WmipInitializeGuidObjectType(
+ VOID);
+
+NTSTATUS
+NTAPI
+WmipOpenGuidObject(
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ ACCESS_MASK DesiredAccess,
+ KPROCESSOR_MODE AccessMode,
+ PHANDLE OutGuidObjectHandle,
+ PVOID *OutGuidObject);