mirror of
https://github.com/reactos/reactos.git
synced 2025-07-06 07:41:27 +00:00
- 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:
parent
7a5dbe8152
commit
ff6b13eb13
1 changed files with 55 additions and 77 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue