mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
IoCreateDevice Changes:
- IoAllocateVpb renamed to IopAllocateVpb and made cleaner - Let ObCreateObject do all the memory allocation since the extra data belongs to the object and it should be responsible for allocating it. No more extra pool allocations or deallocations. - Zero out everythign a single time. - Remove useless code duplication - Use proper I/O Manager types for the object headers. - Honour Exclusive Flag, and Has Name Flag. - Only initialize event if there is a volume. - Initialize a VPB for Virtual Disks also. - Set up Device Object Extension properly - Set DO_DEVICE_INITIALIZING flag. - Use proper sector sizes, don't hardcode 512 (should be 2048 for cds) - Actually insert the object into the object table with ObInsertObject. This might seem useless, but remember that's simply because ROS has a broken Ob Manager which does way too much in ObCreateObject. It will be easier to use the rewrite if this is done properly. - Set the right sizes in some places. svn path=/trunk/; revision=14643
This commit is contained in:
parent
f4c3dd909b
commit
24b6532712
4 changed files with 189 additions and 174 deletions
|
@ -892,8 +892,19 @@ struct _FAST_IO_DISPATCH_TABLE
|
||||||
} FAST_IO_DISPATCH_TABLE, * PFAST_IO_DISPATCH_TABLE;
|
} FAST_IO_DISPATCH_TABLE, * PFAST_IO_DISPATCH_TABLE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IO_TYPE_DRIVER 4L
|
#define IO_TYPE_ADAPTER 0x1L
|
||||||
#define IO_TYPE_FILE 0x0F5L
|
#define IO_TYPE_CONTROLLER 0x2L
|
||||||
|
#define IO_TYPE_DEVICE 0x3L
|
||||||
|
#define IO_TYPE_DRIVER 0x4L
|
||||||
|
#define IO_TYPE_FILE 0x0F5L /* Temp Hack */
|
||||||
|
#define IO_TYPE_IRP 0x6L
|
||||||
|
#define IO_TYPE_MASTER_ADAPTER 0x7L
|
||||||
|
#define IO_TYPE_OPEN_PACKET 0x8L
|
||||||
|
#define IO_TYPE_TIMER 0x9L
|
||||||
|
#define IO_TYPE_VPB 0xaL
|
||||||
|
#define IO_TYPE_ERROR_LOG 0xbL
|
||||||
|
#define IO_TYPE_ERROR_MESSAGE 0xcL
|
||||||
|
#define IO_TYPE_DEVICE_OBJECT_EXTENSION 0xdL
|
||||||
|
|
||||||
#define DRVO_UNLOAD_INVOKED 0x1L
|
#define DRVO_UNLOAD_INVOKED 0x1L
|
||||||
#define DRVO_LEGACY_DRIVER 0x2L
|
#define DRVO_LEGACY_DRIVER 0x2L
|
||||||
|
@ -959,7 +970,6 @@ typedef VOID STDCALL_FUNC
|
||||||
/*
|
/*
|
||||||
* PURPOSE: Special timer associated with each device
|
* PURPOSE: Special timer associated with each device
|
||||||
*/
|
*/
|
||||||
#define IO_TYPE_TIMER 9
|
|
||||||
typedef struct _IO_TIMER {
|
typedef struct _IO_TIMER {
|
||||||
USHORT Type; /* Every IO Object has a Type */
|
USHORT Type; /* Every IO Object has a Type */
|
||||||
USHORT TimerEnabled; /* Tells us if the Timer is enabled or not */
|
USHORT TimerEnabled; /* Tells us if the Timer is enabled or not */
|
||||||
|
|
|
@ -370,7 +370,10 @@ IopCreateDevice(PVOID ObjectBody,
|
||||||
PVOID Parent,
|
PVOID Parent,
|
||||||
PWSTR RemainingPath,
|
PWSTR RemainingPath,
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes);
|
POBJECT_ATTRIBUTES ObjectAttributes);
|
||||||
NTSTATUS IoAttachVpb(PDEVICE_OBJECT DeviceObject);
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
IopAttachVpb(PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
|
PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
|
@ -307,7 +307,6 @@ IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,
|
||||||
SourceDeviceExtension = SourceDevice->DeviceObjectExtension;
|
SourceDeviceExtension = SourceDevice->DeviceObjectExtension;
|
||||||
|
|
||||||
/* Make sure that it's in a correct state */
|
/* Make sure that it's in a correct state */
|
||||||
DPRINT1("flags %d\n", AttachedDevice->DeviceObjectExtension->ExtensionFlags);
|
|
||||||
if (!(AttachedDevice->DeviceObjectExtension->ExtensionFlags &
|
if (!(AttachedDevice->DeviceObjectExtension->ExtensionFlags &
|
||||||
(DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |
|
(DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |
|
||||||
DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED)))
|
DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED)))
|
||||||
|
@ -355,10 +354,6 @@ IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
|
||||||
ExFreePool(DeviceObject->Timer);
|
ExFreePool(DeviceObject->Timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free device extension */
|
|
||||||
if (DeviceObject->DeviceObjectExtension)
|
|
||||||
ExFreePool(DeviceObject->DeviceObjectExtension);
|
|
||||||
|
|
||||||
/* Remove device from driver device list */
|
/* Remove device from driver device list */
|
||||||
Previous = DeviceObject->DriverObject->DeviceObject;
|
Previous = DeviceObject->DriverObject->DeviceObject;
|
||||||
if (Previous == DeviceObject)
|
if (Previous == DeviceObject)
|
||||||
|
@ -652,157 +647,169 @@ IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
|
||||||
* Status
|
* Status
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
IoCreateDevice(
|
STDCALL
|
||||||
PDRIVER_OBJECT DriverObject,
|
IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
||||||
ULONG DeviceExtensionSize,
|
ULONG DeviceExtensionSize,
|
||||||
PUNICODE_STRING DeviceName,
|
PUNICODE_STRING DeviceName,
|
||||||
DEVICE_TYPE DeviceType,
|
DEVICE_TYPE DeviceType,
|
||||||
ULONG DeviceCharacteristics,
|
ULONG DeviceCharacteristics,
|
||||||
BOOLEAN Exclusive,
|
BOOLEAN Exclusive,
|
||||||
PDEVICE_OBJECT *DeviceObject)
|
PDEVICE_OBJECT *DeviceObject)
|
||||||
{
|
{
|
||||||
WCHAR AutoNameBuffer[20];
|
WCHAR AutoNameBuffer[20];
|
||||||
UNICODE_STRING AutoName;
|
UNICODE_STRING AutoName;
|
||||||
PDEVICE_OBJECT CreatedDeviceObject;
|
PDEVICE_OBJECT CreatedDeviceObject;
|
||||||
PDEVOBJ_EXTENSION DeviceObjectExtension;
|
PDEVOBJ_EXTENSION DeviceObjectExtension;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG AlignedDeviceExtensionSize;
|
||||||
|
ULONG TotalSize;
|
||||||
|
HANDLE TempHandle;
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||||
|
DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject);
|
||||||
|
|
||||||
if (DeviceName != NULL)
|
/* Generate a name if we have to */
|
||||||
{
|
if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)
|
||||||
DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",
|
{
|
||||||
DriverObject, DeviceName->Buffer);
|
swprintf(AutoNameBuffer,
|
||||||
}
|
L"\\Device\\%08lx",
|
||||||
else
|
InterlockedIncrementUL(&IopDeviceObjectNumber));
|
||||||
{
|
RtlInitUnicodeString(&AutoName, AutoNameBuffer);
|
||||||
DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject);
|
DeviceName = &AutoName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)
|
/* Initialize the Object Attributes */
|
||||||
{
|
InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
|
||||||
swprintf(AutoNameBuffer,
|
|
||||||
L"\\Device\\%08lx",
|
/* Honour exclusive flag */
|
||||||
InterlockedIncrementUL(&IopDeviceObjectNumber));
|
ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
|
||||||
RtlInitUnicodeString(&AutoName,
|
|
||||||
AutoNameBuffer);
|
/* Align the Extension Size to 8-bytes */
|
||||||
DeviceName = &AutoName;
|
AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7;
|
||||||
}
|
DPRINT("AlignedDeviceExtensionSize %x\n", AlignedDeviceExtensionSize);
|
||||||
|
|
||||||
if (DeviceName != NULL)
|
/* Total Size */
|
||||||
{
|
TotalSize = AlignedDeviceExtensionSize +
|
||||||
InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
|
sizeof(DEVICE_OBJECT) + sizeof(DEVOBJ_EXTENSION);
|
||||||
Status = ObCreateObject(
|
DPRINT("TotalSize %x\n", TotalSize);
|
||||||
KernelMode,
|
|
||||||
IoDeviceObjectType,
|
/* Create the Device Object */
|
||||||
&ObjectAttributes,
|
Status = ObCreateObject(KernelMode,
|
||||||
KernelMode,
|
IoDeviceObjectType,
|
||||||
NULL,
|
&ObjectAttributes,
|
||||||
sizeof(DEVICE_OBJECT),
|
KernelMode,
|
||||||
0,
|
NULL,
|
||||||
0,
|
TotalSize,
|
||||||
(PVOID*)&CreatedDeviceObject);
|
0,
|
||||||
}
|
0,
|
||||||
else
|
(PVOID*)&CreatedDeviceObject);
|
||||||
{
|
|
||||||
Status = ObCreateObject(
|
|
||||||
KernelMode,
|
|
||||||
IoDeviceObjectType,
|
|
||||||
NULL,
|
|
||||||
KernelMode,
|
|
||||||
NULL,
|
|
||||||
sizeof(DEVICE_OBJECT),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
(PVOID*)&CreatedDeviceObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
*DeviceObject = NULL;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DriverObject->DeviceObject == NULL)
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DriverObject->DeviceObject = CreatedDeviceObject;
|
DPRINT1("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
|
||||||
CreatedDeviceObject->NextDevice = NULL;
|
return Status;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Clear the whole Object and extension so we don't null stuff manually */
|
||||||
CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
|
RtlZeroMemory(CreatedDeviceObject, TotalSize);
|
||||||
DriverObject->DeviceObject = CreatedDeviceObject;
|
DPRINT("CreatedDeviceObject %x\n", CreatedDeviceObject);
|
||||||
}
|
|
||||||
|
|
||||||
CreatedDeviceObject->Type = DeviceType;
|
/*
|
||||||
CreatedDeviceObject->DriverObject = DriverObject;
|
* Setup the Type and Size. Note that we don't use the aligned size,
|
||||||
CreatedDeviceObject->CurrentIrp = NULL;
|
* because that's only padding for the DevObjExt and not part of the Object.
|
||||||
CreatedDeviceObject->Flags = 0;
|
*/
|
||||||
|
CreatedDeviceObject->Type = IO_TYPE_DEVICE;
|
||||||
CreatedDeviceObject->DeviceExtension =
|
CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize;
|
||||||
ExAllocatePoolWithTag(
|
|
||||||
NonPagedPool,
|
/* The kernel extension is after the driver internal extension */
|
||||||
DeviceExtensionSize,
|
DeviceObjectExtension = (PDEVOBJ_EXTENSION)
|
||||||
TAG_DEVICE_EXTENSION);
|
((ULONG_PTR)(CreatedDeviceObject + 1) +
|
||||||
|
AlignedDeviceExtensionSize);
|
||||||
if (DeviceExtensionSize > 0 && CreatedDeviceObject->DeviceExtension == NULL)
|
|
||||||
{
|
/* Set the Type and Size. Question: why is Size 0 on Windows? */
|
||||||
ExFreePool(CreatedDeviceObject);
|
DPRINT("DeviceObjectExtension %x\n", DeviceObjectExtension);
|
||||||
DPRINT("IoCreateDevice() ExAllocatePoolWithTag failed, returning: 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES);
|
DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
DeviceObjectExtension->Size = 0;
|
||||||
}
|
|
||||||
|
/* Link the Object and Extension */
|
||||||
if (DeviceExtensionSize > 0)
|
DeviceObjectExtension->DeviceObject = CreatedDeviceObject;
|
||||||
{
|
CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension;
|
||||||
RtlZeroMemory(CreatedDeviceObject->DeviceExtension, DeviceExtensionSize);
|
|
||||||
}
|
/* Set Device Object Data */
|
||||||
|
CreatedDeviceObject->DeviceType = DeviceType;
|
||||||
CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize;
|
CreatedDeviceObject->Characteristics = DeviceCharacteristics;
|
||||||
CreatedDeviceObject->ReferenceCount = 1;
|
CreatedDeviceObject->DeviceExtension = CreatedDeviceObject + 1;
|
||||||
CreatedDeviceObject->AttachedDevice = NULL;
|
CreatedDeviceObject->StackSize = 1;
|
||||||
CreatedDeviceObject->DeviceType = DeviceType;
|
CreatedDeviceObject->AlignmentRequirement = 1; /* FIXME */
|
||||||
CreatedDeviceObject->StackSize = 1;
|
|
||||||
CreatedDeviceObject->AlignmentRequirement = 1;
|
/* Set the Flags */
|
||||||
CreatedDeviceObject->Characteristics = DeviceCharacteristics;
|
/* FIXME: After the Driver is Loaded, the flag below should be removed */
|
||||||
CreatedDeviceObject->Timer = NULL;
|
CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING;
|
||||||
CreatedDeviceObject->Vpb = NULL;
|
if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE;
|
||||||
KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
|
if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME;
|
||||||
|
|
||||||
KeInitializeEvent(
|
/* Attach a Vpb for Disks and Tapes, and create the Device Lock */
|
||||||
&CreatedDeviceObject->DeviceLock,
|
if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK ||
|
||||||
SynchronizationEvent,
|
CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK ||
|
||||||
TRUE);
|
CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM ||
|
||||||
|
CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE)
|
||||||
/* FIXME: Do we need to add network drives too?! */
|
{
|
||||||
if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK ||
|
/* Create Vpb */
|
||||||
CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM ||
|
IopAttachVpb(CreatedDeviceObject);
|
||||||
CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE)
|
|
||||||
{
|
/* Initialize Lock Event */
|
||||||
IoAttachVpb(CreatedDeviceObject);
|
KeInitializeEvent(&CreatedDeviceObject->DeviceLock,
|
||||||
}
|
SynchronizationEvent,
|
||||||
CreatedDeviceObject->SectorSize = 512; /* FIXME */
|
TRUE);
|
||||||
|
}
|
||||||
DeviceObjectExtension =
|
|
||||||
ExAllocatePoolWithTag(
|
/* Set the right Sector Size */
|
||||||
NonPagedPool,
|
switch (DeviceType)
|
||||||
sizeof(DEVOBJ_EXTENSION),
|
{
|
||||||
TAG_DEVICE_EXTENSION);
|
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
||||||
|
case FILE_DEVICE_DISK:
|
||||||
|
case FILE_DEVICE_VIRTUAL_DISK:
|
||||||
|
CreatedDeviceObject->SectorSize = 512;
|
||||||
|
break;
|
||||||
|
|
||||||
RtlZeroMemory(DeviceObjectExtension, sizeof(DEVOBJ_EXTENSION));
|
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
|
||||||
DeviceObjectExtension->Type = 0 /* ?? */;
|
CreatedDeviceObject->SectorSize = 2048;
|
||||||
DeviceObjectExtension->Size = sizeof(DEVOBJ_EXTENSION);
|
break;
|
||||||
DeviceObjectExtension->DeviceObject = CreatedDeviceObject;
|
}
|
||||||
DeviceObjectExtension->DeviceNode = NULL;
|
|
||||||
|
/* Create the Device Queue */
|
||||||
|
KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
|
||||||
|
|
||||||
CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension;
|
/* Insert the Object */
|
||||||
|
Status = ObInsertObject(CreatedDeviceObject,
|
||||||
*DeviceObject = CreatedDeviceObject;
|
NULL,
|
||||||
|
FILE_READ_DATA | FILE_WRITE_DATA,
|
||||||
return STATUS_SUCCESS;
|
0,
|
||||||
|
NULL,
|
||||||
|
&TempHandle);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Cannot insert Device Object into Handle Table\n");
|
||||||
|
*DeviceObject = NULL;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do the final linking */
|
||||||
|
ObReferenceObject(DriverObject);
|
||||||
|
CreatedDeviceObject->DriverObject = DriverObject;
|
||||||
|
CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
|
||||||
|
DriverObject->DeviceObject = CreatedDeviceObject;
|
||||||
|
|
||||||
|
/* Close the temporary handle, but do an extra reference first so it doesn't die */
|
||||||
|
ObReferenceObject(CreatedDeviceObject);
|
||||||
|
NtClose(TempHandle);
|
||||||
|
|
||||||
|
/* Return to caller */
|
||||||
|
*DeviceObject = CreatedDeviceObject;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -30,34 +30,29 @@ IoInitVpbImplementation(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
IoAttachVpb(PDEVICE_OBJECT DeviceObject)
|
STDCALL
|
||||||
|
IopAttachVpb(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PVPB Vpb;
|
PVPB Vpb;
|
||||||
|
|
||||||
Vpb = ExAllocatePoolWithTag(NonPagedPool,
|
/* Allocate the Vpb */
|
||||||
sizeof(VPB),
|
Vpb = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
TAG_VPB);
|
sizeof(VPB),
|
||||||
if (Vpb == NULL)
|
TAG_VPB);
|
||||||
{
|
if (Vpb == NULL) return(STATUS_UNSUCCESSFUL);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
/* Clear it so we don't waste time manually */
|
||||||
|
RtlZeroMemory(Vpb, sizeof(VPB));
|
||||||
|
|
||||||
Vpb->Type = 0;
|
/* Set the Header and Device Field */
|
||||||
Vpb->Size = sizeof(VPB) / sizeof(DWORD);
|
Vpb->Type = IO_TYPE_VPB;
|
||||||
Vpb->Flags = 0;
|
Vpb->Size = sizeof(VPB);
|
||||||
Vpb->VolumeLabelLength = 0;
|
Vpb->RealDevice = DeviceObject;
|
||||||
Vpb->DeviceObject = NULL;
|
|
||||||
Vpb->RealDevice = DeviceObject;
|
|
||||||
Vpb->SerialNumber = 0;
|
|
||||||
Vpb->ReferenceCount = 0;
|
|
||||||
RtlZeroMemory(Vpb->VolumeLabel,
|
|
||||||
sizeof(WCHAR) * MAXIMUM_VOLUME_LABEL_LENGTH);
|
|
||||||
|
|
||||||
DeviceObject->Vpb = Vpb;
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* link it to the Device Object */
|
||||||
|
DeviceObject->Vpb = Vpb;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Queries the volume information
|
* FUNCTION: Queries the volume information
|
||||||
|
|
Loading…
Reference in a new issue