- Implement IoCreateFileSpecifyDeviceObjectHint - will be needed for fltmgr
- Rename IoCreateFile to IopCreateFile and forward both IoCreateFile and IoCreateFileSpecifyDeviceObjectHint to that routine
- Add support to IopParseDevice to check for a top level device hint and use that instead of the real device.
- Create a file object extension in IopParseDevice and use that to store our top level device hint data
- Update IoGetRelatedDeviceObject to check for file object extensions and return the 'fake' top level device if we have one

svn path=/trunk/; revision=71862
This commit is contained in:
Ged Murphy 2016-07-08 13:18:39 +00:00
parent 5095fb9b9e
commit 7a8d83b7ea
3 changed files with 182 additions and 56 deletions

View file

@ -85,6 +85,21 @@
// //
#define IOP_MAX_REPARSE_TRAVERSAL 0x20 #define IOP_MAX_REPARSE_TRAVERSAL 0x20
//
// Private flags for IoCreateFile / IoParseDevice
//
#define IOP_USE_TOP_LEVEL_DEVICE_HINT 0x01
#define IOP_CREATE_FILE_OBJECT_EXTENSION 0x02
typedef struct _FILE_OBJECT_EXTENSION
{
PDEVICE_OBJECT TopDeviceObjectHint;
} FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION;
// //
// We can call the Ob Inlined API, it's the same thing // We can call the Ob Inlined API, it's the same thing
// //

View file

@ -1349,9 +1349,18 @@ IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
/* Check if the extension is really present */ /* Check if the extension is really present */
if (FileObject->FileObjectExtension) if (FileObject->FileObjectExtension)
{ {
/* FIXME: Unhandled yet */ PFILE_OBJECT_EXTENSION FileObjectExtension;
DPRINT1("FOEs not supported\n");
ASSERT(FALSE); ASSERT(FALSE);
/* The extension buffer comes directly after the file object */
FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
/* Check if have a replacement top level device */
if (FileObjectExtension->TopDeviceObjectHint)
{
/* Use this instead of returning the top level device */
return FileObjectExtension->TopDeviceObjectHint;
}
} }
} }

View file

@ -586,13 +586,16 @@ IopParseDevice(IN PVOID ParseObject,
/* Reference it */ /* Reference it */
InterlockedIncrement((PLONG)&Vpb->ReferenceCount); InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
/* Check if we were given a specific top level device to use */
if (OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT)
{
DeviceObject = Vpb->DeviceObject;
}
} }
} }
else else
{ {
/* The device object is the one we were given */
DeviceObject = OriginalDeviceObject;
/* Check if it has a VPB */ /* Check if it has a VPB */
if ((OriginalDeviceObject->Vpb) && !(DirectOpen)) if ((OriginalDeviceObject->Vpb) && !(DirectOpen))
{ {
@ -606,15 +609,27 @@ IopParseDevice(IN PVOID ParseObject,
/* Get the VPB's device object */ /* Get the VPB's device object */
DeviceObject = Vpb->DeviceObject; DeviceObject = Vpb->DeviceObject;
} }
else
{
/* The device object is the one we were given */
DeviceObject = OriginalDeviceObject;
}
/* Check if there's an attached device */ /* If we weren't given a specific top level device, look for an attached device */
if (DeviceObject->AttachedDevice) if (!(OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT) &&
DeviceObject->AttachedDevice)
{ {
/* Get the attached device */ /* Get the attached device */
DeviceObject = IoGetAttachedDevice(DeviceObject); DeviceObject = IoGetAttachedDevice(DeviceObject);
} }
} }
if (OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT)
{
// FIXME: Verify our device object is good to use
ASSERT(DirectOpen == FALSE);
}
/* If we traversed a mount point, reset the information */ /* If we traversed a mount point, reset the information */
if (OpenPacket->TraversedMountPoint) if (OpenPacket->TraversedMountPoint)
{ {
@ -706,6 +721,12 @@ IopParseDevice(IN PVOID ParseObject,
/* Check if we really need to create an object */ /* Check if we really need to create an object */
if (!UseDummyFile) if (!UseDummyFile)
{ {
ULONG ObjectSize = sizeof(FILE_OBJECT);
/* Tag on space for a file object extension */
if (OpenPacket->InternalFlags & IOP_CREATE_FILE_OBJECT_EXTENSION)
ObjectSize += sizeof(FILE_OBJECT_EXTENSION);
/* Create the actual file object */ /* Create the actual file object */
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
NULL, NULL,
@ -717,7 +738,7 @@ IopParseDevice(IN PVOID ParseObject,
&ObjectAttributes, &ObjectAttributes,
AccessMode, AccessMode,
NULL, NULL,
sizeof(FILE_OBJECT), ObjectSize,
0, 0,
0, 0,
(PVOID*)&FileObject); (PVOID*)&FileObject);
@ -787,6 +808,23 @@ IopParseDevice(IN PVOID ParseObject,
/* Set the correct flag for the FSD to read */ /* Set the correct flag for the FSD to read */
FileObject->Flags |= FO_RANDOM_ACCESS; FileObject->Flags |= FO_RANDOM_ACCESS;
} }
/* Check if we were asked to setup a file object extension */
if (OpenPacket->InternalFlags & IOP_CREATE_FILE_OBJECT_EXTENSION)
{
PFILE_OBJECT_EXTENSION FileObjectExtension;
/* Make sure the file object knows it has an extension */
FileObject->Flags |= FO_FILE_OBJECT_HAS_EXTENSION;
FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
/* Add the top level device which we'll send the request to */
if (OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT)
{
FileObjectExtension->TopDeviceObjectHint = DeviceObject;
}
}
} }
else else
{ {
@ -2116,53 +2154,24 @@ IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject,
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
/* FUNCTIONS *****************************************************************/
/*
* @unimplemented
*/
NTSTATUS NTSTATUS
NTAPI NTAPI
IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass, IopCreateFile(OUT PHANDLE FileHandle,
IN ULONG Length, IN ACCESS_MASK DesiredAccess,
IN BOOLEAN SetOperation) IN POBJECT_ATTRIBUTES ObjectAttributes,
{ OUT PIO_STATUS_BLOCK IoStatusBlock,
UNIMPLEMENTED; IN PLARGE_INTEGER AllocationSize OPTIONAL,
return STATUS_NOT_IMPLEMENTED; IN ULONG FileAttributes,
} IN ULONG ShareAccess,
IN ULONG Disposition,
/* IN ULONG CreateOptions,
* @unimplemented IN PVOID EaBuffer OPTIONAL,
*/ IN ULONG EaLength,
NTSTATUS IN CREATE_FILE_TYPE CreateFileType,
NTAPI IN PVOID ExtraCreateParameters OPTIONAL,
IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, IN ULONG Options,
IN ULONG QuotaLength, IN ULONG Flags,
OUT PULONG ErrorOffset) IN PDEVICE_OBJECT DeviceObject OPTIONAL)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IoCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG Disposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options)
{ {
KPROCESSOR_MODE AccessMode; KPROCESSOR_MODE AccessMode;
HANDLE LocalHandle = 0; HANDLE LocalHandle = 0;
@ -2171,7 +2180,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters; PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters;
POPEN_PACKET OpenPacket; POPEN_PACKET OpenPacket;
ULONG EaErrorOffset; ULONG EaErrorOffset;
PAGED_CODE();
IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName); IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
@ -2451,6 +2460,8 @@ IoCreateFile(OUT PHANDLE FileHandle,
OpenPacket->Disposition = Disposition; OpenPacket->Disposition = Disposition;
OpenPacket->CreateFileType = CreateFileType; OpenPacket->CreateFileType = CreateFileType;
OpenPacket->ExtraCreateParameters = ExtraCreateParameters; OpenPacket->ExtraCreateParameters = ExtraCreateParameters;
OpenPacket->InternalFlags = Flags;
OpenPacket->TopDeviceObjectHint = DeviceObject;
/* Update the operation count */ /* Update the operation count */
IopUpdateOperationCount(IopOtherTransfer); IopUpdateOperationCount(IopOtherTransfer);
@ -2567,6 +2578,74 @@ IoCreateFile(OUT PHANDLE FileHandle,
return Status; return Status;
} }
/* FUNCTIONS *****************************************************************/
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass,
IN ULONG Length,
IN BOOLEAN SetOperation)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer,
IN ULONG QuotaLength,
OUT PULONG ErrorOffset)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IoCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG Disposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options)
{
PAGED_CODE();
return IopCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
Disposition,
CreateOptions,
EaBuffer,
EaLength,
CreateFileType,
ExtraCreateParameters,
Options,
0,
NULL);
}
/* /*
* @unimplemented * @unimplemented
*/ */
@ -2588,8 +2667,31 @@ IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle,
IN ULONG Options, IN ULONG Options,
IN PVOID DeviceObject) IN PVOID DeviceObject)
{ {
UNIMPLEMENTED; ULONG Flags = 0;
return STATUS_NOT_IMPLEMENTED;
/* Check if we were passed a device to send the create request to*/
if (DeviceObject)
{
/* We'll tag this request into a file object extension */
Flags = (IOP_CREATE_FILE_OBJECT_EXTENSION | IOP_USE_TOP_LEVEL_DEVICE_HINT);
}
return IopCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
Disposition,
CreateOptions,
EaBuffer,
EaLength,
CreateFileType,
ExtraCreateParameters,
Options | IO_NO_PARAMETER_CHECKING,
Flags,
DeviceObject);
} }
/* /*