- IopGetDevicePointer: Close the handle if we were able to acquire it.

- IoAttachDevice/IoAttachDeviceByPointer: Fail with STATUS_NO_SUCH_DEVICE if we couldn't attach.
- IoAttachDEviceTodEviceStackSafe: VPBs don't get inherited.
- IoCreateDevice: Only set OBJ_PERMAMENT if the caller requested it.
- IoCreateDevice: Return a NULL Device object if we failed to create it.
- IoCreateDevice: Set alignment requirement to 0, x86 doesn't need it.

svn path=/trunk/; revision=22736
This commit is contained in:
Alex Ionescu 2006-07-01 04:21:19 +00:00
parent 7a5dbe8152
commit ff6b13eb13

View file

@ -1,11 +1,11 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/device.c * FILE: ntoskrnl/io/device.c
* PURPOSE: Device Object Management, including Notifications and Queues. * PURPOSE: Device Object Management, including Notifications and Queues.
* * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMERS: Alex Ionescu * Filip Navara (navaraf@reactos.org)
* David Welch (welch@cwcom.net) * Hervé Poussineau (hpoussin@reactos.org)
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -184,10 +184,6 @@ IopGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName,
HANDLE FileHandle; HANDLE FileHandle;
NTSTATUS Status; NTSTATUS Status;
DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x,"
"FileObject %p DeviceObject %p)\n",
ObjectName, DesiredAccess, FileObject, DeviceObject);
/* Open the Device */ /* Open the Device */
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
ObjectName, ObjectName,
@ -200,12 +196,7 @@ IopGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName,
&StatusBlock, &StatusBlock,
0, 0,
FILE_NON_DIRECTORY_FILE | AttachFlag); FILE_NON_DIRECTORY_FILE | AttachFlag);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile failed, Status: 0x%x\n", Status);
return Status;
}
/* Get File Object */ /* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
@ -219,10 +210,10 @@ IopGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName,
/* Return the requested data */ /* Return the requested data */
*DeviceObject = IoGetRelatedDeviceObject(LocalFileObject); *DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
*FileObject = LocalFileObject; *FileObject = LocalFileObject;
ZwClose(FileHandle);
} }
/* Close the handle */ /* Close the handle */
ZwClose(FileHandle);
return Status; return Status;
} }
@ -257,25 +248,22 @@ IoAttachDevice(PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT TargetDevice = NULL; PDEVICE_OBJECT TargetDevice = NULL;
/* Call the helper routine for an attach operation */ /* Call the helper routine for an attach operation */
DPRINT("IoAttachDevice\n");
Status = IopGetDeviceObjectPointer(TargetDeviceName, Status = IopGetDeviceObjectPointer(TargetDeviceName,
FILE_READ_ATTRIBUTES, FILE_READ_ATTRIBUTES,
&FileObject, &FileObject,
&TargetDevice, &TargetDevice,
IO_ATTACH_DEVICE_API); IO_ATTACH_DEVICE_API);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get Device Object\n");
return Status;
}
/* Attach the device */ /* Attach the device */
IoAttachDeviceToDeviceStackSafe(SourceDevice, TargetDevice, AttachedDevice); Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
TargetDevice,
AttachedDevice);
if (!*AttachedDevice) Status = STATUS_NO_SUCH_DEVICE;
/* Derference it */ /* Dereference it */
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return STATUS_SUCCESS; return Status;
} }
/* /*
@ -292,12 +280,9 @@ IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT AttachedDevice; PDEVICE_OBJECT AttachedDevice;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("IoAttachDeviceByPointer(SourceDevice 0x%p, TargetDevice 0x%p)\n",
SourceDevice, TargetDevice);
/* Do the Attach */ /* Do the Attach */
AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice); AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice);
if (AttachedDevice == NULL) Status = STATUS_NO_SUCH_DEVICE; if (!AttachedDevice) Status = STATUS_NO_SUCH_DEVICE;
/* Return the status */ /* Return the status */
return Status; return Status;
@ -318,13 +303,11 @@ IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT LocalAttach; PDEVICE_OBJECT LocalAttach;
/* Attach it safely */ /* Attach it safely */
DPRINT("IoAttachDeviceToDeviceStack\n");
Status = IoAttachDeviceToDeviceStackSafe(SourceDevice, Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
TargetDevice, TargetDevice,
&LocalAttach); &LocalAttach);
/* Return it */ /* Return it */
DPRINT("IoAttachDeviceToDeviceStack DONE: 0x%p\n", LocalAttach);
return LocalAttach; return LocalAttach;
} }
@ -340,25 +323,27 @@ IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT AttachedDevice; PDEVICE_OBJECT AttachedDevice;
PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension; PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension;
DPRINT("IoAttachDeviceToDeviceStack(SourceDevice 0x%p, TargetDevice 0x%p)\n",
SourceDevice, TargetDevice);
/* Get the Attached Device and source extension */ /* Get the Attached Device and source extension */
AttachedDevice = IoGetAttachedDevice(TargetDevice); AttachedDevice = IoGetAttachedDevice(TargetDevice);
SourceDeviceExtension = (PEXTENDED_DEVOBJ_EXTENSION)SourceDevice->DeviceObjectExtension; SourceDeviceExtension = (PEXTENDED_DEVOBJ_EXTENSION)SourceDevice->
DeviceObjectExtension;
/* Make sure that it's in a correct state */ /* Make sure that it's in a correct state */
if (!(((PEXTENDED_DEVOBJ_EXTENSION)AttachedDevice->DeviceObjectExtension)->ExtensionFlags & if (!(((PEXTENDED_DEVOBJ_EXTENSION)AttachedDevice->DeviceObjectExtension)->
(DOE_UNLOAD_PENDING | DOE_DELETE_PENDING | ExtensionFlags & (DOE_UNLOAD_PENDING |
DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED))) DOE_DELETE_PENDING |
DOE_REMOVE_PENDING |
DOE_REMOVE_PROCESSED)))
{ {
/* Update fields */ /* Update atached device fields */
AttachedDevice->AttachedDevice = SourceDevice; AttachedDevice->AttachedDevice = SourceDevice;
SourceDevice->AttachedDevice = NULL; AttachedDevice->Spare1++;
/* Update the source with the attached data */
SourceDevice->StackSize = AttachedDevice->StackSize + 1; SourceDevice->StackSize = AttachedDevice->StackSize + 1;
SourceDevice->AlignmentRequirement = AttachedDevice->AlignmentRequirement; SourceDevice->AlignmentRequirement = AttachedDevice->
AlignmentRequirement;
SourceDevice->SectorSize = AttachedDevice->SectorSize; SourceDevice->SectorSize = AttachedDevice->SectorSize;
SourceDevice->Vpb = AttachedDevice->Vpb;
/* Set the attachment in the device extension */ /* Set the attachment in the device extension */
SourceDeviceExtension->AttachedTo = AttachedDevice; SourceDeviceExtension->AttachedTo = AttachedDevice;
@ -408,13 +393,13 @@ IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,
*/ */
NTSTATUS NTSTATUS
STDCALL STDCALL
IoCreateDevice(PDRIVER_OBJECT DriverObject, IoCreateDevice(IN PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize, IN ULONG DeviceExtensionSize,
PUNICODE_STRING DeviceName, IN PUNICODE_STRING DeviceName,
DEVICE_TYPE DeviceType, IN DEVICE_TYPE DeviceType,
ULONG DeviceCharacteristics, IN ULONG DeviceCharacteristics,
BOOLEAN Exclusive, IN BOOLEAN Exclusive,
PDEVICE_OBJECT *DeviceObject) OUT PDEVICE_OBJECT *DeviceObject)
{ {
WCHAR AutoNameBuffer[20]; WCHAR AutoNameBuffer[20];
UNICODE_STRING AutoName; UNICODE_STRING AutoName;
@ -425,16 +410,17 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
ULONG AlignedDeviceExtensionSize; ULONG AlignedDeviceExtensionSize;
ULONG TotalSize; ULONG TotalSize;
HANDLE TempHandle; HANDLE TempHandle;
PAGED_CODE();
ASSERT_IRQL(PASSIVE_LEVEL); /* Check if we have to generate a name */
DPRINT("IoCreateDevice(DriverObject 0x%p)\n", DriverObject);
/* Generate a name if we have to */
if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME) if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)
{ {
/* Generate it */
swprintf(AutoNameBuffer, swprintf(AutoNameBuffer,
L"\\Device\\%08lx", L"\\Device\\%08lx",
InterlockedIncrementUL(&IopDeviceObjectNumber)); InterlockedIncrementUL(&IopDeviceObjectNumber));
/* Initialize the name */
RtlInitUnicodeString(&AutoName, AutoNameBuffer); RtlInitUnicodeString(&AutoName, AutoNameBuffer);
DeviceName = &AutoName; DeviceName = &AutoName;
} }
@ -443,24 +429,21 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
/* Honor exclusive flag */ /* Honor exclusive flag */
ObjectAttributes.Attributes |= OBJ_EXCLUSIVE; if (Exclusive) ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
/* Create a permanent object for named devices */ /* Create a permanent object for named devices */
if (DeviceName != NULL) if (DeviceName) ObjectAttributes.Attributes |= OBJ_PERMANENT;
{
ObjectAttributes.Attributes |= OBJ_PERMANENT;
}
/* Align the Extension Size to 8-bytes */ /* Align the Extension Size to 8-bytes */
AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7; AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7;
DPRINT("AlignedDeviceExtensionSize %x\n", AlignedDeviceExtensionSize);
/* Total Size */ /* Total Size */
TotalSize = AlignedDeviceExtensionSize + TotalSize = AlignedDeviceExtensionSize +
sizeof(DEVICE_OBJECT) + sizeof(EXTENDED_DEVOBJ_EXTENSION); sizeof(DEVICE_OBJECT) +
DPRINT("TotalSize %x\n", TotalSize); sizeof(EXTENDED_DEVOBJ_EXTENSION);
/* Create the Device Object */ /* Create the Device Object */
*DeviceObject = NULL;
Status = ObCreateObject(KernelMode, Status = ObCreateObject(KernelMode,
IoDeviceObjectType, IoDeviceObjectType,
&ObjectAttributes, &ObjectAttributes,
@ -470,16 +453,10 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
0, 0,
0, 0,
(PVOID*)&CreatedDeviceObject); (PVOID*)&CreatedDeviceObject);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
DPRINT1("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
return Status;
}
/* Clear the whole Object and extension so we don't null stuff manually */ /* Clear the whole Object and extension so we don't null stuff manually */
RtlZeroMemory(CreatedDeviceObject, TotalSize); RtlZeroMemory(CreatedDeviceObject, TotalSize);
DPRINT("CreatedDeviceObject 0x%p\n", CreatedDeviceObject);
/* /*
* Setup the Type and Size. Note that we don't use the aligned size, * Setup the Type and Size. Note that we don't use the aligned size,
@ -494,7 +471,6 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
AlignedDeviceExtensionSize); AlignedDeviceExtensionSize);
/* Set the Type and Size. Question: why is Size 0 on Windows? */ /* Set the Type and Size. Question: why is Size 0 on Windows? */
DPRINT("DeviceObjectExtension 0x%p\n", DeviceObjectExtension);
DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION; DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION;
DeviceObjectExtension->Size = 0; DeviceObjectExtension->Size = 0;
@ -509,10 +485,9 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
CreatedDeviceObject + 1 : CreatedDeviceObject + 1 :
NULL; NULL;
CreatedDeviceObject->StackSize = 1; CreatedDeviceObject->StackSize = 1;
CreatedDeviceObject->AlignmentRequirement = 1; /* FIXME */ CreatedDeviceObject->AlignmentRequirement = 0;
/* Set the Flags */ /* Set the Flags */
/* FIXME: After the Driver is Loaded, the flag below should be removed */
CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING; CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING;
if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE; if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE;
if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME; if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME;
@ -535,15 +510,20 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
/* Set the right Sector Size */ /* Set the right Sector Size */
switch (DeviceType) switch (DeviceType)
{ {
/* All disk systems */
case FILE_DEVICE_DISK_FILE_SYSTEM: case FILE_DEVICE_DISK_FILE_SYSTEM:
case FILE_DEVICE_DISK: case FILE_DEVICE_DISK:
case FILE_DEVICE_VIRTUAL_DISK: case FILE_DEVICE_VIRTUAL_DISK:
/* The default is 512 bytes */
CreatedDeviceObject->SectorSize = 512; CreatedDeviceObject->SectorSize = 512;
break; break;
/* CD-ROM file systems */
case FILE_DEVICE_CD_ROM_FILE_SYSTEM: case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
/* The default is 2048 bytes */
CreatedDeviceObject->SectorSize = 2048; CreatedDeviceObject->SectorSize = 2048;
break;
} }
/* Create the Device Queue */ /* Create the Device Queue */
@ -569,11 +549,9 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
1, 1,
(PVOID*)&CreatedDeviceObject, (PVOID*)&CreatedDeviceObject,
&TempHandle); &TempHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Cannot insert Device Object '%wZ' into Handle Table (status 0x%08lx)\n", /* Clear the device object and fail */
DeviceName, Status);
*DeviceObject = NULL; *DeviceObject = NULL;
return Status; return Status;
} }
@ -583,9 +561,9 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
CreatedDeviceObject->DriverObject = DriverObject; CreatedDeviceObject->DriverObject = DriverObject;
CreatedDeviceObject->NextDevice = DriverObject->DeviceObject; CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
DriverObject->DeviceObject = CreatedDeviceObject; DriverObject->DeviceObject = CreatedDeviceObject;
NtClose(TempHandle);
/* Return to caller */ /* Close the temporary handle and return to caller */
NtClose(TempHandle);
*DeviceObject = CreatedDeviceObject; *DeviceObject = CreatedDeviceObject;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }