[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / io / iomgr / iofunc.c
index 6c2f1b5..22e8710 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#include <ioevent.h>
 #define NDEBUG
 #include <debug.h>
 #include "internal/io_i.h"
@@ -90,16 +91,16 @@ IopFinalizeAsynchronousIo(IN NTSTATUS SynchStatus,
     }
 
     /* Wrap potential user-mode write in SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         *IoStatusBlock = *KernelIosb;
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         /* Get the exception code */
-        FinalStatus = _SEH_GetExceptionCode();
+        FinalStatus = _SEH2_GetExceptionCode();
     }
-    _SEH_END;
+    _SEH2_END;
 
     /* Free the event and return status */
     ExFreePool(Event);
@@ -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;
@@ -217,7 +218,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     /* Check if we came from user mode */
     if (PreviousMode != KernelMode)
     {
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -256,13 +257,12 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                 }
             }
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
 
     /* Don't check for access rights right now, KernelMode can do anything */
@@ -388,7 +388,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
         case METHOD_BUFFERED:
 
             /* Enter SEH for allocations */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Select the right Buffer Length */
                 BufferLength = (InputBufferLength > OutputBufferLength) ?
@@ -425,14 +425,13 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                     Irp->UserBuffer = NULL;
                 }
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Cleanup after exception */
-                IopCleanupAfterException(FileObject, Irp, Event, NULL);
-                Status = _SEH_GetExceptionCode();
+                /* Cleanup after exception and return */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
-            if (!NT_SUCCESS(Status)) return Status;
+            _SEH2_END;
             break;
 
         /* Direct I/O */
@@ -440,7 +439,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
         case METHOD_OUT_DIRECT:
 
             /* Enter SEH */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Check if we got an input buffer */
                 if ((InputBufferLength) && (InputBuffer))
@@ -482,14 +481,13 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                                         IoReadAccess : IoWriteAccess);
                 }
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Cleanup after exception */
-                IopCleanupAfterException(FileObject, Irp, Event, NULL);
-                Status = _SEH_GetExceptionCode();
+                /* Cleanup after exception and return */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
-            if (!NT_SUCCESS(Status)) return Status;
+            _SEH2_END;
             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;
@@ -971,20 +969,17 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
     if (PreviousMode != KernelMode)
     {
         /* Protect probes */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-
-        /* Return exception code, if any */
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
 
     /* 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);
@@ -1104,7 +1105,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
     if (PreviousMode != KernelMode)
     {
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O STatus block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -1112,15 +1113,18 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
             /* Probe the buffer */
             if (BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG));
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
+        _SEH2_END;
 
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status)) return Status;
+        /* Check if CompletionFilter is valid */
+        if (!CompletionFilter || (CompletionFilter & ~FILE_NOTIFY_VALID_MASK))
+        {
+            return STATUS_INVALID_PARAMETER;
+        }
     }
 
     /* Get File Object */
@@ -1142,7 +1146,11 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
                                            PreviousMode,
                                            (PVOID *)&Event,
                                            NULL);
-        if (Status != STATUS_SUCCESS) return Status;
+        if (Status != STATUS_SUCCESS)
+        {
+            ObDereferenceObject(FileObject);
+            return Status;
+        }
         KeClearEvent(Event);
     }
 
@@ -1168,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;
@@ -1219,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;
@@ -1247,7 +1256,7 @@ NtLockFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O STatus block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -1256,20 +1265,13 @@ NtLockFile(IN HANDLE FileHandle,
             CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
             CapturedLength = ProbeForReadLargeInteger(Length);
         }
-        _SEH_HANDLE
-        {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status))
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
             /* Dereference the object and return exception code */
             ObDereferenceObject(FileObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
     else
     {
@@ -1327,7 +1329,7 @@ NtLockFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate local buffer */
         LocalLength = ExAllocatePoolWithTag(NonPagedPool,
@@ -1339,17 +1341,16 @@ NtLockFile(IN HANDLE FileHandle,
         Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
         StackPtr->Parameters.LockControl.Length = LocalLength;
     }
-    _SEH_HANDLE
+    _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 = _SEH_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set Parameters */
     StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
@@ -1391,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;
@@ -1405,7 +1406,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     if (PreviousMode != KernelMode)
     {
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status Block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -1444,16 +1445,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                 SearchPattern->MaximumLength = CapturedFileName.Length;
             }
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get exception code and free the buffer */
+            /* Free buffer and return the exception code */
             if (AuxBuffer) ExFreePool(AuxBuffer);
-            Status = _SEH_GetExceptionCode();
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-
-        /* Return status on failure */
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
 
     /* Get File Object */
@@ -1527,7 +1525,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     if (DeviceObject->Flags & DO_BUFFERED_IO)
     {
         /* Enter SEH */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Allocate a buffer */
             Irp->AssociatedIrp.SystemBuffer =
@@ -1535,17 +1533,16 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                       Length,
                                       TAG_SYSB);
         }
-        _SEH_HANDLE
+        _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 = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
 
         /* Set the buffer and flags */
         Irp->UserBuffer = FileInformation;
@@ -1555,20 +1552,20 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     }
     else if (DeviceObject->Flags & DO_DIRECT_IO)
     {
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Allocate an MDL */
             Mdl = IoAllocateMdl(FileInformation, Length, FALSE, TRUE, Irp);
+            if (!Mdl) ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
             MmProbeAndLockPages(Mdl, PreviousMode, IoWriteAccess);
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Allocating failed, clean up */
+            /* Allocating failed, clean up and return the exception code */
             IopCleanupAfterException(FileObject, Irp, Event, NULL);
-            Status = _SEH_GetExceptionCode();
-            _SEH_YIELD(return Status);
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
+        _SEH2_END;
     }
     else
     {
@@ -1637,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;
@@ -1648,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 */
@@ -1669,7 +1667,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -1677,13 +1675,12 @@ NtQueryInformationFile(IN HANDLE FileHandle,
             /* Probe the information */
             ProbeForWrite(FileInformation, Length, sizeof(ULONG));
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
     else
     {
@@ -1735,7 +1732,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
         if (FileInformationClass == FilePositionInformation)
         {
             /* Protect write in SEH */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Write the offset */
                 ((PFILE_POSITION_INFORMATION)FileInformation)->
@@ -1745,12 +1742,12 @@ NtQueryInformationFile(IN HANDLE FileHandle,
                 IoStatusBlock->Information = sizeof(FILE_POSITION_INFORMATION);
                 Status = IoStatusBlock->Status = STATUS_SUCCESS;
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Get the exception code */
-                Status = _SEH_GetExceptionCode();
+                Status = _SEH2_GetExceptionCode();
             }
-            _SEH_END;
+            _SEH2_END;
 
             /* Release the file lock, dereference the file and return */
             IopUnlockFileObject(FileObject);
@@ -1762,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;
     }
@@ -1791,7 +1793,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate a buffer */
         Irp->AssociatedIrp.SystemBuffer =
@@ -1799,14 +1801,13 @@ NtQueryInformationFile(IN HANDLE FileHandle,
                                   Length,
                                   TAG_SYSB);
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set the flags */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -1847,17 +1848,17 @@ NtQueryInformationFile(IN HANDLE FileHandle,
             Status = KernelIosb.Status;
 
             /* Enter SEH to write the IOSB back */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Write it back to the caller */
                 *IoStatusBlock = KernelIosb;
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Get the exception code */
-                Status = _SEH_GetExceptionCode();
+                Status = _SEH2_GetExceptionCode();
             }
-            _SEH_END;
+            _SEH2_END;
 
             /* Free the event */
             ExFreePool(Event);
@@ -1947,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;
@@ -1963,9 +1964,9 @@ NtReadFile(IN HANDLE FileHandle,
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Validate User-Mode Buffers */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -1983,15 +1984,12 @@ NtReadFile(IN HANDLE FileHandle,
             /* Capture and probe the key */
             if (Key) CapturedKey = ProbeForReadUlong(Key);
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-
-        /* Check for probe failure */
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
     else
     {
@@ -2070,7 +2068,7 @@ NtReadFile(IN HANDLE FileHandle,
     /* Set the IRP */
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-    Irp->RequestorMode = KernelMode;
+    Irp->RequestorMode = PreviousMode;
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
     Irp->UserIosb = IoStatusBlock;
@@ -2096,7 +2094,7 @@ NtReadFile(IN HANDLE FileHandle,
         if (Length)
         {
             /* Enter SEH */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Allocate a buffer */
                 Irp->AssociatedIrp.SystemBuffer =
@@ -2104,14 +2102,13 @@ NtReadFile(IN HANDLE FileHandle,
                                           Length,
                                           TAG_SYSB);
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
-                IopCleanupAfterException(FileObject, Irp, NULL, Event);
-                Status = _SEH_GetExceptionCode();
+                /* Allocating failed, clean up and return the exception code */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
-            if (!NT_SUCCESS(Status)) return Status;
+            _SEH2_END;
 
             /* Set the buffer and flags */
             Irp->UserBuffer = Buffer;
@@ -2130,20 +2127,19 @@ NtReadFile(IN HANDLE FileHandle,
         /* Check if we have a buffer length */
         if (Length)
         {
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Allocate an MDL */
                 Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, Irp);
                 MmProbeAndLockPages(Mdl, PreviousMode, IoWriteAccess);
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
-                IopCleanupAfterException(FileObject, Irp, Event, NULL);
-                Status = _SEH_GetExceptionCode();
-                _SEH_YIELD(return Status);
+                /* Allocating failed, clean up and return the exception code */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
+            _SEH2_END;
 
         }
 
@@ -2219,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;
@@ -2233,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 */
@@ -2254,7 +2251,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -2265,15 +2262,12 @@ NtSetInformationFile(IN HANDLE FileHandle,
                          (Length == sizeof(BOOLEAN)) ?
                          sizeof(BOOLEAN) : sizeof(ULONG));
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
     else
     {
@@ -2325,7 +2319,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
         if (FileInformationClass == FilePositionInformation)
         {
             /* Protect write in SEH */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Write the offset */
                 FileObject->CurrentByteOffset =
@@ -2336,12 +2330,15 @@ NtSetInformationFile(IN HANDLE FileHandle,
                 IoStatusBlock->Information = 0;
                 Status = IoStatusBlock->Status = STATUS_SUCCESS;
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Get the exception code */
-                Status = _SEH_GetExceptionCode();
+                Status = _SEH2_GetExceptionCode();
             }
-            _SEH_END;
+            _SEH2_END;
+
+            /* Update transfer count */
+            IopUpdateTransferCount(IopOtherTransfer, Length);
 
             /* Release the file lock, dereference the file and return */
             IopUnlockFileObject(FileObject);
@@ -2353,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;
     }
@@ -2382,7 +2385,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate a buffer */
         Irp->AssociatedIrp.SystemBuffer =
@@ -2395,14 +2398,13 @@ NtSetInformationFile(IN HANDLE FileHandle,
                       FileInformation,
                       Length);
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set the flags */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -2451,7 +2453,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
                     /* Set the Data */
                     Context->Key = CompletionInfo->Key;
                     Context->Port = Queue;
-                    if (InterlockedCompareExchangePointer(&FileObject->
+                    if (InterlockedCompareExchangePointer((PVOID*)&FileObject->
                                                           CompletionContext,
                                                           Context,
                                                           NULL))
@@ -2506,17 +2508,17 @@ NtSetInformationFile(IN HANDLE FileHandle,
             Status = KernelIosb.Status;
 
             /* Enter SEH to write the IOSB back */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Write it back to the caller */
                 *IoStatusBlock = KernelIosb;
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Get the exception code */
-                Status = _SEH_GetExceptionCode();
+                Status = _SEH2_GetExceptionCode();
             }
-            _SEH_END;
+            _SEH2_END;
 
             /* Free the event */
             ExFreePool(Event);
@@ -2606,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();
@@ -2635,7 +2637,7 @@ NtUnlockFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -2644,20 +2646,13 @@ NtUnlockFile(IN HANDLE FileHandle,
             CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
             CapturedLength = ProbeForReadLargeInteger(Length);
         }
-        _SEH_HANDLE
-        {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        /* Check if probing failed */
-        if (!NT_SUCCESS(Status))
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
             /* Dereference the object and return exception code */
             ObDereferenceObject(FileObject);
-            return Status;
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END;
     }
     else
     {
@@ -2686,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;
     }
@@ -2713,7 +2713,7 @@ NtUnlockFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate a buffer */
         LocalLength = ExAllocatePoolWithTag(NonPagedPool,
@@ -2725,17 +2725,16 @@ NtUnlockFile(IN HANDLE FileHandle,
         Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
         StackPtr->Parameters.LockControl.Length = LocalLength;
     }
-    _SEH_HANDLE
+    _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 = _SEH_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set Parameters */
     StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
@@ -2781,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;
@@ -2807,9 +2806,9 @@ NtWriteFile(IN HANDLE FileHandle,
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Validate User-Mode Buffers */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
-        _SEH_TRY
+        _SEH2_TRY
         {
             /*
              * Check if the handle has either FILE_WRITE_DATA or
@@ -2823,7 +2822,7 @@ NtWriteFile(IN HANDLE FileHandle,
             {
                 /* We failed */
                 ObDereferenceObject(FileObject);
-                _SEH_YIELD(return STATUS_ACCESS_DENIED);
+                _SEH2_YIELD(return STATUS_ACCESS_DENIED);
             }
 
             /* Probe the status block */
@@ -2842,15 +2841,12 @@ NtWriteFile(IN HANDLE FileHandle,
             /* Capture and probe the key */
             if (Key) CapturedKey = ProbeForReadUlong(Key);
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-
-        /* Check for probe failure */
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
     else
     {
@@ -2929,7 +2925,7 @@ NtWriteFile(IN HANDLE FileHandle,
     /* Set the IRP */
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-    Irp->RequestorMode = KernelMode;
+    Irp->RequestorMode = PreviousMode;
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
     Irp->UserIosb = IoStatusBlock;
@@ -2957,7 +2953,7 @@ NtWriteFile(IN HANDLE FileHandle,
         if (Length)
         {
             /* Enter SEH */
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Allocate a buffer */
                 Irp->AssociatedIrp.SystemBuffer =
@@ -2968,14 +2964,13 @@ NtWriteFile(IN HANDLE FileHandle,
                 /* Copy the data into it */
                 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
-                IopCleanupAfterException(FileObject, Irp, Event, NULL);
-                Status = _SEH_GetExceptionCode();
-                _SEH_YIELD(return Status);
+                /* Allocating failed, clean up and return the exception code */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
+            _SEH2_END;
 
             /* Set the flags */
             Irp->Flags = (IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
@@ -2991,20 +2986,19 @@ NtWriteFile(IN HANDLE FileHandle,
         /* Check if we have a buffer length */
         if (Length)
         {
-            _SEH_TRY
+            _SEH2_TRY
             {
                 /* Allocate an MDL */
                 Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, Irp);
                 MmProbeAndLockPages(Mdl, PreviousMode, IoReadAccess);
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Allocating failed, clean up */
-                IopCleanupAfterException(FileObject, Irp, Event, NULL);
-                Status = _SEH_GetExceptionCode();
-                _SEH_YIELD(return Status);
+                /* Allocating failed, clean up and return the exception code */
+                IopCleanupAfterException(FileObject, Irp, EventObject, NULL);
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
             }
-            _SEH_END;
+            _SEH2_END;
         }
 
         /* No allocation flags */
@@ -3068,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);
@@ -3092,7 +3086,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -3100,13 +3094,12 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
             /* Probe the information */
             ProbeForWrite(FsInformation, Length, sizeof(ULONG));
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
 
     /* Get File Object */
@@ -3129,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;
     }
@@ -3161,7 +3159,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate a buffer */
         Irp->AssociatedIrp.SystemBuffer =
@@ -3169,14 +3167,13 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
                                   Length,
                                   TAG_SYSB);
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set the flags for this buffered + deferred I/O */
     Irp->Flags |= (IRP_BUFFERED_IO |
@@ -3227,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);
 
@@ -3255,7 +3253,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
         }
 
         /* Enter SEH for probing */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Probe the I/O Status block */
             ProbeForWriteIoStatusBlock(IoStatusBlock);
@@ -3263,13 +3261,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
             /* Probe the information */
             ProbeForRead(FsInformation, Length, sizeof(ULONG));
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
-        _SEH_END;
-        if (!NT_SUCCESS(Status)) return Status;
+        _SEH2_END;
     }
 
     /* Get File Object */
@@ -3282,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)
     {
@@ -3292,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;
     }
@@ -3304,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;
@@ -3324,7 +3335,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
     StackPtr->FileObject = FileObject;
 
     /* Enter SEH */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Allocate a buffer */
         Irp->AssociatedIrp.SystemBuffer =
@@ -3335,14 +3346,14 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
         /* Copy the data into it */
         RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, FsInformation, Length);
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Allocating failed, clean up */
+        /* Allocating failed, clean up and return the exception code */
         IopCleanupAfterException(FileObject, Irp, NULL, Event);
-        Status = _SEH_GetExceptionCode();
+        if (TargetDeviceObject) ObDereferenceObject(TargetDeviceObject);
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
-    if (!NT_SUCCESS(Status)) return Status;
+    _SEH2_END;
 
     /* Set the flags for this buffered + deferred I/O */
     Irp->Flags |= (IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
@@ -3372,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;
 }