PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
ULONG HidLength = 0, CidLength = 0, BufferLength;
PWCHAR IdBuffer, OriginalIdBuffer;
-
+
/* Open the device instance key */
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
if (Status != STATUS_SUCCESS)
ZwClose(InstanceKey);
return;
}
-
+
/* Copy CID next */
CidLength = PartialInfo->DataLength;
RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength);
/* Free our temp buffer */
ExFreePool(PartialInfo);
-
+
InitializeObjectAttributes(&ObjectAttributes,
&CriticalDeviceKeyU,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
while (*IdBuffer)
{
USHORT StringLength = (USHORT)wcslen(IdBuffer) + 1, Index;
-
+
IopFixupDeviceId(IdBuffer);
-
+
/* Look through all subkeys for a match */
for (Index = 0; TRUE; Index++)
{
ULONG NeededLength;
PKEY_BASIC_INFORMATION BasicInfo;
-
+
Status = ZwEnumerateKey(CriticalDeviceKey,
Index,
KeyBasicInformation,
/* Advance to the next ID */
IdBuffer += StringLength;
}
-
+
ExFreePool(OriginalIdBuffer);
ZwClose(InstanceKey);
ZwClose(CriticalDeviceKey);
{
PDEVICE_OBJECT Fdo;
NTSTATUS Status;
-
+
if (!DriverObject)
{
/* Special case for bus driven devices */
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_EJECT;
-
+
return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_SURPRISE_REMOVAL;
-
+
/* Drivers should never fail a IRP_MN_SURPRISE_REMOVAL request */
IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
IO_STACK_LOCATION Stack;
PVOID Dummy;
NTSTATUS Status;
-
+
ASSERT(DeviceNode);
-
+
IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
&DeviceNode->InstancePath);
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_QUERY_REMOVE_DEVICE;
&GUID_TARGET_DEVICE_QUERY_REMOVE,
NULL,
NULL);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT1("Removal vetoed by %wZ\n", &DeviceNode->InstancePath);
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_QUERY_STOP_DEVICE;
-
+
return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
+ PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+
+ /* Drop all our state for this device in case it isn't really going away */
+ DeviceNode->Flags &= DNF_ENUMERATED | DNF_PROCESSED;
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
&GUID_TARGET_DEVICE_REMOVE_COMPLETE,
NULL,
NULL);
+ ObDereferenceObject(DeviceObject);
}
static
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_CANCEL_REMOVE_DEVICE;
-
+
/* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
IopSynchronousCall(DeviceObject, &Stack, &Dummy);
-
+
IopNotifyPlugPlayNotification(DeviceObject,
EventCategoryTargetDeviceChange,
&GUID_TARGET_DEVICE_REMOVE_CANCELLED,
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_STOP_DEVICE;
-
+
/* Drivers should never fail a IRP_MN_STOP_DEVICE request */
IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
NTSTATUS Status;
PVOID Dummy;
DEVICE_CAPABILITIES DeviceCapabilities;
-
+
/* Get the device node */
DeviceNode = IopGetDeviceNode(DeviceObject);
-
+
ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
- /* Build the I/O stack locaiton */
+ /* Build the I/O stack location */
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_START_DEVICE;
-
+
Stack.Parameters.StartDevice.AllocatedResources =
DeviceNode->ResourceList;
Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
DPRINT1("Warning: PnP Start failed (%wZ) [Status: 0x%x]\n", &DeviceNode->InstancePath, Status);
return;
}
-
+
DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after start)\n");
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
/* Invalidate device state so IRP_MN_QUERY_PNP_DEVICE_STATE is sent */
IoInvalidateDeviceState(DeviceObject);
-
+
/* Otherwise, mark us as started */
DeviceNode->Flags |= DNF_STARTED;
DeviceNode->Flags &= ~DNF_STOPPED;
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
PAGED_CODE();
-
+
/* Sanity check */
ASSERT((DeviceNode->Flags & DNF_ADDED));
ASSERT((DeviceNode->Flags & (DNF_RESOURCE_ASSIGNED |
DNF_RESOURCE_REPORTED |
DNF_NO_RESOURCE_REQUIRED)));
-
+
/* 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 0
if (DeviceNode->Flags & DNF_NEED_QUERY_IDS)
ASSERT(FALSE);
}
#endif
-
+
/* Make sure we're started, and check if we need enumeration */
if ((DeviceNode->Flags & DNF_STARTED) &&
(DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY))
/* Nothing to do */
Status = STATUS_SUCCESS;
}
-
+
/* Return */
return Status;
}
NTSTATUS Status;
PDEVICE_OBJECT TopDeviceObject;
PAGED_CODE();
-
+
/* Call the top of the device stack */
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
-
+
/* Allocate an IRP */
Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
-
+
/* Initialize to failure */
Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = IoStatusBlock.Information = 0;
-
+
/* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
if (IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
{
Irp->IoStatus.Information =
IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
}
-
+
/* Initialize the event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
+
/* Set them up */
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = &Event;
-
+
/* Queue the IRP */
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
IoQueueThreadIrp(Irp);
-
+
/* Copy-in the stack */
IrpStack = IoGetNextIrpStackLocation(Irp);
*IrpStack = *IoStackLocation;
-
+
/* Call the driver */
Status = IoCallDriver(TopDeviceObject, Irp);
if (Status == STATUS_PENDING)
IN PIO_STACK_LOCATION Stack OPTIONAL)
{
IO_STACK_LOCATION IoStackLocation;
-
+
/* Fill out the stack information */
RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
IoStackLocation.MajorFunction = IRP_MJ_PNP;
&Stack->Parameters,
sizeof(Stack->Parameters));
}
-
+
/* Do the PnP call */
IoStatusBlock->Status = IopSynchronousCall(DeviceObject,
&IoStackLocation,
DPRINT("Context 0x%p\n", Context);
- DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %x Context 0x%p)\n",
+ DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p Context 0x%p)\n",
Context->DeviceNode, Context->FirstDeviceNode, Context->Action, Context->Context);
/* Start from the specified device node */
&DeviceNode->InstancePath);
}
- DeviceNode->Flags &= ~DNF_NEED_TO_ENUM;
-
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
UNICODE_STRING KeyString;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
-
+
/* P1 is start, pp is end */
p1 = KeyName->Buffer;
pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
-
+
/* Create the target key */
InitializeObjectAttributes(&ObjectAttributes,
KeyName,
/* Target key failed, so we'll need to create its parent. Setup array */
HandleArray[0] = NULL;
HandleArray[1] = RootHandle;
-
+
/* Keep recursing for each missing parent */
while (Recursing)
{
/* And if we're deep enough, close the last handle */
if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
-
+
/* We're setup to ping-pong between the two handle array entries */
RootHandleIndex = i;
i = (i + 1) & 1;
-
+
/* Clear the one we're attempting to open now */
HandleArray[i] = NULL;
-
+
/* Process the parent key name */
for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
Length = (USHORT)(p - p1) * sizeof(WCHAR);
-
+
/* Is there a parent name? */
if (Length)
{
/* Build the unicode string for it */
KeyString.Buffer = p1;
KeyString.Length = KeyString.MaximumLength = Length;
-
+
/* Now try opening the parent */
InitializeObjectAttributes(&ObjectAttributes,
&KeyString,
Recursing = FALSE;
continue;
}
-
+
/* Now see if there's more parents to create */
p1 = p + 1;
if ((p == pp) || (p1 == pp))
Recursing = FALSE;
}
}
-
+
/* Outer loop check for handle nesting that requires closing the top handle */
if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
}
-
+
/* Check if we broke out of the loop due to success */
if (NT_SUCCESS(Status))
{
*Handle = HandleArray[i];
if (Disposition) *Disposition = KeyDisposition;
}
-
+
/* Return the success state */
return Status;
}
{
PDEVICE_NODE DeviceNode;
PAGED_CODE();
-
+
/* Allocate it */
DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), 'donD');
if (!DeviceNode) return DeviceNode;
-
+
/* Statistics */
InterlockedIncrement(&IopNumberDeviceNodes);
-
+
/* Set it up */
RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE));
DeviceNode->InterfaceType = InterfaceTypeUndefined;
InitializeListHead(&DeviceNode->TargetDeviceNotify);
InitializeListHead(&DeviceNode->DockInfo.ListEntry);
InitializeListHead(&DeviceNode->PendedSetInterfaceState);
-
+
/* Check if there is a PDO */
if (PhysicalDeviceObject)
{
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode;
PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
-
+
/* Return the node */
return DeviceNode;
}
/* Acquire the lock */
ExAcquireFastMutex(&PnpBusTypeGuidList->Lock);
-
+
/* Validate size */
if (Index < PnpBusTypeGuidList->GuidCount)
{
/* Failure path */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
-
+
/* Release lock and return status */
ExReleaseFastMutex(&PnpBusTypeGuidList->Lock);
return Status;
PDEVICE_NODE DeviceNode;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
PAGED_CODE();
-
+
/* Open the enum key */
Status = IopOpenRegistryKeyEx(&KeyHandle,
NULL,
&KeyName,
KEY_READ);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Make sure we have an instance path */
DeviceNode = IopGetDeviceNode(DeviceObject);
if ((DeviceNode) && (DeviceNode->InstancePath.Length))
/* Fail */
Status = STATUS_INVALID_DEVICE_REQUEST;
}
-
+
/* Close the handle and return status */
ZwClose(KeyHandle);
return Status;
ULONG FinalSize, PartialSize, EntrySize, i, j;
PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-
+
/* If we don't have one, that's easy */
if (!ResourceList) return 0;
-
+
/* Start with the minimum size possible */
FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
-
+
/* Loop each full descriptor */
FullDescriptor = ResourceList->List;
for (i = 0; i < ResourceList->Count; i++)
/* Start with the minimum size possible */
PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
-
+
/* Loop each partial descriptor */
PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
{
/* Start with the minimum size possible */
EntrySize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-
+
/* Check if there is extra data */
if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
{
/* Add that data */
EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize;
}
-
+
/* The size of partial descriptors is bigger */
PartialSize += EntrySize;
-
+
/* Go to the next partial descriptor */
PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize);
}
-
+
/* The size of full descriptors is bigger */
FinalSize += PartialSize;
-
+
/* Go to the next full descriptor */
FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize);
}
-
+
/* Return the final size */
return FinalSize;
}
/* This is the format of the returned data */
PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
-
+
case DevicePropertyLegacyBusType:
-
+
/* Validate correct interface type */
if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
return STATUS_OBJECT_NAME_NOT_FOUND;
/* This is the format of the returned data */
PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
-
+
case DevicePropertyBusNumber:
-
+
/* Validate correct bus number */
if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
return STATUS_OBJECT_NAME_NOT_FOUND;
-
+
/* This is the format of the returned data */
PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
-
+
case DevicePropertyEnumeratorName:
/* Get the instance path */
DeviceInstanceName = DeviceNode->InstancePath.Buffer;
-
+
/* Sanity checks */
ASSERT((BufferLength & 1) == 0);
ASSERT(DeviceInstanceName != NULL);
-
+
/* Get the name from the path */
EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
ASSERT(EnumeratorNameEnd);
/* This is the format of the returned data */
PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
DeviceInstanceName);
-
+
case DevicePropertyAddress:
/* Query the device caps */
/* This is the format of the returned data */
PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
-
+
case DevicePropertyBootConfigurationTranslated:
-
+
/* Validate we have resources */
if (!DeviceNode->BootResources)
// if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
*ResultLength = 0;
return STATUS_SUCCESS;
}
-
+
/* This is the format of the returned data */
PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
case DevicePropertyPhysicalDeviceObjectName:
-
+
/* Sanity check for Unicode-sized string */
ASSERT((BufferLength & 1) == 0);
-
+
/* Allocate name buffer */
Length = BufferLength + sizeof(OBJECT_NAME_INFORMATION);
ObjectNameInfo = ExAllocatePool(PagedPool, Length);
if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
-
+
/* Query the PDO name */
Status = ObQueryNameString(DeviceObject,
ObjectNameInfo,
/* Let the caller know how big the name is */
*ResultLength -= sizeof(OBJECT_NAME_INFORMATION);
break;
-
+
/* Handle the registry-based properties */
case DevicePropertyUINumber:
PIP_REGISTRY_DATA(REGSTR_VAL_UI_NUMBER, REG_DWORD);
default:
return STATUS_INVALID_PARAMETER_2;
}
-
+
/* Having a registry value name implies registry data */
if (ValueName)
{
/* We know up-front how much data to expect */
*ResultLength = BufferLength;
-
+
/* Go get the data, use the LogConf subkey if necessary */
Status = PiGetDeviceRegistryProperty(DeviceObject,
ValueType,
/* Terminate the string */
((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL;
}
-
+
/* This is the success path */
Status = STATUS_SUCCESS;
}
Status = STATUS_BUFFER_TOO_SMALL;
}
}
-
+
/* Free any allocation we may have made, and return the status code */
if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
return Status;
ULONG PnPFlags;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
-
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE;
-
+
Status = IopSynchronousCall(PhysicalDeviceObject, &Stack, (PVOID*)&PnPFlags);
if (!NT_SUCCESS(Status))
{
/* Send surprise removal */
IopSendSurpriseRemoval(PhysicalDeviceObject);
-
+
/* Tell the user-mode PnP manager that a device was removed */
IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
&DeviceNode->InstancePath);
-
+
IopSendRemoveDevice(PhysicalDeviceObject);
}
else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
PnPFlags &= ~PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED;
}
}
-
+
/* Resource rebalance */
if (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)
{
DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
-
+
Status = IopInitiatePnpIrp(PhysicalDeviceObject,
&IoStatusBlock,
IRP_MN_QUERY_RESOURCES,
DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
DeviceNode->BootResources = NULL;
}
-
+
DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
-
+
Status = IopInitiatePnpIrp(PhysicalDeviceObject,
&IoStatusBlock,
IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
DeviceNode->ResourceRequirements = NULL;
}
-
+
/* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
if (IopStartDevice(DeviceNode) != STATUS_SUCCESS)
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
NTSTATUS Status;
KIRQL OldIrql;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
ChildDeviceNode = ParentDeviceNode->Child;
while (ChildDeviceNode != NULL)
{
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject, Force);
if (!NT_SUCCESS(Status))
{
FailedRemoveDevice = ChildDeviceNode;
goto cleanup;
}
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
ChildDeviceNode = NextDeviceNode;
}
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
return STATUS_SUCCESS;
-
+
cleanup:
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
ChildDeviceNode = ParentDeviceNode->Child;
{
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
IopCancelPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject);
-
+
/* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
* that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
if (ChildDeviceNode == FailedRemoveDevice)
return Status;
-
+
ChildDeviceNode = NextDeviceNode;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
}
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
return Status;
}
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
KIRQL OldIrql;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
ChildDeviceNode = ParentDeviceNode->Child;
while (ChildDeviceNode != NULL)
{
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
IopSendRemoveDevice(ChildDeviceNode->PhysicalDeviceObject);
-
+
ChildDeviceNode = NextDeviceNode;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
}
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
KIRQL OldIrql;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
ChildDeviceNode = ParentDeviceNode->Child;
while (ChildDeviceNode != NULL)
{
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
-
+
IopCancelPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject);
-
+
ChildDeviceNode = NextDeviceNode;
-
+
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
}
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
{
/* This function DOES NOT dereference the device objects on SUCCESS
* but it DOES dereference device objects on FAILURE */
-
+
ULONG i, j;
NTSTATUS Status;
-
+
for (i = 0; i < DeviceRelations->Count; i++)
{
Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
goto cleanup;
}
}
-
+
return STATUS_SUCCESS;
-
+
cleanup:
/* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
* that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
DeviceRelations->Objects[i] = NULL;
}
ExFreePool(DeviceRelations);
-
+
return Status;
}
IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
{
/* This function DOES dereference the device objects in all cases */
-
+
ULONG i;
-
+
for (i = 0; i < DeviceRelations->Count; i++)
{
IopSendRemoveDevice(DeviceRelations->Objects[i]);
- ObDereferenceObject(DeviceRelations->Objects[i]);
DeviceRelations->Objects[i] = NULL;
}
-
+
ExFreePool(DeviceRelations);
}
IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
{
/* This function DOES dereference the device objects in all cases */
-
+
ULONG i;
-
+
for (i = 0; i < DeviceRelations->Count; i++)
{
IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
ObDereferenceObject(DeviceRelations->Objects[i]);
DeviceRelations->Objects[i] = NULL;
}
-
+
ExFreePool(DeviceRelations);
}
IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_RELATIONS DeviceRelations;
NTSTATUS Status;
-
+
IopCancelRemoveDevice(DeviceObject);
-
+
Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
-
+
Status = IopInitiatePnpIrp(DeviceObject,
&IoStatusBlock,
IRP_MN_QUERY_DEVICE_RELATIONS,
{
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
}
-
+
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
}
DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
return STATUS_UNSUCCESSFUL;
}
-
+
if (!Force && IopQueryRemoveDevice(DeviceObject) != STATUS_SUCCESS)
{
DPRINT1("Removal vetoed by failing the query remove request\n");
-
+
IopCancelRemoveDevice(DeviceObject);
-
+
return STATUS_UNSUCCESSFUL;
}
-
+
Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
Status = IopInitiatePnpIrp(DeviceObject,
return Status;
}
- DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
- DeviceNode->Problem = CM_PROB_WILL_BE_REMOVED;
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
-
+
return STATUS_SUCCESS;
}
IO_STACK_LOCATION Stack;
DEVICE_CAPABILITIES Capabilities;
NTSTATUS Status;
-
+
IopQueueTargetDeviceEvent(&GUID_DEVICE_KERNEL_INITIATED_EJECT,
&DeviceNode->InstancePath);
-
+
if (IopQueryDeviceCapabilities(DeviceNode, &Capabilities) != STATUS_SUCCESS)
{
goto cleanup;
}
-
+
Stack.Parameters.QueryDeviceRelations.Type = EjectionRelations;
-
+
Status = IopInitiatePnpIrp(PhysicalDeviceObject,
&IoStatusBlock,
IRP_MN_QUERY_DEVICE_RELATIONS,
{
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
}
-
+
if (DeviceRelations)
{
Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
if (!NT_SUCCESS(Status))
goto cleanup;
}
-
+
Status = IopQueryRemoveChildDevices(DeviceNode, FALSE);
if (!NT_SUCCESS(Status))
{
IopCancelRemoveDeviceRelations(DeviceRelations);
goto cleanup;
}
-
+
if (IopPrepareDeviceForRemoval(PhysicalDeviceObject, FALSE) != STATUS_SUCCESS)
{
if (DeviceRelations)
IopCancelRemoveChildDevices(DeviceNode);
goto cleanup;
}
-
+
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
{
DeviceNode->Flags |= DNF_DISABLED;
}
-
+
IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT,
&DeviceNode->InstancePath);
-
+
return;
-
+
cleanup:
IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT_VETOED,
&DeviceNode->InstancePath);
IN DEVICE_RELATION_TYPE Type)
{
PAGED_CODE();
-
+
switch (Type)
{
case BusRelations: