RTL_AVL_TABLE PpDeviceReferenceTable;
extern ULONG ExpInitializationPhase;
+extern BOOLEAN ExpInTextModeSetup;
extern BOOLEAN PnpSystemInit;
/* DATA **********************************************************************/
IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS
-IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
+IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
PDEVICE_NODE
FASTCALL
DriverObject, DeviceNode->PhysicalDeviceObject);
if (!NT_SUCCESS(Status))
{
- DPRINT1("%wZ->AddDevice(%wZ) failed with status 0x%x\n",
+ DPRINT1("%wZ->AddDevice(%wZ) failed with status 0x%x\n",
&DriverObject->DriverName,
&DeviceNode->InstancePath,
Status);
return Status;
}
- /* Check if driver added a FDO above the PDO */
Fdo = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
- if (Fdo == DeviceNode->PhysicalDeviceObject)
- {
- /* FIXME: What do we do? Unload the driver or just disable the device? */
- DPRINT1("An FDO was not attached\n");
- ObDereferenceObject(Fdo);
- IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
- return STATUS_UNSUCCESSFUL;
- }
/* Check if we have a ACPI device (needed for power management) */
if (Fdo->DeviceType == FILE_DEVICE_ACPI)
if (!SystemPowerDeviceNodeCreated)
{
PopSystemPowerDeviceNode = DeviceNode;
- ObReferenceObject(PopSystemPowerDeviceNode);
+ ObReferenceObject(PopSystemPowerDeviceNode->PhysicalDeviceObject);
SystemPowerDeviceNodeCreated = TRUE;
}
}
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_EJECT;
- return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+ return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
static
NewList = ExAllocatePool(PagedPool, NewSize);
if (!NewList) {
- /* Fail */
- ExFreePool(PnpBusTypeGuidList);
- goto Quickie;
+ /* Fail */
+ ExFreePool(PnpBusTypeGuidList);
+ goto Quickie;
}
/* Now copy them, decrease the size too */
/*
* DESCRIPTION
- * Creates a device node
+ * Creates a device node
*
* ARGUMENTS
* ParentNode = Pointer to parent device node
* DeviceNode = Pointer to storage for created device node
*
* RETURN VALUE
- * Status
+ * Status
*/
NTSTATUS
IopCreateDeviceNode(PDEVICE_NODE ParentNode,
NTAPI
IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
IN OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG MinorFunction,
+ IN UCHAR MinorFunction,
IN PIO_STACK_LOCATION Stack OPTIONAL)
{
IO_STACK_LOCATION IoStackLocation;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
LPCWSTR Current, Last;
- ULONG dwLength;
+ USHORT Length;
NTSTATUS Status;
/* Assume failure */
*Handle = NULL;
+ /* Create a volatile device tree in 1st stage so we have a clean slate
+ * for enumeration using the correct HAL (chosen in 1st stage setup) */
+ if (ExpInTextModeSetup) CreateOptions |= REG_OPTION_VOLATILE;
+
/* Open root key for device instances */
Status = IopOpenRegistryKeyEx(&hParent, NULL, &EnumU, KEY_CREATE_SUB_KEY);
if (!NT_SUCCESS(Status))
}
/* Prepare relative key name */
- dwLength = (ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer;
- KeyName.MaximumLength = KeyName.Length = dwLength;
+ Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
+ KeyName.MaximumLength = KeyName.Length = Length;
DPRINT("Create '%wZ'\n", &KeyName);
/* Open key */
&ObjectAttributes,
0,
NULL,
- 0,
+ REG_OPTION_VOLATILE,
NULL);
if (NT_SUCCESS(Status))
{
{
ULONG KeyNameBufferLength;
PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
- UNICODE_STRING KeyName;
+ UNICODE_STRING KeyName = {0, 0, NULL};
UNICODE_STRING KeyValue;
UNICODE_STRING ValueName;
HANDLE hKey = NULL;
ParentIdPrefixInformation = ExAllocatePool(PagedPool, KeyNameBufferLength + sizeof(WCHAR));
if (!ParentIdPrefixInformation)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
-
KeyName.Buffer = ExAllocatePool(PagedPool, (49 * sizeof(WCHAR)) + DeviceNode->Parent->InstancePath.Length);
if (!KeyName.Buffer)
{
0,
REG_SZ,
(PVOID)KeyValue.Buffer,
- (wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
+ ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
cleanup:
if (NT_SUCCESS(Status))
while (*Ptr)
{
DPRINT(" %S\n", Ptr);
- Length = wcslen(Ptr) + 1;
+ Length = (ULONG)wcslen(Ptr) + 1;
Ptr += Length;
TotalLength += Length;
RtlInitUnicodeString(&ValueName, L"HardwareID");
Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_MULTI_SZ,
- (PVOID)IoStatusBlock.Information,
- (TotalLength + 1) * sizeof(WCHAR));
+ &ValueName,
+ 0,
+ REG_MULTI_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (TotalLength + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
while (*Ptr)
{
DPRINT(" %S\n", Ptr);
- Length = wcslen(Ptr) + 1;
+ Length = (ULONG)wcslen(Ptr) + 1;
Ptr += Length;
TotalLength += Length;
0,
REG_SZ,
(PVOID)IoStatusBlock.Information,
- (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+ ((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
}
else
{
0,
REG_SZ,
(PVOID)IoStatusBlock.Information,
- (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+ ((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
}
}
- if (!Found)
+ if (!Found && !(Child->Flags & DNF_WILL_BE_REMOVED))
{
+ /* Send removal IRPs to all of its children */
+ IopPrepareDeviceForRemoval(Child->PhysicalDeviceObject, TRUE);
+
+ /* Send the surprise removal IRP */
IopSendSurpriseRemoval(Child->PhysicalDeviceObject);
/* Tell the user-mode PnP manager that a device was removed */
IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
&Child->InstancePath);
+ /* Send the remove device IRP */
IopSendRemoveDevice(Child->PhysicalDeviceObject);
}
{
/* Ignore this DO */
DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u\n", Status, i);
- ObDereferenceObject(ChildDeviceNode);
+ ObDereferenceObject(ChildDeviceObject);
}
}
else
/* Device has a ClassGUID value, but no Service value.
* Suppose it is using the NULL driver, so state the
* device is started */
- DPRINT1("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
+ DPRINT("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
}
else
&ObjectAttributes,
0,
NULL,
- REG_OPTION_NON_VOLATILE,
+ ExpInTextModeSetup ? REG_OPTION_VOLATILE : 0,
NULL);
if (!NT_SUCCESS(Status))
{
&ObjectAttributes,
0,
NULL,
- REG_OPTION_NON_VOLATILE,
+ ExpInTextModeSetup ? REG_OPTION_VOLATILE : 0,
NULL);
ZwClose(hLevel1Key);
if (!NT_SUCCESS(Status))
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hPnpKey;
PKEY_VALUE_PARTIAL_INFORMATION KeyInformation;
- ULONG DesiredLength, Length, KeyValue;
+ ULONG DesiredLength, Length;
+ ULONG KeyValue = 0;
NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, &KeyPathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
else
{
DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU);
- KeyValue = 0;
}
ExFreePool(KeyInformation);
else
{
DPRINT1("Failed to allocate memory for registry query\n");
- KeyValue = 0;
}
}
else
{
DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status);
- KeyValue = 0;
}
ZwClose(hPnpKey);
OUT PULONG Disposition OPTIONAL)
{
OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0, Length;
+ ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
+ USHORT Length;
HANDLE HandleArray[2];
BOOLEAN Recursing = TRUE;
PWCHAR pp, p, p1;
/* Process the parent key name */
for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
- Length = (p - p1) * sizeof(WCHAR);
+ Length = (USHORT)(p - p1) * sizeof(WCHAR);
/* Is there a parent name? */
if (Length)
{
case DevicePropertyBusTypeGuid:
- /* Get the GUID from the internal cache */
+ /* Get the GUID from the internal cache */
Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
if (!NT_SUCCESS(Status)) return Status;
NullTerminate = TRUE;
/* This is the format of the returned data */
- PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
+ PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
DeviceInstanceName);
case DevicePropertyAddress:
case DevicePropertyRemovalPolicy:
PIP_UNIMPLEMENTED();
case DevicePropertyInstallState:
- PIP_UNIMPLEMENTED();
+ PIP_UNIMPLEMENTED();
case DevicePropertyResourceRequirements:
- PIP_UNIMPLEMENTED();
+ PIP_UNIMPLEMENTED();
case DevicePropertyAllocatedResources:
- PIP_UNIMPLEMENTED();
+ PIP_UNIMPLEMENTED();
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;
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
- 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
+ 0, NULL, ExpInTextModeSetup ? REG_OPTION_VOLATILE : 0, NULL);
ZwClose(ObjectAttributes.RootDirectory);
return Status;
static
NTSTATUS
-IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
+IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
NTSTATUS Status;
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
- Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject, Force);
if (!NT_SUCCESS(Status))
{
FailedRemoveDevice = ChildDeviceNode;
static
NTSTATUS
-IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
+IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
{
/* This function DOES NOT dereference the device objects on SUCCESS
* but it DOES dereference device objects on FAILURE */
for (i = 0; i < DeviceRelations->Count; i++)
{
- Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
+ Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
if (!NT_SUCCESS(Status))
{
j = i;
}
NTSTATUS
-IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject)
+IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
{
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
IO_STACK_LOCATION Stack;
PDEVICE_RELATIONS DeviceRelations;
NTSTATUS Status;
- if (DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE)
+ if ((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) && !Force)
{
DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
return STATUS_UNSUCCESSFUL;
}
- if (IopQueryRemoveDevice(DeviceObject) != STATUS_SUCCESS)
+ if (!Force && IopQueryRemoveDevice(DeviceObject) != STATUS_SUCCESS)
{
DPRINT1("Removal vetoed by failing the query remove request\n");
if (DeviceRelations)
{
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
if (!NT_SUCCESS(Status))
return Status;
}
-
- Status = IopQueryRemoveChildDevices(DeviceNode);
+
+ Status = IopQueryRemoveChildDevices(DeviceNode, Force);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
return Status;
}
-
+
+ DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
- Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, FALSE);
if (NT_SUCCESS(Status))
{
IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL,
&DeviceNode->InstancePath);
- DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
return STATUS_SUCCESS;
}
if (DeviceRelations)
{
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
if (!NT_SUCCESS(Status))
goto cleanup;
}
- Status = IopQueryRemoveChildDevices(DeviceNode);
+ Status = IopQueryRemoveChildDevices(DeviceNode, FALSE);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
goto cleanup;
}
- if (IopPrepareDeviceForRemoval(PhysicalDeviceObject) != STATUS_SUCCESS)
+ if (IopPrepareDeviceForRemoval(PhysicalDeviceObject, FALSE) != STATUS_SUCCESS)
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);