Author: sir_richard
Date: Mon Apr 12 21:49:32 2010
New Revision: 46852
URL:
http://svn.reactos.org/svn/reactos?rev=46852&view=rev
Log:
[NTOS]: Try moving towards new ABI. Lots of debug spam will be generated by various device
node flags in incorrect states, and hacks that had to be made to maintain current
functionality. Also document things being done at the wrong place. One small step...
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
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 Apr 12 21:49:32 2010
@@ -136,6 +136,114 @@
IopDeviceNodeSetFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
+{
+ IO_STACK_LOCATION Stack;
+ PDEVICE_NODE DeviceNode;
+ NTSTATUS Status;
+ PVOID Dummy;
+
+ /* Get the device node */
+ DeviceNode = IopGetDeviceNode(DeviceObject);
+
+ /* Build the I/O stack locaiton */
+ RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_START_DEVICE;
+
+ /* Check if we didn't already report the resources */
+ // if (!DeviceNode->Flags & DNF_RESOURCE_REPORTED)
+ {
+ /* Report them */
+ if (DeviceNode->Flags & DNF_RESOURCE_REPORTED)
+ {
+ DPRINT1("Warning: Setting resource pointers even though
DNF_RESOURCE_REPORTED is set\n");
+ }
+ Stack.Parameters.StartDevice.AllocatedResources =
+ DeviceNode->ResourceList;
+ Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
+ DeviceNode->ResourceListTranslated;
+ }
+
+ /* I don't think we set this flag yet */
+ ASSERT(!(DeviceNode->Flags & DNF_STOPPED));
+
+ /* Do the call */
+ Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+ if (!NT_SUCCESS(Status))
+ {
+ /* FIXME: TODO */
+ DPRINT1("Warning: PnP Start failed\n");
+ //ASSERT(FALSE);
+ return;
+ }
+
+ /* Otherwise, mark us as started */
+ DeviceNode->Flags |= DNF_STARTED;
+
+ /* We now need enumeration */
+ DeviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY;
+}
+
+NTSTATUS
+NTAPI
+IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
+{
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Sanity check */
+ // ASSERT((DeviceNode->Flags & DNF_ADDED));
+ if (!(DeviceNode->Flags & DNF_ADDED)) DPRINT1("Warning: Starting a device
node without DNF_ADDED\n");
+ ASSERT((DeviceNode->Flags & (DNF_RESOURCE_ASSIGNED |
+ DNF_RESOURCE_REPORTED |
+ DNF_NO_RESOURCE_REQUIRED |
+ DNF_NO_RESOURCE_REQUIRED)));
+ ASSERT((!(DeviceNode->Flags & (DNF_HAS_PROBLEM |
+ DNF_STARTED |
+ DNF_START_REQUEST_PENDING))));
+
+ /* Get the device object */
+ DeviceObject = DeviceNode->PhysicalDeviceObject;
+
+ /* Check if we're not started yet */
+ //if (!DeviceNode->Flags & DNF_STARTED)
+ {
+ /* Start us */
+ IopStartDevice2(DeviceObject);
+ }
+
+ /* Do we need to query IDs? This happens in the case of manual reporting */
+ //if (DeviceNode->Flags & DNF_NEED_QUERY_IDS)
+ //{
+ // DPRINT1("Warning: Device node has DNF_NEED_QUERY_IDS\n");
+ /* And that case shouldn't happen yet */
+ // ASSERT(FALSE);
+ //}
+
+ /* Make sure we're started, and check if we need enumeration */
+ if ((DeviceNode->Flags & DNF_STARTED) &&
+ (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY))
+ {
+ /* Enumerate us */
+ //Status = IopEnumerateDevice(DeviceObject);
+ IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
+ IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Nothing to do */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Return */
+ return Status;
}
NTSTATUS
@@ -195,47 +303,16 @@
if (!NT_SUCCESS(Status))
goto ByeBye;
- DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
- Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
- Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
DeviceNode->ResourceListTranslated;
-
- /*
- * Windows NT Drivers receive IRP_MN_START_DEVICE in a critical region and
- * actually _depend_ on this!. This is because NT will lock the Device Node
- * with an ERESOURCE, which of course requires APCs to be disabled.
- */
- KeEnterCriticalRegion();
-
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_START_DEVICE,
- &Stack);
-
- KeLeaveCriticalRegion();
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IRP_MN_START_DEVICE failed for %wZ\n",
&DeviceNode->InstancePath);
- IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
- goto ByeBye;
- }
- else
- {
- if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY))
- {
- DPRINT("Device needs enumeration, invalidating bus relations\n");
- /* Invalidate device relations synchronously
- (otherwise there will be dirty read of DeviceNode) */
- IopEnumerateDevice(DeviceNode->PhysicalDeviceObject);
- IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
- }
- }
-
+ /* New PnP ABI */
+ IopStartAndEnumerateDevice(DeviceNode);
+
+ /* FIX: Should be done in new device instance code */
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0,
&InstanceHandle);
if (!NT_SUCCESS(Status))
goto ByeBye;
+ /* FIX: Should be done in IoXxxPrepareDriverLoading */
+ // {
RtlInitUnicodeString(&KeyName, L"Control");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
@@ -248,7 +325,9 @@
RtlInitUnicodeString(&KeyName, L"ActiveService");
Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ,
DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length);
-
+ // }
+
+ /* FIX: Should be done somewhere in resoure code? */
if (NT_SUCCESS(Status) && DeviceNode->ResourceList)
{
RtlInitUnicodeString(&KeyName, L"AllocConfig");