- Same sort of changes for NtSetVolumeInformationFile.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 2 Jul 2006 22:19:29 +0000 (22:19 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 2 Jul 2006 22:19:29 +0000 (22:19 +0000)
svn path=/trunk/; revision=22788

reactos/ntoskrnl/io/iomgr/iofunc.c

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