Author: sginsberg
Date: Mon Aug 18 08:30:17 2008
New Revision: 35427
URL:
http://svn.reactos.org/svn/reactos?rev=35427&view=rev
Log:
- Cleanup and reformat parts of pnpmgr (no code change)
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugpla…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,16 +1,14 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/plugplay.c
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/plugplay.c
* PURPOSE: Plug-and-play interface routines
- *
* PROGRAMMERS: Eric Kohl <eric.kohl(a)t-online.de>
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-
#define NDEBUG
#include <internal/debug.h>
@@ -113,127 +111,6 @@
return STATUS_SUCCESS;
}
-
-
-/*
- * Plug and Play event structure used by NtGetPlugPlayEvent.
- *
- * EventGuid
- * Can be one of the following values:
- * GUID_HWPROFILE_QUERY_CHANGE
- * GUID_HWPROFILE_CHANGE_CANCELLED
- * GUID_HWPROFILE_CHANGE_COMPLETE
- * GUID_TARGET_DEVICE_QUERY_REMOVE
- * GUID_TARGET_DEVICE_REMOVE_CANCELLED
- * GUID_TARGET_DEVICE_REMOVE_COMPLETE
- * GUID_PNP_CUSTOM_NOTIFICATION
- * GUID_PNP_POWER_NOTIFICATION
- * GUID_DEVICE_* (see above)
- *
- * EventCategory
- * Type of the event that happened.
- *
- * Result
- * ?
- *
- * Flags
- * ?
- *
- * TotalSize
- * Size of the event block including the device IDs and other
- * per category specific fields.
- */
-/*
- * NtGetPlugPlayEvent
- *
- * Returns one Plug & Play event from a global queue.
- *
- * Parameters
- * Reserved1
- * Reserved2
- * Always set to zero.
- *
- * Buffer
- * The buffer that will be filled with the event information on
- * successful return from the function.
- *
- * BufferSize
- * Size of the buffer pointed by the Buffer parameter. If the
- * buffer size is not large enough to hold the whole event
- * information, error STATUS_BUFFER_TOO_SMALL is returned and
- * the buffer remains untouched.
- *
- * Return Values
- * STATUS_PRIVILEGE_NOT_HELD
- * STATUS_BUFFER_TOO_SMALL
- * STATUS_SUCCESS
- *
- * Remarks
- * This function isn't multi-thread safe!
- *
- * @implemented
- */
-NTSTATUS STDCALL
-NtGetPlugPlayEvent(IN ULONG Reserved1,
- IN ULONG Reserved2,
- OUT PPLUGPLAY_EVENT_BLOCK Buffer,
- IN ULONG BufferSize)
-{
- PPNP_EVENT_ENTRY Entry;
- NTSTATUS Status;
-
- DPRINT("NtGetPlugPlayEvent() called\n");
-
- /* Function can only be called from user-mode */
- if (KeGetPreviousMode() == KernelMode)
- {
- DPRINT1("NtGetPlugPlayEvent cannot be called from kernel mode!\n");
- return STATUS_ACCESS_DENIED;
- }
-
- /* Check for Tcb privilege */
- if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
- UserMode))
- {
- DPRINT1("NtGetPlugPlayEvent: Caller does not hold the SeTcbPrivilege
privilege!\n");
- return STATUS_PRIVILEGE_NOT_HELD;
- }
-
- /* Wait for a PnP event */
- DPRINT("Waiting for pnp notification event\n");
- Status = KeWaitForSingleObject(&IopPnpNotifyEvent,
- UserRequest,
- KernelMode,
- FALSE,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KeWaitForSingleObject() failed (Status %lx)\n", Status);
- return Status;
- }
-
- /* Get entry from the tail of the queue */
- Entry = CONTAINING_RECORD(IopPnpEventQueueHead.Blink,
- PNP_EVENT_ENTRY,
- ListEntry);
-
- /* Check the buffer size */
- if (BufferSize < Entry->Event.TotalSize)
- {
- DPRINT1("Buffer is too small for the pnp-event\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- /* Copy event data to the user buffer */
- memcpy(Buffer,
- &Entry->Event,
- Entry->Event.TotalSize);
-
- DPRINT("NtGetPlugPlayEvent() done\n");
-
- return STATUS_SUCCESS;
-}
-
static PDEVICE_OBJECT
IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
@@ -706,6 +583,128 @@
return Status;
}
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * Plug and Play event structure used by NtGetPlugPlayEvent.
+ *
+ * EventGuid
+ * Can be one of the following values:
+ * GUID_HWPROFILE_QUERY_CHANGE
+ * GUID_HWPROFILE_CHANGE_CANCELLED
+ * GUID_HWPROFILE_CHANGE_COMPLETE
+ * GUID_TARGET_DEVICE_QUERY_REMOVE
+ * GUID_TARGET_DEVICE_REMOVE_CANCELLED
+ * GUID_TARGET_DEVICE_REMOVE_COMPLETE
+ * GUID_PNP_CUSTOM_NOTIFICATION
+ * GUID_PNP_POWER_NOTIFICATION
+ * GUID_DEVICE_* (see above)
+ *
+ * EventCategory
+ * Type of the event that happened.
+ *
+ * Result
+ * ?
+ *
+ * Flags
+ * ?
+ *
+ * TotalSize
+ * Size of the event block including the device IDs and other
+ * per category specific fields.
+ */
+
+/*
+ * NtGetPlugPlayEvent
+ *
+ * Returns one Plug & Play event from a global queue.
+ *
+ * Parameters
+ * Reserved1
+ * Reserved2
+ * Always set to zero.
+ *
+ * Buffer
+ * The buffer that will be filled with the event information on
+ * successful return from the function.
+ *
+ * BufferSize
+ * Size of the buffer pointed by the Buffer parameter. If the
+ * buffer size is not large enough to hold the whole event
+ * information, error STATUS_BUFFER_TOO_SMALL is returned and
+ * the buffer remains untouched.
+ *
+ * Return Values
+ * STATUS_PRIVILEGE_NOT_HELD
+ * STATUS_BUFFER_TOO_SMALL
+ * STATUS_SUCCESS
+ *
+ * Remarks
+ * This function isn't multi-thread safe!
+ *
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtGetPlugPlayEvent(IN ULONG Reserved1,
+ IN ULONG Reserved2,
+ OUT PPLUGPLAY_EVENT_BLOCK Buffer,
+ IN ULONG BufferSize)
+{
+ PPNP_EVENT_ENTRY Entry;
+ NTSTATUS Status;
+
+ DPRINT("NtGetPlugPlayEvent() called\n");
+
+ /* Function can only be called from user-mode */
+ if (KeGetPreviousMode() == KernelMode)
+ {
+ DPRINT1("NtGetPlugPlayEvent cannot be called from kernel mode!\n");
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Check for Tcb privilege */
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
+ UserMode))
+ {
+ DPRINT1("NtGetPlugPlayEvent: Caller does not hold the SeTcbPrivilege
privilege!\n");
+ return STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ /* Wait for a PnP event */
+ DPRINT("Waiting for pnp notification event\n");
+ Status = KeWaitForSingleObject(&IopPnpNotifyEvent,
+ UserRequest,
+ KernelMode,
+ FALSE,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("KeWaitForSingleObject() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Get entry from the tail of the queue */
+ Entry = CONTAINING_RECORD(IopPnpEventQueueHead.Blink,
+ PNP_EVENT_ENTRY,
+ ListEntry);
+
+ /* Check the buffer size */
+ if (BufferSize < Entry->Event.TotalSize)
+ {
+ DPRINT1("Buffer is too small for the pnp-event\n");
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Copy event data to the user buffer */
+ memcpy(Buffer,
+ &Entry->Event,
+ Entry->Event.TotalSize);
+
+ DPRINT("NtGetPlugPlayEvent() done\n");
+
+ return STATUS_SUCCESS;
+}
/*
* NtPlugPlayControl
@@ -763,7 +762,8 @@
*
* @unimplemented
*/
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass,
IN OUT PVOID Buffer,
IN ULONG BufferLength)
@@ -844,5 +844,3 @@
return STATUS_NOT_IMPLEMENTED;
}
-
-/* EOF */
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/pnpdma.c
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/pnpdma.c
* PURPOSE: PnP manager DMA routines
- *
* PROGRAMMERS: Filip Navara (xnavara(a)volny.cz)
*/
@@ -14,69 +13,74 @@
#include <internal/debug.h>
#include <wdmguid.h>
-/* FUNCTIONS *****************************************************************/
+/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
-PDMA_ADAPTER STDCALL
-IoGetDmaAdapter(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PDEVICE_DESCRIPTION DeviceDescription,
- IN OUT PULONG NumberOfMapRegisters)
+PDMA_ADAPTER
+NTAPI
+IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PDEVICE_DESCRIPTION DeviceDescription,
+ IN OUT PULONG NumberOfMapRegisters)
{
- NTSTATUS Status;
- ULONG ResultLength;
- BUS_INTERFACE_STANDARD BusInterface;
- IO_STATUS_BLOCK IoStatusBlock;
- IO_STACK_LOCATION Stack;
- DEVICE_DESCRIPTION PrivateDeviceDescription;
- PDMA_ADAPTER Adapter = NULL;
+ NTSTATUS Status;
+ ULONG ResultLength;
+ BUS_INTERFACE_STANDARD BusInterface;
+ IO_STATUS_BLOCK IoStatusBlock;
+ IO_STACK_LOCATION Stack;
+ DEVICE_DESCRIPTION PrivateDeviceDescription;
+ PDMA_ADAPTER Adapter = NULL;
- DPRINT("IoGetDmaAdapter called\n");
+ DPRINT("IoGetDmaAdapter called\n");
- /*
- * Try to create DMA adapter through bus driver.
- */
- if (PhysicalDeviceObject != NULL)
- {
- if (DeviceDescription->InterfaceType == PNPBus ||
- DeviceDescription->InterfaceType == InterfaceTypeUndefined)
+ /* Try to create DMA adapter through bus driver */
+ if (PhysicalDeviceObject)
{
- RtlCopyMemory(&PrivateDeviceDescription, DeviceDescription,
- sizeof(DEVICE_DESCRIPTION));
- Status = IoGetDeviceProperty(PhysicalDeviceObject,
- DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE),
- &PrivateDeviceDescription.InterfaceType, &ResultLength);
- if (!NT_SUCCESS(Status))
- PrivateDeviceDescription.InterfaceType = Internal;
- DeviceDescription = &PrivateDeviceDescription;
+ if (DeviceDescription->InterfaceType == PNPBus ||
+ DeviceDescription->InterfaceType == InterfaceTypeUndefined)
+ {
+ RtlCopyMemory(&PrivateDeviceDescription,
+ DeviceDescription,
+ sizeof(DEVICE_DESCRIPTION));
+
+ Status = IoGetDeviceProperty(PhysicalDeviceObject,
+ DevicePropertyLegacyBusType,
+ sizeof(INTERFACE_TYPE),
+ &PrivateDeviceDescription.InterfaceType,
+ &ResultLength);
+
+ if (!NT_SUCCESS(Status))
+ PrivateDeviceDescription.InterfaceType = Internal;
+
+ DeviceDescription = &PrivateDeviceDescription;
+ }
+
+ Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
+ Stack.Parameters.QueryInterface.Version = 1;
+ Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
+ Stack.Parameters.QueryInterface.InterfaceType =
+ &GUID_BUS_INTERFACE_STANDARD;
+
+ Status = IopInitiatePnpIrp(PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_INTERFACE,
+ &Stack);
+
+ if (NT_SUCCESS(Status))
+ {
+ Adapter = BusInterface.GetDmaAdapter(BusInterface.Context,
+ DeviceDescription,
+ NumberOfMapRegisters);
+
+ BusInterface.InterfaceDereference(BusInterface.Context);
+ if (Adapter) return Adapter;
+ }
}
- Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
- Stack.Parameters.QueryInterface.Version = 1;
- Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
- Stack.Parameters.QueryInterface.InterfaceType =
- &GUID_BUS_INTERFACE_STANDARD;
- Status = IopInitiatePnpIrp(PhysicalDeviceObject, &IoStatusBlock,
- IRP_MN_QUERY_INTERFACE, &Stack);
- if (NT_SUCCESS(Status))
- {
- Adapter = BusInterface.GetDmaAdapter(BusInterface.Context,
- DeviceDescription, NumberOfMapRegisters);
- BusInterface.InterfaceDereference(BusInterface.Context);
- if (Adapter != NULL)
- return Adapter;
- }
- }
-
- /*
- * Fallback to HAL.
- */
-
- return HalGetDmaAdapter(PhysicalDeviceObject, DeviceDescription,
- NumberOfMapRegisters);
+ /* Fall back to HAL */
+ return HalGetDmaAdapter(PhysicalDeviceObject,
+ DeviceDescription,
+ NumberOfMapRegisters);
}
-
-/* EOF */
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,17 +1,15 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/pnpmgr.c
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/pnpmgr.c
* PURPOSE: Initializes the PnP manager
- *
* PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
- * Hervé Poussineau (hpoussin(a)reactos.org)
+ * Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
-
#define NDEBUG
#include <internal/debug.h>
@@ -224,7 +222,7 @@
}
NTSTATUS
-STDCALL
+NTAPI
IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
PDEVICE_CAPABILITIES DeviceCaps)
{
@@ -265,466 +263,6 @@
ExFreePool(Data);
}
-/*
- * @implemented
- */
-VOID
-NTAPI
-IoInvalidateDeviceRelations(
- IN PDEVICE_OBJECT DeviceObject,
- IN DEVICE_RELATION_TYPE Type)
-{
- PIO_WORKITEM WorkItem;
- PINVALIDATE_DEVICE_RELATION_DATA Data;
-
- Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
- if (!Data)
- return;
- WorkItem = IoAllocateWorkItem(DeviceObject);
- if (!WorkItem)
- {
- ExFreePool(Data);
- return;
- }
-
- ObReferenceObject(DeviceObject);
- Data->DeviceObject = DeviceObject;
- Data->Type = Type;
- Data->WorkItem = WorkItem;
-
- IoQueueWorkItem(
- WorkItem,
- IopAsynchronousInvalidateDeviceRelations,
- DelayedWorkQueue,
- Data);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
- IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
- IN ULONG BufferLength,
- OUT PVOID PropertyBuffer,
- OUT PULONG ResultLength)
-{
- PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
- DEVICE_CAPABILITIES DeviceCaps;
- ULONG Length;
- PVOID Data = NULL;
- PWSTR Ptr;
- NTSTATUS Status;
-
- DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
-
- *ResultLength = 0;
-
- if (DeviceNode == NULL)
- return STATUS_INVALID_DEVICE_REQUEST;
-
- switch (DeviceProperty)
- {
- case DevicePropertyBusNumber:
- Length = sizeof(ULONG);
- Data = &DeviceNode->ChildBusNumber;
- break;
-
- /* Complete, untested */
- case DevicePropertyBusTypeGuid:
- /* Sanity check */
- if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
- (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
- {
- /* Return the GUID */
- *ResultLength = sizeof(GUID);
-
- /* Check if the buffer given was large enough */
- if (BufferLength < *ResultLength)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- /* Copy the GUID */
- RtlCopyMemory(PropertyBuffer,
- &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
- sizeof(GUID));
- return STATUS_SUCCESS;
- }
- else
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
- break;
-
- case DevicePropertyLegacyBusType:
- Length = sizeof(INTERFACE_TYPE);
- Data = &DeviceNode->ChildInterfaceType;
- break;
-
- case DevicePropertyAddress:
- /* Query the device caps */
- Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
- if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
- {
- /* Return length */
- *ResultLength = sizeof(ULONG);
-
- /* Check if the buffer given was large enough */
- if (BufferLength < *ResultLength)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- /* Return address */
- *(PULONG)PropertyBuffer = DeviceCaps.Address;
- return STATUS_SUCCESS;
- }
- else
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
- break;
-
-// case DevicePropertyUINumber:
-// if (DeviceNode->CapabilityFlags == NULL)
-// return STATUS_INVALID_DEVICE_REQUEST;
-// Length = sizeof(ULONG);
-// Data = &DeviceNode->CapabilityFlags->UINumber;
-// break;
-
- case DevicePropertyClassName:
- case DevicePropertyClassGuid:
- case DevicePropertyDriverKeyName:
- case DevicePropertyManufacturer:
- case DevicePropertyFriendlyName:
- case DevicePropertyHardwareID:
- case DevicePropertyCompatibleIDs:
- case DevicePropertyDeviceDescription:
- case DevicePropertyLocationInformation:
- case DevicePropertyUINumber:
- {
- LPCWSTR RegistryPropertyName;
- UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
- UNICODE_STRING ValueName;
- KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
- ULONG ValueInformationLength;
- HANDLE KeyHandle, EnumRootHandle;
- NTSTATUS Status;
-
- switch (DeviceProperty)
- {
- case DevicePropertyClassName:
- RegistryPropertyName = L"Class"; break;
- case DevicePropertyClassGuid:
- RegistryPropertyName = L"ClassGuid"; break;
- case DevicePropertyDriverKeyName:
- RegistryPropertyName = L"Driver"; break;
- case DevicePropertyManufacturer:
- RegistryPropertyName = L"Mfg"; break;
- case DevicePropertyFriendlyName:
- RegistryPropertyName = L"FriendlyName"; break;
- case DevicePropertyHardwareID:
- RegistryPropertyName = L"HardwareID"; break;
- case DevicePropertyCompatibleIDs:
- RegistryPropertyName = L"CompatibleIDs"; break;
- case DevicePropertyDeviceDescription:
- RegistryPropertyName = L"DeviceDesc"; break;
- case DevicePropertyLocationInformation:
- RegistryPropertyName = L"LocationInformation"; break;
- case DevicePropertyUINumber:
- RegistryPropertyName = L"UINumber"; break;
- default:
- /* Should not happen */
- ASSERT(FALSE);
- return STATUS_UNSUCCESSFUL;
- }
-
- DPRINT("Registry property %S\n", RegistryPropertyName);
-
- /* Open Enum key */
- Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL,
- &EnumRoot, KEY_READ);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
- return Status;
- }
-
- /* Open instance key */
- Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle,
- &DeviceNode->InstancePath, KEY_READ);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error opening InstancePath, Status=0x%08x\n",
Status);
- ZwClose(EnumRootHandle);
- return Status;
- }
-
- /* Allocate buffer to read as much data as required by the caller */
- ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
- Data[0]) + BufferLength;
- ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
- if (!ValueInformation)
- {
- ZwClose(KeyHandle);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Read the value */
- RtlInitUnicodeString(&ValueName, RegistryPropertyName);
- Status = ZwQueryValueKey(KeyHandle, &ValueName,
- KeyValuePartialInformation, ValueInformation,
- ValueInformationLength,
- &ValueInformationLength);
- ZwClose(KeyHandle);
-
- /* Return data */
- *ResultLength = ValueInformation->DataLength;
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status,
*ResultLength);
- ExFreePool(ValueInformation);
- if (Status == STATUS_BUFFER_OVERFLOW)
- return STATUS_BUFFER_TOO_SMALL;
- else
- return Status;
- }
-
- /* FIXME: Verify the value (NULL-terminated, correct format). */
- RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
- ValueInformation->DataLength);
- ExFreePool(ValueInformation);
-
- return STATUS_SUCCESS;
- }
-
- case DevicePropertyBootConfiguration:
- Length = 0;
- if (DeviceNode->BootResources->Count != 0)
- {
- Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
- }
- Data = &DeviceNode->BootResources;
- break;
-
- /* FIXME: use a translated boot configuration instead */
- case DevicePropertyBootConfigurationTranslated:
- Length = 0;
- if (DeviceNode->BootResources->Count != 0)
- {
- Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
- }
- Data = &DeviceNode->BootResources;
- break;
-
- case DevicePropertyEnumeratorName:
- /* A buffer overflow can't happen here, since InstancePath
- * always contains the enumerator name followed by \\ */
- Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
- ASSERT(Ptr);
- Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
- Data = DeviceNode->InstancePath.Buffer;
- break;
-
- case DevicePropertyPhysicalDeviceObjectName:
- /* InstancePath buffer is NULL terminated, so we can do this */
- Length = DeviceNode->InstancePath.MaximumLength;
- Data = DeviceNode->InstancePath.Buffer;
- break;
-
- default:
- return STATUS_INVALID_PARAMETER_2;
- }
-
- /* Prepare returned values */
- *ResultLength = Length;
- if (BufferLength < Length)
- return STATUS_BUFFER_TOO_SMALL;
- RtlCopyMemory(PropertyBuffer, Data, Length);
-
- /* NULL terminate the string (if required) */
- if (DeviceProperty == DevicePropertyEnumeratorName)
- ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- return STATUS_SUCCESS;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
- UNIMPLEMENTED;
-}
-
-/**
- * @name IoOpenDeviceRegistryKey
- *
- * Open a registry key unique for a specified driver or device instance.
- *
- * @param DeviceObject Device to get the registry key for.
- * @param DevInstKeyType Type of the key to return.
- * @param DesiredAccess Access mask (eg. KEY_READ | KEY_WRITE).
- * @param DevInstRegKey Handle to the opened registry key on
- * successful return.
- *
- * @return Status.
- *
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DevInstKeyType,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE DevInstRegKey)
-{
- static WCHAR RootKeyName[] =
- L"\\Registry\\Machine\\System\\CurrentControlSet\\";
- static WCHAR ProfileKeyName[] =
- L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
- static WCHAR ClassKeyName[] = L"Control\\Class\\";
- static WCHAR EnumKeyName[] = L"Enum\\";
- static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
- ULONG KeyNameLength;
- LPWSTR KeyNameBuffer;
- UNICODE_STRING KeyName;
- ULONG DriverKeyLength;
- OBJECT_ATTRIBUTES ObjectAttributes;
- PDEVICE_NODE DeviceNode = NULL;
- NTSTATUS Status;
-
- DPRINT("IoOpenDeviceRegistryKey() called\n");
-
- if ((DevInstKeyType & (PLUGPLAY_REGKEY_DEVICE | PLUGPLAY_REGKEY_DRIVER)) == 0)
- {
- DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
- return STATUS_INVALID_PARAMETER;
- }
-
- /*
- * Calculate the length of the base key name. This is the full
- * name for driver key or the name excluding "Device Parameters"
- * subkey for device key.
- */
-
- KeyNameLength = sizeof(RootKeyName);
- if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
- KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
- if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
- {
- KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
- Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
- 0, NULL, &DriverKeyLength);
- if (Status != STATUS_BUFFER_TOO_SMALL)
- return Status;
- KeyNameLength += DriverKeyLength;
- }
- else
- {
- DeviceNode = IopGetDeviceNode(DeviceObject);
- KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
- DeviceNode->InstancePath.Length;
- }
-
- /*
- * Now allocate the buffer for the key name...
- */
-
- KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
- if (KeyNameBuffer == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- KeyName.Length = 0;
- KeyName.MaximumLength = (USHORT)KeyNameLength;
- KeyName.Buffer = KeyNameBuffer;
-
- /*
- * ...and build the key name.
- */
-
- KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
- RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
-
- if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
- RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
-
- if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
- {
- RtlAppendUnicodeToString(&KeyName, ClassKeyName);
- Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
- DriverKeyLength, KeyNameBuffer +
- (KeyName.Length / sizeof(WCHAR)),
- &DriverKeyLength);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n",
Status);
- ExFreePool(KeyNameBuffer);
- return Status;
- }
- KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
- }
- else
- {
- RtlAppendUnicodeToString(&KeyName, EnumKeyName);
- Status = RtlAppendUnicodeStringToString(&KeyName,
&DeviceNode->InstancePath);
- if (DeviceNode->InstancePath.Length == 0)
- {
- ExFreePool(KeyNameBuffer);
- return Status;
- }
- }
-
- /*
- * Open the base key.
- */
- Status = IopOpenRegistryKeyEx(DevInstRegKey, NULL, &KeyName, DesiredAccess);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting...
(Status 0x%08lx)\n", &KeyName, Status);
- ExFreePool(KeyNameBuffer);
- return Status;
- }
- ExFreePool(KeyNameBuffer);
-
- /*
- * For driver key we're done now.
- */
-
- if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
- return Status;
-
- /*
- * Let's go further. For device key we must open "Device Parameters"
- * subkey and create it if it doesn't exist yet.
- */
-
- RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
- InitializeObjectAttributes(&ObjectAttributes, &KeyName,
- OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
- Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
- 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
- ZwClose(ObjectAttributes.RootDirectory);
-
- return Status;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
- UNIMPLEMENTED;
-}
-
-
NTSTATUS
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
{
@@ -743,7 +281,7 @@
}
USHORT
-STDCALL
+NTAPI
IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
{
USHORT i = 0, FoundIndex = 0xFFFF;
@@ -2137,158 +1675,6 @@
}
/*
- * @implemented
- */
-VOID
-NTAPI
-IoSynchronousInvalidateDeviceRelations(
- IN PDEVICE_OBJECT DeviceObject,
- IN DEVICE_RELATION_TYPE Type)
-{
- PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
- DEVICETREE_TRAVERSE_CONTEXT Context;
- PDEVICE_RELATIONS DeviceRelations;
- IO_STATUS_BLOCK IoStatusBlock;
- PDEVICE_NODE ChildDeviceNode;
- IO_STACK_LOCATION Stack;
- BOOLEAN BootDrivers;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
- HANDLE Handle;
- NTSTATUS Status;
- ULONG i;
-
- DPRINT("DeviceObject 0x%p\n", DeviceObject);
-
- DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
-
- Stack.Parameters.QueryDeviceRelations.Type = Type;
-
- Status = IopInitiatePnpIrp(
- DeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_DEVICE_RELATIONS,
- &Stack);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
- return;
- }
-
- DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
-
- if (!DeviceRelations || DeviceRelations->Count <= 0)
- {
- DPRINT("No PDOs\n");
- if (DeviceRelations)
- {
- ExFreePool(DeviceRelations);
- }
- return;
- }
-
- DPRINT("Got %d PDOs\n", DeviceRelations->Count);
-
- /*
- * Create device nodes for all discovered devices
- */
- for (i = 0; i < DeviceRelations->Count; i++)
- {
- if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL)
- {
- ObDereferenceObject(DeviceRelations->Objects[i]);
- continue;
- }
- Status = IopCreateDeviceNode(
- DeviceNode,
- DeviceRelations->Objects[i],
- NULL,
- &ChildDeviceNode);
- DeviceNode->Flags |= DNF_ENUMERATED;
- if (!NT_SUCCESS(Status))
- {
- DPRINT("No resources\n");
- for (i = 0; i < DeviceRelations->Count; i++)
- ObDereferenceObject(DeviceRelations->Objects[i]);
- ExFreePool(DeviceRelations);
- return;
- }
- }
- ExFreePool(DeviceRelations);
-
- /*
- * Retrieve information about all discovered children from the bus driver
- */
- IopInitDeviceTreeTraverseContext(
- &Context,
- DeviceNode,
- IopActionInterrogateDeviceStack,
- DeviceNode);
-
- Status = IopTraverseDeviceTree(&Context);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n",
Status);
- return;
- }
-
- /*
- * Retrieve configuration from the registry for discovered children
- */
- IopInitDeviceTreeTraverseContext(
- &Context,
- DeviceNode,
- IopActionConfigureChildServices,
- DeviceNode);
-
- Status = IopTraverseDeviceTree(&Context);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n",
Status);
- return;
- }
-
- /*
- * Get the state of the system boot. If the \\SystemRoot link isn't
- * created yet, we will assume that it's possible to load only boot
- * drivers.
- */
- InitializeObjectAttributes(
- &ObjectAttributes,
- &LinkName,
- 0,
- NULL,
- NULL);
- Status = ZwOpenFile(
- &Handle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- 0);
- if (NT_SUCCESS(Status))
- {
- BootDrivers = FALSE;
- ZwClose(Handle);
- }
- else
- BootDrivers = TRUE;
-
- /*
- * Initialize services for discovered children. Only boot drivers will
- * be loaded from boot driver!
- */
- Status = IopInitializePnpServices(DeviceNode, BootDrivers);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n",
Status);
- return;
- }
-
- DPRINT("IopInvalidateDeviceRelations() finished\n");
-}
-
-/*
* IopActionConfigureChildServices
*
* Retrieve configuration for all (direct) child nodes of a parent node.
@@ -3476,4 +2862,615 @@
}
}
-/* EOF */
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
+ IN ULONG BufferLength,
+ OUT PVOID PropertyBuffer,
+ OUT PULONG ResultLength)
+{
+ PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+ DEVICE_CAPABILITIES DeviceCaps;
+ ULONG Length;
+ PVOID Data = NULL;
+ PWSTR Ptr;
+ NTSTATUS Status;
+
+ DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
+
+ *ResultLength = 0;
+
+ if (DeviceNode == NULL)
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ switch (DeviceProperty)
+ {
+ case DevicePropertyBusNumber:
+ Length = sizeof(ULONG);
+ Data = &DeviceNode->ChildBusNumber;
+ break;
+
+ /* Complete, untested */
+ case DevicePropertyBusTypeGuid:
+ /* Sanity check */
+ if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
+ (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
+ {
+ /* Return the GUID */
+ *ResultLength = sizeof(GUID);
+
+ /* Check if the buffer given was large enough */
+ if (BufferLength < *ResultLength)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Copy the GUID */
+ RtlCopyMemory(PropertyBuffer,
+ &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
+ sizeof(GUID));
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ break;
+
+ case DevicePropertyLegacyBusType:
+ Length = sizeof(INTERFACE_TYPE);
+ Data = &DeviceNode->ChildInterfaceType;
+ break;
+
+ case DevicePropertyAddress:
+ /* Query the device caps */
+ Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
+ if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
+ {
+ /* Return length */
+ *ResultLength = sizeof(ULONG);
+
+ /* Check if the buffer given was large enough */
+ if (BufferLength < *ResultLength)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Return address */
+ *(PULONG)PropertyBuffer = DeviceCaps.Address;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ break;
+
+// case DevicePropertyUINumber:
+// if (DeviceNode->CapabilityFlags == NULL)
+// return STATUS_INVALID_DEVICE_REQUEST;
+// Length = sizeof(ULONG);
+// Data = &DeviceNode->CapabilityFlags->UINumber;
+// break;
+
+ case DevicePropertyClassName:
+ case DevicePropertyClassGuid:
+ case DevicePropertyDriverKeyName:
+ case DevicePropertyManufacturer:
+ case DevicePropertyFriendlyName:
+ case DevicePropertyHardwareID:
+ case DevicePropertyCompatibleIDs:
+ case DevicePropertyDeviceDescription:
+ case DevicePropertyLocationInformation:
+ case DevicePropertyUINumber:
+ {
+ LPCWSTR RegistryPropertyName;
+ UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
+ UNICODE_STRING ValueName;
+ KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
+ ULONG ValueInformationLength;
+ HANDLE KeyHandle, EnumRootHandle;
+ NTSTATUS Status;
+
+ switch (DeviceProperty)
+ {
+ case DevicePropertyClassName:
+ RegistryPropertyName = L"Class"; break;
+ case DevicePropertyClassGuid:
+ RegistryPropertyName = L"ClassGuid"; break;
+ case DevicePropertyDriverKeyName:
+ RegistryPropertyName = L"Driver"; break;
+ case DevicePropertyManufacturer:
+ RegistryPropertyName = L"Mfg"; break;
+ case DevicePropertyFriendlyName:
+ RegistryPropertyName = L"FriendlyName"; break;
+ case DevicePropertyHardwareID:
+ RegistryPropertyName = L"HardwareID"; break;
+ case DevicePropertyCompatibleIDs:
+ RegistryPropertyName = L"CompatibleIDs"; break;
+ case DevicePropertyDeviceDescription:
+ RegistryPropertyName = L"DeviceDesc"; break;
+ case DevicePropertyLocationInformation:
+ RegistryPropertyName = L"LocationInformation"; break;
+ case DevicePropertyUINumber:
+ RegistryPropertyName = L"UINumber"; break;
+ default:
+ /* Should not happen */
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DPRINT("Registry property %S\n", RegistryPropertyName);
+
+ /* Open Enum key */
+ Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL,
+ &EnumRoot, KEY_READ);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
+ return Status;
+ }
+
+ /* Open instance key */
+ Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle,
+ &DeviceNode->InstancePath, KEY_READ);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error opening InstancePath, Status=0x%08x\n",
Status);
+ ZwClose(EnumRootHandle);
+ return Status;
+ }
+
+ /* Allocate buffer to read as much data as required by the caller */
+ ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
+ Data[0]) + BufferLength;
+ ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
+ if (!ValueInformation)
+ {
+ ZwClose(KeyHandle);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Read the value */
+ RtlInitUnicodeString(&ValueName, RegistryPropertyName);
+ Status = ZwQueryValueKey(KeyHandle, &ValueName,
+ KeyValuePartialInformation, ValueInformation,
+ ValueInformationLength,
+ &ValueInformationLength);
+ ZwClose(KeyHandle);
+
+ /* Return data */
+ *ResultLength = ValueInformation->DataLength;
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status,
*ResultLength);
+ ExFreePool(ValueInformation);
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ return STATUS_BUFFER_TOO_SMALL;
+ else
+ return Status;
+ }
+
+ /* FIXME: Verify the value (NULL-terminated, correct format). */
+ RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
+ ValueInformation->DataLength);
+ ExFreePool(ValueInformation);
+
+ return STATUS_SUCCESS;
+ }
+
+ case DevicePropertyBootConfiguration:
+ Length = 0;
+ if (DeviceNode->BootResources->Count != 0)
+ {
+ Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+ }
+ Data = &DeviceNode->BootResources;
+ break;
+
+ /* FIXME: use a translated boot configuration instead */
+ case DevicePropertyBootConfigurationTranslated:
+ Length = 0;
+ if (DeviceNode->BootResources->Count != 0)
+ {
+ Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+ }
+ Data = &DeviceNode->BootResources;
+ break;
+
+ case DevicePropertyEnumeratorName:
+ /* A buffer overflow can't happen here, since InstancePath
+ * always contains the enumerator name followed by \\ */
+ Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
+ ASSERT(Ptr);
+ Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
+ Data = DeviceNode->InstancePath.Buffer;
+ break;
+
+ case DevicePropertyPhysicalDeviceObjectName:
+ /* InstancePath buffer is NULL terminated, so we can do this */
+ Length = DeviceNode->InstancePath.MaximumLength;
+ Data = DeviceNode->InstancePath.Buffer;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Prepare returned values */
+ *ResultLength = Length;
+ if (BufferLength < Length)
+ return STATUS_BUFFER_TOO_SMALL;
+ RtlCopyMemory(PropertyBuffer, Data, Length);
+
+ /* NULL terminate the string (if required) */
+ if (DeviceProperty == DevicePropertyEnumeratorName)
+ ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ UNIMPLEMENTED;
+}
+
+/**
+ * @name IoOpenDeviceRegistryKey
+ *
+ * Open a registry key unique for a specified driver or device instance.
+ *
+ * @param DeviceObject Device to get the registry key for.
+ * @param DevInstKeyType Type of the key to return.
+ * @param DesiredAccess Access mask (eg. KEY_READ | KEY_WRITE).
+ * @param DevInstRegKey Handle to the opened registry key on
+ * successful return.
+ *
+ * @return Status.
+ *
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG DevInstKeyType,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE DevInstRegKey)
+{
+ static WCHAR RootKeyName[] =
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\";
+ static WCHAR ProfileKeyName[] =
+ L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
+ static WCHAR ClassKeyName[] = L"Control\\Class\\";
+ static WCHAR EnumKeyName[] = L"Enum\\";
+ static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
+ ULONG KeyNameLength;
+ LPWSTR KeyNameBuffer;
+ UNICODE_STRING KeyName;
+ ULONG DriverKeyLength;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PDEVICE_NODE DeviceNode = NULL;
+ NTSTATUS Status;
+
+ DPRINT("IoOpenDeviceRegistryKey() called\n");
+
+ if ((DevInstKeyType & (PLUGPLAY_REGKEY_DEVICE | PLUGPLAY_REGKEY_DRIVER)) == 0)
+ {
+ DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /*
+ * Calculate the length of the base key name. This is the full
+ * name for driver key or the name excluding "Device Parameters"
+ * subkey for device key.
+ */
+
+ KeyNameLength = sizeof(RootKeyName);
+ if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
+ KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
+ if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+ {
+ KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
+ Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+ 0, NULL, &DriverKeyLength);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ return Status;
+ KeyNameLength += DriverKeyLength;
+ }
+ else
+ {
+ DeviceNode = IopGetDeviceNode(DeviceObject);
+ KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
+ DeviceNode->InstancePath.Length;
+ }
+
+ /*
+ * Now allocate the buffer for the key name...
+ */
+
+ KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
+ if (KeyNameBuffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ KeyName.Length = 0;
+ KeyName.MaximumLength = (USHORT)KeyNameLength;
+ KeyName.Buffer = KeyNameBuffer;
+
+ /*
+ * ...and build the key name.
+ */
+
+ KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
+ RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
+
+ if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
+ RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
+
+ if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+ {
+ RtlAppendUnicodeToString(&KeyName, ClassKeyName);
+ Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+ DriverKeyLength, KeyNameBuffer +
+ (KeyName.Length / sizeof(WCHAR)),
+ &DriverKeyLength);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n",
Status);
+ ExFreePool(KeyNameBuffer);
+ return Status;
+ }
+ KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
+ }
+ else
+ {
+ RtlAppendUnicodeToString(&KeyName, EnumKeyName);
+ Status = RtlAppendUnicodeStringToString(&KeyName,
&DeviceNode->InstancePath);
+ if (DeviceNode->InstancePath.Length == 0)
+ {
+ ExFreePool(KeyNameBuffer);
+ return Status;
+ }
+ }
+
+ /*
+ * Open the base key.
+ */
+ Status = IopOpenRegistryKeyEx(DevInstRegKey, NULL, &KeyName, DesiredAccess);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting...
(Status 0x%08lx)\n", &KeyName, Status);
+ ExFreePool(KeyNameBuffer);
+ return Status;
+ }
+ ExFreePool(KeyNameBuffer);
+
+ /*
+ * For driver key we're done now.
+ */
+
+ if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+ return Status;
+
+ /*
+ * Let's go further. For device key we must open "Device Parameters"
+ * subkey and create it if it doesn't exist yet.
+ */
+
+ RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName,
+ OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
+ Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
+ 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
+ ZwClose(ObjectAttributes.RootDirectory);
+
+ return Status;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ UNIMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IoInvalidateDeviceRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_RELATION_TYPE Type)
+{
+ PIO_WORKITEM WorkItem;
+ PINVALIDATE_DEVICE_RELATION_DATA Data;
+
+ Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
+ if (!Data)
+ return;
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (!WorkItem)
+ {
+ ExFreePool(Data);
+ return;
+ }
+
+ ObReferenceObject(DeviceObject);
+ Data->DeviceObject = DeviceObject;
+ Data->Type = Type;
+ Data->WorkItem = WorkItem;
+
+ IoQueueWorkItem(
+ WorkItem,
+ IopAsynchronousInvalidateDeviceRelations,
+ DelayedWorkQueue,
+ Data);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IoSynchronousInvalidateDeviceRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_RELATION_TYPE Type)
+{
+ PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+ DEVICETREE_TRAVERSE_CONTEXT Context;
+ PDEVICE_RELATIONS DeviceRelations;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PDEVICE_NODE ChildDeviceNode;
+ IO_STACK_LOCATION Stack;
+ BOOLEAN BootDrivers;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
+ HANDLE Handle;
+ NTSTATUS Status;
+ ULONG i;
+
+ DPRINT("DeviceObject 0x%p\n", DeviceObject);
+
+ DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
+
+ Stack.Parameters.QueryDeviceRelations.Type = Type;
+
+ Status = IopInitiatePnpIrp(
+ DeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_DEVICE_RELATIONS,
+ &Stack);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
+ return;
+ }
+
+ DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
+
+ if (!DeviceRelations || DeviceRelations->Count <= 0)
+ {
+ DPRINT("No PDOs\n");
+ if (DeviceRelations)
+ {
+ ExFreePool(DeviceRelations);
+ }
+ return;
+ }
+
+ DPRINT("Got %d PDOs\n", DeviceRelations->Count);
+
+ /*
+ * Create device nodes for all discovered devices
+ */
+ for (i = 0; i < DeviceRelations->Count; i++)
+ {
+ if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL)
+ {
+ ObDereferenceObject(DeviceRelations->Objects[i]);
+ continue;
+ }
+ Status = IopCreateDeviceNode(
+ DeviceNode,
+ DeviceRelations->Objects[i],
+ NULL,
+ &ChildDeviceNode);
+ DeviceNode->Flags |= DNF_ENUMERATED;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("No resources\n");
+ for (i = 0; i < DeviceRelations->Count; i++)
+ ObDereferenceObject(DeviceRelations->Objects[i]);
+ ExFreePool(DeviceRelations);
+ return;
+ }
+ }
+ ExFreePool(DeviceRelations);
+
+ /*
+ * Retrieve information about all discovered children from the bus driver
+ */
+ IopInitDeviceTreeTraverseContext(
+ &Context,
+ DeviceNode,
+ IopActionInterrogateDeviceStack,
+ DeviceNode);
+
+ Status = IopTraverseDeviceTree(&Context);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n",
Status);
+ return;
+ }
+
+ /*
+ * Retrieve configuration from the registry for discovered children
+ */
+ IopInitDeviceTreeTraverseContext(
+ &Context,
+ DeviceNode,
+ IopActionConfigureChildServices,
+ DeviceNode);
+
+ Status = IopTraverseDeviceTree(&Context);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n",
Status);
+ return;
+ }
+
+ /*
+ * Get the state of the system boot. If the \\SystemRoot link isn't
+ * created yet, we will assume that it's possible to load only boot
+ * drivers.
+ */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &LinkName,
+ 0,
+ NULL,
+ NULL);
+ Status = ZwOpenFile(
+ &Handle,
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ 0,
+ 0);
+ if (NT_SUCCESS(Status))
+ {
+ BootDrivers = FALSE;
+ ZwClose(Handle);
+ }
+ else
+ BootDrivers = TRUE;
+
+ /*
+ * Initialize services for discovered children. Only boot drivers will
+ * be loaded from boot driver!
+ */
+ Status = IopInitializePnpServices(DeviceNode, BootDrivers);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n",
Status);
+ return;
+ }
+
+ DPRINT("IopInvalidateDeviceRelations() finished\n");
+}
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpnoti…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/pnpnotify.c
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/pnpnotify.c
* PURPOSE: Plug & Play notification functions
- *
* PROGRAMMERS: Filip Navara (xnavara(a)volny.cz)
* Hervé Poussineau (hpoussin(a)reactos.org)
*/
@@ -14,184 +13,22 @@
#define NDEBUG
#include <debug.h>
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, IopInitPnpNotificationImplementation)
-#endif
-
-
/* TYPES *******************************************************************/
typedef struct _PNP_NOTIFY_ENTRY
{
- LIST_ENTRY PnpNotifyList;
- IO_NOTIFICATION_EVENT_CATEGORY EventCategory;
- PVOID Context;
- UNICODE_STRING Guid;
- PFILE_OBJECT FileObject;
- PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc;
+ LIST_ENTRY PnpNotifyList;
+ IO_NOTIFICATION_EVENT_CATEGORY EventCategory;
+ PVOID Context;
+ UNICODE_STRING Guid;
+ PFILE_OBJECT FileObject;
+ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc;
} PNP_NOTIFY_ENTRY, *PPNP_NOTIFY_ENTRY;
KGUARDED_MUTEX PnpNotifyListLock;
LIST_ENTRY PnpNotifyListHead;
/* FUNCTIONS *****************************************************************/
-
-/*
- * @unimplemented
- */
-ULONG
-STDCALL
-IoPnPDeliverServicePowerNotification(
- ULONG VetoedPowerOperation OPTIONAL,
- ULONG PowerNotification,
- ULONG Unknown OPTIONAL,
- BOOLEAN Synchronous
- )
-{
- UNIMPLEMENTED;
- return 0;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoRegisterPlugPlayNotification(
- IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
- IN ULONG EventCategoryFlags,
- IN PVOID EventCategoryData OPTIONAL,
- IN PDRIVER_OBJECT DriverObject,
- IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,
- IN PVOID Context,
- OUT PVOID *NotificationEntry)
-{
- PPNP_NOTIFY_ENTRY Entry;
- PWSTR SymbolicLinkList;
- NTSTATUS Status;
-
- PAGED_CODE();
-
- DPRINT("IoRegisterPlugPlayNotification(EventCategory 0x%x, EventCategoryFlags
0x%lx, DriverObject %p) called.\n",
- EventCategory,
- EventCategoryFlags,
- DriverObject);
-
- ObReferenceObject(DriverObject);
-
- /* Try to allocate entry for notification before sending any notification */
- Entry = ExAllocatePoolWithTag(
- NonPagedPool,
- sizeof(PNP_NOTIFY_ENTRY),
- TAG_PNP_NOTIFY);
- if (!Entry)
- {
- DPRINT("ExAllocatePool() failed\n");
- ObDereferenceObject(DriverObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if (EventCategory == EventCategoryDeviceInterfaceChange
- && EventCategoryFlags &
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
- {
- DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
- UNICODE_STRING SymbolicLinkU;
- PWSTR SymbolicLink;
-
- Status = IoGetDeviceInterfaces(
- (LPGUID)EventCategoryData,
- NULL, /* PhysicalDeviceObject OPTIONAL */
- 0, /* Flags */
- &SymbolicLinkList);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoGetDeviceInterfaces() failed with status 0x%08lx\n", Status);
- ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
- ObDereferenceObject(DriverObject);
- return Status;
- }
- /* Enumerate SymbolicLinkList */
- NotificationInfos.Version = 1;
- NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
- RtlCopyMemory(&NotificationInfos.Event, &GUID_DEVICE_INTERFACE_ARRIVAL,
sizeof(GUID));
- RtlCopyMemory(&NotificationInfos.InterfaceClassGuid, EventCategoryData,
sizeof(GUID));
- NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
- for (SymbolicLink = SymbolicLinkList; *SymbolicLink; SymbolicLink +=
wcslen(SymbolicLink) + 1)
- {
- RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
- DPRINT("Calling callback routine for %S\n", SymbolicLink);
- (*CallbackRoutine)(&NotificationInfos, Context);
- }
- ExFreePool(SymbolicLinkList);
- }
-
- Entry->PnpNotificationProc = CallbackRoutine;
- Entry->EventCategory = EventCategory;
- Entry->Context = Context;
- switch (EventCategory)
- {
- case EventCategoryDeviceInterfaceChange:
- {
- Status = RtlStringFromGUID(EventCategoryData, &Entry->Guid);
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
- ObDereferenceObject(DriverObject);
- return Status;
- }
- break;
- }
- case EventCategoryHardwareProfileChange:
- {
- /* nothing to do */
- break;
- }
- case EventCategoryTargetDeviceChange:
- {
- Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
- break;
- }
- default:
- {
- DPRINT1("IoRegisterPlugPlayNotification(): unknown EventCategory 0x%x
UNIMPLEMENTED\n", EventCategory);
- break;
- }
- }
-
- KeAcquireGuardedMutex(&PnpNotifyListLock);
- InsertHeadList(&PnpNotifyListHead,
- &Entry->PnpNotifyList);
- KeReleaseGuardedMutex(&PnpNotifyListLock);
-
- DPRINT("IoRegisterPlugPlayNotification() returns NotificationEntry %p\n",
- Entry);
- *NotificationEntry = Entry;
- return STATUS_SUCCESS;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoUnregisterPlugPlayNotification(
- IN PVOID NotificationEntry)
-{
- PPNP_NOTIFY_ENTRY Entry;
-
- PAGED_CODE();
-
- Entry = (PPNP_NOTIFY_ENTRY)NotificationEntry;
- DPRINT("IoUnregisterPlugPlayNotification(NotificationEntry %p) called\n",
- Entry);
-
- KeAcquireGuardedMutex(&PnpNotifyListLock);
- RtlFreeUnicodeString(&Entry->Guid);
- RemoveEntryList(&Entry->PnpNotifyList);
- KeReleaseGuardedMutex(&PnpNotifyListLock);
-
- return STATUS_SUCCESS;
-}
VOID
IopNotifyPlugPlayNotification(
@@ -323,4 +160,166 @@
ExFreePoolWithTag(NotificationStructure, TAG_PNP_NOTIFY);
}
-/* EOF */
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @unimplemented
+ */
+ULONG
+NTAPI
+IoPnPDeliverServicePowerNotification(ULONG VetoedPowerOperation OPTIONAL,
+ ULONG PowerNotification,
+ ULONG Unknown OPTIONAL,
+ BOOLEAN Synchronous)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoRegisterPlugPlayNotification(IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
+ IN ULONG EventCategoryFlags,
+ IN PVOID EventCategoryData OPTIONAL,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,
+ IN PVOID Context,
+ OUT PVOID *NotificationEntry)
+{
+ PPNP_NOTIFY_ENTRY Entry;
+ PWSTR SymbolicLinkList;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ DPRINT("__FUNCTION__(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject
%p) called.\n",
+ EventCategory,
+ EventCategoryFlags,
+ DriverObject);
+
+ ObReferenceObject(DriverObject);
+
+ /* Try to allocate entry for notification before sending any notification */
+ Entry = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(PNP_NOTIFY_ENTRY),
+ TAG_PNP_NOTIFY);
+
+ if (!Entry)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ObDereferenceObject(DriverObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (EventCategory == EventCategoryDeviceInterfaceChange &&
+ EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
+ {
+ DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
+ UNICODE_STRING SymbolicLinkU;
+ PWSTR SymbolicLink;
+
+ Status = IoGetDeviceInterfaces((LPGUID)EventCategoryData,
+ NULL, /* PhysicalDeviceObject OPTIONAL */
+ 0, /* Flags */
+ &SymbolicLinkList);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoGetDeviceInterfaces() failed with status 0x%08lx\n",
+ Status);
+ ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
+ ObDereferenceObject(DriverObject);
+ return Status;
+ }
+
+ /* Enumerate SymbolicLinkList */
+ NotificationInfos.Version = 1;
+ NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
+ RtlCopyMemory(&NotificationInfos.Event,
+ &GUID_DEVICE_INTERFACE_ARRIVAL,
+ sizeof(GUID));
+ RtlCopyMemory(&NotificationInfos.InterfaceClassGuid,
+ EventCategoryData,
+ sizeof(GUID));
+ NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
+
+ for (SymbolicLink = SymbolicLinkList;
+ *SymbolicLink;
+ SymbolicLink += wcslen(SymbolicLink) + 1)
+ {
+ RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
+ DPRINT("Calling callback routine for %S\n", SymbolicLink);
+ (*CallbackRoutine)(&NotificationInfos, Context);
+ }
+
+ ExFreePool(SymbolicLinkList);
+ }
+
+ Entry->PnpNotificationProc = CallbackRoutine;
+ Entry->EventCategory = EventCategory;
+ Entry->Context = Context;
+ switch (EventCategory)
+ {
+ case EventCategoryDeviceInterfaceChange:
+ {
+ Status = RtlStringFromGUID(EventCategoryData, &Entry->Guid);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
+ ObDereferenceObject(DriverObject);
+ return Status;
+ }
+ break;
+ }
+ case EventCategoryHardwareProfileChange:
+ {
+ /* nothing to do */
+ break;
+ }
+ case EventCategoryTargetDeviceChange:
+ {
+ Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
+ break;
+ }
+ default:
+ {
+ DPRINT1("__FUNCTION__(): unknown EventCategory 0x%x
UNIMPLEMENTED\n",
+ EventCategory);
+ break;
+ }
+ }
+
+ KeAcquireGuardedMutex(&PnpNotifyListLock);
+ InsertHeadList(&PnpNotifyListHead,
+ &Entry->PnpNotifyList);
+ KeReleaseGuardedMutex(&PnpNotifyListLock);
+
+ DPRINT("IoRegisterPlugPlayNotification() returns NotificationEntry %p\n",
+ Entry);
+
+ *NotificationEntry = Entry;
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
+{
+ PPNP_NOTIFY_ENTRY Entry;
+ PAGED_CODE();
+
+ Entry = (PPNP_NOTIFY_ENTRY)NotificationEntry;
+ DPRINT("__FUNCTION__(NotificationEntry %p) called\n", Entry);
+
+ KeAcquireGuardedMutex(&PnpNotifyListLock);
+ RtlFreeUnicodeString(&Entry->Guid);
+ RemoveEntryList(&Entry->PnpNotifyList);
+ KeReleaseGuardedMutex(&PnpNotifyListLock);
+
+ return STATUS_SUCCESS;
+}
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnprepo…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/pnpreport.c
- * PURPOSE: Device Changes Reporting functions
- *
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/pnpreport.c
+ * PURPOSE: Device Changes Reporting Functions
* PROGRAMMERS: Filip Navara (xnavara(a)volny.cz)
*/
@@ -13,116 +12,127 @@
#define NDEBUG
#include <debug.h>
-/* FUNCTIONS *****************************************************************/
+/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
-STDCALL
-IoReportDetectedDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN INTERFACE_TYPE LegacyBusType,
- IN ULONG BusNumber,
- IN ULONG SlotNumber,
- IN PCM_RESOURCE_LIST ResourceList,
- IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL,
- IN BOOLEAN ResourceAssigned,
- IN OUT PDEVICE_OBJECT *DeviceObject)
+NTAPI
+IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
+ IN INTERFACE_TYPE LegacyBusType,
+ IN ULONG BusNumber,
+ IN ULONG SlotNumber,
+ IN PCM_RESOURCE_LIST ResourceList,
+ IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL,
+ IN BOOLEAN ResourceAssigned,
+ IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
{
- PDEVICE_NODE DeviceNode;
- PDEVICE_OBJECT Pdo;
- NTSTATUS Status = STATUS_SUCCESS;
+ PDEVICE_NODE DeviceNode;
+ PDEVICE_OBJECT Pdo;
+ NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
- DeviceObject, DeviceObject ? *DeviceObject : NULL);
+ DPRINT("__FUNCTION__ (DeviceObject %p, *DeviceObject %p)\n",
+ DeviceObject, DeviceObject ? *DeviceObject : NULL);
- /* if *DeviceObject is not NULL, we must use it as a PDO,
- * and don't create a new one.
- */
- if (DeviceObject && *DeviceObject)
- Pdo = *DeviceObject;
- else
- {
- UNICODE_STRING ServiceName;
- ServiceName.Buffer = DriverObject->DriverName.Buffer + sizeof(DRIVER_ROOT_NAME) /
sizeof(WCHAR) - 1;
- ServiceName.Length = ServiceName.MaximumLength = DriverObject->DriverName.Length -
sizeof(DRIVER_ROOT_NAME) + sizeof(WCHAR);
+ /* if *DeviceObject is not NULL, we must use it as a PDO, and don't create a new
one */
+ if (DeviceObject && *DeviceObject)
+ {
+ Pdo = *DeviceObject;
+ }
+ else
+ {
+ UNICODE_STRING ServiceName;
+ ServiceName.Buffer = DriverObject->DriverName.Buffer +
+ sizeof(DRIVER_ROOT_NAME) / sizeof(WCHAR) - 1;
+ ServiceName.Length = DriverObject->DriverName.Length -
+ sizeof(DRIVER_ROOT_NAME) + sizeof(WCHAR);
+ ServiceName.MaximumLength = ServiceName.Length;
- /* create a new PDO and return it in *DeviceObject */
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName,
&DeviceNode);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
- return Status;
- }
- Pdo = DeviceNode->PhysicalDeviceObject;
- if (DeviceObject)
- *DeviceObject = Pdo;
+ /* create a new PDO and return it in *DeviceObject */
+ Status = IopCreateDeviceNode(IopRootDeviceNode,
+ NULL,
+ &ServiceName,
+ &DeviceNode);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ Pdo = DeviceNode->PhysicalDeviceObject;
+ if (DeviceObject) *DeviceObject = Pdo;
}
- /* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
-
- return Status;
+ /* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
+ return Status;
}
/*
* @unimplemented
*/
NTSTATUS
-STDCALL
-IoReportResourceForDetection(
- IN PDRIVER_OBJECT DriverObject,
- IN PCM_RESOURCE_LIST DriverList OPTIONAL,
- IN ULONG DriverListSize OPTIONAL,
- IN PDEVICE_OBJECT DeviceObject OPTIONAL,
- IN PCM_RESOURCE_LIST DeviceList OPTIONAL,
- IN ULONG DeviceListSize OPTIONAL,
- OUT PBOOLEAN ConflictDetected)
+NTAPI
+IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject,
+ IN PCM_RESOURCE_LIST DriverList OPTIONAL,
+ IN ULONG DriverListSize OPTIONAL,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ IN PCM_RESOURCE_LIST DeviceList OPTIONAL,
+ IN ULONG DeviceListSize OPTIONAL,
+ OUT PBOOLEAN ConflictDetected)
{
- static int warned = 0;
- if (!warned)
- {
- DPRINT1("IoReportResourceForDetection partly implemented\n");
- warned = 1;
- }
+ static int warned = 0;
+ if (!warned)
+ {
+ DPRINT1("IoReportResourceForDetection partly implemented\n");
+ warned = 1;
+ }
- *ConflictDetected = FALSE;
+ *ConflictDetected = FALSE;
- if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)
- {
- /* We hope legacy devices will be enumerated by ACPI */
- *ConflictDetected = TRUE;
- return STATUS_CONFLICTING_ADDRESSES;
- }
- return STATUS_SUCCESS;
+ if (PopSystemPowerDeviceNode && DriverListSize > 0)
+ {
+ /* We hope legacy devices will be enumerated by ACPI */
+ *ConflictDetected = TRUE;
+ return STATUS_CONFLICTING_ADDRESSES;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+IopSetEvent(IN PVOID Context)
+{
+ PKEVENT Event = Context;
+
+ /* Set the event */
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
/*
* @unimplemented
*/
NTSTATUS
-STDCALL
-IoReportTargetDeviceChange(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PVOID NotificationStructure)
+NTAPI
+IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PVOID NotificationStructure)
{
- DPRINT1("IoReportTargetDeviceChange called (UNIMPLEMENTED)\n");
- return STATUS_NOT_IMPLEMENTED;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
-STDCALL
-IoReportTargetDeviceChangeAsynchronous(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PVOID NotificationStructure,
- IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
- IN PVOID Context OPTIONAL)
+NTAPI
+IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PVOID NotificationStructure,
+ IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback
OPTIONAL,
+ IN PVOID Context OPTIONAL)
{
- DPRINT1("IoReportTargetDeviceChangeAsynchronous called (UNIMPLEMENTED)\n");
- return STATUS_NOT_IMPLEMENTED;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-
-/* EOF */
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/pnproot.c
+ * PROJECT: ReactOS Kernel
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/pnpmgr/pnproot.c
* PURPOSE: PnP manager root device
- *
* PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
* Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org)
*/
@@ -1135,5 +1134,3 @@
return STATUS_SUCCESS;
}
-
-/* EOF */