- Finally fix IoCreateStreamFileObject. I had fixed it a long time ago but back then it was causing regressions. It now properly creates a handle for the FO and sets the right flags.

svn path=/trunk/; revision=22854
This commit is contained in:
Alex Ionescu 2006-07-05 00:17:34 +00:00
parent ef41fc2623
commit b450016579

View file

@ -24,7 +24,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength); PULONG BufferLength);
/* INTERNAL FUNCTIONS ********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -619,6 +619,118 @@ IopCloseFile(IN PEPROCESS Process OPTIONAL,
IoFreeIrp(Irp); IoFreeIrp(Irp);
} }
NTSTATUS
NTAPI
IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN FILE_INFORMATION_CLASS FileInformationClass,
OUT PVOID FileInformation)
{
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
NTSTATUS Status;
KPROCESSOR_MODE AccessMode;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
OBJECT_ATTRIBUTES LocalObjectAttributes;
ULONG BufferSize;
union
{
FILE_BASIC_INFORMATION BasicInformation;
FILE_NETWORK_OPEN_INFORMATION NetworkOpenInformation;
}LocalFileInformation;
if (FileInformationClass == FileBasicInformation)
{
BufferSize = sizeof(FILE_BASIC_INFORMATION);
}
else if (FileInformationClass == FileNetworkOpenInformation)
{
BufferSize = sizeof(FILE_NETWORK_OPEN_INFORMATION);
}
else
{
return STATUS_INVALID_PARAMETER;
}
AccessMode = ExGetPreviousMode();
if (AccessMode != KernelMode)
{
Status = STATUS_SUCCESS;
_SEH_TRY
{
ProbeForWrite(FileInformation,
BufferSize,
sizeof(ULONG));
}
_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
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status;
}
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -1022,41 +1134,16 @@ IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle,
} }
/* /*
* NAME EXPORTED
* IoCreateStreamFileObject@8
*
* DESCRIPTION
*
* ARGUMENTS
* FileObject
* ?
*
* DeviceObject
* ?
*
* RETURN VALUE
*
* NOTE
*
* REVISIONS
*
* @implemented * @implemented
*/ */
PFILE_OBJECT PFILE_OBJECT
STDCALL NTAPI
IoCreateStreamFileObject(PFILE_OBJECT FileObject, IoCreateStreamFileObject(IN PFILE_OBJECT FileObject,
PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
PFILE_OBJECT CreatedFileObject; PFILE_OBJECT CreatedFileObject;
NTSTATUS Status; NTSTATUS Status;
HANDLE FileHandle;
/* FIXME: This function should call ObInsertObject. The "Lite" version
doesnt. This function is also called from IoCreateFile for some
reason. These hacks need to be removed.
*/
DPRINT("IoCreateStreamFileObject(FileObject 0x%p, DeviceObject 0x%p)\n",
FileObject, DeviceObject);
PAGED_CODE(); PAGED_CODE();
/* Create the File Object */ /* Create the File Object */
@ -1066,33 +1153,35 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
KernelMode, KernelMode,
NULL, NULL,
sizeof(FILE_OBJECT), sizeof(FILE_OBJECT),
0, sizeof(FILE_OBJECT),
0, 0,
(PVOID*)&CreatedFileObject); (PVOID*)&CreatedFileObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return (NULL);
{
DPRINT1("Could not create FileObject\n");
return (NULL);
}
/* Choose Device Object */ /* Choose Device Object */
if (FileObject) DeviceObject = FileObject->DeviceObject; if (FileObject) DeviceObject = FileObject->DeviceObject;
DPRINT("DeviceObject 0x%p\n", DeviceObject);
/* HACK */
DeviceObject = IoGetAttachedDevice(DeviceObject);
/* Set File Object Data */ /* Set File Object Data */
RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
CreatedFileObject->DeviceObject = DeviceObject; CreatedFileObject->DeviceObject = DeviceObject;
CreatedFileObject->Vpb = DeviceObject->Vpb;
CreatedFileObject->Type = IO_TYPE_FILE; CreatedFileObject->Type = IO_TYPE_FILE;
CreatedFileObject->Flags |= FO_STREAM_FILE; CreatedFileObject->Size = sizeof(FILE_OBJECT);
CreatedFileObject->Flags = FO_STREAM_FILE;
/* Initialize Lock and Event */ /* Initialize the wait event */
KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE); KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
KeInitializeEvent(&CreatedFileObject->Lock, SynchronizationEvent, TRUE);
/* Return file */ /* Insert it to create a handle for it */
Status = ObInsertObject(CreatedFileObject,
NULL,
FILE_READ_DATA,
1,
(PVOID*)&CreatedFileObject,
&FileHandle);
CreatedFileObject->Flags |= FO_HANDLE_CREATED;
/* Close the extra handle and return file */
NtClose(FileHandle);
return CreatedFileObject; return CreatedFileObject;
} }
@ -1440,118 +1529,6 @@ NtOpenFile(PHANDLE FileHandle,
0); 0);
} }
NTSTATUS
IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN FILE_INFORMATION_CLASS FileInformationClass,
OUT PVOID FileInformation)
{
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
NTSTATUS Status;
KPROCESSOR_MODE AccessMode;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
OBJECT_ATTRIBUTES LocalObjectAttributes;
ULONG BufferSize;
union
{
FILE_BASIC_INFORMATION BasicInformation;
FILE_NETWORK_OPEN_INFORMATION NetworkOpenInformation;
}LocalFileInformation;
if (FileInformationClass == FileBasicInformation)
{
BufferSize = sizeof(FILE_BASIC_INFORMATION);
}
else if (FileInformationClass == FileNetworkOpenInformation)
{
BufferSize = sizeof(FILE_NETWORK_OPEN_INFORMATION);
}
else
{
return STATUS_INVALID_PARAMETER;
}
AccessMode = ExGetPreviousMode();
if (AccessMode != KernelMode)
{
Status = STATUS_SUCCESS;
_SEH_TRY
{
ProbeForWrite(FileInformation,
BufferSize,
sizeof(ULONG));
}
_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
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status;
}
NTSTATUS NTSTATUS
STDCALL STDCALL
NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,