mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Cleanup and reformat parts of pnpmgr (no code change)
svn path=/trunk/; revision=35427
This commit is contained in:
parent
5f26c6070c
commit
e3f8231305
6 changed files with 1074 additions and 1069 deletions
|
@ -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@t-online.de>
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
@ -114,127 +112,6 @@ IopRemovePlugPlayEvent(VOID)
|
|||
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 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
|
|||
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 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
|
|||
*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass,
|
||||
IN OUT PVOID Buffer,
|
||||
IN ULONG BufferLength)
|
||||
|
@ -844,5 +844,3 @@ NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass,
|
|||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -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@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 */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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@volny.cz)
|
||||
* Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
@ -14,21 +13,16 @@
|
|||
#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;
|
||||
|
@ -36,163 +30,6 @@ 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(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -323,4 +160,166 @@ IopNotifyPlugPlayNotification(
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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@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);
|
||||
|
||||
/* create a new PDO and return it in *DeviceObject */
|
||||
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* if *DeviceObject is not NULL, we must use it as a PDO, and don't create a new one */
|
||||
if (DeviceObject && *DeviceObject)
|
||||
{
|
||||
DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
Pdo = *DeviceObject;
|
||||
}
|
||||
Pdo = DeviceNode->PhysicalDeviceObject;
|
||||
if (DeviceObject)
|
||||
*DeviceObject = Pdo;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -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@users.sourceforge.net)
|
||||
* Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
@ -1135,5 +1134,3 @@ PnpRootDriverEntry(
|
|||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue