[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / io / iomgr / iofunc.c
index a4efbe4..22e8710 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#include <ioevent.h>
 #define NDEBUG
 #include <debug.h>
 #include "internal/io_i.h"
@@ -196,7 +197,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                      IN ULONG OutputBufferLength OPTIONAL,
                      IN BOOLEAN IsDevIoCtl)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PFILE_OBJECT FileObject;
     PDEVICE_OBJECT DeviceObject;
     PIRP Irp;
@@ -258,11 +259,10 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Don't check for access rights right now, KernelMode can do anything */
@@ -427,12 +427,11 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Cleanup after exception */
+                /* Cleanup after exception and return */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
-            if (!NT_SUCCESS(Status)) return Status;
             break;
 
         /* Direct I/O */
@@ -484,12 +483,11 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Cleanup after exception */
+                /* Cleanup after exception and return */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
-            if (!NT_SUCCESS(Status)) return Status;
             break;
 
         case METHOD_NEITHER:
@@ -958,7 +956,7 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
     PFILE_OBJECT FileObject;
     PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PDEVICE_OBJECT DeviceObject;
     PKEVENT Event = NULL;
     BOOLEAN LocalEvent = FALSE;
@@ -978,13 +976,10 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-
-        /* Return exception code, if any */
-        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get the File Object */
@@ -1021,6 +1016,12 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            /* We failed */
+            ObDereferenceObject(FileObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -1095,7 +1096,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
     PFILE_OBJECT FileObject;
     PIO_STACK_LOCATION IoStack;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     BOOLEAN LockedForSync = FALSE;
     PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
@@ -1114,14 +1115,11 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
 
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status)) return Status;
-
         /* Check if CompletionFilter is valid */
         if (!CompletionFilter || (CompletionFilter & ~FILE_NOTIFY_VALID_MASK))
         {
@@ -1178,6 +1176,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
     Irp->RequestorMode = PreviousMode;
     Irp->UserIosb = IoStatusBlock;
     Irp->UserEvent = Event;
+    Irp->UserBuffer = Buffer;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
@@ -1229,7 +1228,7 @@ NtLockFile(IN HANDLE FileHandle,
     BOOLEAN LockedForSync = FALSE;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     LARGE_INTEGER CapturedByteOffset, CapturedLength;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     OBJECT_HANDLE_INFORMATION HandleInformation;
     PAGED_CODE();
     CapturedByteOffset.QuadPart = 0;
@@ -1267,19 +1266,12 @@ NtLockFile(IN HANDLE FileHandle,
             CapturedLength = ProbeForReadLargeInteger(Length);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference the object and return exception code */
             ObDereferenceObject(FileObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
     else
     {
@@ -1351,15 +1343,14 @@ NtLockFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, Event, NULL);
         if (LocalLength) ExFreePool(LocalLength);
 
-        /* Get status */
-        Status = _SEH2_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set Parameters */
     StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
@@ -1401,7 +1392,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     PFILE_OBJECT FileObject;
     PIO_STACK_LOCATION StackPtr;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     BOOLEAN LockedForSynch = FALSE;
     PKEVENT Event = NULL;
     PVOID AuxBuffer = NULL;
@@ -1456,14 +1447,11 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get exception code and free the buffer */
+            /* Free buffer and return the exception code */
             if (AuxBuffer) ExFreePool(AuxBuffer);
-            Status = _SEH2_GetExceptionCode();
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-
-        /* Return status on failure */
-        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get File Object */
@@ -1547,15 +1535,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Allocating failed, clean up */
+            /* Allocating failed, clean up and return the exception code */
             IopCleanupAfterException(FileObject, Irp, Event, NULL);
             if (AuxBuffer) ExFreePool(AuxBuffer);
 
-            /* Get status */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if (!NT_SUCCESS(Status)) return Status;
 
         /* Set the buffer and flags */
         Irp->UserBuffer = FileInformation;
@@ -1569,14 +1556,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         {
             /* Allocate an MDL */
             Mdl = IoAllocateMdl(FileInformation, Length, FALSE, TRUE, Irp);
+            if (!Mdl) ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
             MmProbeAndLockPages(Mdl, PreviousMode, IoWriteAccess);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Allocating failed, clean up */
+            /* Allocating failed, clean up and return the exception code */
             IopCleanupAfterException(FileObject, Irp, Event, NULL);
-            Status = _SEH2_GetExceptionCode();
-            _SEH2_YIELD(return Status);
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
     }
@@ -1647,7 +1634,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
 {
     OBJECT_HANDLE_INFORMATION HandleInformation;
     PFILE_OBJECT FileObject;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION StackPtr;
@@ -1658,6 +1645,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     PVOID NormalContext;
     KIRQL OldIrql;
     IO_STATUS_BLOCK KernelIosb;
+    PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
@@ -1689,11 +1677,10 @@ NtQueryInformationFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if (!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -1772,6 +1759,11 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            ObDereferenceObject(FileObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -1811,12 +1803,11 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH2_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set the flags */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -1957,7 +1948,7 @@ NtReadFile(IN HANDLE FileHandle,
            IN PLARGE_INTEGER ByteOffset OPTIONAL,
            IN PULONG Key OPTIONAL)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PFILE_OBJECT FileObject;
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
@@ -1973,7 +1964,7 @@ NtReadFile(IN HANDLE FileHandle,
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Validate User-Mode Buffers */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
@@ -1995,13 +1986,10 @@ NtReadFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-
-        /* Check for probe failure */
-        if (!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -2116,12 +2104,11 @@ NtReadFile(IN HANDLE FileHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
+                /* Allocating failed, clean up and return the exception code */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
-            if (!NT_SUCCESS(Status)) return Status;
 
             /* Set the buffer and flags */
             Irp->UserBuffer = Buffer;
@@ -2148,10 +2135,9 @@ NtReadFile(IN HANDLE FileHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
+                /* Allocating failed, clean up and return the exception code */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
-                _SEH2_YIELD(return Status);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
 
@@ -2229,7 +2215,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
                      IN FILE_INFORMATION_CLASS FileInformationClass)
 {
     PFILE_OBJECT FileObject;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION StackPtr;
@@ -2243,6 +2229,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
     PVOID Queue;
     PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
     PIO_COMPLETION_CONTEXT Context;
+    PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
@@ -2277,13 +2264,10 @@ NtSetInformationFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -2353,6 +2337,9 @@ NtSetInformationFile(IN HANDLE FileHandle,
             }
             _SEH2_END;
 
+            /* Update transfer count */
+            IopUpdateTransferCount(IopOtherTransfer, Length);
+
             /* Release the file lock, dereference the file and return */
             IopUnlockFileObject(FileObject);
             ObDereferenceObject(FileObject);
@@ -2363,6 +2350,12 @@ NtSetInformationFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            ObDereferenceObject(FileObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -2407,12 +2400,11 @@ NtSetInformationFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH2_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set the flags */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -2616,7 +2608,7 @@ NtUnlockFile(IN HANDLE FileHandle,
     BOOLEAN LocalEvent = FALSE;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     LARGE_INTEGER CapturedByteOffset, CapturedLength;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     OBJECT_HANDLE_INFORMATION HandleInformation;
     IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
@@ -2655,19 +2647,12 @@ NtUnlockFile(IN HANDLE FileHandle,
             CapturedLength = ProbeForReadLargeInteger(Length);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status))
         {
             /* Dereference the object and return exception code */
             ObDereferenceObject(FileObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
     else
     {
@@ -2696,6 +2681,11 @@ NtUnlockFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            ObDereferenceObject(FileObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -2737,15 +2727,14 @@ NtUnlockFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
         if (LocalLength) ExFreePool(LocalLength);
 
-        /* Get exception status */
-        Status = _SEH2_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set Parameters */
     StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
@@ -2791,7 +2780,7 @@ NtWriteFile(IN HANDLE FileHandle,
             IN PLARGE_INTEGER ByteOffset OPTIONAL,
             IN PULONG Key OPTIONAL)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PFILE_OBJECT FileObject;
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
@@ -2817,7 +2806,7 @@ NtWriteFile(IN HANDLE FileHandle,
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Validate User-Mode Buffers */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
@@ -2854,13 +2843,10 @@ NtWriteFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-
-        /* Check for probe failure */
-        if (!NT_SUCCESS(Status)) return Status;
     }
     else
     {
@@ -2980,10 +2966,9 @@ NtWriteFile(IN HANDLE FileHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
+                /* Allocating failed, clean up and return the exception code */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
-                _SEH2_YIELD(return Status);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
 
@@ -3009,10 +2994,9 @@ NtWriteFile(IN HANDLE FileHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
+                /* Allocating failed, clean up and return the exception code */
                 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
-                Status = _SEH2_GetExceptionCode();
-                _SEH2_YIELD(return Status);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
             _SEH2_END;
         }
@@ -3078,7 +3062,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
     PKEVENT Event = NULL;
     BOOLEAN LocalEvent = FALSE;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
@@ -3112,11 +3096,10 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get File Object */
@@ -3139,6 +3122,11 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            ObDereferenceObject(FileObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -3181,12 +3169,11 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH2_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set the flags for this buffered + deferred I/O */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -3237,12 +3224,13 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
     PFILE_OBJECT FileObject;
     PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
-    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_OBJECT DeviceObject, TargetDeviceObject;
     PKEVENT Event = NULL;
     BOOLEAN LocalEvent = FALSE;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     IO_STATUS_BLOCK KernelIosb;
+    TARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure;
     PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
@@ -3275,11 +3263,10 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get File Object */
@@ -3292,6 +3279,10 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
                                        NULL);
     if (!NT_SUCCESS(Status)) return Status;
 
+    /* Get target device for notification */
+    Status = IoGetRelatedTargetDevice(FileObject, &TargetDeviceObject);
+    if (!NT_SUCCESS(Status)) TargetDeviceObject = NULL;
+
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -3302,6 +3293,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
     {
         /* Use local event */
         Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        if (!Event)
+        {
+            ObDereferenceObject(FileObject);
+            if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
         KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
@@ -3314,7 +3311,11 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
 
     /* Allocate the IRP */
     Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
-    if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, Event);
+    if (!Irp)
+    {
+        if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject);
+        return IopCleanupFailedIrp(FileObject, NULL, Event);
+    }
 
     /* Set up the IRP */
     Irp->RequestorMode = PreviousMode;
@@ -3347,12 +3348,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH2_GetExceptionCode();
+        if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject);
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
-    if (!NT_SUCCESS(Status)) return Status;
 
     /* Set the flags for this buffered + deferred I/O */
     Irp->Flags |= (IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
@@ -3382,6 +3383,17 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
                                            IoStatusBlock);
     }
 
+    if (TargetDeviceObject && NT_SUCCESS(Status))
+    {
+        /* Time to report change */
+        NotificationStructure.Version = 1;
+        NotificationStructure.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
+        NotificationStructure.Event = GUID_IO_VOLUME_NAME_CHANGE;
+        NotificationStructure.FileObject = NULL;
+        NotificationStructure.NameBufferOffset = - 1;
+        Status = IoReportTargetDeviceChange(TargetDeviceObject, &NotificationStructure);
+    }
+
     /* Return status */
     return Status;
 }