Author: ion
Date: Mon Jul 3 02:19:29 2006
New Revision: 22788
URL:
http://svn.reactos.org/svn/reactos?rev=22788&view=rev
Log:
- Same sort of changes for NtSetVolumeInformationFile.
Modified:
trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iofunc.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Mon Jul 3 02:19:29 2006
@@ -25,7 +25,7 @@
//
// TODO:
// - Lock/Unlock <= DONE
-// - Query/Set Volume Info
+// - Query/Set Volume Info <= DONE
// - Read/Write file
// - QuerySet/ File Info
// - NtQueryDirectoryFile
@@ -2649,7 +2649,6 @@
BOOLEAN LocalEvent = FALSE;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
- OBJECT_HANDLE_INFORMATION HandleInformation;
IO_STATUS_BLOCK KernelIosb;
PAGED_CODE();
@@ -2684,7 +2683,7 @@
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
- &HandleInformation);
+ NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Check if we should use Sync IO or not */
@@ -2788,125 +2787,135 @@
IN FS_INFORMATION_CLASS FsInformationClass)
{
PFILE_OBJECT FileObject;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
+ PKEVENT Event = NULL;
+ BOOLEAN LocalEvent = FALSE;
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
- PIO_STACK_LOCATION StackPtr;
- PVOID SystemBuffer;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-
+ IO_STATUS_BLOCK KernelIosb;
+ PAGED_CODE();
+
+ /* Check if we're called from user mode */
if (PreviousMode != KernelMode)
{
+ /* Enter SEH for probing */
_SEH_TRY
{
- if (IoStatusBlock)
- {
- ProbeForWrite(IoStatusBlock,
- sizeof(IO_STATUS_BLOCK),
- sizeof(ULONG));
- }
-
+ /* Probe the I/O Status block */
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+
+ /* Probe the information */
if (Length) ProbeForRead(FsInformation, Length, 1);
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
+ /* Check if probing failed */
if (!NT_SUCCESS(Status)) return Status;
}
+ /* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
- FILE_WRITE_ATTRIBUTES,
- NULL,
+ 0, // FIXME
+ IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
- if (Status != STATUS_SUCCESS) return Status;
-
- DeviceObject = FileObject->DeviceObject;
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
- if (!Irp)
- {
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if we should use Sync IO or not */
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+ {
+ /* Lock it */
+ IopLockFileObject(FileObject);
+ }
+ else
+ {
+ /* Use local event */
+ Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+ KeInitializeEvent(Event, SynchronizationEvent, FALSE);
+ LocalEvent = TRUE;
+ }
+
+ /* Get the device object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ /* Clear File Object event */
+ KeClearEvent(&FileObject->Event);
+
+ /* Allocate the IRP */
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+ if (!Irp) return IopCleanupFailedIrp(FileObject, Event);
+
+ /* Set up the IRP */
+ Irp->RequestorMode = PreviousMode;
+ Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
+ Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
+ Irp->UserEvent = (LocalEvent) ? Event : NULL;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
+ Irp->UserBuffer = FsInformation;
+ Irp->AssociatedIrp.SystemBuffer = NULL;
+ Irp->MdlAddress = NULL;
+
+ /* Set up Stack Data */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
+ StackPtr->FileObject = FileObject;
+
+ /* Allocate system buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ Length,
+ TAG_SYSB);
+ if (!Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* Fail */
+ IoFreeIrp(Irp);
+ if (Event) ObDereferenceObject(Event);
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
- SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_SYSB);
- if (!SystemBuffer)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto failfreeirp;
- }
-
- if (PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- /* no need to probe again */
- RtlCopyMemory(SystemBuffer, FsInformation, Length);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(SystemBuffer, TAG_SYSB);
-failfreeirp:
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return Status;
- }
- }
- else
- {
- RtlCopyMemory(SystemBuffer, FsInformation, Length);
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = PreviousMode;
- Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
- KeResetEvent( &FileObject->Event );
- Irp->UserEvent = &FileObject->Event;
- Irp->UserIosb = IoStatusBlock;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = FileObject;
+ /* Copy the data into the buffer */
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, FsInformation, Length);
+
+ /* Set the flags for this buffered + deferred I/O */
+ Irp->Flags |= (IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
+
+ /* Set Parameters */
StackPtr->Parameters.SetVolume.Length = Length;
- StackPtr->Parameters.SetVolume.FsInformationClass =
- FsInformationClass;
-
- Status = IoCallDriver(DeviceObject,Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event,
- UserRequest,
- PreviousMode,
- FALSE,
- NULL);
- _SEH_TRY
- {
- Status = IoStatusBlock->Status;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
-
- ExFreePool(SystemBuffer);
+ StackPtr->Parameters.SetVolume.FsInformationClass = FsInformationClass;
+
+ /* Call the Driver */
+ Status = IopPerformSynchronousRequest(DeviceObject,
+ Irp,
+ FileObject,
+ TRUE,
+ PreviousMode,
+ !LocalEvent,
+ IopOtherTransfer);
+
+ /* Check if this was async I/O */
+ if (LocalEvent)
+ {
+ /* It was, finalize this request */
+ Status = IopFinalizeAsynchronousIo(Status,
+ Event,
+ Irp,
+ PreviousMode,
+ &KernelIosb,
+ IoStatusBlock);
+ }
+
+ /* Return status */
return Status;
}