mirror of
https://github.com/reactos/reactos.git
synced 2024-08-10 13:17:56 +00:00
- Uber-optimize IopQueryAttributesFile by using the OPEN_PACKET mechanism to query file attributes, instead of doing lots of slow native calls.
- Modify IopParseDevice to detect when OPEN_PACKET optimizations are in use (query or deletion (deletion not yet implemented)) and have some codepaths be slightly different and use DUMMY_FILE_OBJECT. - Implement QueryOnly case in IopParseDevice to handle attribute queries. - Add a missing dereference, and remove an extra DO reference. svn path=/trunk/; revision=22928
This commit is contained in:
parent
8ac94d67d0
commit
6555616bb6
|
@ -38,18 +38,12 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
||||||
IO_SECURITY_CONTEXT SecurityContext;
|
IO_SECURITY_CONTEXT SecurityContext;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
BOOLEAN DirectOpen = FALSE;
|
BOOLEAN DirectOpen = FALSE, OpenCancelled, UseDummyFile;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
BOOLEAN OpenCancelled;
|
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
DPRINT("IopParseDevice:\n"
|
PDUMMY_FILE_OBJECT DummyFileObject;
|
||||||
"DeviceObject : %p\n"
|
PFILE_BASIC_INFORMATION FileBasicInfo;
|
||||||
"RelatedFileObject : %p\n"
|
ULONG ReturnLength;
|
||||||
"CompleteName : %wZ, RemainingName : %wZ\n",
|
|
||||||
ParseObject,
|
|
||||||
Context,
|
|
||||||
CompleteName,
|
|
||||||
RemainingName);
|
|
||||||
|
|
||||||
/* Assume failure */
|
/* Assume failure */
|
||||||
*Object = NULL;
|
*Object = NULL;
|
||||||
|
@ -76,8 +70,13 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
SeSetAccessStateGenericMapping(AccessState,
|
SeSetAccessStateGenericMapping(AccessState,
|
||||||
&IoFileObjectType->TypeInfo.GenericMapping);
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
|
|
||||||
|
/* Check if we can simply use a dummy file */
|
||||||
|
UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
|
||||||
|
|
||||||
/* Check if this is a direct open */
|
/* Check if this is a direct open */
|
||||||
if (!(RemainingName->Length) && !(OpenPacket->RelatedFileObject))
|
if (!(RemainingName->Length) &&
|
||||||
|
!(OpenPacket->RelatedFileObject) &&
|
||||||
|
!(UseDummyFile))
|
||||||
{
|
{
|
||||||
/* Remember this for later */
|
/* Remember this for later */
|
||||||
DirectOpen = TRUE;
|
DirectOpen = TRUE;
|
||||||
|
@ -127,6 +126,9 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we really need to create an object */
|
||||||
|
if (!UseDummyFile)
|
||||||
|
{
|
||||||
/* Create the actual file object */
|
/* Create the actual file object */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -144,15 +146,6 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
(PVOID*)&FileObject);
|
(PVOID*)&FileObject);
|
||||||
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
||||||
|
|
||||||
/* Set the device object and reference it */
|
|
||||||
Status = IopReferenceDeviceObject(DeviceObject);
|
|
||||||
FileObject->DeviceObject = DeviceObject;
|
|
||||||
|
|
||||||
/* Setup the file header */
|
|
||||||
FileObject->Type = IO_TYPE_FILE;
|
|
||||||
FileObject->Size = sizeof(FILE_OBJECT);
|
|
||||||
FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
|
|
||||||
|
|
||||||
/* Check if this is Synch I/O */
|
/* Check if this is Synch I/O */
|
||||||
if (OpenPacket->CreateOptions &
|
if (OpenPacket->CreateOptions &
|
||||||
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
||||||
|
@ -182,7 +175,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
FileObject->Flags |= FO_WRITE_THROUGH;
|
FileObject->Flags |= FO_WRITE_THROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the caller believes the file will be only read sequentially */
|
/* Check if the caller says the file will be only read sequentially */
|
||||||
if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
|
if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
|
||||||
{
|
{
|
||||||
/* Set the correct flag for the FSD to read */
|
/* Set the correct flag for the FSD to read */
|
||||||
|
@ -195,6 +188,24 @@ 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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use the dummy object instead */
|
||||||
|
DummyFileObject = OpenPacket->DummyFileObject;
|
||||||
|
RtlZeroMemory(DummyFileObject, sizeof(DUMMY_FILE_OBJECT));
|
||||||
|
|
||||||
|
/* Set it up */
|
||||||
|
FileObject = (PFILE_OBJECT)&DummyFileObject->ObjectHeader.Body;
|
||||||
|
DummyFileObject->ObjectHeader.Type = IoFileObjectType;
|
||||||
|
DummyFileObject->ObjectHeader.PointerCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the file header */
|
||||||
|
FileObject->Type = IO_TYPE_FILE;
|
||||||
|
FileObject->Size = sizeof(FILE_OBJECT);
|
||||||
|
FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
|
||||||
|
FileObject->DeviceObject = DeviceObject;
|
||||||
|
|
||||||
/* Check if this is a direct device open */
|
/* Check if this is a direct device open */
|
||||||
if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
|
if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
|
||||||
|
@ -315,8 +326,11 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
if (Vpb) IopDereferenceVpb(Vpb);
|
||||||
|
|
||||||
/* Clear the FO */
|
/* Clear the FO and dereference it */
|
||||||
FileObject->DeviceObject = NULL;
|
FileObject->DeviceObject = NULL;
|
||||||
|
if (!UseDummyFile) ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
|
/* Fail */
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +338,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
/* Copy the name */
|
/* Copy the name */
|
||||||
RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
|
RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
|
||||||
|
|
||||||
/* Reference the file object and call the driver */
|
/* Reference the file object */
|
||||||
ObReferenceObject(FileObject);
|
ObReferenceObject(FileObject);
|
||||||
|
|
||||||
/* Initialize the File Object event and set the FO */
|
/* Initialize the File Object event and set the FO */
|
||||||
|
@ -402,7 +416,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
OpenPacket->FileObject = NULL;
|
OpenPacket->FileObject = NULL;
|
||||||
|
|
||||||
/* Dereference the file object */
|
/* Dereference the file object */
|
||||||
ObDereferenceObject(FileObject);
|
if (!UseDummyFile) ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Unless the driver canelled the open, dereference the VPB */
|
/* Unless the driver canelled the open, dereference the VPB */
|
||||||
if (!(OpenCancelled) && (Vpb)) IopDereferenceVpb(Vpb);
|
if (!(OpenCancelled) && (Vpb)) IopDereferenceVpb(Vpb);
|
||||||
|
@ -417,14 +431,77 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, we were successful. Reference the object, set status */
|
/* Make sure we are not using a dummy */
|
||||||
|
if (!UseDummyFile)
|
||||||
|
{
|
||||||
|
/* Reference the object and set the parse check */
|
||||||
ObReferenceObject(FileObject);
|
ObReferenceObject(FileObject);
|
||||||
|
*Object = FileObject;
|
||||||
OpenPacket->FinalStatus = IoStatusBlock.Status;
|
OpenPacket->FinalStatus = IoStatusBlock.Status;
|
||||||
OpenPacket->ParseCheck = TRUE;
|
OpenPacket->ParseCheck = TRUE;
|
||||||
|
|
||||||
/* Return the object and status */
|
|
||||||
*Object = FileObject;
|
|
||||||
return OpenPacket->FinalStatus;
|
return OpenPacket->FinalStatus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if this was a query */
|
||||||
|
if (OpenPacket->QueryOnly)
|
||||||
|
{
|
||||||
|
/* Check if the caller wants basic info only */
|
||||||
|
if (!OpenPacket->FullAttributes)
|
||||||
|
{
|
||||||
|
/* Allocate the buffer */
|
||||||
|
FileBasicInfo = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(*FileBasicInfo),
|
||||||
|
TAG_IO);
|
||||||
|
if (FileBasicInfo)
|
||||||
|
{
|
||||||
|
/* Do the query */
|
||||||
|
Status = IoQueryFileInformation(FileObject,
|
||||||
|
FileBasicInformation,
|
||||||
|
sizeof(*FileBasicInfo),
|
||||||
|
FileBasicInfo,
|
||||||
|
&ReturnLength);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Copy the data */
|
||||||
|
RtlCopyMemory(OpenPacket->BasicInformation,
|
||||||
|
FileBasicInfo,
|
||||||
|
ReturnLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free our buffer */
|
||||||
|
ExFreePool(FileBasicInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is a full query */
|
||||||
|
Status = IoQueryFileInformation(
|
||||||
|
FileObject,
|
||||||
|
FileNetworkOpenInformation,
|
||||||
|
sizeof(FILE_NETWORK_OPEN_INFORMATION),
|
||||||
|
OpenPacket->NetworkInformation,
|
||||||
|
&ReturnLength);
|
||||||
|
if (!NT_SUCCESS(Status)) ASSERT(Status != STATUS_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete the file object */
|
||||||
|
IopDeleteFile(FileObject);
|
||||||
|
|
||||||
|
/* Clear out the file */
|
||||||
|
OpenPacket->FileObject = NULL;
|
||||||
|
|
||||||
|
/* Set and return status */
|
||||||
|
OpenPacket->FinalStatus = Status;
|
||||||
|
OpenPacket->ParseCheck = TRUE;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -957,112 +1034,119 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||||
|
IN ULONG FileInformationSize,
|
||||||
OUT PVOID FileInformation)
|
OUT PVOID FileInformation)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
HANDLE FileHandle;
|
KPROCESSOR_MODE AccessMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status;
|
DUMMY_FILE_OBJECT DummyFileObject;
|
||||||
KPROCESSOR_MODE AccessMode;
|
FILE_NETWORK_OPEN_INFORMATION NetworkOpenInfo;
|
||||||
UNICODE_STRING ObjectName;
|
HANDLE Handle;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OPEN_PACKET OpenPacket;
|
||||||
OBJECT_ATTRIBUTES LocalObjectAttributes;
|
BOOLEAN IsBasic;
|
||||||
ULONG BufferSize;
|
PAGED_CODE();
|
||||||
union
|
|
||||||
{
|
|
||||||
FILE_BASIC_INFORMATION BasicInformation;
|
|
||||||
FILE_NETWORK_OPEN_INFORMATION NetworkOpenInformation;
|
|
||||||
}LocalFileInformation;
|
|
||||||
|
|
||||||
if (FileInformationClass == FileBasicInformation)
|
/* Check if the caller was user mode */
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
{
|
{
|
||||||
BufferSize = sizeof(FILE_BASIC_INFORMATION);
|
/* Protect probe in SEH */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the buffer */
|
||||||
|
ProbeForWrite(FileInformation, FileInformationSize, sizeof(ULONG));
|
||||||
}
|
}
|
||||||
else if (FileInformationClass == FileNetworkOpenInformation)
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
BufferSize = sizeof(FILE_NETWORK_OPEN_INFORMATION);
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if (!NT_SUCCESS(Status))return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is a basic or full request */
|
||||||
|
IsBasic = (FileInformationSize == sizeof(FILE_BASIC_INFORMATION));
|
||||||
|
|
||||||
|
/* Setup the Open Packet */
|
||||||
|
OpenPacket.Type = IO_TYPE_OPEN_PACKET;
|
||||||
|
OpenPacket.Size = sizeof(OPEN_PACKET);
|
||||||
|
OpenPacket.FileObject = NULL;
|
||||||
|
OpenPacket.FinalStatus = STATUS_SUCCESS;
|
||||||
|
OpenPacket.Information = 0;
|
||||||
|
OpenPacket.ParseCheck = 0;
|
||||||
|
OpenPacket.RelatedFileObject = NULL;
|
||||||
|
OpenPacket.AllocationSize.QuadPart = 0;
|
||||||
|
OpenPacket.CreateOptions = FILE_OPEN_REPARSE_POINT;
|
||||||
|
OpenPacket.FileAttributes = 0;
|
||||||
|
OpenPacket.ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||||
|
OpenPacket.EaBuffer = NULL;
|
||||||
|
OpenPacket.EaLength = 0;
|
||||||
|
OpenPacket.Options = 0;
|
||||||
|
OpenPacket.Disposition = FILE_OPEN;
|
||||||
|
OpenPacket.BasicInformation = IsBasic ? FileInformation : NULL;
|
||||||
|
OpenPacket.NetworkInformation = IsBasic ? &NetworkOpenInfo :
|
||||||
|
(AccessMode != KernelMode) ?
|
||||||
|
&NetworkOpenInfo : FileInformation;
|
||||||
|
OpenPacket.CreateFileType = 0;
|
||||||
|
OpenPacket.MailslotOrPipeParameters = NULL;
|
||||||
|
OpenPacket.Override = FALSE;
|
||||||
|
OpenPacket.QueryOnly = TRUE;
|
||||||
|
OpenPacket.DeleteOnly = FALSE;
|
||||||
|
OpenPacket.FullAttributes = IsBasic ? FALSE : TRUE;
|
||||||
|
OpenPacket.DummyFileObject = &DummyFileObject;
|
||||||
|
OpenPacket.InternalFlags = 0;
|
||||||
|
|
||||||
|
/* Update the operation count */
|
||||||
|
IopUpdateOperationCount(IopOtherTransfer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt opening the file. This will call the I/O Parse Routine for
|
||||||
|
* the File Object (IopParseDevice) which will use the dummy file obejct
|
||||||
|
* send the IRP to its device object. Note that we have two statuses
|
||||||
|
* to worry about: the Object Manager's status (in Status) and the I/O
|
||||||
|
* status, which is in the Open Packet's Final Status, and determined
|
||||||
|
* by the Parse Check member.
|
||||||
|
*/
|
||||||
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
AccessMode,
|
||||||
|
NULL,
|
||||||
|
FILE_READ_ATTRIBUTES,
|
||||||
|
&OpenPacket,
|
||||||
|
&Handle);
|
||||||
|
if (OpenPacket.ParseCheck != TRUE)
|
||||||
|
{
|
||||||
|
/* Parse failed */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_PARAMETER;
|
/* Use the Io status */
|
||||||
|
Status = OpenPacket.FinalStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessMode = ExGetPreviousMode();
|
/* Check if we were succesful and this was user mode and a full query */
|
||||||
|
if ((NT_SUCCESS(Status)) && (AccessMode != KernelMode) && !(IsBasic))
|
||||||
if (AccessMode != KernelMode)
|
|
||||||
{
|
{
|
||||||
Status = STATUS_SUCCESS;
|
/* Enter SEH for copy */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
ProbeForWrite(FileInformation,
|
/* Copy the buffer back */
|
||||||
BufferSize,
|
RtlMoveMemory(FileInformation,
|
||||||
sizeof(ULONG));
|
&NetworkOpenInfo,
|
||||||
}
|
FileInformationSize);
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
|
||||||
AccessMode,
|
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
|
||||||
&ObjectName);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
InitializeObjectAttributes(&LocalObjectAttributes,
|
|
||||||
&ObjectName,
|
|
||||||
ObjectCreateInfo.Attributes,
|
|
||||||
ObjectCreateInfo.RootDirectory,
|
|
||||||
ObjectCreateInfo.SecurityDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file */
|
|
||||||
Status = ZwOpenFile(&FileHandle,
|
|
||||||
SYNCHRONIZE | FILE_READ_ATTRIBUTES,
|
|
||||||
AccessMode == KernelMode ? ObjectAttributes : &LocalObjectAttributes,
|
|
||||||
&IoStatusBlock,
|
|
||||||
0,
|
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
|
||||||
if (AccessMode != KernelMode)
|
|
||||||
{
|
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS (Status))
|
|
||||||
{
|
|
||||||
DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get file attributes */
|
|
||||||
Status = ZwQueryInformationFile(FileHandle,
|
|
||||||
&IoStatusBlock,
|
|
||||||
AccessMode == KernelMode ? FileInformation : &LocalFileInformation,
|
|
||||||
BufferSize,
|
|
||||||
FileInformationClass);
|
|
||||||
if (!NT_SUCCESS (Status))
|
|
||||||
{
|
|
||||||
DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
|
|
||||||
}
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status) && AccessMode != KernelMode)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
memcpy(FileInformation, &LocalFileInformation, BufferSize);
|
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
/* Get exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1228,6 +1312,9 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
OpenPacket.DummyFileObject = NULL;
|
OpenPacket.DummyFileObject = NULL;
|
||||||
OpenPacket.InternalFlags = 0;
|
OpenPacket.InternalFlags = 0;
|
||||||
|
|
||||||
|
/* Update the operation count */
|
||||||
|
IopUpdateOperationCount(IopOtherTransfer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt opening the file. This will call the I/O Parse Routine for
|
* Attempt opening the file. This will call the I/O Parse Routine for
|
||||||
* the File Object (IopParseDevice) which will create the object and
|
* the File Object (IopParseDevice) which will create the object and
|
||||||
|
@ -1386,7 +1473,7 @@ IoCreateStreamFileObject(IN PFILE_OBJECT FileObject,
|
||||||
sizeof(FILE_OBJECT),
|
sizeof(FILE_OBJECT),
|
||||||
0,
|
0,
|
||||||
(PVOID*)&CreatedFileObject);
|
(PVOID*)&CreatedFileObject);
|
||||||
if (!NT_SUCCESS(Status)) return (NULL);
|
if (!NT_SUCCESS(Status)) return NULL;
|
||||||
|
|
||||||
/* Choose Device Object */
|
/* Choose Device Object */
|
||||||
if (FileObject) DeviceObject = FileObject->DeviceObject;
|
if (FileObject) DeviceObject = FileObject->DeviceObject;
|
||||||
|
@ -1764,8 +1851,10 @@ STDCALL
|
||||||
NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
OUT PFILE_BASIC_INFORMATION FileInformation)
|
OUT PFILE_BASIC_INFORMATION FileInformation)
|
||||||
{
|
{
|
||||||
|
/* Call the internal helper API */
|
||||||
return IopQueryAttributesFile(ObjectAttributes,
|
return IopQueryAttributesFile(ObjectAttributes,
|
||||||
FileBasicInformation,
|
FileBasicInformation,
|
||||||
|
sizeof(FILE_BASIC_INFORMATION),
|
||||||
FileInformation);
|
FileInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,8 +1863,10 @@ STDCALL
|
||||||
NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
|
OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
|
||||||
{
|
{
|
||||||
|
/* Call the internal helper API */
|
||||||
return IopQueryAttributesFile(ObjectAttributes,
|
return IopQueryAttributesFile(ObjectAttributes,
|
||||||
FileNetworkOpenInformation,
|
FileNetworkOpenInformation,
|
||||||
|
sizeof(FILE_NETWORK_OPEN_INFORMATION),
|
||||||
FileInformation);
|
FileInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue