[CDFS_NEW] Replace old driver with a Ms-PL licensed version straight out of the drive...
authorDavid Quintana <gigaherz@gmail.com>
Thu, 23 Nov 2017 20:02:16 +0000 (21:02 +0100)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 25 Nov 2017 12:36:47 +0000 (13:36 +0100)
38 files changed:
drivers/filesystems/cdfs_new/CMakeLists.txt
drivers/filesystems/cdfs_new/README.md [new file with mode: 0644]
drivers/filesystems/cdfs_new/allocsup.c
drivers/filesystems/cdfs_new/cachesup.c
drivers/filesystems/cdfs_new/cd.h
drivers/filesystems/cdfs_new/cddata.c
drivers/filesystems/cdfs_new/cddata.h
drivers/filesystems/cdfs_new/cdfs.rc
drivers/filesystems/cdfs_new/cdinit.c
drivers/filesystems/cdfs_new/cdprocs.h
drivers/filesystems/cdfs_new/cdprocssrc.c [new file with mode: 0644]
drivers/filesystems/cdfs_new/cdstruc.h
drivers/filesystems/cdfs_new/cleanup.c
drivers/filesystems/cdfs_new/close.c
drivers/filesystems/cdfs_new/create.c
drivers/filesystems/cdfs_new/devctrl.c
drivers/filesystems/cdfs_new/deviosup.c
drivers/filesystems/cdfs_new/dirctrl.c
drivers/filesystems/cdfs_new/dirsup.c
drivers/filesystems/cdfs_new/fieldoff.c
drivers/filesystems/cdfs_new/fileinfo.c
drivers/filesystems/cdfs_new/filobsup.c
drivers/filesystems/cdfs_new/fsctrl.c
drivers/filesystems/cdfs_new/fspdisp.c
drivers/filesystems/cdfs_new/lockctrl.c
drivers/filesystems/cdfs_new/namesup.c
drivers/filesystems/cdfs_new/nodetype.h
drivers/filesystems/cdfs_new/pathsup.c
drivers/filesystems/cdfs_new/pnp.c
drivers/filesystems/cdfs_new/prefxsup.c
drivers/filesystems/cdfs_new/read.c
drivers/filesystems/cdfs_new/resrcsup.c
drivers/filesystems/cdfs_new/shutdown.c [new file with mode: 0644]
drivers/filesystems/cdfs_new/strucsup.c
drivers/filesystems/cdfs_new/verfysup.c
drivers/filesystems/cdfs_new/volinfo.c
drivers/filesystems/cdfs_new/workque.c
drivers/filesystems/cdfs_new/write.c [new file with mode: 0644]

index c0b56e9..8bf4fa2 100644 (file)
@@ -6,6 +6,7 @@ list(APPEND SOURCE
     cachesup.c
     cddata.c
     cdinit.c
+    cdprocssrc.c
     cleanup.c
     close.c
     create.c
@@ -24,10 +25,12 @@ list(APPEND SOURCE
     prefxsup.c
     read.c
     resrcsup.c
+    shutdown.c
     strucsup.c
     verfysup.c
     volinfo.c
-    workque.c)
+    workque.c
+    write.c)
 
 add_library(cdfs SHARED ${SOURCE} cdfs.rc)
 set_module_type(cdfs kernelmodedriver)
diff --git a/drivers/filesystems/cdfs_new/README.md b/drivers/filesystems/cdfs_new/README.md
new file mode 100644 (file)
index 0000000..cbe8e4c
--- /dev/null
@@ -0,0 +1,20 @@
+<!---
+    name: CDFS File System Driver
+    platform: WDM
+    language: cpp
+    category: FileSystem
+    description: The CD-ROM file system driver (cdfs) sample is a file system driver for removable media.
+    samplefwlink: http://go.microsoft.com/fwlink/p/?LinkId=617642
+--->
+
+
+CDFS File System Driver
+=======================
+
+The CD-ROM file system driver (cdfs) sample is a sample file system driver that you can use to write new file systems.
+
+Cdfs is a read-only file system that addresses various issues such as accessing data on disk, interacting with the cache manager, and handling various I/O operations such as opening files, performing reads on a file, retrieving information on a file, and performing various control operations on the file system. The Cdfs file system is included with the Microsoft Windows operating system.
+
+## Universal Windows Driver Compliant
+This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.
+
index 93b35bc..6a92817 100755 (executable)
@@ -44,7 +44,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -58,18 +58,18 @@ Abstract:
 
 ULONG
 CdFindMcbEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG FileOffset
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG FileOffset
     );
 
 VOID
 CdDiskOffsetFromMcbEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_MCB_ENTRY McbEntry,
-    IN LONGLONG FileOffset,
-    IN PLONGLONG DiskOffset,
-    IN PULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_MCB_ENTRY McbEntry,
+    _In_ LONGLONG FileOffset,
+    _Out_ PLONGLONG DiskOffset,
+    _Out_ PULONG ByteCount
     );
 
 #ifdef ALLOC_PRAGMA
@@ -84,13 +84,16 @@ CdDiskOffsetFromMcbEntry (
 #endif
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 VOID
+// PREFast currently has no way to express the Fcb==Fcb->Vcb->VolumeDasdFcb early return
+#pragma warning(suppress: 6001 6101) 
 CdLookupAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG FileOffset,
-    OUT PLONGLONG DiskOffset,
-    OUT PULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG FileOffset,
+    _Out_ PLONGLONG DiskOffset,
+    _Out_ PULONG ByteCount
     )
 
 /*++
@@ -128,7 +131,7 @@ Return Value:
 {
     BOOLEAN FirstPass = TRUE;
     ULONG McbEntryOffset;
-    PFCB ParentFcb = NULL; /* ReactOS Change: GCC uninitialized variable bug */
+    PFCB ParentFcb = NULL;
     BOOLEAN CleanupParent = FALSE;
 
     BOOLEAN UnlockFcb = FALSE;
@@ -137,19 +140,31 @@ Return Value:
     ULONG CurrentMcbOffset;
     PCD_MCB_ENTRY CurrentMcbEntry;
 
-    DIRENT_ENUM_CONTEXT DirContext;
-    DIRENT Dirent;
+    DIRENT_ENUM_CONTEXT DirContext = {0};
+    DIRENT Dirent = {0};
 
     PAGED_CODE();
 
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
 
+    //
+    //  For DASD IO we already have clamped the read to the volume limits.
+    //  We'll allow reading beyond those limits for extended DASD IO, so
+    //  no MCB lookup here.
+    //
+
+    if (Fcb == Fcb->Vcb->VolumeDasdFcb) {
+
+        *DiskOffset = FileOffset;
+        return;
+    }
+
     //
     //  Use a try finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We use a loop to perform the lookup.  If we don't find the mapping in the
@@ -215,10 +230,7 @@ Return Value:
             //  Do an unsafe test to see if we need to create a file object.
             //
 
-            if (ParentFcb->FileObject == NULL) {
-
-                CdCreateInternalStream( IrpContext, ParentFcb->Vcb, ParentFcb );
-            }
+            CdVerifyOrCreateDirStreamFile( IrpContext, ParentFcb);
 
             //
             //  Initialize the local variables to indicate the first dirent
@@ -296,7 +308,7 @@ Return Value:
             FirstPass = FALSE;
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         if (CleanupParent) {
 
@@ -311,7 +323,7 @@ Return Value:
         }
 
         if (UnlockFcb) { CdUnlockFcb( IrpContext, Fcb ); }
-    } _SEH2_END;
+    }
 
     return;
 }
@@ -319,11 +331,11 @@ Return Value:
 \f
 VOID
 CdAddAllocationFromDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG McbEntryOffset,
-    IN LONGLONG StartingFileOffset,
-    IN PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ ULONG McbEntryOffset,
+    _In_ LONGLONG StartingFileOffset,
+    _In_ PDIRENT Dirent
     )
 
 /*++
@@ -358,6 +370,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
     ASSERT_LOCKED_FCB( Fcb );
@@ -466,10 +480,10 @@ Return Value:
 \f
 VOID
 CdAddInitialAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG StartingBlock,
-    IN LONGLONG DataLength
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ ULONG StartingBlock,
+    _In_ LONGLONG DataLength
     )
 
 /*++
@@ -505,11 +519,13 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
     ASSERT_LOCKED_FCB( Fcb );
-    ASSERT( 0 == Fcb->Mcb.CurrentEntryCount);
-    ASSERT( CDFS_NTC_FCB_DATA != Fcb->NodeTypeCode);
+    NT_ASSERT( 0 == Fcb->Mcb.CurrentEntryCount);
+    NT_ASSERT( CDFS_NTC_FCB_DATA != Fcb->NodeTypeCode);
 
     //
     //  Update the new entry with the input data.
@@ -555,9 +571,9 @@ Return Value:
 \f
 VOID
 CdTruncateAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingFileOffset
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ LONGLONG StartingFileOffset
     )
 
 /*++
@@ -591,7 +607,7 @@ Return Value:
     ASSERT_LOCKED_FCB( Fcb );
 
     //
-    //  Find the entry containing this starting offset.
+    //  Find the entry containg this starting offset.
     //
 
     McbEntryOffset = CdFindMcbEntry( IrpContext, Fcb, StartingFileOffset );
@@ -606,10 +622,11 @@ Return Value:
 }
 
 \f
+_At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
 VOID
 CdInitializeMcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
     )
 
 /*++
@@ -635,6 +652,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
 
@@ -652,10 +671,14 @@ Return Value:
 }
 
 \f
+_At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_PATH_TABLE, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_INDEX, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_DATA, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_DATA)))
 VOID
 CdUninitializeMcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
     )
 
 /*++
@@ -681,6 +704,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
 
@@ -698,14 +723,14 @@ Return Value:
 
 \f
 //
-//  Local support routine
+//  Local suupport routine
 //
 
 ULONG
 CdFindMcbEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG FileOffset
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG FileOffset
     )
 
 /*++
@@ -736,6 +761,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
     ASSERT_LOCKED_FCB( Fcb );
@@ -781,11 +808,11 @@ Return Value:
 
 VOID
 CdDiskOffsetFromMcbEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_MCB_ENTRY McbEntry,
-    IN LONGLONG FileOffset,
-    IN PLONGLONG DiskOffset,
-    IN PULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_MCB_ENTRY McbEntry,
+    _In_ LONGLONG FileOffset,
+    _Out_ PLONGLONG DiskOffset,
+    _Out_ PULONG ByteCount
     )
 
 /*++
@@ -827,6 +854,9 @@ Return Value:
     LONGLONG LocalByteCount;
 
     PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     ASSERT_IRP_CONTEXT( IrpContext );
 
     //
index 600262f..eea1fd2 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -36,9 +36,10 @@ Abstract:
 \f
 VOID
 CdCreateInternalStream (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB Fcb,
+    _In_ PUNICODE_STRING Name
     )
 
 /*++
@@ -69,8 +70,8 @@ Return Value:
     BOOLEAN CleanupDirContext = FALSE;
     BOOLEAN UpdateFcbSizes = FALSE;
 
-    DIRENT Dirent;
-    DIRENT_ENUM_CONTEXT DirContext;
+    DIRENT Dirent = {0};
+    DIRENT_ENUM_CONTEXT DirContext = {0};
 
     PAGED_CODE();
 
@@ -94,14 +95,14 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Create the internal stream.  The Vpb should be pointing at our volume
         //  device object at this point.
         //
 
-        StreamFile = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice );
+        StreamFile = IoCreateStreamFileObjectLite( NULL, Vcb->Vpb->RealDevice );
 
         if (StreamFile == NULL) {
 
@@ -127,6 +128,14 @@ Return Value:
                          StreamFileOpen,
                          Fcb,
                          NULL );
+        
+        //
+        //  We'll give stream file objects a name to aid IO profiling etc. We 
+        //  NULL this in CdDeleteInternalStream before OB deletes the file object,
+        //  and before CdRemovePrefix is called (which frees Fcb names).
+        //
+
+        StreamFile->FileName = *Name;
 
         //
         //  We will reference the current Fcb twice to keep it from going
@@ -272,7 +281,7 @@ Return Value:
             }
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Cleanup any dirent structures we may have used.
@@ -290,6 +299,14 @@ Return Value:
 
         if (StreamFile != NULL) {
 
+            //
+            //  Null the name pointer, since the stream file object never actually
+            //  'owns' the names, we just point it to existing ones.
+            //
+
+            StreamFile->FileName.Buffer = NULL;
+            StreamFile->FileName.MaximumLength = StreamFile->FileName.Length = 0;
+
             ObDereferenceObject( StreamFile );
             Fcb->FileObject = NULL;
         }
@@ -306,7 +323,7 @@ Return Value:
         }
 
         CdUnlockFcb( IrpContext, Fcb );
-    } _SEH2_END;
+    }
 
     return;
 }
@@ -314,8 +331,8 @@ Return Value:
 \f
 VOID
 CdDeleteInternalStream (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb
     )
 
 /*++
@@ -342,6 +359,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_FCB( Fcb );
 
@@ -375,17 +394,23 @@ Return Value:
             CcUninitializeCacheMap( FileObject, NULL, NULL );
         }
 
+        //
+        //  Null the name pointer, since the stream file object never actually
+        //  'owns' the names, we just point it to existing ones.
+        //
+        
+        FileObject->FileName.Buffer = NULL;
+        FileObject->FileName.MaximumLength = FileObject->FileName.Length = 0;
+
         ObDereferenceObject( FileObject );
     }
-
-    return;
 }
 
 \f
 NTSTATUS
 CdCompleteMdl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -434,11 +459,13 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdPurgeVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN BOOLEAN DismountUnderway
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ BOOLEAN DismountUnderway
     )
 
 /*++
@@ -592,7 +619,7 @@ Return Value:
         if (Vcb->PathTableFcb != NULL) {
 
             ThisFcb = Vcb->PathTableFcb;
-            InterlockedIncrement( &Vcb->PathTableFcb->FcbReference );
+            InterlockedIncrement( (LONG*)&Vcb->PathTableFcb->FcbReference );
 
             if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
                 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
@@ -606,7 +633,7 @@ Return Value:
 
             CdDeleteInternalStream( IrpContext, ThisFcb );
 
-            InterlockedDecrement( &ThisFcb->FcbReference );
+            InterlockedDecrement( (LONG*)&ThisFcb->FcbReference );
 
             CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
         }
@@ -614,7 +641,7 @@ Return Value:
         if (Vcb->VolumeDasdFcb != NULL) {
 
             ThisFcb = Vcb->VolumeDasdFcb;
-            InterlockedIncrement( &ThisFcb->FcbReference );
+            InterlockedIncrement( (LONG*)&ThisFcb->FcbReference );
 
             if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
                 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
@@ -626,7 +653,7 @@ Return Value:
                 Status = STATUS_UNABLE_TO_DELETE_SECTION;
             }
 
-            InterlockedDecrement( &ThisFcb->FcbReference );
+            InterlockedDecrement( (LONG*)&ThisFcb->FcbReference );
 
             CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
         }
index ef41b58..f830210 100755 (executable)
@@ -221,7 +221,7 @@ typedef struct _RAW_JOLIET_VD {
     UCHAR       Reserved[8];        // reserved 8 = 0
     ULONG       VolSpaceI;          // size of the volume in LBN's Intel
     ULONG       VolSpaceM;          // size of the volume in LBN's Motorola
-    UCHAR       CharSet[32];        // character set bytes 0 = ASCII, Joliet Seq here
+    UCHAR       CharSet[32];        // character set bytes 0 = ASCII, Joliett Seq here
     USHORT      VolSetSizeI;        // volume set size Intel
     USHORT      VolSetSizeM;        // volume set size Motorola
     USHORT      VolSeqNumI;         // volume set sequence number Intel
@@ -383,9 +383,9 @@ typedef RAW_DIRENT *PRAW_DIRENT;
 //
 //  VOID
 //  CdConvertCdTimeToNtTime (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PCHAR CdTime,
-//      OUT PLARGE_INTEGER NtTime
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PCHAR CdTime,
+//      _Out_ PLARGE_INTEGER NtTime
 //      );
 //
 
index c836723..15cfe2d 100755 (executable)
@@ -17,7 +17,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 #ifdef CD_SANITY
 BOOLEAN CdTestTopLevel = TRUE;
@@ -178,16 +178,42 @@ LONG CdXAFileHeader[] = {
     -44                                 // <CD-XA Raw Sectors>          ADJUST
 };
 
+#ifdef CDFS_TELEMETRY_DATA
+
+//
+// Telemetry Data for reporting
+//
+
+CDFS_TELEMETRY_DATA_CONTEXT CdTelemetryData;
+
+#endif // CDFS_TELEMETRY_DATA
+
 #ifdef ALLOC_PRAGMA
 #pragma alloc_text(PAGE, CdFastIoCheckIfPossible)
 #pragma alloc_text(PAGE, CdSerial32)
+#pragma alloc_text(PAGE, CdSetThreadContext)
 #endif
 
-\f
+_IRQL_requires_max_(APC_LEVEL)
+__drv_dispatchType(DRIVER_DISPATCH)
+__drv_dispatchType(IRP_MJ_CREATE)
+__drv_dispatchType(IRP_MJ_CLOSE)
+__drv_dispatchType(IRP_MJ_READ)
+__drv_dispatchType(IRP_MJ_WRITE)
+__drv_dispatchType(IRP_MJ_QUERY_INFORMATION)
+__drv_dispatchType(IRP_MJ_SET_INFORMATION)
+__drv_dispatchType(IRP_MJ_QUERY_VOLUME_INFORMATION)
+__drv_dispatchType(IRP_MJ_DIRECTORY_CONTROL)
+__drv_dispatchType(IRP_MJ_FILE_SYSTEM_CONTROL)
+__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
+__drv_dispatchType(IRP_MJ_LOCK_CONTROL)
+__drv_dispatchType(IRP_MJ_CLEANUP)
+__drv_dispatchType(IRP_MJ_PNP)
+__drv_dispatchType(IRP_MJ_SHUTDOWN)
 NTSTATUS
 CdFsdDispatch (
-    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
-    IN PIRP Irp
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -214,7 +240,7 @@ Routine Description:
 
 Arguments:
 
-    VolumeDeviceObject - Supplies the volume device object for this request
+    DeviceObject - Supplies the volume device object for this request
 
     Irp - Supplies the Irp being processed
 
@@ -225,7 +251,7 @@ Return Value:
 --*/
 
 {
-    THREAD_CONTEXT ThreadContext;
+    THREAD_CONTEXT ThreadContext = {0};
     PIRP_CONTEXT IrpContext = NULL;
     BOOLEAN Wait;
 
@@ -243,6 +269,8 @@ Return Value:
 
     ASSERT_OPTIONAL_IRP( Irp );
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     FsRtlEnterFileSystem();
 
 #ifdef CD_SANITY
@@ -259,7 +287,7 @@ Return Value:
         //  Use a try-except to handle the exception cases.
         //
 
-        _SEH2_TRY {
+        try {
 
             //
             //  If the IrpContext is NULL then this is the first pass through
@@ -293,7 +321,7 @@ Return Value:
                 CdSetThreadContext( IrpContext, &ThreadContext );
 
 #ifdef CD_SANITY
-                ASSERT( !CdTestTopLevel ||
+                NT_ASSERT( !CdTestTopLevel ||
                         SafeNodeType( IrpContext->TopLevel ) == CDFS_NTC_IRP_CONTEXT );
 #endif
 
@@ -347,6 +375,11 @@ Return Value:
 
                 break;
 
+            case IRP_MJ_WRITE :
+
+                Status = CdCommonWrite( IrpContext, Irp );
+                break;
+
             case IRP_MJ_QUERY_INFORMATION :
 
                 Status = CdCommonQueryInfo( IrpContext, Irp );
@@ -392,40 +425,46 @@ Return Value:
                 Status = CdCommonPnp( IrpContext, Irp );
                 break;
 
+            case IRP_MJ_SHUTDOWN :
+            
+                Status = CdCommonShutdown( IrpContext, Irp );
+                break;
+
             default :
 
                 Status = STATUS_INVALID_DEVICE_REQUEST;
                 CdCompleteRequest( IrpContext, Irp, Status );
             }
 
-        } _SEH2_EXCEPT( CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
+        } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) {
 
-            Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
-        } _SEH2_END;
+            Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
+        }
 
     } while (Status == STATUS_CANT_WAIT);
 
 #ifdef CD_SANITY
-    ASSERT( !CdTestTopLevel ||
+    NT_ASSERT( !CdTestTopLevel ||
             (PreviousTopLevel == IoGetTopLevelIrp()) );
 #endif
 
     FsRtlExitFileSystem();
 
-    ASSERT( SaveIrql == KeGetCurrentIrql( ));
+    NT_ASSERT( SaveIrql == KeGetCurrentIrql( ));
 
     return Status;
 }
 
+
 #ifdef CD_SANITY
 
 VOID
-CdRaiseStatusEx(
-    IN PIRP_CONTEXT IrpContext,
-    IN NTSTATUS Status,
-    IN BOOLEAN NormalizeStatus,
-    IN OPTIONAL ULONG FileId,
-    IN OPTIONAL ULONG Line
+CdRaiseStatusEx (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ NTSTATUS Status,
+    _In_ BOOLEAN NormalizeStatus,
+    _In_opt_ ULONG FileId,
+    _In_opt_ ULONG Line
     )
 {
     BOOLEAN BreakIn = FALSE;
@@ -461,7 +500,7 @@ CdRaiseStatusEx(
         DbgPrint( "CDFS: Contact CDFS.SYS component owner for triage.\n");
         DbgPrint( "CDFS: 'eb %p 0;eb %p 0' to disable this alert.\n", &CdTestRaisedStatus, &CdBreakOnAnyRaise);
 
-        DbgBreakPoint();
+        NT_ASSERT(FALSE);
     }
     
     if (NormalizeStatus)  {
@@ -480,10 +519,11 @@ CdRaiseStatusEx(
 
 #endif
 
+
 LONG
 CdExceptionFilter (
-    IN PIRP_CONTEXT IrpContext,
-    IN PEXCEPTION_POINTERS ExceptionPointer
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PEXCEPTION_POINTERS ExceptionPointer
     )
 
 /*++
@@ -557,6 +597,7 @@ Return Value:
 
     if (TestStatus && !FsRtlIsNtstatusExpected( ExceptionCode )) {
 
+#pragma prefast( suppress: __WARNING_USE_OTHER_FUNCTION, "We're corrupted." )    
         CdBugCheck( (ULONG_PTR) ExceptionPointer->ExceptionRecord,
                     (ULONG_PTR) ExceptionPointer->ContextRecord,
                     (ULONG_PTR) ExceptionPointer->ExceptionRecord->ExceptionAddress );
@@ -567,11 +608,13 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdProcessException (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PIRP Irp,
-    IN NTSTATUS ExceptionCode
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ NTSTATUS ExceptionCode
     )
 
 /*++
@@ -601,7 +644,7 @@ Return Value:
 --*/
 
 {
-    PDEVICE_OBJECT Device;
+    PDEVICE_OBJECT Device = NULL;
     PVPB Vpb;
     PETHREAD Thread;
 
@@ -625,17 +668,6 @@ Return Value:
 
     ExceptionCode = IrpContext->ExceptionStatus;
 
-    //
-    //  If we are not a top level request then we just complete the request
-    //  with the current status code.
-    //
-
-    if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) {
-
-        CdCompleteRequest( IrpContext, Irp, ExceptionCode );
-        return ExceptionCode;
-    }
-
     //
     //  Check if we are posting this request.  One of the following must be true
     //  if we are to post a request.
@@ -644,7 +676,8 @@ Return Value:
     //          or we are forcing this to be posted.
     //
     //      - Status code is STATUS_VERIFY_REQUIRED and we are at APC level
-    //          or higher.  Can't wait for IO in the verify path in this case.
+    //          or higher, or within a guarded region.  Can't wait for IO in 
+    //          the verify path in this case.
     //
     //  Set the MORE_PROCESSING flag in the IrpContext to keep if from being
     //  deleted if this is a retryable condition.
@@ -653,27 +686,26 @@ Return Value:
     //  Note that (children of) CdFsdPostRequest can raise (Mdl allocation).
     //
 
-    _SEH2_TRY {
-    
+    try {
+
         if (ExceptionCode == STATUS_CANT_WAIT) {
 
             if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST )) {
 
                 ExceptionCode = CdFsdPostRequest( IrpContext, Irp );
             }
-
-        } else if (ExceptionCode == STATUS_VERIFY_REQUIRED) {
-
-            if (KeGetCurrentIrql() >= APC_LEVEL) {
-
-                ExceptionCode = CdFsdPostRequest( IrpContext, Irp );
-            }
+        } 
+        else if ((ExceptionCode == STATUS_VERIFY_REQUIRED) &&
+                 FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) &&
+                 KeAreAllApcsDisabled()) {
+                 
+            ExceptionCode = CdFsdPostRequest( IrpContext, Irp );
         }
     }
-    _SEH2_EXCEPT( CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() ))  {
+    except( CdExceptionFilter( IrpContext, GetExceptionInformation() ))  {
     
-        ExceptionCode = _SEH2_GetExceptionCode();        
-    } _SEH2_END;
+        ExceptionCode = GetExceptionCode();        
+    }
     
     //
     //  If we posted the request or our caller will retry then just return here.
@@ -687,6 +719,17 @@ Return Value:
 
     ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
 
+    //
+    //  If we are not a top level request then we just complete the request
+    //  with the current status code.
+    //
+
+    if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) {
+
+        CdCompleteRequest( IrpContext, Irp, ExceptionCode );
+        return ExceptionCode;
+    }
+
     //
     //  Store this error into the Irp for posting back to the Io system.
     //
@@ -722,20 +765,34 @@ Return Value:
                 Device = IoGetDeviceToVerify( PsGetCurrentThread() );
                 IoSetDeviceToVerify( PsGetCurrentThread(), NULL );
 
-                ASSERT( Device != NULL );
+                NT_ASSERT( Device != NULL );
 
-                //
-                //  Let's not BugCheck just because the driver messes up.
-                //
+            }
 
-                if (Device == NULL) {
+            //
+            //  It turns out some storage drivers really do set invalid non-NULL device 
+            //  objects to verify.
+            //
+            //  To work around this, completely ignore the device to verify in the thread, 
+            //  and just use our real device object instead.
+            //
 
-                    ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR;
+            if (IrpContext->Vcb) {
 
-                    CdCompleteRequest( IrpContext, Irp, ExceptionCode );
+                Device = IrpContext->Vcb->Vpb->RealDevice;
+            }
 
-                    return ExceptionCode;
-                }
+            //
+            //  Let's not BugCheck just because the device to verify is somehow still NULL.
+            //
+
+            if (Device == NULL) {
+
+                ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR;
+
+                CdCompleteRequest( IrpContext, Irp, ExceptionCode );
+
+                return ExceptionCode;
             }
 
             //
@@ -773,6 +830,7 @@ Return Value:
                 Vpb = NULL;
             }
 
+
             //
             //  The device to verify is either in my thread local storage
             //  or that of the thread that owns the Irp.
@@ -786,18 +844,31 @@ Return Value:
                 Thread = PsGetCurrentThread();
                 Device = IoGetDeviceToVerify( Thread );
 
-                ASSERT( Device != NULL );
+                NT_ASSERT( Device != NULL );
+            }
 
-                //
-                //  Let's not BugCheck just because the driver messes up.
-                //
+            //
+            //  It turns out some storage drivers really do set invalid non-NULL device 
+            //  objects to verify.
+            //
+            //  To work around this, completely ignore the device to verify in the thread, 
+            //  and just use our real device object instead.
+            //
 
-                if (Device == NULL) {
+            if (IrpContext->Vcb) {
 
-                    CdCompleteRequest( IrpContext, Irp, ExceptionCode );
+                Device = IrpContext->Vcb->Vpb->RealDevice;
+            }
 
-                    return ExceptionCode;
-                }
+            //
+            //  Let's not BugCheck just because the device to verify is somehow still NULL.
+            //
+
+            if (Device == NULL) {
+
+                CdCompleteRequest( IrpContext, Irp, ExceptionCode );
+
+                return ExceptionCode;
             }
 
             //
@@ -839,9 +910,9 @@ Return Value:
 \f
 VOID
 CdCompleteRequest (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PIRP Irp OPTIONAL,
-    IN NTSTATUS Status
+    _Inout_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_opt_ PIRP Irp,
+    _In_ NTSTATUS Status
     )
 
 /*++
@@ -906,8 +977,8 @@ Return Value:
 \f
 VOID
 CdSetThreadContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PTHREAD_CONTEXT ThreadContext
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PTHREAD_CONTEXT ThreadContext
     )
 
 /*++
@@ -938,8 +1009,6 @@ Return Value:
 
 {
     PTHREAD_CONTEXT CurrentThreadContext;
-    ULONG_PTR StackTop;
-    ULONG_PTR StackBottom;
 
     PAGED_CODE();
 
@@ -971,12 +1040,9 @@ Return Value:
     //  If this is not a valid Cdfs context then use the input thread
     //  context and store it in the top level context.
     //
-
-    IoGetStackLimits( &StackTop, &StackBottom);
-
+#pragma warning(suppress: 6011) // Bug in PREFast around bitflag operations
     if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) ||
-        (((ULONG_PTR) CurrentThreadContext > StackBottom - sizeof( THREAD_CONTEXT )) ||
-         ((ULONG_PTR) CurrentThreadContext <= StackTop) ||
+        (!IoWithinStackLimits( (ULONG_PTR)CurrentThreadContext, sizeof( THREAD_CONTEXT ) ) ||
          FlagOn( (ULONG_PTR) CurrentThreadContext, 0x3 ) ||
          (CurrentThreadContext->Cdfs != 0x53464443))) {
 
@@ -1002,18 +1068,23 @@ Return Value:
     return;
 }
 
-\f
+
+_Function_class_(FAST_IO_CHECK_IF_POSSIBLE)
+_IRQL_requires_same_
+_Success_(return != FALSE)
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastIoCheckIfPossible (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN ULONG Length,
-    IN BOOLEAN Wait,
-    IN ULONG LockKey,
-    IN BOOLEAN CheckForReadOperation,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PLARGE_INTEGER FileOffset,
+    _In_ ULONG Length,
+    _In_ BOOLEAN Wait,
+    _In_ ULONG LockKey,
+    _In_ BOOLEAN CheckForReadOperation,
+    _Pre_notnull_
+    _When_(return != FALSE, _Post_equal_to_(_Old_(IoStatus)))
+    _When_(return == FALSE, _Post_valid_)
+    PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -1054,6 +1125,9 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( Wait );
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     //
     //  Decode the type of file object we're being asked to process and
     //  make sure that is is only a user file open.
@@ -1090,8 +1164,8 @@ Return Value:
 \f
 ULONG
 CdSerial32 (
-    IN PCHAR Buffer,
-    IN ULONG ByteCount
+    _In_reads_bytes_(ByteCount) PCHAR Buffer,
+    _In_ ULONG ByteCount
     )
 /*++
 
index a03fc36..395b186 100755 (executable)
@@ -94,82 +94,77 @@ extern LONG CdXAFileHeader[];
 extern LONG CdAudioPlayHeader[];
 extern LONG CdXAAudioPhileHeader[];
 
-\f
+#ifdef CDFS_TELEMETRY_DATA
+
 //
-//  Turn on pseudo-asserts if CD_FREE_ASSERTS is defined.
+//  Globals for Telemetry data.
 //
 
-#if !DBG
-#ifdef CD_FREE_ASSERTS
-#undef ASSERT
-#undef ASSERTMSG
-#define ASSERT(exp)        if (!(exp)) { extern BOOLEAN KdDebuggerEnabled; DbgPrint("%s:%d %s\n",__FILE__,__LINE__,#exp); if (KdDebuggerEnabled) { DbgBreakPoint(); } }
-#define ASSERTMSG(msg,exp) if (!(exp)) { extern BOOLEAN KdDebuggerEnabled; DbgPrint("%s:%d %s %s\n",__FILE__,__LINE__,msg,#exp); if (KdDebuggerEnabled) { DbgBreakPoint(); } }
-#endif
-#endif
+extern CDFS_TELEMETRY_DATA_CONTEXT CdTelemetryData;
+
+#endif // CDFS_TELEMETRY_DATA
 
-\f
 //
 //  The following assertion macros ensure that the indicated structure
 //  is valid
 //
-//      ASSERT_STRUCT( IN PVOID Struct, IN CSHORT NodeType );
-//      ASSERT_OPTIONAL_STRUCT( IN PVOID Struct OPTIONAL, IN CSHORT NodeType );
+//      ASSERT_STRUCT( _In_ PVOID Struct, _In_ CSHORT NodeType );
+//      ASSERT_OPTIONAL_STRUCT( _In_opt_ PVOID Struct, _In_ CSHORT NodeType );
 //
-//      ASSERT_VCB( IN PVCB Vcb );
-//      ASSERT_OPTIONAL_VCB( IN PVCB Vcb OPTIONAL );
+//      ASSERT_VCB( _In_ PVCB Vcb );
+//      ASSERT_OPTIONAL_VCB( _In_opt_ PVCB Vcb );
 //
-//      ASSERT_FCB( IN PFCB Fcb );
-//      ASSERT_OPTIONAL_FCB( IN PFCB Fcb OPTIONAL );
+//      ASSERT_FCB( _In_ PFCB Fcb );
+//      ASSERT_OPTIONAL_FCB( _In_opt_ PFCB Fcb );
 //
-//      ASSERT_FCB_NONPAGED( IN PFCB_NONPAGED FcbNonpaged );
-//      ASSERT_OPTIONAL_FCB( IN PFCB_NONPAGED FcbNonpaged OPTIONAL );
+//      ASSERT_FCB_NONPAGED( _In_ PFCB_NONPAGED FcbNonpaged );
+//      ASSERT_OPTIONAL_FCB( _In_opt_ PFCB_NONPAGED FcbNonpaged );
 //
-//      ASSERT_CCB( IN PSCB Ccb );
-//      ASSERT_OPTIONAL_CCB( IN PSCB Ccb OPTIONAL );
+//      ASSERT_CCB( _In_ PSCB Ccb );
+//      ASSERT_OPTIONAL_CCB( _In_opt_ PSCB Ccb );
 //
-//      ASSERT_IRP_CONTEXT( IN PIRP_CONTEXT IrpContext );
-//      ASSERT_OPTIONAL_IRP_CONTEXT( IN PIRP_CONTEXT IrpContext OPTIONAL );
+//      ASSERT_IRP_CONTEXT( _In_ PIRP_CONTEXT IrpContext );
+//      ASSERT_OPTIONAL_IRP_CONTEXT( _In_opt_ PIRP_CONTEXT IrpContext );
 //
-//      ASSERT_IRP( IN PIRP Irp );
-//      ASSERT_OPTIONAL_IRP( IN PIRP Irp OPTIONAL );
+//      ASSERT_IRP( _In_ PIRP Irp );
+//      ASSERT_OPTIONAL_IRP( _In_opt_ PIRP Irp );
 //
-//      ASSERT_FILE_OBJECT( IN PFILE_OBJECT FileObject );
-//      ASSERT_OPTIONAL_FILE_OBJECT( IN PFILE_OBJECT FileObject OPTIONAL );
+//      ASSERT_FILE_OBJECT( _In_ PFILE_OBJECT FileObject );
+//      ASSERT_OPTIONAL_FILE_OBJECT( _In_opt_ PFILE_OBJECT FileObject );
 //
 //  The following macros are used to check the current thread owns
 //  the indicated resource
 //
-//      ASSERT_EXCLUSIVE_RESOURCE( IN PERESOURCE Resource );
+//      ASSERT_EXCLUSIVE_RESOURCE( _In_ PERESOURCE Resource );
 //
-//      ASSERT_SHARED_RESOURCE( IN PERESOURCE Resource );
+//      ASSERT_SHARED_RESOURCE( _In_ PERESOURCE Resource );
 //
-//      ASSERT_RESOURCE_NOT_MINE( IN PERESOURCE Resource );
+//      ASSERT_RESOURCE_NOT_MINE( _In_ PERESOURCE Resource );
 //
 //  The following macros are used to check whether the current thread
-//  owns the resource in the given structures.
+//  owns the resoures in the given structures.
 //
 //      ASSERT_EXCLUSIVE_CDDATA
 //
-//      ASSERT_EXCLUSIVE_VCB( IN PVCB Vcb );
+//      ASSERT_EXCLUSIVE_VCB( _In_ PVCB Vcb );
 //
-//      ASSERT_SHARED_VCB( IN PVCB Vcb );
+//      ASSERT_SHARED_VCB( _In_ PVCB Vcb );
 //
-//      ASSERT_EXCLUSIVE_FCB( IN PFCB Fcb );
+//      ASSERT_EXCLUSIVE_FCB( _In_ PFCB Fcb );
 //
-//      ASSERT_SHARED_FCB( IN PFCB Fcb );
+//      ASSERT_SHARED_FCB( _In_ PFCB Fcb );
 //
-//      ASSERT_EXCLUSIVE_FILE( IN PFCB Fcb );
+//      ASSERT_EXCLUSIVE_FILE( _In_ PFCB Fcb );
 //
-//      ASSERT_SHARED_FILE( IN PFCB Fcb );
+//      ASSERT_SHARED_FILE( _In_ PFCB Fcb );
 //
-//      ASSERT_LOCKED_VCB( IN PVCB Vcb );
+//      ASSERT_LOCKED_VCB( _In_ PVCB Vcb );
 //
-//      ASSERT_NOT_LOCKED_VCB( IN PVCB Vcb );
+//      ASSERT_NOT_LOCKED_VCB( _In_ PVCB Vcb );
 //
-//      ASSERT_LOCKED_FCB( IN PFCB Fcb );
+//      ASSERT_LOCKED_FCB( _In_ PFCB Fcb );
 //
-//      ASSERT_NOT_LOCKED_FCB( IN PFCB Fcb );
+//      ASSERT_NOT_LOCKED_FCB( _In_ PFCB Fcb );
 //
 
 //
@@ -183,19 +178,19 @@ extern LONG CdXAAudioPhileHeader[];
 
 #ifdef CD_SANITY
 
-#define ASSERT_STRUCT(S,T)                  ASSERT( SafeNodeType( S ) == (T) )
-#define ASSERT_OPTIONAL_STRUCT(S,T)         ASSERT( ((S) == NULL) ||  (SafeNodeType( S ) == (T)) )
+#define ASSERT_STRUCT(S,T)                  NT_ASSERT( SafeNodeType( S ) == (T) )
+#define ASSERT_OPTIONAL_STRUCT(S,T)         NT_ASSERT( ((S) == NULL) ||  (SafeNodeType( S ) == (T)) )
 
 #define ASSERT_VCB(V)                       ASSERT_STRUCT( (V), CDFS_NTC_VCB )
 #define ASSERT_OPTIONAL_VCB(V)              ASSERT_OPTIONAL_STRUCT( (V), CDFS_NTC_VCB )
 
 #define ASSERT_FCB(F)                                           \
-    ASSERT( (SafeNodeType( F ) == CDFS_NTC_FCB_DATA ) ||        \
+    NT_ASSERT( (SafeNodeType( F ) == CDFS_NTC_FCB_DATA ) ||        \
             (SafeNodeType( F ) == CDFS_NTC_FCB_INDEX ) ||       \
             (SafeNodeType( F ) == CDFS_NTC_FCB_PATH_TABLE ) )
 
 #define ASSERT_OPTIONAL_FCB(F)                                  \
-    ASSERT( ((F) == NULL) ||                                    \
+    NT_ASSERT( ((F) == NULL) ||                                    \
             (SafeNodeType( F ) == CDFS_NTC_FCB_DATA ) ||        \
             (SafeNodeType( F ) == CDFS_NTC_FCB_INDEX ) ||       \
             (SafeNodeType( F ) == CDFS_NTC_FCB_PATH_TABLE ) )
@@ -215,27 +210,27 @@ extern LONG CdXAAudioPhileHeader[];
 #define ASSERT_FILE_OBJECT(FO)              ASSERT_STRUCT( (FO), IO_TYPE_FILE )
 #define ASSERT_OPTIONAL_FILE_OBJECT(FO)     ASSERT_OPTIONAL_STRUCT( (FO), IO_TYPE_FILE )
 
-#define ASSERT_EXCLUSIVE_RESOURCE(R)        ASSERT( ExIsResourceAcquiredExclusiveLite( R ))
+#define ASSERT_EXCLUSIVE_RESOURCE(R)        NT_ASSERT( ExIsResourceAcquiredExclusiveLite( R ))
 
-#define ASSERT_SHARED_RESOURCE(R)           ASSERT( ExIsResourceAcquiredSharedLite( R ))
+#define ASSERT_SHARED_RESOURCE(R)           NT_ASSERT( ExIsResourceAcquiredSharedLite( R ))
 
-#define ASSERT_RESOURCE_NOT_MINE(R)         ASSERT( !ExIsResourceAcquiredSharedLite( R ))
+#define ASSERT_RESOURCE_NOT_MINE(R)         NT_ASSERT( !ExIsResourceAcquiredSharedLite( R ))
 
-#define ASSERT_EXCLUSIVE_CDDATA             ASSERT( ExIsResourceAcquiredExclusiveLite( &CdData.DataResource ))
-#define ASSERT_EXCLUSIVE_VCB(V)             ASSERT( ExIsResourceAcquiredExclusiveLite( &(V)->VcbResource ))
-#define ASSERT_SHARED_VCB(V)                ASSERT( ExIsResourceAcquiredSharedLite( &(V)->VcbResource ))
+#define ASSERT_EXCLUSIVE_CDDATA             NT_ASSERT( ExIsResourceAcquiredExclusiveLite( &CdData.DataResource ))
+#define ASSERT_EXCLUSIVE_VCB(V)             NT_ASSERT( ExIsResourceAcquiredExclusiveLite( &(V)->VcbResource ))
+#define ASSERT_SHARED_VCB(V)                NT_ASSERT( ExIsResourceAcquiredSharedLite( &(V)->VcbResource ))
 
-#define ASSERT_EXCLUSIVE_FCB(F)             ASSERT( ExIsResourceAcquiredExclusiveLite( &(F)->FcbNonpaged->FcbResource ))
-#define ASSERT_SHARED_FCB(F)                ASSERT( ExIsResourceAcquiredSharedLite( &(F)->FcbNonpaged->FcbResource ))
+#define ASSERT_EXCLUSIVE_FCB(F)             NT_ASSERT( ExIsResourceAcquiredExclusiveLite( &(F)->FcbNonpaged->FcbResource ))
+#define ASSERT_SHARED_FCB(F)                NT_ASSERT( ExIsResourceAcquiredSharedLite( &(F)->FcbNonpaged->FcbResource ))
 
-#define ASSERT_EXCLUSIVE_FILE(F)            ASSERT( ExIsResourceAcquiredExclusiveLite( (F)->Resource ))
-#define ASSERT_SHARED_FILE(F)               ASSERT( ExIsResourceAcquiredSharedLite( (F)->Resource ))
+#define ASSERT_EXCLUSIVE_FILE(F)            NT_ASSERT( ExIsResourceAcquiredExclusiveLite( (F)->Resource ))
+#define ASSERT_SHARED_FILE(F)               NT_ASSERT( ExIsResourceAcquiredSharedLite( (F)->Resource ))
 
-#define ASSERT_LOCKED_VCB(V)                ASSERT( (V)->VcbLockThread == PsGetCurrentThread() )
-#define ASSERT_NOT_LOCKED_VCB(V)            ASSERT( (V)->VcbLockThread != PsGetCurrentThread() )
+#define ASSERT_LOCKED_VCB(V)                NT_ASSERT( (V)->VcbLockThread == PsGetCurrentThread() )
+#define ASSERT_NOT_LOCKED_VCB(V)            NT_ASSERT( (V)->VcbLockThread != PsGetCurrentThread() )
 
-#define ASSERT_LOCKED_FCB(F)                ASSERT( !FlagOn( (F)->FcbState, FCB_STATE_IN_FCB_TABLE) || ((F)->FcbLockThread == PsGetCurrentThread()))
-#define ASSERT_NOT_LOCKED_FCB(F)            ASSERT( (F)->FcbLockThread != PsGetCurrentThread() )
+#define ASSERT_LOCKED_FCB(F)                NT_ASSERT( !FlagOn( (F)->FcbState, FCB_STATE_IN_FCB_TABLE) || ((F)->FcbLockThread == PsGetCurrentThread()))
+#define ASSERT_NOT_LOCKED_FCB(F)            NT_ASSERT( (F)->FcbLockThread != PsGetCurrentThread() )
 
 #else
 
index 1cf70c6..5d4dcaf 100644 (file)
@@ -1,7 +1,14 @@
-/* $Id: cdfs.rc 21710 2006-04-22 16:36:21Z tretiakov $ */
+//
+//    Copyright (C) Microsoft.  All rights reserved.
+//
+#include <verrsrc.h>
+
+#include <ntverp.h>
+
+#define        VER_FILETYPE    VFT_DRV
+#define        VER_FILESUBTYPE VFT2_DRV_SYSTEM
+#define VER_FILEDESCRIPTION_STR     "CD-ROM File System Driver"
+#define VER_INTERNALNAME_STR        "cdfs.sys"
+
+#include "common.ver"
 
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION   "ISO9660 Driver\0"
-#define REACTOS_STR_INTERNAL_NAME      "cdfs\0"
-#define REACTOS_STR_ORIGINAL_FILENAME  "cdfs.sys\0"
-#include <reactos/version.rc>
index b6bec14..5ec9d50 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -21,40 +21,33 @@ Abstract:
 
 #define BugCheckFileId                   (CDFS_BUG_CHECK_CDINIT)
 
+//  Tell prefast the function type.
+DRIVER_INITIALIZE DriverEntry;
+
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 DriverEntry(
-    IN PDRIVER_OBJECT DriverObject,
-    IN PUNICODE_STRING RegistryPath
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PUNICODE_STRING RegistryPath
     );
 
+
+// tell prefast this is a driver unload function
+DRIVER_UNLOAD CdUnload;
+
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdUnload(
-    IN PDRIVER_OBJECT DriverObject
+    _In_ PDRIVER_OBJECT DriverObject
     );
 
 NTSTATUS
 CdInitializeGlobalData (
-    IN PDRIVER_OBJECT DriverObject,
-    IN PDEVICE_OBJECT FileSystemDeviceObject
-#ifdef __REACTOS__
-    ,
-    IN PDEVICE_OBJECT HddFileSystemDeviceObject
-#endif
-    );
-
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdShutdown (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PDEVICE_OBJECT FileSystemDeviceObject
     );
 
 #ifdef ALLOC_PRAGMA
 #pragma alloc_text(INIT, DriverEntry)
 #pragma alloc_text(PAGE, CdUnload)
-#pragma alloc_text(PAGE, CdShutdown)
 #pragma alloc_text(INIT, CdInitializeGlobalData)
 #endif
 
@@ -64,10 +57,9 @@ CdShutdown (
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 DriverEntry(
-    IN PDRIVER_OBJECT DriverObject,
-    IN PUNICODE_STRING RegistryPath
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PUNICODE_STRING RegistryPath
     )
 
 /*++
@@ -93,9 +85,9 @@ Return Value:
     NTSTATUS Status;
     UNICODE_STRING UnicodeString;
     PDEVICE_OBJECT CdfsFileSystemDeviceObject;
-#ifdef __REACTOS__
-    PDEVICE_OBJECT HddFileSystemDeviceObject;
-#endif
+    FS_FILTER_CALLBACKS FilterCallbacks;
+
+    UNREFERENCED_PARAMETER( RegistryPath );
 
     //
     // Create the device object.
@@ -115,27 +107,14 @@ Return Value:
         return Status;
     }
 
-#ifdef __REACTOS__
-    //
-    // Create the HDD device object.
-    //
-
-    RtlInitUnicodeString( &UnicodeString, L"\\CdfsHdd" );
-
-    Status = IoCreateDevice( DriverObject,
-                             0,
-                             &UnicodeString,
-                             FILE_DEVICE_DISK_FILE_SYSTEM,
-                             0,
-                             FALSE,
-                             &HddFileSystemDeviceObject );
+#pragma prefast(push)
+#pragma prefast(disable: 28155, "the dispatch routine has the correct type, prefast is just being paranoid.")
+#pragma prefast(disable: 28168, "the dispatch routine has the correct type, prefast is just being paranoid.")
+#pragma prefast(disable: 28169, "the dispatch routine has the correct type, prefast is just being paranoid.")
+#pragma prefast(disable: 28175, "we're allowed to change these.")
 
-    if (!NT_SUCCESS( Status )) {
-        IoDeleteDevice (CdfsFileSystemDeviceObject);
-        return Status;
-    }
-#endif
     DriverObject->DriverUnload = CdUnload;
+
     //
     //  Note that because of the way data caching is done, we set neither
     //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
@@ -153,6 +132,7 @@ Return Value:
     DriverObject->MajorFunction[IRP_MJ_CREATE]                  =
     DriverObject->MajorFunction[IRP_MJ_CLOSE]                   =
     DriverObject->MajorFunction[IRP_MJ_READ]                    =
+    DriverObject->MajorFunction[IRP_MJ_WRITE]                   =
     DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]       =
     DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]         =
     DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]=
@@ -161,17 +141,29 @@ Return Value:
     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]          =
     DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]            =
     DriverObject->MajorFunction[IRP_MJ_CLEANUP]                 =
-    DriverObject->MajorFunction[IRP_MJ_PNP]                     = (PDRIVER_DISPATCH) CdFsdDispatch;
-    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                = CdShutdown;
+    DriverObject->MajorFunction[IRP_MJ_PNP]                     = 
+    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                = (PDRIVER_DISPATCH) CdFsdDispatch;
+#pragma prefast(pop)
 
+#pragma prefast(suppress: 28175, "this is a file system driver, we're allowed to touch FastIoDispatch.")
     DriverObject->FastIoDispatch = &CdFastIoDispatch;
 
-    Status = IoRegisterShutdownNotification (CdfsFileSystemDeviceObject);
-    if (!NT_SUCCESS (Status)) {
-        IoDeleteDevice (CdfsFileSystemDeviceObject);
-#ifdef __REACTOS__
-        IoDeleteDevice (HddFileSystemDeviceObject);
-#endif
+    //
+    //  Initialize the filter callbacks we use.
+    //
+
+    RtlZeroMemory( &FilterCallbacks,
+                   sizeof(FS_FILTER_CALLBACKS) );
+
+    FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
+    FilterCallbacks.PreAcquireForSectionSynchronization = CdFilterCallbackAcquireForCreateSection;
+
+    Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject,
+                                                     &FilterCallbacks );
+
+    if (!NT_SUCCESS( Status )) {
+
+        IoDeleteDevice( CdfsFileSystemDeviceObject );
         return Status;
     }
 
@@ -179,16 +171,9 @@ Return Value:
     //  Initialize the global data structures
     //
 
-#ifndef __REACTOS__
     Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject );
-#else
-    Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject, HddFileSystemDeviceObject );
-#endif
     if (!NT_SUCCESS (Status)) {
         IoDeleteDevice (CdfsFileSystemDeviceObject);
-#ifdef __REACTOS__
-        IoDeleteDevice (HddFileSystemDeviceObject);
-#endif
         return Status;
     }
 
@@ -199,69 +184,30 @@ Return Value:
     //
 
     CdfsFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM;
-#ifdef __REACTOS__
-    HddFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM;
-#endif
 
     IoRegisterFileSystem( CdfsFileSystemDeviceObject );
     ObReferenceObject (CdfsFileSystemDeviceObject);
-#ifdef __REACTOS__
-    IoRegisterFileSystem( HddFileSystemDeviceObject );
-    ObReferenceObject (HddFileSystemDeviceObject);
-#endif
 
+#ifdef CDFS_TELEMETRY_DATA
     //
-    //  And return to our caller
+    //  Initialize Telemetry
     //
 
-    return( STATUS_SUCCESS );
-}
-
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdShutdown (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
-    )
-/*++
-
-Routine Description:
-
-    This routine is the shutdown handler for CDFS.
+    CdInitializeTelemetry();
 
-Arguments:
-
-    DeviceObject - Supplies the registered device object for CDFS.
-    Irp - Shutdown IRP
-    
-
-Return Value:
-
-    None.
-
---*/
-{
-#ifdef __REACTOS__
-    ASSERT(DeviceObject == CdData.FileSystemDeviceObject ||
-           DeviceObject == CdData.HddFileSystemDeviceObject);
 #endif
 
-    IoUnregisterFileSystem (DeviceObject);
-#ifndef __REACTOS__
-    IoDeleteDevice (CdData.FileSystemDeviceObject);
-#else
-    IoDeleteDevice (DeviceObject);
-#endif
+    //
+    //  And return to our caller
+    //
 
-    CdCompleteRequest( NULL, Irp, STATUS_SUCCESS );
-    return STATUS_SUCCESS;
+    return( STATUS_SUCCESS );
 }
 
 
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdUnload(
-    IN PDRIVER_OBJECT DriverObject
+    _In_ PDRIVER_OBJECT DriverObject
     )
 /*++
 
@@ -281,6 +227,10 @@ Return Value:
 {
     PIRP_CONTEXT IrpContext;
 
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( DriverObject );
+
     //
     // Free any IRP contexts
     //
@@ -295,9 +245,6 @@ Return Value:
     IoFreeWorkItem (CdData.CloseItem);
     ExDeleteResourceLite( &CdData.DataResource );
     ObDereferenceObject (CdData.FileSystemDeviceObject);
-#ifdef __REACTOS__
-    ObDereferenceObject (CdData.HddFileSystemDeviceObject);
-#endif
 }
 \f
 //
@@ -306,12 +253,8 @@ Return Value:
 
 NTSTATUS
 CdInitializeGlobalData (
-    IN PDRIVER_OBJECT DriverObject,
-    IN PDEVICE_OBJECT FileSystemDeviceObject
-#ifdef __REACTOS__
-    ,
-    IN PDEVICE_OBJECT HddFileSystemDeviceObject
-#endif
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PDEVICE_OBJECT FileSystemDeviceObject
     )
 
 /*++
@@ -340,6 +283,10 @@ Return Value:
     RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH ));
 
     CdFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
+
+#pragma prefast(push)
+#pragma prefast(disable:28155, "these are all correct")
+
     CdFastIoDispatch.FastIoCheckIfPossible =   CdFastIoCheckIfPossible;  //  CheckForFastIo
     CdFastIoDispatch.FastIoRead =              FsRtlCopyRead;            //  Read
     CdFastIoDispatch.FastIoQueryBasicInfo =    CdFastQueryBasicInfo;     //  QueryBasicInfo
@@ -348,7 +295,12 @@ Return Value:
     CdFastIoDispatch.FastIoUnlockSingle =      CdFastUnlockSingle;       //  UnlockSingle
     CdFastIoDispatch.FastIoUnlockAll =         CdFastUnlockAll;          //  UnlockAll
     CdFastIoDispatch.FastIoUnlockAllByKey =    CdFastUnlockAllByKey;     //  UnlockAllByKey
-    CdFastIoDispatch.AcquireFileForNtCreateSection =  CdAcquireForCreateSection;
+
+    //
+    //  This callback has been replaced by CdFilterCallbackAcquireForCreateSection.
+    //
+
+    CdFastIoDispatch.AcquireFileForNtCreateSection =  NULL;
     CdFastIoDispatch.ReleaseFileForNtCreateSection =  CdReleaseForCreateSection;
     CdFastIoDispatch.FastIoQueryNetworkOpenInfo =     CdFastQueryNetworkInfo;   //  QueryNetworkInfo
     
@@ -357,6 +309,8 @@ Return Value:
     CdFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
     CdFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;
 
+#pragma prefast(pop)
+
     //
     //  Initialize the CdData structure.
     //
@@ -368,9 +322,6 @@ Return Value:
 
     CdData.DriverObject = DriverObject;
     CdData.FileSystemDeviceObject = FileSystemDeviceObject;
-#ifdef __REACTOS__
-    CdData.HddFileSystemDeviceObject = HddFileSystemDeviceObject;
-#endif
 
     InitializeListHead( &CdData.VcbQueue );
 
@@ -380,10 +331,10 @@ Return Value:
     //  Initialize the cache manager callback routines
     //
 
-    CdData.CacheManagerCallbacks.AcquireForLazyWrite  = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
-    CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
-    CdData.CacheManagerCallbacks.AcquireForReadAhead  = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
-    CdData.CacheManagerCallbacks.ReleaseFromReadAhead = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
+    CdData.CacheManagerCallbacks.AcquireForLazyWrite  = &CdAcquireForCache;
+    CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = &CdReleaseFromCache;
+    CdData.CacheManagerCallbacks.AcquireForReadAhead  = &CdAcquireForCache;
+    CdData.CacheManagerCallbacks.ReleaseFromReadAhead = &CdReleaseFromCache;
 
     CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite  = &CdNoopAcquire;
     CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease;
index 2b066e7..d2f7db0 100755 (executable)
@@ -17,24 +17,36 @@ Abstract:
 #ifndef _CDPROCS_
 #define _CDPROCS_
 
+#pragma warning( disable: 4127 ) // conditional expression is constant
+
+#pragma warning( push )
+#pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union
+#pragma warning( disable: 4214 ) // nonstandard extension used : bit field types
+
 #include <ntifs.h>
 
 #include <ntddcdrm.h>
 #include <ntdddisk.h>
 #include <ntddscsi.h>
-#ifdef __REACTOS__
-#include <pseh/pseh2.h>
-#endif
 
 #ifndef INLINE
 #define INLINE __inline
 #endif
 
 #include "nodetype.h"
-#include "cd.h"
-#include "cdstruc.h"
-#include "cddata.h"
+#include "Cd.h"
+#include "CdStruc.h"
+#include "CdData.h"
+
+#ifdef CDFS_TELEMETRY_DATA
+
+#include <winmeta.h>
+#include <TraceLoggingProvider.h>
+#include <telemetry\MicrosoftTelemetry.h>
+
+#endif // CDFS_TELEMETRY_DATA
 
+#pragma warning( pop )
 
 //**** x86 compiler bug ****
 
@@ -43,6 +55,14 @@ Abstract:
 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
 #endif
 
+#ifndef Min
+#define Min(a, b)   ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef Max
+#define Max(a, b)   ((a) > (b) ? (a) : (b))
+#endif
+
 //
 //  Here are the different pool tags.
 //
@@ -91,9 +111,9 @@ Abstract:
 //
 //  BOOLEAN
 //  CdIllegalFcbAccess (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN TYPE_OF_OPEN TypeOfOpen,
-//      IN ACCESS_MASK DesiredAccess
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ TYPE_OF_OPEN TypeOfOpen,
+//      _In_ ACCESS_MASK DesiredAccess
 //      );
 //
 
@@ -117,49 +137,55 @@ Abstract:
 //  These routines are for querying allocation on individual streams.
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdLookupAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG FileOffset,
-    OUT PLONGLONG DiskOffset,
-    OUT PULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG FileOffset,
+    _Out_ PLONGLONG DiskOffset,
+    _Out_ PULONG ByteCount
     );
 
 VOID
 CdAddAllocationFromDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG McbEntryOffset,
-    IN LONGLONG StartingFileOffset,
-    IN PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ ULONG McbEntryOffset,
+    _In_ LONGLONG StartingFileOffset,
+    _In_ PDIRENT Dirent
     );
 
 VOID
 CdAddInitialAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG StartingBlock,
-    IN LONGLONG DataLength
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ ULONG StartingBlock,
+    _In_ LONGLONG DataLength
     );
 
 VOID
 CdTruncateAllocation (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingFileOffset
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ LONGLONG StartingFileOffset
     );
 
+_At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
 VOID
 CdInitializeMcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
     );
 
+_At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_PATH_TABLE, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_INDEX, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
+_When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_DATA, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_DATA)))
 VOID
 CdUninitializeMcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
     );
 
 \f
@@ -169,35 +195,58 @@ CdUninitializeMcb (
 
 VOID
 CdCreateInternalStream (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB Fcb,
+    _In_ PUNICODE_STRING Name
     );
 
 VOID
 CdDeleteInternalStream (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb
     );
 
 NTSTATUS
 CdCompleteMdl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdPurgeVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN BOOLEAN DismountUnderway
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ BOOLEAN DismountUnderway
     );
 
+VOID
+INLINE
+CdVerifyOrCreateDirStreamFile (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb
+    )
+{
+    //
+    //  Unsafe test to see if call / lock neccessary.
+    //
+    
+    if (NULL == Fcb->FileObject) {
+        
+        CdCreateInternalStream( IrpContext,
+                                Fcb->Vcb,
+                                Fcb, 
+                                &Fcb->FileNamePrefix.ExactCaseName.FileName);
+    }
+}
+
+
 //
 //  VOID
 //  CdUnpinData (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN OUT PBCB *Bcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PBCB *Bcb
 //      );
 //
 
@@ -212,56 +261,97 @@ CdPurgeVolume (
 //  the on disk structure and do not alter any other data structures.
 //
 
+_Requires_lock_held_(_Global_critical_region_)
+VOID
+CdFreeDirCache (
+    _In_ PIRP_CONTEXT IrpContext
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdNonCachedRead (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdNonCachedXARead (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdVolumeDasdWrite (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
     );
 
 BOOLEAN
 CdReadSectors (
-    IN PIRP_CONTEXT IrpContext,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN BOOLEAN RaiseOnError,
-    IN OUT PVOID Buffer,
-    IN PDEVICE_OBJECT TargetDeviceObject
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _In_ BOOLEAN ReturnError,
+    _Out_writes_bytes_(ByteCount) PVOID Buffer,
+    _In_ PDEVICE_OBJECT TargetDeviceObject
     );
 
 NTSTATUS
 CdCreateUserMdl (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG BufferLength,
-    IN BOOLEAN RaiseOnError
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG BufferLength,
+    _In_ BOOLEAN RaiseOnError,
+    _In_ LOCK_OPERATION Operation
     );
 
 NTSTATUS
+FASTCALL
 CdPerformDevIoCtrl (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG IoControlCode,
-    IN PDEVICE_OBJECT Device,
-    OUT PVOID OutputBuffer OPTIONAL,
-    IN ULONG OutputBufferLength,
-    IN BOOLEAN InternalDeviceIoControl,
-    IN BOOLEAN OverrideVerify,
-    OUT PIO_STATUS_BLOCK Iosb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG IoControlCode,
+    _In_ PDEVICE_OBJECT Device,
+    _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
+    _In_ ULONG OutputBufferLength,
+    _In_ BOOLEAN InternalDeviceIoControl,
+    _In_ BOOLEAN OverrideVerify,
+    _Out_opt_ PIO_STATUS_BLOCK Iosb
+    );
+
+NTSTATUS
+CdPerformDevIoCtrlEx (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG IoControlCode,
+    _In_ PDEVICE_OBJECT Device,
+    _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
+    _In_ ULONG InputBufferLength,
+    _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
+    _In_ ULONG OutputBufferLength,
+    _In_ BOOLEAN InternalDeviceIoControl,
+    _In_ BOOLEAN OverrideVerify,
+    _Out_opt_ PIO_STATUS_BLOCK Iosb
+    );
+
+NTSTATUS
+CdHijackIrpAndFlushDevice (
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PDEVICE_OBJECT TargetDeviceObject
     );
 
+
 //
 //  VOID
 //  CdMapUserBuffer (
-//      IN PIRP_CONTEXT IrpContext
-//      OUT PVOID UserBuffer
+//      _In_ PIRP_CONTEXT IrpContext
+//      _Out_ PVOID UserBuffer
 //      );
 //
 //  Returns pointer to sys address.  Will raise on failure.
@@ -269,25 +359,25 @@ CdPerformDevIoCtrl (
 //
 //  VOID
 //  CdLockUserBuffer (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN ULONG BufferLength
+//      _Inout_ PIRP_CONTEXT IrpContext,
+//      _In_ ULONG BufferLength
 //      );
 //
 
 #define CdMapUserBuffer(IC, UB) {                                               \
             *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ?                 \
                     (IC)->Irp->UserBuffer :                                     \
-                    (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority)));   \
+                    (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute)));   \
             if (NULL == *(UB))  {                         \
                 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES);            \
             }                                                                   \
         }                                                                       
         
 
-#define CdLockUserBuffer(IC,BL) {                   \
-    if ((IC)->Irp->MdlAddress == NULL) {            \
-        (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
-    }                                               \
+#define CdLockUserBuffer(IC,BL,OP) {                        \
+    if ((IC)->Irp->MdlAddress == NULL) {                    \
+        (VOID) CdCreateUserMdl( (IC), (BL), TRUE, (OP) );   \
+    }                                                       \
 }
 
 \f
@@ -297,122 +387,124 @@ CdPerformDevIoCtrl (
 
 VOID
 CdLookupDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG DirentOffset,
-    OUT PDIRENT_ENUM_CONTEXT DirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG DirentOffset,
+    _Out_ PDIRENT_ENUM_CONTEXT DirContext
     );
 
 BOOLEAN
 CdLookupNextDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PDIRENT_ENUM_CONTEXT CurrentDirContext,
-    OUT PDIRENT_ENUM_CONTEXT NextDirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PDIRENT_ENUM_CONTEXT CurrentDirContext,
+    _Inout_ PDIRENT_ENUM_CONTEXT NextDirContext
     );
 
+_At_(Dirent->CdTime, _Post_notnull_)\f
 VOID
 CdUpdateDirentFromRawDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PDIRENT_ENUM_CONTEXT DirContext,
-    IN OUT PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PDIRENT_ENUM_CONTEXT DirContext,
+    _Inout_ PDIRENT Dirent
     );
 
 VOID
 CdUpdateDirentName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PDIRENT Dirent,
-    IN ULONG IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PDIRENT Dirent,
+    _In_ ULONG IgnoreCase
     );
 
-BOOLEAN
+_Success_(return != FALSE) BOOLEAN
 CdFindFile (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    OUT PCD_NAME *MatchingName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _Out_ PCD_NAME *MatchingName
     );
 
 BOOLEAN
 CdFindDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     );
 
+_At_(FileContext->ShortName.FileName.MaximumLength, _In_range_(>=, BYTE_COUNT_8_DOT_3))
 BOOLEAN
 CdFindFileByShortName (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN ULONG ShortNameDirentOffset,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ ULONG ShortNameDirentOffset,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     );
 
 BOOLEAN
 CdLookupNextInitialFileDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     );
 
 VOID
 CdLookupLastFileDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     );
 
 VOID
 CdCleanupFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     );
 
 //
 //  VOID
 //  CdInitializeFileContext (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFILE_ENUM_CONTEXT FileContext
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Out_ PFILE_ENUM_CONTEXT FileContext
 //      );
 //
 //
 //  VOID
 //  CdInitializeDirent (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PDIRENT Dirent
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Out_ PDIRENT Dirent
 //      );
 //
 //  VOID
 //  CdInitializeDirContext (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PDIRENT_ENUM_CONTEXT DirContext
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Out_ PDIRENT_ENUM_CONTEXT DirContext
 //      );
 //
 //  VOID
 //  CdCleanupDirent (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PDIRENT Dirent
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PDIRENT Dirent
 //      );
 //
 //  VOID
 //  CdCleanupDirContext (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PDIRENT_ENUM_CONTEXT DirContext
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PDIRENT_ENUM_CONTEXT DirContext
 //      );
 //
 //  VOID
 //  CdLookupInitialFileDirent (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
-//      IN PFILE_ENUM_CONTEXT FileContext,
-//      IN ULONG DirentOffset
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PFCB Fcb,
+//      _Out_ PFILE_ENUM_CONTEXT FileContext,
+//      _In_ ULONG DirentOffset
 //      );
 //
 
@@ -472,27 +564,33 @@ typedef enum _TYPE_OF_OPEN {
 } TYPE_OF_OPEN;
 typedef TYPE_OF_OPEN *PTYPE_OF_OPEN;
 
+_When_(TypeOfOpen == UnopenedFileObject, _At_(Fcb, _In_opt_))
+_When_(TypeOfOpen != UnopenedFileObject, _At_(Fcb, _In_))
 VOID
 CdSetFileObject (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN PFCB Fcb OPTIONAL,
-    IN PCCB Ccb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFILE_OBJECT FileObject,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    PFCB Fcb,
+    _In_opt_ PCCB Ccb
     );
 
+_When_(return == UnopenedFileObject, _At_(*Fcb, _Post_null_))
+_When_(return != UnopenedFileObject, _At_(Fcb, _Outptr_))
+_When_(return == UnopenedFileObject, _At_(*Ccb, _Post_null_))
+_When_(return != UnopenedFileObject, _At_(Ccb, _Outptr_))
 TYPE_OF_OPEN
 CdDecodeFileObject (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    OUT PFCB *Fcb,
-    OUT PCCB *Ccb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    PFCB *Fcb,
+    PCCB *Ccb
     );
 
 TYPE_OF_OPEN
 CdFastDecodeFileObject (
-    IN PFILE_OBJECT FileObject,
-    OUT PFCB *Fcb
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFCB *Fcb
     );
 
 \f
@@ -500,69 +598,77 @@ CdFastDecodeFileObject (
 //  Name support routines, implemented in NameSup.c
 //
 
+_Post_satisfies_(_Old_(CdName->FileName.Length) >=
+                 CdName->FileName.Length + CdName->VersionString.Length)
 VOID
 CdConvertNameToCdName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PCD_NAME CdName
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PCD_NAME CdName
     );
 
 VOID
 CdConvertBigToLittleEndian (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCHAR BigEndian,
-    IN ULONG ByteCount,
-    OUT PCHAR LittleEndian
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_reads_bytes_(ByteCount) PCHAR BigEndian,
+    _In_ ULONG ByteCount,
+    _Out_writes_bytes_(ByteCount) PCHAR LittleEndian
     );
 
 VOID
 CdUpcaseName (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_NAME Name,
-    IN OUT PCD_NAME UpcaseName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_NAME Name,
+    _Inout_ PCD_NAME UpcaseName
     );
 
 VOID
 CdDissectName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PUNICODE_STRING RemainingName,
-    OUT PUNICODE_STRING FinalName
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PUNICODE_STRING RemainingName,
+    _Out_ PUNICODE_STRING FinalName
+    );
+
+BOOLEAN
+CdIsLegalName (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING FileName
     );
 
 BOOLEAN
 CdIs8dot3Name (
-    IN PIRP_CONTEXT IrpContext,
-    IN UNICODE_STRING FileName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ UNICODE_STRING FileName
     );
 
 VOID
 CdGenerate8dot3Name (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING FileName,
-    IN ULONG DirentOffset,
-    OUT PWCHAR ShortFileName,
-    OUT PUSHORT ShortByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING FileName,
+    _In_ ULONG DirentOffset,
+    _Out_writes_bytes_to_(BYTE_COUNT_8_DOT_3, *ShortByteCount) PWCHAR ShortFileName,
+    _Out_ PUSHORT ShortByteCount
     );
 
 BOOLEAN
 CdIsNameInExpression (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_NAME CurrentName,
-    IN PCD_NAME SearchExpression,
-    IN ULONG  WildcardFlags,
-    IN BOOLEAN CheckVersion
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_NAME CurrentName,
+    _In_ PCD_NAME SearchExpression,
+    _In_ ULONG  WildcardFlags,
+    _In_ BOOLEAN CheckVersion
     );
 
 ULONG
 CdShortNameDirentOffset (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING Name
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING Name
     );
 
 FSRTL_COMPARISON_RESULT
 CdFullCompareNames (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING NameA,
-    IN PUNICODE_STRING NameB
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING NameA,
+    _In_ PUNICODE_STRING NameB
     );
 
 \f
@@ -570,18 +676,20 @@ CdFullCompareNames (
 //  Filesystem control operations.  Implemented in Fsctrl.c
 //
 
+_Requires_lock_held_(_Global_critical_region_)
+_Requires_lock_held_(Vcb->VcbResource)
 NTSTATUS
 CdLockVolumeInternal (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_OBJECT FileObject OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_opt_ PFILE_OBJECT FileObject
     );
 
 NTSTATUS
 CdUnlockVolumeInternal (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_OBJECT FileObject OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_opt_ PFILE_OBJECT FileObject
     );
 
 \f
@@ -591,47 +699,48 @@ CdUnlockVolumeInternal (
 
 VOID
 CdLookupPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG PathEntryOffset,
-    IN ULONG Ordinal,
-    IN BOOLEAN VerifyBounds,
-    IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG PathEntryOffset,
+    _In_ ULONG Ordinal,
+    _In_ BOOLEAN VerifyBounds,
+    _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
     );
 
 BOOLEAN
 CdLookupNextPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PPATH_ENUM_CONTEXT PathContext,
-    IN OUT PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PPATH_ENUM_CONTEXT PathContext,
+    _Inout_ PPATH_ENTRY PathEntry
     );
 
+_Success_(return != FALSE)\f
 BOOLEAN
 CdFindPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB ParentFcb,
-    IN PCD_NAME DirName,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB ParentFcb,
+    _In_ PCD_NAME DirName,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
     );
 
 VOID
 CdUpdatePathEntryName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PPATH_ENTRY PathEntry,
-    IN BOOLEAN IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PPATH_ENTRY PathEntry,
+    _In_ BOOLEAN IgnoreCase
     );
 
 //
 //  VOID
 //  CdInitializeCompoundPathEntry (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
 //      );
 //
 //  VOID
 //  CdCleanupCompoundPathEntry (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
 //      );
 //
 
@@ -655,26 +764,27 @@ CdUpdatePathEntryName (
 
 VOID
 CdInsertPrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PFCB ParentFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _Inout_ PFCB ParentFcb
     );
 
 VOID
 CdRemovePrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdFindPrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PFCB *CurrentFcb,
-    IN OUT PUNICODE_STRING RemainingName,
-    IN BOOLEAN IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB *CurrentFcb,
+    _Inout_ PUNICODE_STRING RemainingName,
+    _In_ BOOLEAN IgnoreCase
     );
 
 \f
@@ -706,93 +816,98 @@ typedef enum _TYPE_OF_ACQUIRE {
 
 } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE;
 
+_Requires_lock_held_(_Global_critical_region_)
+_When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
+_When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
+_When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
+_When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
 BOOLEAN
 CdAcquireResource (
-    IN PIRP_CONTEXT IrpContext,
-    IN PERESOURCE Resource,
-    IN BOOLEAN IgnoreWait,
-    IN TYPE_OF_ACQUIRE Type
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PERESOURCE Resource,
+    _In_ BOOLEAN IgnoreWait,
+    _In_ TYPE_OF_ACQUIRE Type
     );
 
 //
 //  BOOLEAN
 //  CdAcquireCdData (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdReleaseCdData (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //    );
 //
 //  BOOLEAN
 //  CdAcquireVcbExclusive (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PVCB Vcb,
-//      IN BOOLEAN IgnoreWait
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PVCB Vcb,
+//      _In_ BOOLEAN IgnoreWait
 //      );
 //
 //  BOOLEAN
 //  CdAcquireVcbShared (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PVCB Vcb,
-//      IN BOOLEAN IgnoreWait
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PVCB Vcb,
+//      _In_ BOOLEAN IgnoreWait
 //      );
 //
 //  VOID
 //  CdReleaseVcb (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PVCB Vcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PVCB Vcb
 //      );
 //
 //  VOID
 //  CdAcquireAllFiles (
-//      IN PIRP_CONTEXT,
-//      IN PVCB Vcb
+//      _In_ PIRP_CONTEXT,
+//      _In_ PVCB Vcb
 //      );
 //
 //  VOID
 //  CdReleaseAllFiles (
-//      IN PIRP_CONTEXT,
-//      IN PVCB Vcb
+//      _In_ PIRP_CONTEXT,
+//      _In_ PVCB Vcb
 //      );
 //
 //  VOID
 //  CdAcquireFileExclusive (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb,
 //      );
 //
 //  VOID
 //  CdAcquireFileShared (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdReleaseFile (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //    );
 //
 //  BOOLEAN
 //  CdAcquireFcbExclusive (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
-//      IN BOOLEAN IgnoreWait
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb,
+//      _In_ BOOLEAN IgnoreWait
 //      );
 //
 //  BOOLEAN
 //  CdAcquireFcbShared (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
-//      IN BOOLEAN IgnoreWait
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb,
+//      _In_ BOOLEAN IgnoreWait
 //      );
 //
 //  BOOLEAN
 //  CdReleaseFcb (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
@@ -805,27 +920,40 @@ CdAcquireResource (
 //
 //  VOID
 //  CdLockVcb (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdUnlockVcb (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdLockFcb (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdUnlockFcb (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 
+
+#define CdAcquireCacheForRead( IC)                                                      \
+    ExAcquireResourceSharedLite( &(IC)->Vcb->SectorCacheResource, TRUE)
+    
+#define CdAcquireCacheForUpdate( IC)                                                    \
+    ExAcquireResourceExclusiveLite( &(IC)->Vcb->SectorCacheResource, TRUE)
+    
+#define CdReleaseCache( IC)                                                             \
+    ExReleaseResourceLite( &(IC)->Vcb->SectorCacheResource);
+
+#define CdConvertCacheToShared( IC)                                                     \
+    ExConvertExclusiveToSharedLite( &(IC)->Vcb->SectorCacheResource);
+
 #define CdAcquireCdData(IC)                                                             \
     ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
 
@@ -878,21 +1006,38 @@ CdAcquireResource (
 
 #define CdLockVcb(IC,V)                                                                 \
     ExAcquireFastMutex( &(V)->VcbMutex );                                               \
-    ASSERT( NULL == (V)->VcbLockThread);                                                \
+    NT_ASSERT( NULL == (V)->VcbLockThread);                                             \
     (V)->VcbLockThread = PsGetCurrentThread()
 
 #define CdUnlockVcb(IC,V)                                                               \
-    ASSERT( NULL != (V)->VcbLockThread);                                                \
+    NT_ASSERT( NULL != (V)->VcbLockThread);                                             \
     (V)->VcbLockThread = NULL;                                                          \
     ExReleaseFastMutex( &(V)->VcbMutex )
 
+#if defined(_PREFAST_)
+
+_Success_(return)
+_IRQL_saves_global_(OldIrql, FastMutex)
+BOOLEAN DummySaveIrql(_Inout_ PFAST_MUTEX FastMutex);
+
+_Success_(return)
+_IRQL_restores_global_(OldIrql, FastMutex)
+BOOLEAN DummyRestoreIrql(_Inout_ PFAST_MUTEX FastMutex);
+#endif // _PREFAST_
+
 #define CdLockFcb(IC,F) {                                                               \
     PVOID _CurrentThread = PsGetCurrentThread();                                        \
     if (_CurrentThread != (F)->FcbLockThread) {                                         \
         ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex );                              \
-        ASSERT( (F)->FcbLockCount == 0 );                                               \
+        NT_ASSERT( (F)->FcbLockCount == 0 );                                            \
+        _Analysis_assume_( (F)->FcbLockCount == 0 );                                    \
         (F)->FcbLockThread = _CurrentThread;                                            \
     }                                                                                   \
+    else                                                                                \
+    {                                                                                   \
+        _Analysis_assume_lock_held_( (F)->FcbNonpaged->FcbMutex );                      \
+        _Analysis_assume_(FALSE != DummySaveIrql(&(F)->FcbNonpaged->FcbMutex));   \
+    }                                                                                   \
     (F)->FcbLockCount += 1;                                                             \
 }
 
@@ -902,44 +1047,67 @@ CdAcquireResource (
         (F)->FcbLockThread = NULL;                                                      \
         ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex );                              \
     }                                                                                   \
+    else                                                                                \
+    {                                                                                   \
+        _Analysis_assume_lock_not_held_( (F)->FcbNonpaged->FcbMutex );                  \
+        _Analysis_assume_(FALSE != DummyRestoreIrql(&(F)->FcbNonpaged->FcbMutex)); \
+    }                                                                                   \
 }
 
+//
+//  The following macro is used to retrieve the oplock structure within
+//  the Fcb. This structure was moved to the advanced Fcb header
+//  in Win8.
+//
+
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+
+#define CdGetFcbOplock(F)   &(F)->Header.Oplock
+
+#else
+
+#define CdGetFcbOplock(F)   &(F)->Oplock
+
+#endif
+
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdNoopAcquire (
-    IN PVOID Fcb,
-    IN BOOLEAN Wait
+    _In_ PVOID Fcb,
+    _In_ BOOLEAN Wait
     );
 
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdNoopRelease (
-    IN PVOID Fcb
+    _In_ PVOID Fcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdAcquireForCache (
-    IN PFCB Fcb,
-    IN BOOLEAN Wait
+    _Inout_ PFCB Fcb,
+    _In_ BOOLEAN Wait
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_lock_(*Fcb->Resource)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdReleaseFromCache (
-    IN PFCB Fcb
+    _Inout_ PFCB Fcb
     );
 
-VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdAcquireForCreateSection (
-    IN PFILE_OBJECT FileObject
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdFilterCallbackAcquireForCreateSection (
+    _In_ PFS_FILTER_CALLBACK_DATA CallbackData,
+    _Unreferenced_parameter_ PVOID *CompletionContext
     );
 
+_Function_class_(FAST_IO_RELEASE_FILE)
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdReleaseForCreateSection (
-    IN PFILE_OBJECT FileObject
+    _In_ PFILE_OBJECT FileObject
     );
 
 \f
@@ -949,108 +1117,110 @@ CdReleaseForCreateSection (
 
 VOID
 CdInitializeVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb,
-    IN PDEVICE_OBJECT TargetDeviceObject,
-    IN PVPB Vpb,
-    IN PCDROM_TOC CdromToc,
-    IN ULONG TocLength,
-    IN ULONG TocTrackCount,
-    IN ULONG TocDiskFlags,
-    IN ULONG BlockFactor,
-    IN ULONG MediaChangeCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_ __drv_aliasesMem PDEVICE_OBJECT TargetDeviceObject,
+    _In_ __drv_aliasesMem PVPB Vpb,
+    _In_ __drv_aliasesMem PCDROM_TOC_LARGE CdromToc,
+    _In_ ULONG TocLength,
+    _In_ ULONG TocTrackCount,
+    _In_ ULONG TocDiskFlags,
+    _In_ ULONG BlockFactor,
+    _In_ ULONG MediaChangeCount
     );
 
 VOID
 CdUpdateVcbFromVolDescriptor (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb,
-    IN PCHAR RawIsoVd OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_reads_bytes_opt_(SECTOR_SIZE) PCHAR RawIsoVd
     );
 
 VOID
 CdDeleteVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     );
 
 PFCB
 CdCreateFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN FILE_ID FileId,
-    IN NODE_TYPE_CODE NodeTypeCode,
-    OUT PBOOLEAN FcbExisted OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ FILE_ID FileId,
+    _In_ NODE_TYPE_CODE NodeTypeCode,
+    _Out_opt_ PBOOLEAN FcbExisted
     );
 
 VOID
 CdInitializeFcbFromPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFCB ParentFcb OPTIONAL,
-    IN PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_opt_ PFCB ParentFcb,
+    _In_ PPATH_ENTRY PathEntry
     );
 
 VOID
 CdInitializeFcbFromFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFCB ParentFcb OPTIONAL,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ PFCB ParentFcb,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     );
 
 PCCB
 CdCreateCcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG Flags
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG Flags
     );
 
 VOID
 CdDeleteCcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCCB Ccb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ __drv_freesMem( Pool ) PCCB Ccb
     );
 
+_When_(RaiseOnError || return, _At_(Fcb->FileLock, _Post_notnull_))
+_When_(RaiseOnError, _At_(IrpContext, _Pre_notnull_))
 BOOLEAN
 CdCreateFileLock (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PFCB Fcb,
-    IN BOOLEAN RaiseOnError
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ BOOLEAN RaiseOnError
     );
 
 VOID
 CdDeleteFileLock (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_LOCK FileLock
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFILE_LOCK FileLock
     );
 
-PIRP_CONTEXT
+_Ret_valid_ PIRP_CONTEXT
 CdCreateIrpContext (
-    IN PIRP Irp,
-    IN BOOLEAN Wait
+    _In_ PIRP Irp,
+    _In_ BOOLEAN Wait
     );
 
 VOID
 CdCleanupIrpContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN BOOLEAN Post
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ BOOLEAN Post
     );
 
 VOID
 CdInitializeStackIrpContext (
-    OUT PIRP_CONTEXT IrpContext,
-    IN PIRP_CONTEXT_LITE IrpContextLite
+    _Out_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP_CONTEXT_LITE IrpContextLite
     );
 
 //
 //  PIRP_CONTEXT_LITE
 //  CdCreateIrpContextLite (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdFreeIrpContextLite (
-//      IN PIRP_CONTEXT_LITE IrpContextLite
+//      _Inout_ PIRP_CONTEXT_LITE IrpContextLite
 //      );
 //
 
@@ -1060,52 +1230,53 @@ CdInitializeStackIrpContext (
 #define CdFreeIrpContextLite(ICL)  \
     CdFreePool( &(ICL) )
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdTeardownStructures (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB StartingFcb,
-    OUT PBOOLEAN RemovedStartingFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB StartingFcb,
+    _Out_ PBOOLEAN RemovedStartingFcb
     );
 
 //
 //  VOID
 //  CdIncrementCleanupCounts (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdDecrementCleanupCounts (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdIncrementReferenceCounts (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
-//      IN ULONG ReferenceCount
-//      IN ULONG UserReferenceCount
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb,
+//      _In_ ULONG ReferenceCount
+//      _In_ ULONG UserReferenceCount
 //      );
 //
 //  VOID
 //  CdDecrementReferenceCounts (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb,
-//      IN ULONG ReferenceCount
-//      IN ULONG UserReferenceCount
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb,
+//      _In_ ULONG ReferenceCount
+//      _In_ ULONG UserReferenceCount
 //      );
 //
 //  VOID
 //  CdIncrementFcbReference (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdDecrementFcbReference (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 
@@ -1157,26 +1328,26 @@ CdTeardownStructures (
 
 PFCB
 CdLookupFcbTable (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN FILE_ID FileId
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ FILE_ID FileId
     );
 
 PFCB
 CdGetNextFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PVOID *RestartKey
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ PVOID *RestartKey
     );
 
 NTSTATUS
 CdProcessToc (
-    IN PIRP_CONTEXT IrpContext,
-    IN PDEVICE_OBJECT TargetDeviceObject,
-    IN PCDROM_TOC CdromToc,
-    IN OUT PULONG Length,
-    OUT PULONG TrackCount,
-    OUT PULONG DiskFlags
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PDEVICE_OBJECT TargetDeviceObject,
+    _In_ PCDROM_TOC_LARGE CdromToc,
+    _Inout_ PULONG Length,
+    _Out_ PULONG TrackCount,
+    _Inout_ PULONG DiskFlags
     );
 
 //
@@ -1185,19 +1356,19 @@ CdProcessToc (
 //
 
 #define CdPagedPool                 PagedPool
-#define CdNonPagedPool              NonPagedPool
-#define CdNonPagedPoolCacheAligned  NonPagedPoolCacheAligned
+#define CdNonPagedPool              NonPagedPoolNx
+#define CdNonPagedPoolCacheAligned  NonPagedPoolNxCacheAligned
 
 
 //
 //  Verification support routines.  Contained in verfysup.c
 //
 
-/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
-static inline
+
+INLINE
 BOOLEAN
-CdOperationIsDasdOpen(
-    IN PIRP_CONTEXT IrpContext
+CdOperationIsDasdOpen (
+    _In_ PIRP_CONTEXT IrpContext
     )
 {
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
@@ -1207,37 +1378,44 @@ CdOperationIsDasdOpen(
             (IrpSp->FileObject->RelatedFileObject == NULL));
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdPerformVerify (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PDEVICE_OBJECT DeviceToVerify
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PDEVICE_OBJECT DeviceToVerify
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdCheckForDismount (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB,
-    IN BOOLEAN Force
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_ BOOLEAN Force
+    );
+
+BOOLEAN
+CdMarkDevForVerifyIfVcbMounted (
+    _Inout_ PVCB Vcb
     );
 
 VOID
 CdVerifyVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     );
 
 BOOLEAN
 CdVerifyFcbOperation (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PFCB Fcb
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdDismountVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     );
 
 
@@ -1258,8 +1436,8 @@ CdDismountVcb (
 //
 //  BOOLEAN
 //  CdIsRawDevice (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN NTSTATUS Status
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ NTSTATUS Status
 //      );
 //
 
@@ -1274,24 +1452,25 @@ CdDismountVcb (
 //  workque.c
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
-CdFsdPostRequest(
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+CdFsdPostRequest (
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdPrePostIrp (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdOplockComplete (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 \f
@@ -1304,9 +1483,7 @@ CdOplockComplete (
 //  otherwise
 //
 
-/* ReactOS Change: GCC doesn't understand the comment style */
-/*
- //#ifndef BooleanFlagOn
+//#ifndef BooleanFlagOn
 //#define BooleanFlagOn(F,SF) (    \
 //    (BOOLEAN)(((F) & (SF)) != 0) \
 //)
@@ -1323,20 +1500,19 @@ CdOplockComplete (
 //    (Flags) &= ~(SingleFlag);         \
 //}
 //#endif
-*/
 
 //
 //      CAST
 //      Add2Ptr (
-//          IN PVOID Pointer,
-//          IN ULONG Increment
-//          IN (CAST)
+//          _In_ PVOID Pointer,
+//          _In_ ULONG Increment
+//          _In_ (CAST)
 //          );
 //
 //      ULONG
 //      PtrOffset (
-//          IN PVOID BasePtr,
-//          IN PVOID OffsetPtr
+//          _In_ PVOID BasePtr,
+//          _In_ PVOID OffsetPtr
 //          );
 //
 
@@ -1399,6 +1575,15 @@ CdOplockComplete (
     ((ULONG) (L)) >> SECTOR_SHIFT                                       \
 )
 
+INLINE
+ULONG
+SectorsFromLlBytes( 
+    ULONGLONG Bytes
+) {
+
+    return (ULONG)(Bytes >> SECTOR_SHIFT);
+}
+
 #define LlBytesFromSectors(L) (                                         \
     Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT )                       \
 )
@@ -1499,61 +1684,97 @@ typedef union _USHORT2 {
     *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
     }
 
-\f
+//
+//  This macro copies an unaligned src longword to a dst longword,
+//  performing an little/big endian swap.
+//
+
+#define SwapCopyUchar4(Dst,Src) {                                        \
+    *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3);     \
+    *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \
+    *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
+    *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src));     \
+}
+
+VOID
+CdLbnToMmSsFf (
+    _In_ ULONG Blocks,
+    _Out_writes_(3) PUCHAR Msf
+    );
+
 //
 //  Following routines handle entry in and out of the filesystem.  They are
 //  contained in CdData.c
 //
 
+_IRQL_requires_max_(APC_LEVEL)
+__drv_dispatchType(DRIVER_DISPATCH)
+__drv_dispatchType(IRP_MJ_CREATE)
+__drv_dispatchType(IRP_MJ_CLOSE)
+__drv_dispatchType(IRP_MJ_READ)
+__drv_dispatchType(IRP_MJ_WRITE)
+__drv_dispatchType(IRP_MJ_QUERY_INFORMATION)
+__drv_dispatchType(IRP_MJ_SET_INFORMATION)
+__drv_dispatchType(IRP_MJ_QUERY_VOLUME_INFORMATION)
+__drv_dispatchType(IRP_MJ_DIRECTORY_CONTROL)
+__drv_dispatchType(IRP_MJ_FILE_SYSTEM_CONTROL)
+__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
+__drv_dispatchType(IRP_MJ_LOCK_CONTROL)
+__drv_dispatchType(IRP_MJ_CLEANUP)
+__drv_dispatchType(IRP_MJ_PNP)
+__drv_dispatchType(IRP_MJ_SHUTDOWN)
 NTSTATUS
 CdFsdDispatch (
-    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
-    IN PIRP Irp
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp
     );
 
+// DRIVER_DISPATCH CdFsdDispatch;
+
 LONG
 CdExceptionFilter (
-    IN PIRP_CONTEXT IrpContext,
-    IN PEXCEPTION_POINTERS ExceptionPointer
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PEXCEPTION_POINTERS ExceptionPointer
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdProcessException (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PIRP Irp,
-    IN NTSTATUS ExceptionCode
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ NTSTATUS ExceptionCode
     );
 
 VOID
 CdCompleteRequest (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PIRP Irp OPTIONAL,
-    IN NTSTATUS Status
+    _Inout_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_opt_ PIRP Irp,
+    _In_ NTSTATUS Status
     );
 
 //
 //  VOID
 //  CdRaiseStatus (
-//      IN PRIP_CONTEXT IrpContext,
-//      IN NT_STATUS Status
+//      _In_ PRIP_CONTEXT IrpContext,
+//      _In_ NT_STATUS Status
 //      );
 //
 //  VOID
 //  CdNormalizeAndRaiseStatus (
-//      IN PRIP_CONTEXT IrpContext,
-//      IN NT_STATUS Status
+//      _In_ PRIP_CONTEXT IrpContext,
+//      _In_ NT_STATUS Status
 //      );
 //
 
 #if 0
 #define AssertVerifyDevice(C, S)                                                    \
-    ASSERT( (C) == NULL ||                                                          \
+    NT_ASSERT( (C) == NULL ||                                                          \
             FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) ||                        \
             !((S) == STATUS_VERIFY_REQUIRED &&                                      \
               IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
 
 #define AssertVerifyDeviceIrp(I)                                                    \
-    ASSERT( (I) == NULL ||                                                          \
+    NT_ASSERT( (I) == NULL ||                                                          \
             !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED &&                   \
               ((I)->Tail.Overlay.Thread == NULL ||                                  \
                 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
@@ -1567,12 +1788,12 @@ CdCompleteRequest (
 
 DECLSPEC_NORETURN
 VOID
-CdRaiseStatusEx(
-    IN PIRP_CONTEXT IrpContext,
-    IN NTSTATUS Status,
-    IN BOOLEAN NormalizeStatus,
-    IN OPTIONAL ULONG FileId,
-    IN OPTIONAL ULONG Line
+CdRaiseStatusEx (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ NTSTATUS Status,
+    _In_ BOOLEAN NormalizeStatus,
+    _In_opt_ ULONG FileId,
+    _In_opt_ ULONG Line
     );
 
 #else
@@ -1581,11 +1802,11 @@ INLINE
 DECLSPEC_NORETURN
 VOID
 CdRaiseStatusEx(
-    IN PIRP_CONTEXT IrpContext,
-    IN NTSTATUS Status,
-    IN BOOLEAN NormalizeStatus,
-    IN ULONG Fileid,
-    IN ULONG Line
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ NTSTATUS Status,
+    _In_ BOOLEAN NormalizeStatus,
+    _In_ ULONG Fileid,
+    _In_ ULONG Line
     )
 {
     if (NormalizeStatus)  {
@@ -1611,93 +1832,104 @@ CdRaiseStatusEx(
 //  Following are the fast entry points.
 //
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastQueryBasicInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    IN OUT PFILE_BASIC_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+//  _Success_(return != FALSE)
+//  BOOLEAN
+//  CdFastQueryBasicInfo (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ BOOLEAN Wait,
+//      _Out_ PFILE_BASIC_INFORMATION Buffer,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastQueryStdInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    IN OUT PFILE_STANDARD_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+FAST_IO_QUERY_BASIC_INFO CdFastQueryBasicInfo;
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastLock (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN PLARGE_INTEGER Length,
-    PEPROCESS ProcessId,
-    ULONG Key,
-    BOOLEAN FailImmediately,
-    BOOLEAN ExclusiveLock,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+//  _Success_(return != FALSE)
+//  BOOLEAN
+//  CdFastQueryStdInfo (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ BOOLEAN Wait,
+//      _Out_ PFILE_STANDARD_INFORMATION Buffer,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastUnlockSingle (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN PLARGE_INTEGER Length,
-    PEPROCESS ProcessId,
-    ULONG Key,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+FAST_IO_QUERY_STANDARD_INFO CdFastQueryStdInfo;
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastUnlockAll (
-    IN PFILE_OBJECT FileObject,
-    PEPROCESS ProcessId,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+//  BOOLEAN
+//  CdFastLock (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ PLARGE_INTEGER FileOffset,
+//      _In_ PLARGE_INTEGER Length,
+//      _In_ PEPROCESS ProcessId,
+//      _In_ ULONG Key,
+//      _In_ BOOLEAN FailImmediately,
+//      _In_ BOOLEAN ExclusiveLock,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastUnlockAllByKey (
-    IN PFILE_OBJECT FileObject,
-    PVOID ProcessId,
-    ULONG Key,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+FAST_IO_LOCK CdFastLock;
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastIoCheckIfPossible (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN ULONG Length,
-    IN BOOLEAN Wait,
-    IN ULONG LockKey,
-    IN BOOLEAN CheckForReadOperation,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+//  BOOLEAN
+//  CdFastUnlockSingle (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ PLARGE_INTEGER FileOffset,
+//      _In_ PLARGE_INTEGER Length,
+//      _In_ PEPROCESS ProcessId,
+//      _In_ ULONG Key,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
 
-BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdFastQueryNetworkInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
-    );
+FAST_IO_UNLOCK_SINGLE CdFastUnlockSingle;
+
+//  BOOLEAN
+//  CdFastUnlockAll (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ PEPROCESS ProcessId,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
+
+FAST_IO_UNLOCK_ALL CdFastUnlockAll;
+
+//  BOOLEAN
+//  CdFastUnlockAllByKey (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ PVOID ProcessId,
+//      _In_ ULONG Key,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
+
+FAST_IO_UNLOCK_ALL_BY_KEY CdFastUnlockAllByKey;
+
+//  BOOLEAN
+//  CdFastIoCheckIfPossible (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ PLARGE_INTEGER FileOffset,
+//      _In_ ULONG Length,
+//      _In_ BOOLEAN Wait,
+//      _In_ ULONG LockKey,
+//      _In_ BOOLEAN CheckForReadOperation,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
+
+FAST_IO_CHECK_IF_POSSIBLE CdFastIoCheckIfPossible;
+
+//  _Success_(return != FALSE)
+//  BOOLEAN
+//  CdFastQueryNetworkInfo (
+//      _In_ PFILE_OBJECT FileObject,
+//      _In_ BOOLEAN Wait,
+//      _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
+//      _Out_ PIO_STATUS_BLOCK IoStatus,
+//      _In_ PDEVICE_OBJECT DeviceObject
+//      );
+
+FAST_IO_QUERY_NETWORK_OPEN_INFO CdFastQueryNetworkInfo;
 
 //
 //  Following are the routines to handle the top level thread logic.
@@ -1705,15 +1937,15 @@ CdFastQueryNetworkInfo (
 
 VOID
 CdSetThreadContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PTHREAD_CONTEXT ThreadContext
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PTHREAD_CONTEXT ThreadContext
     );
 
 
 //
 //  VOID
 //  CdRestoreThreadContext (
-//      IN PIRP_CONTEXT IrpContext
+//      _Inout_ PIRP_CONTEXT IrpContext
 //      );
 //
 
@@ -1724,8 +1956,8 @@ CdSetThreadContext (
 
 ULONG
 CdSerial32 (
-    IN PCHAR Buffer,
-    IN ULONG ByteCount
+    _In_reads_bytes_(ByteCount) PCHAR Buffer,
+    _In_ ULONG ByteCount
     );
 
 //
@@ -1751,7 +1983,7 @@ CdSerial32 (
 
 #define CdIsFastIoPossible(F) ((BOOLEAN)                                            \
     ((((F)->Vcb->VcbCondition != VcbMounted ) ||                                    \
-      !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ?                               \
+      !FsRtlOplockIsFastIoPossible( CdGetFcbOplock(F) )) ?                          \
                                                                                     \
      FastIoIsNotPossible :                                                          \
                                                                                     \
@@ -1769,14 +2001,16 @@ CdSerial32 (
 //  work routine.
 //
 
-VOID
-CdFspDispatch (                             //  implemented in FspDisp.c
-    IN PIRP_CONTEXT IrpContext
-    );
+//  VOID
+//  CdFspDispatch (                             //  implemented in FspDisp.c
+//      _Inout_ PIRP_CONTEXT IrpContext
+//      );
+
+WORKER_THREAD_ROUTINE CdFspDispatch;
 
 VOID
 CdFspClose (                                //  implemented in Close.c
-    IN PVCB Vcb OPTIONAL
+    _In_opt_ PVCB Vcb
     );
 
 //
@@ -1784,78 +2018,103 @@ CdFspClose (                                //  implemented in Close.c
 //  based on the IrpSp major functions.
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonCreate (                            //  Implemented in Create.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonClose (                             //  Implemented in Close.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonRead (                              //  Implemented in Read.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdCommonWrite (                             //  Implemented in Write.c
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonQueryInfo (                         //  Implemented in FileInfo.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonSetInfo (                           //  Implemented in FileInfo.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonQueryVolInfo (                      //  Implemented in VolInfo.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonDirControl (                        //  Implemented in DirCtrl.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonFsControl (                         //  Implemented in FsCtrl.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 NTSTATUS
 CdCommonDevControl (                        //  Implemented in DevCtrl.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 NTSTATUS
 CdCommonLockControl (                       //  Implemented in LockCtrl.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonCleanup (                           //  Implemented in Cleanup.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonPnp (                               //  Implemented in Pnp.c
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdCommonShutdown (                         //  Implemented in Shutdown.c
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+
 \f
 //
 //  The following macros are used to establish the semantics needed
@@ -1885,24 +2144,17 @@ CdCommonPnp (                               //  Implemented in Pnp.c
 //      #define try_return(S)  { S; goto try_exit; }
 //
 
-#ifndef __REACTOS__
 #define try_return(S) { S; goto try_exit; }
 #define try_leave(S) { S; leave; }
-#else
-#define try_return(S) { S; goto try_exit; }
-#define try_leave(S) { S; _SEH2_LEAVE; }
-#endif
-
 
 //
 //  Encapsulate safe pool freeing
 //
-/* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
-#define CdFreePool(x) _CdFreePool((PVOID*)(x))
 
-/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
-static inline void _CdFreePool(
-    IN PVOID *Pool
+INLINE
+VOID
+CdFreePool(
+    _Inout_ _At_(*Pool, __drv_freesMem(Mem) _Post_null_) PVOID *Pool
     )
 {
     if (*Pool != NULL) {
@@ -1912,6 +2164,116 @@ static inline void _CdFreePool(
     }
 }
 
+#ifdef CDFS_TELEMETRY_DATA
+
+//
+//  CDFS Telemetry.  Current implementation uses the Telemetry TraceLogging APIs.
+//
+//  The Telemetry TraceLoggingWrite() routines use a lot of stack space. We must
+//  therefor wrap all our telemetry points with our own routines, and add a guard to
+//  make sure there's enough stack space to call these routines.
+//
+//  These telemetry routines should not be called on high-performance code paths.
+//
+
+TRACELOGGING_DECLARE_PROVIDER( CdTelemetryProvider );
+
+VOID
+CdInitializeTelemetry (
+    VOID
+    );
+
+DECLSPEC_NOINLINE
+VOID
+CdTelemetryMount (
+        __in PGUID VolumeGuid,
+        __in NTSTATUS Status,
+        __in PVCB Vcb
+        );
+
+//
+//  Every additional argument passed to TraceLoggingWrite() consumes an additional
+//  16 to 32 bytes extra stack space. Having 512 bytes reserved space should be
+//  sufficient for up to 20 arguments or so. This will be less of course if our
+//  wrapper routines also declare their own local variables.
+//
+
+#define CDFS_TELEMETRY_STACK_THRESHOLD_DEFAULT  512    // for "small" telemetry points
+#define CDFS_TELEMETRY_STACK_THRESHOLD_LARGE    2048   // for "large" telemetry points
+
+INLINE
+BOOLEAN
+CdTelemetryGuard (
+    __in ULONG StackSpaceNeeded )
+/*++
+
+Routine Description:
+
+    This routine returns TRUE only when:
+
+      1)  There is an ETW listener, AND
+      2)  There is enough free stack space to safely call the Telemetry TraceLogging APIs
+
+    We'll also count how many times there wasn't enough stack space, and include this
+    value as part of the periodic cdfs Telemetry.
+
+Arguments:
+
+    StackSpaceNeeded - Stack space needed in bytes
+
+--*/
+{
+    ASSERT( IoGetRemainingStackSize() >= StackSpaceNeeded );
+
+    if (CdTelemetryProvider->LevelPlus1 <= 5) {
+
+        //
+        //  Bail out early if there are no ETW listeners
+        //
+
+        return FALSE;
+    }
+
+    if (IoGetRemainingStackSize() < StackSpaceNeeded) {
+
+        //
+        //  Count how many times it was unsafe to generate telemetry because of
+        //  not enough stack space.
+        //
+
+        InterlockedIncrement( &CdTelemetryData.MissedTelemetryPoints );
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+#define CdTelemetryMountSafe( VolumeGuid, Status, Vcb ) \
+    if (CdTelemetryGuard( CDFS_TELEMETRY_STACK_THRESHOLD_LARGE )) { \
+        CdTelemetryMount( VolumeGuid, Status, Vcb ); \
+    }
+
+#if DBG
+#define CDFS_TELEMETRY_PERIODIC_INTERVAL  CdTelemetryData.PeriodicInterval
+#else
+#define CDFS_TELEMETRY_PERIODIC_INTERVAL  INTERVAL_ONE_DAY
+#endif
+
+#else  // CDFS_TELEMETRY_DATA
+
+//
+//  When CDFS_TELEMETRY_DATA is not defined then the CdTelemetry___Safe() routines
+//  expand to nothing.  This minimizes the cdfs.sys binary footprint.  This also
+//  means that the places where these Safe() routines are called do not
+//  have to have to be surrounded by  #ifdef CDFS_TELEMETRY_DATA .. #endif
+//
+
+
+#define CdTelemetryMountSafe( ... )           NOTHING
+
+#endif  // CDFS_TELEMETRY_DATA
+
 #endif // _CDPROCS_
 
 
diff --git a/drivers/filesystems/cdfs_new/cdprocssrc.c b/drivers/filesystems/cdfs_new/cdprocssrc.c
new file mode 100644 (file)
index 0000000..a370cab
--- /dev/null
@@ -0,0 +1 @@
+#include "cdprocs.h"
\ No newline at end of file
index 1259349..72abe0a 100755 (executable)
@@ -133,7 +133,7 @@ Abstract:
         5. A fast mutex in the Vcb will protect access to the Fcb table and
             the open counts in the Vcb.  It is also used to modify the reference
             counts in all Fcbs.  This mutex cannot be acquired
-            exclusively and is an end resource.
+            exclusely and is an end resource.
 
         6. A fast mutex in the Fcb will synchronize access to all Fcb fields
             which aren't synchronized in some other way.  A thread may acquire
@@ -244,7 +244,7 @@ typedef struct _CD_NAME {
     UNICODE_STRING FileName;
 
     //
-    //  String containing the version number.
+    //  String containging the version number.
     //
 
     UNICODE_STRING VersionString;
@@ -318,7 +318,7 @@ typedef struct _CD_DATA {
     //  The type and size of this record (must be CDFS_NTC_DATA_HEADER)
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_DATA_HEADER) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
@@ -349,10 +349,6 @@ typedef struct _CD_DATA {
 
     PDEVICE_OBJECT FileSystemDeviceObject;
 
-#ifdef __REACTOS__
-    PDEVICE_OBJECT HddFileSystemDeviceObject;
-#endif
-
     //
     //  Following are used to manage the async and delayed close queue.
     //
@@ -360,7 +356,7 @@ typedef struct _CD_DATA {
     //      two close queues.
     //  ReduceDelayedClose - Indicates that we have hit the upper threshold
     //      for the delayed close queue and need to reduce it to lower threshold.
-    //
+    //  Flags - CD flags.
     //  AsyncCloseQueue - Queue of IrpContext waiting for async close operation.
     //  AsyncCloseCount - Number of entries on the async close queue.
     //
@@ -368,7 +364,7 @@ typedef struct _CD_DATA {
     //      operation.
     //  MaxDelayedCloseCount - Trigger delay close work at this threshold.
     //  MinDelayedCloseCount - Turn off delay close work at this threshold.
-    //  DelayedCloseCount - Number of entries on the delayed close queue.
+    //  DelayedCloseCount - Number of entries on the delayted close queue.
     //
     //  CloseItem - Workqueue item used to start FspClose thread.
     //
@@ -377,7 +373,7 @@ typedef struct _CD_DATA {
     ULONG AsyncCloseCount;
     BOOLEAN FspCloseActive;
     BOOLEAN ReduceDelayedClose;
-    USHORT PadUshort;
+    USHORT Flags;
 
     //
     //  The following fields describe the deferred close file objects.
@@ -418,7 +414,48 @@ typedef struct _CD_DATA {
 } CD_DATA;
 typedef CD_DATA *PCD_DATA;
 
-\f
+
+#define CD_FLAGS_SHUTDOWN                   (0x0001)
+
+
+//
+//  Since DVD drives allow > 100 "sessions", we need to use a larger TOC
+//  than the legacy CD definition.  The maximum is theoretically 0xaa-16 (max
+//  number of open tracks in a session), but it's quite possible that some
+//  drive does not enforce this, so we'll go with 169 (track 0xaa is always the 
+//  leadout).
+//
+
+#define MAXIMUM_NUMBER_TRACKS_LARGE 0xAA
+
+typedef struct _CDROM_TOC_LARGE {
+
+    //
+    // Header
+    //
+
+    UCHAR Length[2];  // add two bytes for this field
+    UCHAR FirstTrack;
+    UCHAR LastTrack;
+
+    //
+    // Track data
+    //
+
+    TRACK_DATA TrackData[ MAXIMUM_NUMBER_TRACKS_LARGE];
+    
+} CDROM_TOC_LARGE, *PCDROM_TOC_LARGE;
+
+typedef struct _CD_SECTOR_CACHE_CHUNK {
+
+    ULONG BaseLbn;
+    PUCHAR Buffer;
+    
+} CD_SECTOR_CACHE_CHUNK, *PCD_SECTOR_CACHE_CHUNK;
+
+#define CD_SEC_CACHE_CHUNKS  4
+#define CD_SEC_CHUNK_BLOCKS  0x18
+
 //
 //  The Vcb (Volume control block) record corresponds to every
 //  volume mounted by the file system.  They are ordered in a queue off
@@ -460,7 +497,7 @@ typedef struct _VCB {
     //  The type and size of this record (must be CDFS_NTC_VCB)
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_VCB) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
@@ -508,8 +545,8 @@ typedef struct _VCB {
     //
 
     ULONG VcbCleanup;
-    LONG VcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */
-    LONG VcbUserReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */
+    __volatile ULONG VcbReference;
+    __volatile ULONG VcbUserReference;
 
     //
     //  Fcb for the Volume Dasd file, root directory and the Path Table.
@@ -593,7 +630,7 @@ typedef struct _VCB {
     //  Volume TOC.  Cache this information for quick lookup.
     //
 
-    PCDROM_TOC CdromToc;
+    PCDROM_TOC_LARGE CdromToc;
     ULONG TocLength;
     ULONG TrackCount;
     ULONG DiskFlags;
@@ -625,8 +662,42 @@ typedef struct _VCB {
 
     PVPB SwapVpb;
 
-} VCB;
-typedef VCB *PVCB;
+    //
+    //  Directory block cache. Read large numbers of blocks on directory
+    //  reads, hoping to benefit from the fact that most mastered/pressed
+    //  discs clump metadata in one place thus allowing us to crudely
+    //  pre-cache and reduce seeks back to directory data during app install, 
+    //  file copy etc.
+    //
+    //  Note that the purpose of this is to PRE cache unread data,
+    //  not cache already read data (since Cc already provides that), thus
+    //  speeding initial access to the volume.
+    //
+
+    PUCHAR SectorCacheBuffer;
+    CD_SECTOR_CACHE_CHUNK SecCacheChunks[ CD_SEC_CACHE_CHUNKS];
+    ULONG SecCacheLRUChunkIndex;
+    
+    PIRP SectorCacheIrp;
+    KEVENT SectorCacheEvent;
+    ERESOURCE SectorCacheResource;
+
+#ifdef CDFS_TELEMETRY_DATA
+
+    //
+    //  An ID that is common across the volume stack used to correlate volume events and for telemetry purposes.
+    //  It may have a different value than the VolumeGuid.
+    //
+
+    GUID VolumeCorrelationId;
+
+#endif // CDFS_TELEMETRY_DATA
+
+#if DBG
+    ULONG SecCacheHits;
+    ULONG SecCacheMisses;
+#endif
+} VCB, *PVCB;
 
 #define VCB_STATE_HSG                               (0x00000001)
 #define VCB_STATE_ISO                               (0x00000002)
@@ -637,6 +708,8 @@ typedef VCB *PVCB;
 #define VCB_STATE_AUDIO_DISK                        (0x00000080)
 #define VCB_STATE_NOTIFY_REMOUNT                    (0x00000100)
 #define VCB_STATE_VPB_NOT_ON_DEVICE                 (0x00000200)
+#define VCB_STATE_SHUTDOWN                          (0x00000400)
+#define VCB_STATE_DISMOUNTED                        (0x00000800)
 
 \f
 //
@@ -659,7 +732,7 @@ typedef struct _VOLUME_DEVICE_OBJECT {
     //  executed later.
     //
 
-    LONG PostedRequestCount; /* ReactOS Change: GCC "pointer targets in passing argument 1 of 'InterlockedDecrement' differ in signedness" */
+    __volatile ULONG PostedRequestCount;
 
     //
     //  The following field indicates the number of IRP's waiting
@@ -706,12 +779,14 @@ typedef enum _FCB_CONDITION {
 
 typedef struct _FCB_DATA {
 
+#if (NTDDI_VERSION < NTDDI_WIN8)
     //
     //  The following field is used by the oplock module
     //  to maintain current oplock information.
     //
 
     OPLOCK Oplock;
+#endif
 
     //
     //  The following field is used by the filelock module
@@ -780,12 +855,12 @@ typedef struct _FCB_NONPAGED {
     //  Type and size of this record must be CDFS_NTC_FCB_NONPAGED
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_FCB_NONPAGED) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
     //  The following field contains a record of special pointers used by
-    //  MM and Cache to manipulate section objects.  Note that the values
+    //  MM and Cache to manipluate section objects.  Note that the values
     //  are set outside of the file system.  However the file system on an
     //  open/create will set the file object's SectionObject field to
     //  point to this field
@@ -882,7 +957,7 @@ typedef struct _FCB {
     //
 
     ULONG FcbCleanup;
-    LONG FcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */
+    __volatile ULONG FcbReference;
     ULONG FcbUserReference;
 
     //
@@ -991,7 +1066,7 @@ typedef struct _CCB {
     //  Type and size of this record (must be CDFS_NTC_CCB)
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_CCB) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
@@ -1026,6 +1101,7 @@ typedef CCB *PCCB;
 #define CCB_FLAG_IGNORE_CASE                    (0x00000004)
 #define CCB_FLAG_OPEN_WITH_VERSION              (0x00000008)
 #define CCB_FLAG_DISMOUNT_ON_CLOSE              (0x00000010)
+#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO         (0x00000020)
 
 //
 //  Following flags refer to index enumeration.
@@ -1041,7 +1117,7 @@ typedef CCB *PCCB;
 
 \f
 //
-//  The Irp Context record is allocated for every originating Irp.  It is
+//  The Irp Context record is allocated for every orginating Irp.  It is
 //  created by the Fsd dispatch routines, and deallocated by the CdComplete
 //  request routine
 //
@@ -1052,7 +1128,7 @@ typedef struct _IRP_CONTEXT {
     //  Type and size of this record (must be CDFS_NTC_IRP_CONTEXT)
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_IRP_CONTEXT) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
@@ -1197,7 +1273,7 @@ typedef struct _IRP_CONTEXT_LITE {
     //  Type and size of this record (must be CDFS_NTC_IRP_CONTEXT_LITE)
     //
 
-    NODE_TYPE_CODE NodeTypeCode;
+    _Field_range_(==, CDFS_NTC_IRP_CONTEXT_LITE) NODE_TYPE_CODE NodeTypeCode;
     NODE_BYTE_SIZE NodeByteSize;
 
     //
@@ -1242,9 +1318,9 @@ typedef struct _CD_IO_CONTEXT {
     //  These two fields are used for multiple run Io
     //
 
-    LONG IrpCount;
+    __volatile LONG IrpCount;
     PIRP MasterIrp;
-    NTSTATUS Status;
+    __volatile NTSTATUS Status;
     BOOLEAN AllocatedContext;
 
     union {
@@ -1491,7 +1567,7 @@ typedef DIRENT_ENUM_CONTEXT *PDIRENT_ENUM_CONTEXT;
 \f
 //
 //  Following structure is used to smooth out the differences in the HSG, ISO
-//  and Joliet directory entries.
+//  and Joliett directory entries.
 //
 
 typedef struct _DIRENT {
@@ -1763,5 +1839,71 @@ typedef AUDIO_PLAY_HEADER *PAUDIO_PLAY_HEADER;
         }                                                                               \
 }
 
+#ifdef CDFS_TELEMETRY_DATA
+// ============================================================================
+// ============================================================================
+//
+//                  Telemetry
+//
+// ============================================================================
+// ============================================================================
+
+typedef struct _CDFS_TELEMETRY_DATA_CONTEXT {
+
+    //
+    //  Number of times there was not enough stack space to generate telemetry
+    //
+
+    volatile LONG MissedTelemetryPoints;
+
+    //
+    //  System Time of the last periodic telemtry event.  System Time
+    //  is according to KeQuerySystemTime()
+    //
+
+    LARGE_INTEGER LastPeriodicTelemetrySystemTime;
+
+    //
+    //  TickCount of the last periodic telemtry event.  TickCount is
+    //  according to KeQueryTickCount()
+    //
+
+    LARGE_INTEGER LastPeriodicTelemetryTickCount;
+
+    //
+    //  Hint for Worker thread whether to generate
+    //  periodic telemetry or not
+    //
+
+    BOOLEAN GeneratePeriodicTelemetry;
+
+    //
+    // Guid for ID parity with other file systems telemetry.
+    //
+
+    GUID VolumeGuid;
+
+
+#if DBG
+
+    //
+    //  For DBG builds we want a machanism to change the frequency of
+    //  periodic events
+    //
+
+    LONGLONG PeriodicInterval;
+
+#endif
+
+    //
+    //  File system statistics at time of last period telemetry event
+    //
+
+    FILESYSTEM_STATISTICS CommonStats;
+
+} CDFS_TELEMETRY_DATA_CONTEXT, *PCDFS_TELEMETRY_DATA_CONTEXT;
+
+#endif // CDFS_TELEMETRY_DATA
+
 #endif // _CDSTRUC_
 
index a89be2f..a0d8ce4 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -22,11 +22,11 @@ Abstract:
 
 #define BugCheckFileId                   (CDFS_BUG_CHECK_CLEANUP)
 
-
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonCleanup (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -82,7 +82,7 @@ Return Value:
     TYPE_OF_OPEN TypeOfOpen;
 
     BOOLEAN SendUnlockNotification = FALSE;
-    BOOLEAN AttemptTeardown;
+    BOOLEAN AttemptTeardown = FALSE;
     BOOLEAN VcbAcquired = FALSE;
 
     PVCB Vcb;
@@ -148,7 +148,38 @@ Return Value:
     SetFlag( FileObject->Flags, FO_CLEANUP_COMPLETE );
 
     CdReleaseFile( IrpContext, Fcb);
-    
+
+    if (TypeOfOpen == UserVolumeOpen) {
+
+        //
+        //  For a force dismount, physically disconnect this Vcb from the device so 
+        //  a new mount can occur.  Vcb deletion cannot happen at this time since 
+        //  there is a reference on it associated with this very request,  but we'll 
+        //  call check for dismount again later after we process this close.
+        //
+        
+        if (FlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE )) {
+        
+            CdAcquireCdData( IrpContext );
+        
+            CdCheckForDismount( IrpContext, Vcb, TRUE );
+        
+            CdReleaseCdData( IrpContext );
+        
+        //
+        //  If this handle actually wrote something, flush the device buffers,
+        //  and then set the verify bit now just to be safe (in case there is no
+        //  dismount).
+        //
+        
+        } else if (FlagOn( FileObject->Flags, FO_FILE_MODIFIED )) {
+        
+            CdHijackIrpAndFlushDevice( IrpContext, Irp, Vcb->TargetDeviceObject );
+        
+            CdMarkDevForVerifyIfVcbMounted( Vcb );
+        }
+    }
+
     //
     //  Acquire the current file.
     //
@@ -159,7 +190,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
     
         //
         //  Case on the type of open that we are trying to cleanup.
@@ -187,7 +218,7 @@ Return Value:
             //  need to check for STATUS_PENDING.
             //
 
-            FsRtlCheckOplock( &Fcb->Oplock,
+            FsRtlCheckOplock( CdGetFcbOplock(Fcb),
                               Irp,
                               IrpContext,
                               NULL,
@@ -221,12 +252,13 @@ Return Value:
 
             break;
 
-        case UserVolumeOpen :
+        case UserVolumeOpen:
 
             break;
 
         default :
 
+#pragma prefast( suppress:__WARNING_USE_OTHER_FUNCTION, "argument bogus" )        
             CdBugCheck( TypeOfOpen, 0, 0 );
         }
 
@@ -257,7 +289,7 @@ Return Value:
 
         if (FileObject == Vcb->VolumeLockFileObject) {
 
-            ASSERT( FlagOn( Vcb->VcbState, VCB_STATE_LOCKED));
+            NT_ASSERT( FlagOn( Vcb->VcbState, VCB_STATE_LOCKED));
 
             IoAcquireVpbSpinLock( &SavedIrql ); 
 
@@ -279,15 +311,15 @@ Return Value:
 
         IoRemoveShareAccess( FileObject, &Fcb->ShareAccess );
 
-    } _SEH2_FINALLY {
+    } finally {
 
-        CdReleaseFcb( IrpContext, Fcb );
+       CdReleaseFcb( IrpContext, Fcb );
         
         if (SendUnlockNotification) {
             
             FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK );
         }
-    } _SEH2_END;
+    }
 
     //
     //  If appropriate, try to spark teardown by purging the volume.  Should
@@ -305,19 +337,19 @@ Return Value:
         
         CdAcquireCdData( IrpContext);
 
-        _SEH2_TRY {
+        try {
             
             CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
             VcbAcquired = TRUE;
             
             CdPurgeVolume( IrpContext, Vcb, FALSE );
 
-        } _SEH2_FINALLY {
+        } finally {
 
             if (VcbAcquired) { CdReleaseVcb( IrpContext, Vcb ); }
             
             CdReleaseCdData( IrpContext);
-        } _SEH2_END;
+        }
     }
 
     //
index d282779..5e45587 100755 (executable)
@@ -42,7 +42,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -54,36 +54,40 @@ Abstract:
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdCommonClosePrivate (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFCB Fcb,
-    IN ULONG UserReference,
-    IN BOOLEAN FromFsd
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ PFCB Fcb,
+    _In_ ULONG UserReference,
+    _In_ BOOLEAN FromFsd
     );
 
 VOID
 CdQueueClose (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG UserReference,
-    IN BOOLEAN DelayedClose
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG UserReference,
+    _In_ BOOLEAN DelayedClose
     );
 
 PIRP_CONTEXT
 CdRemoveClose (
-    IN PVCB Vcb OPTIONAL
+    _In_opt_ PVCB Vcb
     );
 
+//  Tell prefast this is a workitem routine
+IO_WORKITEM_ROUTINE CdCloseWorker;
+
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdCloseWorker (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID Context
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_opt_ PVOID Context
     );
 
 #ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, CdFspClose)
 #pragma alloc_text(PAGE, CdCommonClose)
 #pragma alloc_text(PAGE, CdCommonClosePrivate)
 #pragma alloc_text(PAGE, CdQueueClose)
@@ -94,7 +98,7 @@ CdCloseWorker (
 
 VOID
 CdFspClose (
-    IN PVCB Vcb OPTIONAL
+    _In_opt_ PVCB Vcb
     )
 
 /*++
@@ -120,7 +124,7 @@ Return Value:
     PIRP_CONTEXT IrpContext;
     IRP_CONTEXT StackIrpContext;
 
-    THREAD_CONTEXT ThreadContext;
+    THREAD_CONTEXT ThreadContext = {0};
 
     PFCB Fcb;
     ULONG UserReference;
@@ -137,8 +141,8 @@ Return Value:
     //
     //  Continue processing until there are no more closes to process.
     //
-    /* ReactOS Change: "GCC suggest parentheses around assignment used as truth value" */
-    while ((IrpContext = CdRemoveClose( Vcb ))) {
+
+    while ((IrpContext = CdRemoveClose( Vcb )) != NULL) {
 
         //
         //  If we don't have an IrpContext then use the one on the stack.
@@ -166,7 +170,7 @@ Return Value:
             //  Free the IrpContextLite.
             //
 
-            CdFreeIrpContextLite( IrpContext ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */
+            CdFreeIrpContextLite( (PIRP_CONTEXT_LITE) IrpContext );
 
             //
             //  Remember we have the IrpContext from the stack.
@@ -191,6 +195,8 @@ Return Value:
             IrpContext->ExceptionStatus = STATUS_SUCCESS;
         }
 
+        _Analysis_assume_(Fcb != NULL && Fcb->Vcb != NULL);
+
         //
         //  We have an IrpContext.  Now we need to set the top level thread
         //  context.
@@ -261,6 +267,9 @@ Return Value:
             }
 
             CurrentVcb = Fcb->Vcb;
+
+            _Analysis_assume_( CurrentVcb != NULL );
+            
             CdAcquireVcbShared( IrpContext, CurrentVcb, FALSE );
 
             VcbHoldCount = 0;
@@ -309,14 +318,15 @@ Return Value:
 
     }
 
+#pragma prefast(suppress:26165, "Esp:1153")
     FsRtlExitFileSystem();
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonClose (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -349,7 +359,6 @@ Return Value:
     ULONG UserReference = 0;
 
     BOOLEAN PotentialVcbTeardown = FALSE;
-    BOOLEAN ForceDismount = FALSE;
 
     PAGED_CODE();
 
@@ -397,13 +406,6 @@ Return Value:
 
         UserReference = 1;
 
-        //
-        //  Was a FSCTL_DISMOUNT issued on this handle?  If so,  we need to
-        //  force a dismount of the volume now.
-        //
-        
-        ForceDismount = BooleanFlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE);
-
         //
         //  We can always deallocate the Ccb if present.
         //
@@ -431,7 +433,8 @@ Return Value:
     //  if we can't acquire all of the resources.
     //
 
-    } else {
+    } 
+    else {
 
         //
         //  If we may be dismounting this volume then acquire the CdData
@@ -439,7 +442,7 @@ Return Value:
         //
         //  Since we now must make volumes go away as soon as reasonable after
         //  the last user handles closes, key off of the cleanup count.  It is
-        //  OK to do this more than necessary.  Since this Fcb could be holding
+        //  OK to do this more than neccesary.  Since this Fcb could be holding
         //  a number of other Fcbs (and thus their references), a simple check
         //  on reference count is not appropriate.
         //
@@ -447,33 +450,17 @@ Return Value:
         //  common case.
         //
 
-        if (((Vcb->VcbCleanup == 0) || ForceDismount) &&
+        if ((Vcb->VcbCleanup == 0) &&
             (Vcb->VcbCondition != VcbMounted))  {
 
             //
-            //  Possible.  Acquire CdData to synchronise with the remount path,  and
-            //  then repeat the tests.
-            //
-            //  Note that we must send the notification outside of any locks,  since 
-            //  the worker that processes the notify could also be calling into our 
-            //  pnp path which wants both CdData and VcbResource.  For a force dismount
-            //  the volume will be marked invalid (no going back),  so we will definitely
-            //  go ahead and dismount below.
+            //  Possible dismount.  Acquire CdData to synchronise with the remount path
+            //  before looking at the vcb condition again.
             //
 
-            if (ForceDismount)  {
-            
-                //
-                //  Send notification.
-                //
-                
-                FsRtlNotifyVolumeEvent( IoGetCurrentIrpStackLocation( Irp )->FileObject, 
-                                        FSRTL_VOLUME_DISMOUNT );
-            }
-            
             CdAcquireCdData( IrpContext );
 
-            if (((Vcb->VcbCleanup == 0) || ForceDismount) &&
+            if ((Vcb->VcbCleanup == 0) &&
                 (Vcb->VcbCondition != VcbMounted) &&
                 (Vcb->VcbCondition != VcbMountInProgress) &&
                 FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS ))  {
@@ -486,21 +473,16 @@ Return Value:
                 //  We can't dismount this volume now,  there are other references or
                 //  it's just been remounted.
                 //
-
-                CdReleaseCdData( IrpContext);
             }
-        }
 
-        if (ForceDismount)  {
-        
             //
-            //  Physically disconnect this Vcb from the device so a new mount can
-            //  occur.  Vcb deletion cannot happen at this time since there is
-            //  a handle on it associated with this very request,  but we'll call
-            //  check for dismount again later anyway.
+            //  Drop the global lock if we don't need it anymore.
             //
 
-            CdCheckForDismount( IrpContext, Vcb, TRUE );
+            if (!PotentialVcbTeardown) {
+
+                CdReleaseCdData( IrpContext );
+            }
         }
         
         //
@@ -522,7 +504,8 @@ Return Value:
         //  the request.
         //
 
-        } else if (PotentialVcbTeardown) {
+        } 
+        else if (PotentialVcbTeardown) {
 
             CdCheckForDismount( IrpContext, Vcb, FALSE );
         }
@@ -551,13 +534,14 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdCommonClosePrivate (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFCB Fcb,
-    IN ULONG UserReference,
-    IN BOOLEAN FromFsd
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ PFCB Fcb,
+    _In_ ULONG UserReference,
+    _In_ BOOLEAN FromFsd
     )
 
 /*++
@@ -651,6 +635,9 @@ Return Value:
 
         CdReleaseFcb( IrpContext, Fcb );
     }
+    else {
+        _Analysis_assume_lock_not_held_(Fcb->FcbNonpaged->FcbResource);
+    }
 
     //
     //  Release the Vcb and return to our caller.  Let him know we completed
@@ -663,10 +650,9 @@ Return Value:
 }
 
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdCloseWorker (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID Context
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_opt_ PVOID Context
     )
 /*++
 
@@ -687,16 +673,21 @@ Return Value:
 --*/
 
 {
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( DeviceObject );
+    UNREFERENCED_PARAMETER( Context );
+
     CdFspClose (NULL);
 }
 
 \f
 VOID
 CdQueueClose (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG UserReference,
-    IN BOOLEAN DelayedClose
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG UserReference,
+    _In_ BOOLEAN DelayedClose
     )
 
 /*++
@@ -880,7 +871,7 @@ Return Value:
 
 PIRP_CONTEXT
 CdRemoveClose (
-    IN PVCB Vcb OPTIONAL
+    _In_opt_ PVCB Vcb
     )
 
 /*++
index 3cab9b9..695121d 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -26,73 +26,84 @@ Abstract:
 //  Local support routines
 //
 
+_When_(RelatedTypeOfOpen != UnopenedFileObject, _At_(RelatedCcb, _In_))
+_When_(RelatedTypeOfOpen == UnopenedFileObject, _At_(RelatedCcb, _In_opt_))
+_When_(RelatedTypeOfOpen != UnopenedFileObject, _At_(RelatedFileName, _In_))
+_When_(RelatedTypeOfOpen == UnopenedFileObject, _At_(RelatedFileName, _In_opt_))
 NTSTATUS
 CdNormalizeFileNames (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN BOOLEAN OpenByFileId,
-    IN BOOLEAN IgnoreCase,
-    IN TYPE_OF_OPEN RelatedTypeOfOpen,
-    IN PCCB RelatedCcb OPTIONAL,
-    IN PUNICODE_STRING RelatedFileName OPTIONAL,
-    IN OUT PUNICODE_STRING FileName,
-    IN OUT PCD_NAME RemainingName
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ BOOLEAN OpenByFileId,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ TYPE_OF_OPEN RelatedTypeOfOpen,
+    PCCB RelatedCcb,
+    PUNICODE_STRING RelatedFileName,
+    _Inout_ PUNICODE_STRING FileName,
+    _Inout_ PCD_NAME RemainingName
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Acquires_exclusive_lock_((*CurrentFcb)->FcbNonpaged->FcbResource)
 NTSTATUS
 CdOpenByFileId (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOpenExistingFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN OUT PFCB *CurrentFcb,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN BOOLEAN IgnoreCase,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    _In_ BOOLEAN IgnoreCase,
+    _In_opt_ PCCB RelatedCcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Acquires_lock_((*CurrentFcb)->FcbNonpaged->FcbResource)
 NTSTATUS
 CdOpenDirectoryFromPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN PCD_NAME DirName,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PPATH_ENTRY PathEntry,
-    IN BOOLEAN PerformUserOpen,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ PCD_NAME DirName,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _In_ PPATH_ENTRY PathEntry,
+    _In_ BOOLEAN PerformUserOpen,
+    _In_opt_ PCCB RelatedCcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOpenFileFromFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN PCD_NAME FileName,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PFILE_ENUM_CONTEXT FileContext,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ PCD_NAME FileName,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _In_ PFILE_ENUM_CONTEXT FileContext,
+    _In_opt_ PCCB RelatedCcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCompleteFcbOpen (
-    IN PIRP_CONTEXT IrpContext,
-    PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN ULONG UserCcbFlags,
-    IN ACCESS_MASK DesiredAccess
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    _In_ ULONG UserCcbFlags,
+    _In_ ACCESS_MASK DesiredAccess
     );
 
 #ifdef ALLOC_PRAGMA
@@ -106,10 +117,12 @@ CdCompleteFcbOpen (
 #endif
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
+#pragma prefast(suppress:26165, "Esp:1153")
 CdCommonCreate (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -155,10 +168,10 @@ Return Value:
 
     PFILE_OBJECT FileObject;
 
-    COMPOUND_PATH_ENTRY CompoundPathEntry;
+    COMPOUND_PATH_ENTRY CompoundPathEntry = {0};
     BOOLEAN CleanupCompoundPathEntry = FALSE;
 
-    FILE_ENUM_CONTEXT FileContext;
+    FILE_ENUM_CONTEXT FileContext = {0};
     BOOLEAN CleanupFileContext = FALSE;
     BOOLEAN FoundEntry;
 
@@ -216,9 +229,9 @@ Return Value:
     PUNICODE_STRING FileName;
     PUNICODE_STRING RelatedFileName = NULL;
 
-    CD_NAME RemainingName;
+    CD_NAME RemainingName = {0};
     CD_NAME FinalName;
-    PCD_NAME MatchingName;
+    PCD_NAME MatchingName = NULL;
 
     PAGED_CODE();
 
@@ -259,6 +272,18 @@ Return Value:
         return STATUS_ACCESS_DENIED;
     }
 
+#if (NTDDI_VERSION >= NTDDI_WIN7)
+    //
+    //  CDFS does not support FILE_OPEN_REQUIRING_OPLOCK
+    //
+
+    if (FlagOn( IrpSp->Parameters.Create.Options, FILE_OPEN_REQUIRING_OPLOCK )) {
+
+        CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
+        return STATUS_INVALID_PARAMETER;
+    }
+#endif
+
     //
     //  Copy the Vcb to a local.  Assume the starting directory is the root.
     //
@@ -357,7 +382,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify that the Vcb is not in an unusable condition.  This routine
@@ -901,7 +926,7 @@ Return Value:
                                                         RelatedCcb ));
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Cleanup the PathEntry if initialized.
@@ -926,15 +951,16 @@ Return Value:
         //  condition.
         //
 
-        if (_SEH2_AbnormalTermination()) {
+        if (AbnormalTermination()) {
 
 
             //
             //  In the error path we start by calling our teardown routine if we
-            //  have a CurrentFcb.
+            //  have a CurrentFcb and its not the volume Dasd Fcb.
             //
 
-            if (CurrentFcb != NULL) {
+            if ((CurrentFcb != NULL) &&
+                (CurrentFcb != Vcb->VolumeDasdFcb)) {
 
                 BOOLEAN RemovedFcb;
 
@@ -969,7 +995,7 @@ Return Value:
         //
 
         if (CurrentFcb != NULL) {
-
+            _Analysis_assume_lock_held_(CurrentFcb->FcbNonpaged->FcbResource);
             CdReleaseFcb( IrpContext, CurrentFcb );
         }
 
@@ -985,7 +1011,7 @@ Return Value:
         //
 
         CdCompleteRequest( IrpContext, Irp, Status );
-    } _SEH2_END;
+    }
 
     return Status;
 }
@@ -994,18 +1020,21 @@ Return Value:
 //
 //  Local support routine
 //
-
+_When_(RelatedTypeOfOpen != UnopenedFileObject, _At_(RelatedCcb, _In_))
+_When_(RelatedTypeOfOpen == UnopenedFileObject, _At_(RelatedCcb, _In_opt_))
+_When_(RelatedTypeOfOpen != UnopenedFileObject, _At_(RelatedFileName, _In_))
+_When_(RelatedTypeOfOpen == UnopenedFileObject, _At_(RelatedFileName, _In_opt_))
 NTSTATUS
 CdNormalizeFileNames (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN BOOLEAN OpenByFileId,
-    IN BOOLEAN IgnoreCase,
-    IN TYPE_OF_OPEN RelatedTypeOfOpen,
-    IN PCCB RelatedCcb OPTIONAL,
-    IN PUNICODE_STRING RelatedFileName OPTIONAL,
-    IN OUT PUNICODE_STRING FileName,
-    IN OUT PCD_NAME RemainingName
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ BOOLEAN OpenByFileId,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ TYPE_OF_OPEN RelatedTypeOfOpen,
+    PCCB RelatedCcb,
+    PUNICODE_STRING RelatedFileName,
+    _Inout_ PUNICODE_STRING FileName,
+    _Inout_ PCD_NAME RemainingName
     )
 
 /*++
@@ -1048,7 +1077,7 @@ Return Value:
 --*/
 
 {
-    ULONG RemainingNameLength;
+    ULONG RemainingNameLength = 0;
     ULONG RelatedNameLength = 0;
     ULONG SeparatorLength = 0;
 
@@ -1319,8 +1348,10 @@ Return Value:
             //
             //  Do a quick check to make sure there are no wildcards.
             //
-
+#pragma prefast(push)
+#pragma prefast(suppress:26000, "RemainingName->FileName.Buffer = FileName.Buffer + (RelatedNameLength + SeparatorLength); FileName.MaximumLength < (RelatedNameLength + SeparatorLength + RemainingNameLength).")
             if (FsRtlDoesNameContainWildCards( &RemainingName->FileName )) {
+#pragma prefast(pop)
 
                 return STATUS_OBJECT_NAME_INVALID;
             }
@@ -1422,7 +1453,10 @@ Return Value:
         }
     }
 
+#pragma prefast(push)
+#pragma prefast(suppress:26030, "RemainingName->FileName.Buffer = FileName.Buffer + (RelatedNameLength + SeparatorLength); FileName.MaximumLength < (RelatedNameLength + SeparatorLength + RemainingNameLength).")
     return STATUS_SUCCESS;
+#pragma prefast(pop)
 }
 
 \f
@@ -1430,12 +1464,14 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
+_Acquires_exclusive_lock_((*CurrentFcb)->FcbNonpaged->FcbResource)
 NTSTATUS
 CdOpenByFileId (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb
     )
 
 /*++
@@ -1492,7 +1528,7 @@ Return Value:
     FILE_ENUM_CONTEXT FileContext;
     BOOLEAN CleanupFileContext = FALSE;
 
-    COMPOUND_PATH_ENTRY CompoundPathEntry;
+    COMPOUND_PATH_ENTRY CompoundPathEntry = {0};
     BOOLEAN CleanupCompoundPathEntry = FALSE;
 
     FILE_ID FileId;
@@ -1512,7 +1548,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Go ahead and figure out the TypeOfOpen and NodeType.  We can
@@ -1722,10 +1758,7 @@ Return Value:
                 //  the Fcb with the size from the self entry.
                 //
 
-                if (NextFcb->FileObject == NULL) {
-
-                    CdCreateInternalStream( IrpContext, Vcb, NextFcb );
-                }
+                CdVerifyOrCreateDirStreamFile( IrpContext, NextFcb);
 
                 //
                 //  If our offset is beyond the end of the directory then the
@@ -1883,6 +1916,9 @@ Return Value:
 
         *CurrentFcb = NextFcb;
 
+        // Lock object is acquired using internal state
+        _Analysis_suppress_lock_checking_(NextFcb->FcbNonpaged->FcbResource);
+
         //
         //  Check the requested access on this Fcb.
         //
@@ -1902,10 +1938,11 @@ Return Value:
                                         TypeOfOpen,
                                         CCB_FLAG_OPEN_BY_ID,
                                         IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
+
         }
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         if (UnlockVcb) {
 
@@ -1921,7 +1958,7 @@ Return Value:
 
             CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
         }
-    } _SEH2_END;
+    }
 
     return Status;
 }
@@ -1931,14 +1968,15 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOpenExistingFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN OUT PFCB *CurrentFcb,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN BOOLEAN IgnoreCase,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    _In_ BOOLEAN IgnoreCase,
+    _In_opt_ PCCB RelatedCcb
     )
 
 /*++
@@ -2032,18 +2070,20 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
+_Acquires_lock_((*CurrentFcb)->FcbNonpaged->FcbResource)
 NTSTATUS
 CdOpenDirectoryFromPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN PCD_NAME DirName,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PPATH_ENTRY PathEntry,
-    IN BOOLEAN PerformUserOpen,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ PCD_NAME DirName,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _In_ PPATH_ENTRY PathEntry,
+    _In_ BOOLEAN PerformUserOpen,
+    _In_opt_ PCCB RelatedCcb
     )
 
 /*++
@@ -2106,7 +2146,7 @@ Return Value:
     PFCB NextFcb;
     PFCB ParentFcb = NULL;
 
-    NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC uninitialized variable */
+    NTSTATUS Status = STATUS_SUCCESS;
 
     PAGED_CODE();
 
@@ -2126,7 +2166,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Check the related Ccb to see if this was an OpenByFileId.
@@ -2207,6 +2247,9 @@ Return Value:
 
         ParentFcb = *CurrentFcb;
         *CurrentFcb = NextFcb;
+        
+        // Lock object is acquired using internal state
+        _Analysis_suppress_lock_checking_(NextFcb->FcbNonpaged->FcbResource);
 
         //
         //  Store this name into the prefix table for the parent.
@@ -2281,7 +2324,7 @@ Return Value:
                                         IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Unlock the Vcb if held.
@@ -2300,7 +2343,7 @@ Return Value:
 
             CdReleaseFcb( IrpContext, ParentFcb );
         }
-    } _SEH2_END;
+    }
 
     return Status;
 }
@@ -2310,17 +2353,18 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOpenFileFromFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN PCD_NAME FileName,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PFILE_ENUM_CONTEXT FileContext,
-    IN PCCB RelatedCcb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ PCD_NAME FileName,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _In_ PFILE_ENUM_CONTEXT FileContext,
+    _In_opt_ PCCB RelatedCcb
     )
 
 /*++
@@ -2380,7 +2424,7 @@ Return Value:
     PFCB NextFcb;
     PFCB ParentFcb = NULL;
 
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     PAGED_CODE();
 
@@ -2399,7 +2443,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Check if a version number was used to open this file.
@@ -2554,6 +2598,7 @@ Return Value:
         //  Release the parent Fcb at this point.
         //
 
+        _Analysis_assume_same_lock_(ParentFcb->FcbNonpaged->FcbResource, NextFcb->FcbNonpaged->FcbResource);
         CdReleaseFcb( IrpContext, ParentFcb );
         ParentFcb = NULL;
 
@@ -2569,7 +2614,7 @@ Return Value:
                                     CcbFlags,
                                     IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Unlock the Vcb if held.
@@ -2588,7 +2633,7 @@ Return Value:
 
             CdReleaseFcb( IrpContext, ParentFcb );
         }
-    } _SEH2_END;
+    }
 
     return Status;
 }
@@ -2598,15 +2643,16 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCompleteFcbOpen (
-    IN PIRP_CONTEXT IrpContext,
-    PIO_STACK_LOCATION IrpSp,
-    IN PVCB Vcb,
-    IN OUT PFCB *CurrentFcb,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN ULONG UserCcbFlags,
-    IN ACCESS_MASK DesiredAccess
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PVCB Vcb,
+    _Inout_ PFCB *CurrentFcb,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    _In_ ULONG UserCcbFlags,
+    _In_ ACCESS_MASK DesiredAccess
     )
 
 /*++
@@ -2745,7 +2791,7 @@ Return Value:
 
             IrpContext->TeardownFcb = CurrentFcb;
 
-            if (FsRtlCurrentBatchOplock( &Fcb->Oplock )) {
+            if (FsRtlCurrentBatchOplock( CdGetFcbOplock(Fcb) )) {
 
                 //
                 //  We remember if a batch oplock break is underway for the
@@ -2754,11 +2800,11 @@ Return Value:
 
                 Information = FILE_OPBATCH_BREAK_UNDERWAY;
 
-                OplockStatus = FsRtlCheckOplock( &Fcb->Oplock,
+                OplockStatus = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
                                                  IrpContext->Irp,
                                                  IrpContext,
-                                                 (PVOID)CdOplockComplete,   /* ReactOS Change: GCC "assignment from incompatible pointer type" */
-                                                 (PVOID)CdPrePostIrp );   /* ReactOS Change: GCC "assignment from incompatible pointer type" */
+                                                 CdOplockComplete,
+                                                 CdPrePostIrp );
 
                 if (OplockStatus == STATUS_PENDING) {
 
@@ -2786,11 +2832,11 @@ Return Value:
             //  file.
             //
 
-            OplockStatus = FsRtlCheckOplock( &Fcb->Oplock,
+            OplockStatus = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
                                              IrpContext->Irp,
                                              IrpContext,
-                                             (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
-                                             (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */
+                                             CdOplockComplete,
+                                             CdPrePostIrp );
 
             if (OplockStatus == STATUS_PENDING) {
 
index 4146152..ce120f5 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -26,12 +26,14 @@ Abstract:
 //  Local support routines
 //
 
+//  Tell prefast this is a completion routine
+IO_COMPLETION_ROUTINE CdDevCtrlCompletionRoutine;
+
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdDevCtrlCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Contxt
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ PIRP Irp,
+    _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
     );
 
 #ifdef ALLOC_PRAGMA
@@ -41,8 +43,8 @@ CdDevCtrlCompletionRoutine (
 \f
 NTSTATUS
 CdCommonDevControl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -65,8 +67,6 @@ Return Value:
     PIO_STACK_LOCATION IrpSp;
     PIO_STACK_LOCATION NextIrpSp;
 
-//    PVOID TargetBuffer = NULL; /* ReactOS Change: GCC unused variable */
-
     PAGED_CODE();
 
     //
@@ -172,11 +172,10 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdDevCtrlCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Contxt
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ PIRP Irp,
+    _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
     )
 
 {
index c12f1aa..b2f9467 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -99,110 +99,104 @@ typedef IO_RUN *PIO_RUN;
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdPrepareBuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PFCB Fcb,
-    IN PVOID UserBuffer,
-    IN ULONG UserBufferOffset,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PIO_RUN IoRuns,
-    IN PULONG RunCount,
-    IN PULONG ThisByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP Irp,
+    _In_ PFCB Fcb,
+    _In_reads_bytes_(ByteCount) PVOID UserBuffer,
+    _In_ ULONG UserBufferOffset,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _Out_ PIO_RUN IoRuns,
+    _Out_ PULONG RunCount,
+    _Out_ PULONG ThisByteCount
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdPrepareXABuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PFCB Fcb,
-    IN PVOID UserBuffer,
-    IN ULONG UserBufferOffset,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PIO_RUN IoRuns,
-    IN PULONG RunCount,
-    IN PULONG ThisByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP Irp,
+    _In_ PFCB Fcb,
+    _In_reads_bytes_(ByteCount) PVOID UserBuffer,
+    _In_ ULONG UserBufferOffset,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _Out_ PIO_RUN IoRuns,
+    _Out_ PULONG RunCount,
+    _Out_ PULONG ThisByteCount
     );
 
 BOOLEAN
 CdFinishBuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_RUN IoRuns,
-    IN ULONG RunCount,
-    IN BOOLEAN FinalCleanup,
-    IN BOOLEAN SaveXABuffer
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIO_RUN IoRuns,
+    _In_ ULONG RunCount,
+    _In_ BOOLEAN FinalCleanup,
+    _In_ BOOLEAN SaveXABuffer
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdMultipleAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG RunCount,
-    IN PIO_RUN IoRuns
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG RunCount,
+    _Inout_ PIO_RUN IoRuns
     );
 
 VOID
 CdMultipleXAAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG RunCount,
-    IN PIO_RUN IoRuns,
-    IN PRAW_READ_INFO RawReads,
-    IN TRACK_MODE_TYPE TrackMode
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG RunCount,
+    _Inout_ PIO_RUN IoRuns,
+    _In_ PRAW_READ_INFO RawReads,
+    _In_ TRACK_MODE_TYPE TrackMode
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdSingleAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN LONGLONG ByteOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_RUN Run,
+    _In_ PFCB Fcb
     );
 
 VOID
 CdWaitSync (
-    IN PIRP_CONTEXT IrpContext
+    _In_ PIRP_CONTEXT IrpContext
     );
 
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdMultiSyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    );
+//  Tell prefast this is a completion routine.
+IO_COMPLETION_ROUTINE CdMultiSyncCompletionRoutine;
 
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdMultiAsyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    );
+//  Tell prefast this is a completion routine
+IO_COMPLETION_ROUTINE CdMultiAsyncCompletionRoutine;
 
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdSingleSyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    );
+//  Tell prefast this is a completion routine
+IO_COMPLETION_ROUTINE CdSingleSyncCompletionRoutine;
 
-NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdSingleAsyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    );
+//  Tell prefast this is a completion routine
+IO_COMPLETION_ROUTINE CdSingleAsyncCompletionRoutine;
 
+_When_(SafeNodeType(Fcb) != CDFS_NTC_FCB_PATH_TABLE && StartingOffset == 0, _At_(ByteCount, _In_range_(>=, CdAudioDirentSize + sizeof(RAW_DIRENT))))
+_When_(SafeNodeType(Fcb) != CDFS_NTC_FCB_PATH_TABLE && StartingOffset != 0, _At_(ByteCount, _In_range_(>=, CdAudioDirentSize + SECTOR_SIZE)))
 VOID
 CdReadAudioSystemFile (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PVOID SystemBuffer
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ _In_range_(>=, CdAudioDirentSize) ULONG ByteCount,
+    _Out_writes_bytes_(ByteCount) PVOID SystemBuffer
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
+BOOLEAN
+CdReadDirDataThroughCache (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_RUN Run
     );
 
 #ifdef ALLOC_PRAGMA
@@ -211,20 +205,58 @@ CdReadAudioSystemFile (
 #pragma alloc_text(PAGE, CdMultipleXAAsync)
 #pragma alloc_text(PAGE, CdNonCachedRead)
 #pragma alloc_text(PAGE, CdNonCachedXARead)
+#pragma alloc_text(PAGE, CdVolumeDasdWrite)
 #pragma alloc_text(PAGE, CdFinishBuffers)
 #pragma alloc_text(PAGE, CdPerformDevIoCtrl)
+#pragma alloc_text(PAGE, CdPerformDevIoCtrlEx)
 #pragma alloc_text(PAGE, CdPrepareBuffers)
+#pragma alloc_text(PAGE, CdPrepareXABuffers)
 #pragma alloc_text(PAGE, CdReadAudioSystemFile)
 #pragma alloc_text(PAGE, CdReadSectors)
 #pragma alloc_text(PAGE, CdSingleAsync)
 #pragma alloc_text(PAGE, CdWaitSync)
+#pragma alloc_text(PAGE, CdReadDirDataThroughCache)
+#pragma alloc_text(PAGE, CdFreeDirCache)
+#pragma alloc_text(PAGE, CdLbnToMmSsFf)
+#pragma alloc_text(PAGE, CdHijackIrpAndFlushDevice)
 #endif
 
-\f
+
+VOID
+CdLbnToMmSsFf (
+    _In_ ULONG Blocks,
+    _Out_writes_(3) PUCHAR Msf
+    )
+
+/*++
+
+Routine Description:
+
+    Convert Lbn to MSF format.
+
+Arguments:
+
+    Msf - on output, set to 0xMmSsFf representation of blocks.
+    
+--*/
+
+{
+    PAGED_CODE();
+
+    Blocks += 150;                  // Lbn 0 == 00:02:00, 1sec == 75 frames.
+    
+    Msf[0] = (UCHAR)(Blocks % 75);  // Frames
+    Blocks /= 75;                   // -> Seconds
+    Msf[1] = (UCHAR)(Blocks % 60);  // Seconds 
+    Blocks /= 60;                   // -> Minutes
+    Msf[2] = (UCHAR)Blocks;         // Minutes
+}
+
+
 __inline
 TRACK_MODE_TYPE
 CdFileTrackMode (
-    IN PFCB Fcb
+    _In_ PFCB Fcb
     )
 
 /*++
@@ -244,7 +276,7 @@ Return Value:
 
 --*/
 {
-    ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE |
+    NT_ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE |
                                    FCB_STATE_MODE2_FILE |
                                    FCB_STATE_DA_FILE ));
 
@@ -266,12 +298,13 @@ Return Value:
 }
 
 \f
+_Requires_lock_held_(_Global_critical_region_)    
 NTSTATUS
 CdNonCachedRead (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
     )
 
 /*++
@@ -329,7 +362,7 @@ Return Value:
 
     if (IrpContext->Irp->MdlAddress == NULL) {
 
-        CdCreateUserMdl( IrpContext, ByteCount, TRUE );
+        CdCreateUserMdl( IrpContext, ByteCount, TRUE, IoWriteAccess );
     }
 
     CdMapUserBuffer( IrpContext, &UserBuffer);
@@ -351,11 +384,30 @@ Return Value:
         return STATUS_SUCCESS;
     }
 
+    //
+    //  If we're going to use the sector cache for this request, then
+    //  mark the request waitable.
+    //
+    
+    if ((SafeNodeType( Fcb) == CDFS_NTC_FCB_INDEX) &&
+        (NULL != Fcb->Vcb->SectorCacheBuffer) &&
+        (VcbMounted == IrpContext->Vcb->VcbCondition)) {
+
+        if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
+
+            KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
+                               NotificationEvent,
+                               FALSE );
+
+            SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
+        }
+    }
+
     //
     //  Use a try-finally to perform the final cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Loop while there are more bytes to transfer.
@@ -405,9 +457,7 @@ Return Value:
 
             if ((RunCount == 1) && !Unaligned && FirstPass) {
 
-                CdSingleAsync( IrpContext,
-                               IoRuns[0].DiskOffset,
-                               IoRuns[0].DiskByteCount );
+                CdSingleAsync( IrpContext,&IoRuns[0], Fcb );
 
                 //
                 //  No cleanup needed for the IoRuns array here.
@@ -443,7 +493,7 @@ Return Value:
             //  Otherwise we will perform multiple Io to read in the data.
             //
 
-            CdMultipleAsync( IrpContext, RunCount, IoRuns );
+            CdMultipleAsync( IrpContext, Fcb, RunCount, IoRuns );
 
             //
             //  If this is a synchronous request then perform any necessary
@@ -518,7 +568,7 @@ Return Value:
         }
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Perform final cleanup on the IoRuns if necessary.
@@ -528,18 +578,20 @@ Return Value:
 
             CdFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE, FALSE );
         }
-    } _SEH2_END;
+    }
 
     return Status;
 }
 
 \f
+    
+_Requires_lock_held_(_Global_critical_region_)    
 NTSTATUS
 CdNonCachedXARead (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
     )
 
 /*++
@@ -590,7 +642,8 @@ Return Value:
     ULONG UserBufferOffset = 0;
     LONGLONG CurrentOffset = StartingOffset;
     ULONG RemainingByteCount = ByteCount;
-    ULONG ThisByteCount;
+    ULONG ThisByteCount = 0;
+    ULONG Address = 0;
 
     BOOLEAN TryingYellowbookMode2 = FALSE;
 
@@ -604,7 +657,7 @@ Return Value:
 
     if (IrpContext->Irp->MdlAddress == NULL) {
 
-        CdCreateUserMdl( IrpContext, ByteCount, TRUE );
+        CdCreateUserMdl( IrpContext, ByteCount, TRUE, IoWriteAccess );
     }
 
     //
@@ -624,7 +677,7 @@ Return Value:
     //  Use a try-finally to perform the final cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  If the initial offset lies within the RIFF header then copy the
@@ -647,7 +700,6 @@ Return Value:
 
                     PAUDIO_PLAY_HEADER AudioPlayHeader;
                     PTRACK_DATA TrackData;
-                    ULONG SectorCount;
 
                     AudioPlayHeader = (PAUDIO_PLAY_HEADER) &LocalRiffHeader;
                     TrackData = &Fcb->Vcb->CdromToc->TrackData[Fcb->XAFileNumber];
@@ -668,32 +720,21 @@ Return Value:
                     AudioPlayHeader->DiskID = Fcb->Vcb->Vpb->SerialNumber;
                     AudioPlayHeader->TrackNumber = TrackData->TrackNumber;
 
-                    //
-                    //  TOC contains MSF (Minute/Second/Frame) addresses.  This is very
-                    //  arcane, and we wind up having to bias around by the size of the
-                    //  leadins and other such silliness to find real live sector addrs.
                     //
                     //  One frame == One sector.
                     //  One second == 75 frames (winds up being a 44.1khz sample)
                     //
-
-                    //
-                    //  Fill in the address and length fields.
+                    //  Note: LBN 0 == 0:2:0 (MSF)
                     //
-
-                    AudioPlayHeader->TrackAddress[2] = TrackData->Address[1];
-                    AudioPlayHeader->TrackAddress[1] = TrackData->Address[2];
-                    AudioPlayHeader->TrackAddress[0] = TrackData->Address[3];
-
-                    AudioPlayHeader->StartingSector = TrackData->Address[3];
-                    AudioPlayHeader->StartingSector += (TrackData->Address[2] * 75);
-                    AudioPlayHeader->StartingSector += (TrackData->Address[1] * 60 * 75);
-
+                    
                     //
-                    //  Subtract 2 seconds for the block number.
+                    //  Fill in the address (both MSF and Lbn format) and length fields.
                     //
-
-                    AudioPlayHeader->StartingSector -= 150;
+                    
+                    SwapCopyUchar4( &Address, TrackData->Address);
+                    CdLbnToMmSsFf( Address, AudioPlayHeader->TrackAddress);
+                    
+                    SwapCopyUchar4( &AudioPlayHeader->StartingSector, TrackData->Address);
 
                     //
                     //  Go to the next track and find the starting point.
@@ -701,23 +742,7 @@ Return Value:
 
                     TrackData = &Fcb->Vcb->CdromToc->TrackData[Fcb->XAFileNumber + 1];
 
-                    AudioPlayHeader->SectorCount = TrackData->Address[3];
-                    AudioPlayHeader->SectorCount += (TrackData->Address[2] * 75);
-                    AudioPlayHeader->SectorCount += (TrackData->Address[1] * 60 * 75);
-
-                    //
-                    //  Bias the sector count by 2 seconds.
-                    //  Check that the offset is at least two seconds.
-                    //
-
-                    if (AudioPlayHeader->SectorCount < 150) {
-
-                        AudioPlayHeader->SectorCount = 0;
-
-                    } else {
-
-                        AudioPlayHeader->SectorCount -= 150;
-                    }
+                    SwapCopyUchar4( &AudioPlayHeader->SectorCount, TrackData->Address);
 
                     //
                     //  Now compute the difference.  If there is an error then use
@@ -734,18 +759,12 @@ Return Value:
                     }
 
                     //
-                    //  Use the sector count to determine the MSF length.
+                    //  Use the sector count to determine the MSF length. Bias by 150 to make
+                    //  it an "lbn" since the conversion routine corrects for Lbn 0 == 0:2:0;
                     //
 
-                    SectorCount = AudioPlayHeader->SectorCount;
-
-                    AudioPlayHeader->TrackLength[0] = (UCHAR) (SectorCount % 75);
-                    SectorCount /= 75;
-
-                    AudioPlayHeader->TrackLength[1] = (UCHAR) (SectorCount % 60);
-                    SectorCount /= 60;
-
-                    AudioPlayHeader->TrackLength[2] = (UCHAR) (SectorCount % 60);
+                    Address = AudioPlayHeader->SectorCount - 150;
+                    CdLbnToMmSsFf( Address, AudioPlayHeader->TrackLength);
 
                     ThisByteCount = sizeof( RIFF_HEADER ) - (ULONG) CurrentOffset;
 
@@ -793,7 +812,7 @@ Return Value:
             
             } else { 
     
-                ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2_FILE | FCB_STATE_MODE2FORM2_FILE ));
+                NT_ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2_FILE | FCB_STATE_MODE2FORM2_FILE ));
 
                 RiffHeader = &LocalRiffHeader;
 
@@ -925,7 +944,7 @@ Return Value:
                 if (TryingYellowbookMode2) {
 
                     //
-                    //  We successfully got data when we tried switching the trackmode,
+                    //  We succesfully got data when we tried switching the trackmode,
                     //  so change the state of the FCB to remember that.
                     //
 
@@ -960,7 +979,7 @@ Return Value:
         KeFlushIoBuffers( IrpContext->Irp->MdlAddress, TRUE, FALSE );
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Perform final cleanup on the IoRuns if necessary.
@@ -970,20 +989,101 @@ Return Value:
 
             CdFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE, FALSE );
         }
-    } _SEH2_END;
+    }
+
+    return Status;
+}
+
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdVolumeDasdWrite (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount
+    )
+
+/*++
+
+Routine Description:
+
+    This routine performs the non-cached writes to 'cooked' sectors (2048 bytes
+    per sector).  This is done by filling the IoRun for the desired request 
+    and send it down to the device.
+
+Arguments:
+
+    Fcb - Fcb representing the file to read.
+
+    StartingOffset - Logical offset in the file to read from.
+
+    ByteCount - Number of bytes to read.
+
+Return Value:
+
+    NTSTATUS - Status indicating the result of the operation.
+
+--*/
+
+{
+    NTSTATUS Status;
+    IO_RUN IoRun;
+
+    PAGED_CODE();
+
+    //
+    //  We want to make sure the user's buffer is locked in all cases.
+    //
+
+    CdLockUserBuffer( IrpContext, ByteCount, IoReadAccess );
+
+    //
+    //  The entire Io can be contained in a single run, just pass
+    //  the Io down to the driver.  Send the driver down
+    //  and wait on the result if this is synchronous.
+    //
+
+    RtlZeroMemory( &IoRun, sizeof( IoRun ) );
+
+    IoRun.DiskOffset = StartingOffset;
+    IoRun.DiskByteCount = ByteCount;
+
+    CdSingleAsync( IrpContext, &IoRun, Fcb );
+
+    //
+    //  Wait if we are synchronous, otherwise return
+    //
+
+    if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
+
+        CdWaitSync( IrpContext );
+
+        Status = IrpContext->Irp->IoStatus.Status;
+
+    //
+    //  Our completion routine will free the Io context but
+    //  we do want to return STATUS_PENDING.
+    //
+
+    } else {
+
+        ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
+        Status = STATUS_PENDING;
+    }
 
     return Status;
 }
 
+
 \f
 BOOLEAN
 CdReadSectors (
-    IN PIRP_CONTEXT IrpContext,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN BOOLEAN ReturnError,
-    IN OUT PVOID Buffer,
-    IN PDEVICE_OBJECT TargetDeviceObject
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _In_ BOOLEAN ReturnError,
+    _Out_writes_bytes_(ByteCount) PVOID Buffer,
+    _In_ PDEVICE_OBJECT TargetDeviceObject
     )
 
 /*++
@@ -1119,9 +1219,10 @@ Return Value:
 \f
 NTSTATUS
 CdCreateUserMdl (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG BufferLength,
-    IN BOOLEAN RaiseOnError
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG BufferLength,
+    _In_ BOOLEAN RaiseOnError,
+    _In_ LOCK_OPERATION Operation
     )
 
 /*++
@@ -1142,6 +1243,8 @@ Arguments:
     RaiseOnError - Indicates if our caller wants this routine to raise on
         an error condition.
 
+    Operation - IoWriteAccess or IoReadAccess
+
 Return Value:
 
     NTSTATUS - Status from this routine.  Error status only returned if
@@ -1155,9 +1258,12 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( Operation );
+    UNREFERENCED_PARAMETER( IrpContext );
+
     ASSERT_IRP_CONTEXT( IrpContext );
     ASSERT_IRP( IrpContext->Irp );
-    ASSERT( IrpContext->Irp->MdlAddress == NULL );
+    NT_ASSERT( IrpContext->Irp->MdlAddress == NULL );
 
     //
     // Allocate the Mdl, and Raise if we fail.
@@ -1176,15 +1282,16 @@ Return Value:
         //  deallocate the Mdl and return the appropriate "expected" status.
         //
 
-        _SEH2_TRY {
+        try {
 
             MmProbeAndLockPages( Mdl, IrpContext->Irp->RequestorMode, IoWriteAccess );
 
             Status = STATUS_SUCCESS;
 
-        } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+#pragma warning(suppress: 6320)
+        } except(EXCEPTION_EXECUTE_HANDLER) {
 
-            Status = _SEH2_GetExceptionCode();
+            Status = GetExceptionCode();
 
             IoFreeMdl( Mdl );
             IrpContext->Irp->MdlAddress = NULL;
@@ -1193,7 +1300,7 @@ Return Value:
 
                 Status = STATUS_INVALID_USER_BUFFER;
             }
-        } _SEH2_END;
+        }
     }
 
     //
@@ -1217,15 +1324,17 @@ Return Value:
 
 \f
 NTSTATUS
-CdPerformDevIoCtrl (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG IoControlCode,
-    IN PDEVICE_OBJECT Device,
-    OUT PVOID OutputBuffer OPTIONAL,
-    IN ULONG OutputBufferLength,
-    IN BOOLEAN InternalDeviceIoControl,
-    IN BOOLEAN OverrideVerify,
-    OUT PIO_STATUS_BLOCK Iosb OPTIONAL
+CdPerformDevIoCtrlEx (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG IoControlCode,
+    _In_ PDEVICE_OBJECT Device,
+    _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
+    _In_ ULONG InputBufferLength,
+    _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
+    _In_ ULONG OutputBufferLength,
+    _In_ BOOLEAN InternalDeviceIoControl,
+    _In_ BOOLEAN OverrideVerify,
+    _Out_opt_ PIO_STATUS_BLOCK Iosb
     )
 
 /*++
@@ -1269,6 +1378,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Check if the user gave us an Iosb.
     //
@@ -1285,8 +1396,8 @@ Return Value:
 
     Irp = IoBuildDeviceIoControlRequest( IoControlCode,
                                          Device,
-                                         NULL,
-                                         0,
+                                         InputBuffer,
+                                         InputBufferLength,
                                          OutputBuffer,
                                          OutputBufferLength,
                                          InternalDeviceIoControl,
@@ -1322,28 +1433,58 @@ Return Value:
         Status = IosbToUse->Status;
     }
 
-    ASSERT( !(OverrideVerify && (STATUS_VERIFY_REQUIRED == Status)));
+    NT_ASSERT( !(OverrideVerify && (STATUS_VERIFY_REQUIRED == Status)));
 
     return Status;
 }
 
+
+NTSTATUS
+FASTCALL
+CdPerformDevIoCtrl (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG IoControlCode,
+    _In_ PDEVICE_OBJECT Device,
+    _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
+    _In_ ULONG OutputBufferLength,
+    _In_ BOOLEAN InternalDeviceIoControl,
+    _In_ BOOLEAN OverrideVerify,
+    _Out_opt_ PIO_STATUS_BLOCK Iosb
+    )
+{
+    PAGED_CODE();
+
+    return CdPerformDevIoCtrlEx( IrpContext, 
+                                 IoControlCode, 
+                                 Device, 
+                                 NULL, 
+                                 0, 
+                                 OutputBuffer, 
+                                 OutputBufferLength, 
+                                 InternalDeviceIoControl,
+                                 OverrideVerify,
+                                 Iosb);
+}
+
+
 \f
 //
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdPrepareBuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PFCB Fcb,
-    IN PVOID UserBuffer,
-    IN ULONG UserBufferOffset,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PIO_RUN IoRuns,
-    IN PULONG RunCount,
-    IN PULONG ThisByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP Irp,
+    _In_ PFCB Fcb,
+    _In_reads_bytes_(ByteCount) PVOID UserBuffer,
+    _In_ ULONG UserBufferOffset,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _Out_ PIO_RUN IoRuns,
+    _Out_ PULONG RunCount,
+    _Out_ PULONG ThisByteCount
     )
 
 /*++
@@ -1414,16 +1555,13 @@ Return Value:
     PVOID CurrentUserBuffer = UserBuffer;
     ULONG CurrentUserBufferOffset = UserBufferOffset;
 
-    PVOID ScratchUserBuffer = UserBuffer;
-    ULONG ScratchUserBufferOffset = UserBufferOffset;
-
     //
     //  The following is the next contiguous bytes on the disk to
     //  transfer.  Read from the allocation package.
     //
 
-    LONGLONG DiskOffset;
-    ULONG CurrentByteCount;
+    LONGLONG DiskOffset = 0;
+    ULONG CurrentByteCount = RemainingByteCount;
 
     PAGED_CODE();
 
@@ -1478,18 +1616,17 @@ Return Value:
         //
         //      Byte count is a multiple of 2048 (Length of transfer)
         //
-        //      Current buffer offset is also on a 2048 byte boundary.
-        //
         //  If the ByteCount is at least one sector then do the
         //  unaligned transfer only for the tail.  We can use the
         //  user's buffer for the aligned portion.
         //
 
         if (FlagOn( (ULONG) DiskOffset, SECTOR_MASK ) ||
-            FlagOn( CurrentUserBufferOffset, SECTOR_MASK ) ||
             (FlagOn( (ULONG) CurrentByteCount, SECTOR_MASK ) &&
              (CurrentByteCount < SECTOR_SIZE))) {
 
+            NT_ASSERT( SafeNodeType(Fcb) != CDFS_NTC_FCB_INDEX);
+            
             //
             //  If we can't wait then raise.
             //
@@ -1515,93 +1652,50 @@ Return Value:
             ThisIoRun->DiskOffset = LlSectorTruncate( DiskOffset );
 
             //
-            //  Check if we can use a free portion of the user's buffer.
-            //  If we can copy the bytes to an earlier portion of the
-            //  buffer then read into that location and slide the bytes
-            //  up.
-            //
-            //  We can use the user's buffer if:
-            //
-            //      The temporary location in the buffer is before the
-            //      final destination.
-            //
-            //      There is at least one sector of data to read.
+            //  We need to allocate an auxilary buffer for the next sector.
+            //  Read up to a page containing the partial data.
             //
 
-            if ((ScratchUserBufferOffset + ThisIoRun->TransferBufferOffset < CurrentUserBufferOffset) &&
-                (ThisIoRun->TransferBufferOffset + CurrentByteCount >= SECTOR_SIZE)) {
+            ThisIoRun->DiskByteCount = SectorAlign( ThisIoRun->TransferBufferOffset + CurrentByteCount );
 
-                ThisIoRun->DiskByteCount = SectorTruncate( ThisIoRun->TransferBufferOffset + CurrentByteCount );
-                CurrentByteCount = ThisIoRun->DiskByteCount - ThisIoRun->TransferBufferOffset;
-                ThisIoRun->TransferByteCount = CurrentByteCount;
+            if (ThisIoRun->DiskByteCount > PAGE_SIZE) {
 
-                //
-                //  Point to the user's buffer and Mdl for this transfer.
-                //
+                ThisIoRun->DiskByteCount = PAGE_SIZE;
+            }
 
-                ThisIoRun->TransferBuffer = ScratchUserBuffer;
-                ThisIoRun->TransferMdl = Irp->MdlAddress;
-                ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer,
-                                                             ScratchUserBufferOffset,
-                                                             PVOID );
+            if (ThisIoRun->TransferBufferOffset + CurrentByteCount > ThisIoRun->DiskByteCount) {
 
-                ScratchUserBuffer = Add2Ptr( ScratchUserBuffer,
-                                             ThisIoRun->DiskByteCount,
-                                             PVOID );
+                CurrentByteCount = ThisIoRun->DiskByteCount - ThisIoRun->TransferBufferOffset;
+            }
 
-                ScratchUserBufferOffset += ThisIoRun->DiskByteCount;
+            ThisIoRun->TransferByteCount = CurrentByteCount;
 
             //
-            //  Otherwise we need to allocate an auxiliary buffer for the next sector.
+            //  Allocate a buffer for the non-aligned transfer.
             //
 
-            } else {
-
-                //
-                //  Read up to a page containing the partial data
-                //
-
-                ThisIoRun->DiskByteCount = SectorAlign( ThisIoRun->TransferBufferOffset + CurrentByteCount );
-
-                if (ThisIoRun->DiskByteCount > PAGE_SIZE) {
-
-                    ThisIoRun->DiskByteCount = PAGE_SIZE;
-                }
-
-                if (ThisIoRun->TransferBufferOffset + CurrentByteCount > ThisIoRun->DiskByteCount) {
-
-                    CurrentByteCount = ThisIoRun->DiskByteCount - ThisIoRun->TransferBufferOffset;
-                }
-
-                ThisIoRun->TransferByteCount = CurrentByteCount;
-
-                //
-                //  Allocate a buffer for the non-aligned transfer.
-                //
-
-                ThisIoRun->TransferBuffer = FsRtlAllocatePoolWithTag( CdNonPagedPool, PAGE_SIZE, TAG_IO_BUFFER );
-
-                //
-                //  Allocate and build the Mdl to describe this buffer.
-                //
+            ThisIoRun->TransferBuffer = FsRtlAllocatePoolWithTag( CdNonPagedPool, PAGE_SIZE, TAG_IO_BUFFER );
 
-                ThisIoRun->TransferMdl = IoAllocateMdl( ThisIoRun->TransferBuffer,
-                                                        PAGE_SIZE,
-                                                        FALSE,
-                                                        FALSE,
-                                                        NULL );
+            //
+            //  Allocate and build the Mdl to describe this buffer.
+            //
 
-                ThisIoRun->TransferVirtualAddress = ThisIoRun->TransferBuffer;
+            ThisIoRun->TransferMdl = IoAllocateMdl( ThisIoRun->TransferBuffer,
+                                                    PAGE_SIZE,
+                                                    FALSE,
+                                                    FALSE,
+                                                    NULL );
 
-                if (ThisIoRun->TransferMdl == NULL) {
+            ThisIoRun->TransferVirtualAddress = ThisIoRun->TransferBuffer;
 
-                    IrpContext->Irp->IoStatus.Information = 0;
-                    CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
-                }
+            if (ThisIoRun->TransferMdl == NULL) {
 
-                MmBuildMdlForNonPagedPool( ThisIoRun->TransferMdl );
+                IrpContext->Irp->IoStatus.Information = 0;
+                CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
             }
 
+            MmBuildMdlForNonPagedPool( ThisIoRun->TransferMdl );
+
             //
             //  Remember we found an unaligned transfer.
             //
@@ -1639,12 +1733,6 @@ Return Value:
             ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer,
                                                          CurrentUserBufferOffset,
                                                          PVOID );
-
-            ScratchUserBuffer = Add2Ptr( CurrentUserBuffer,
-                                         CurrentByteCount,
-                                         PVOID );
-
-            ScratchUserBufferOffset += CurrentByteCount;
         }
 
         //
@@ -1684,18 +1772,19 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdPrepareXABuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PFCB Fcb,
-    IN PVOID UserBuffer,
-    IN ULONG UserBufferOffset,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PIO_RUN IoRuns,
-    IN PULONG RunCount,
-    IN PULONG ThisByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP Irp,
+    _In_ PFCB Fcb,
+    _In_reads_bytes_(ByteCount) PVOID UserBuffer,
+    _In_ ULONG UserBufferOffset,
+    _In_ LONGLONG StartingOffset,
+    _In_ ULONG ByteCount,
+    _Out_ PIO_RUN IoRuns,
+    _Out_ PULONG RunCount,
+    _Out_ PULONG ThisByteCount
     )
 
 /*++
@@ -1771,18 +1860,14 @@ Return Value:
     PVOID CurrentUserBuffer = UserBuffer;
     ULONG CurrentUserBufferOffset = UserBufferOffset;
 
-    PVOID ScratchUserBuffer = UserBuffer;
-    ULONG ScratchUserBufferOffset = UserBufferOffset;
-    BOOLEAN RoundScratchBuffer = TRUE;
-
     //
     //  The following is the next contiguous bytes on the disk to
     //  transfer.  These are represented by cooked byte offset and length.
     //  We also compute the number of raw bytes in the current transfer.
     //
 
-    LONGLONG DiskOffset;
-    ULONG CurrentCookedByteCount;
+    LONGLONG DiskOffset = 0;
+    ULONG CurrentCookedByteCount = 0;
     ULONG CurrentRawByteCount;
 
     PAGED_CODE();
@@ -1805,6 +1890,7 @@ Return Value:
 
         CurrentRawOffset = (LONGLONG) ((ULONG) CurrentRawOffset / RAW_SECTOR_SIZE);
 
+#pragma prefast( suppress: __WARNING_RESULTOFSHIFTCASTTOLARGERSIZE, "This is fine beacuse raw sector size > sector shift" )        
         CurrentCookedOffset = (LONGLONG) ((ULONG) CurrentRawOffset << SECTOR_SHIFT );
 
         CurrentRawOffset = (LONGLONG) ((ULONG) CurrentRawOffset * RAW_SECTOR_SIZE);
@@ -1849,26 +1935,6 @@ Return Value:
         PerformedCopy = FALSE;
         *RunCount += 1;
 
-        //
-        //  Round the scratch buffer up to a sector boundary for alignment.
-        //
-
-        if (RoundScratchBuffer) {
-
-            if (SectorOffset( ScratchUserBuffer ) != 0) {
-
-                CurrentRawByteCount = SECTOR_SIZE - SectorOffset( ScratchUserBuffer );
-
-                ScratchUserBuffer = Add2Ptr( ScratchUserBuffer,
-                                             CurrentRawByteCount,
-                                             PVOID );
-
-                ScratchUserBufferOffset += CurrentRawByteCount;
-            }
-
-            RoundScratchBuffer = FALSE;
-        }
-
         //
         //  Initialize the current position in the IoRuns array.  Find the 
         //  eventual destination in the user's buffer for this portion of the transfer.
@@ -1933,27 +1999,13 @@ Return Value:
                 ThisIoRun -= 1;
 
                 //
-                //  Remember that we performed a copy operation and update
-                //  the next available position in the scratch buffer.
+                //  Remember that we performed a copy operation.
                 //
 
                 PerformedCopy = TRUE;
 
-                ScratchUserBuffer = Add2Ptr( ScratchUserBuffer,
-                                             CurrentRawByteCount,
-                                             PVOID );
-
-                ScratchUserBufferOffset += CurrentRawByteCount;
-
                 CurrentCookedByteCount = SECTOR_SIZE;
 
-                //
-                //  Set the flag indicating we want to round the scratch buffer
-                //  to a sector boundary.
-                //
-                
-                RoundScratchBuffer = TRUE;
-
             } else {
 
                 //
@@ -2001,8 +2053,7 @@ Return Value:
             //
 
             if ((RawSectorOffset == 0) &&
-                (ScratchUserBufferOffset <= CurrentUserBufferOffset) &&
-                (CurrentUserBufferOffset - ScratchUserBufferOffset + RemainingRawByteCount >= RAW_SECTOR_SIZE)) {
+                (RemainingRawByteCount >= RAW_SECTOR_SIZE)) {
 
                 //
                 //  We can use the scratch buffer.  We must ensure we don't send down reads
@@ -2024,7 +2075,7 @@ Return Value:
                 //  Now make sure we are within the page transfer limit.
                 //
 
-                while (ADDRESS_AND_SIZE_TO_SPAN_PAGES(ScratchUserBuffer, RawSectorAlign( CurrentRawByteCount)) > 
+                while (ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentUserBuffer, RawSectorAlign( CurrentRawByteCount)) > 
                        Fcb->Vcb->MaximumPhysicalPages )  {
 
                     CurrentRawByteCount -= RAW_SECTOR_SIZE;
@@ -2036,8 +2087,7 @@ Return Value:
                 //  account of the fact that we must read in whole raw sector multiples.
                 //
 
-                while ( RawSectorAlign( CurrentRawByteCount) > 
-                        (CurrentUserBufferOffset - ScratchUserBufferOffset + RemainingRawByteCount) )  {
+                while (RawSectorAlign( CurrentRawByteCount) > RemainingRawByteCount)  {
 
                     CurrentRawByteCount -= RAW_SECTOR_SIZE;
                     CurrentCookedByteCount -= SECTOR_SIZE;
@@ -2059,40 +2109,15 @@ Return Value:
 
                 ThisIoRun->DiskByteCount = SectorAlign( CurrentCookedByteCount);
 
-                //
-                //  Store the number of bytes which we actually care about from this transfer
-                //
-                
-                ThisIoRun->TransferByteCount = CurrentRawByteCount;
-
                 //
                 //  Point to the user's buffer and Mdl for this transfer.
                 //
 
-                ThisIoRun->TransferBuffer = ScratchUserBuffer;
+                ThisIoRun->TransferBuffer = CurrentUserBuffer;
                 ThisIoRun->TransferMdl = Irp->MdlAddress;
                 ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer, 
-                                                             ScratchUserBufferOffset,
+                                                             CurrentUserBufferOffset,
                                                              PVOID);
-                //
-                //  Update the scratch buffer pointer.  Note that since the underlying
-                //  driver stack will always transfer in multiples of raw sectors,
-                //  we must round up here rather than simply advancing by the length of the
-                //  of the data which we actually care about.
-                //
-
-                ScratchUserBuffer = Add2Ptr( ScratchUserBuffer,
-                                             RawSectorAlign( CurrentRawByteCount),
-                                             PVOID );
-                                             
-                ScratchUserBufferOffset += RawSectorAlign( CurrentRawByteCount);
-
-                //
-                //  Set the flag indicating we want to round the scratch buffer
-                //  to a cooked sector boundary.
-                //
-
-                RoundScratchBuffer = TRUE;
 
             } else {
 
@@ -2188,11 +2213,11 @@ Return Value:
 
 BOOLEAN
 CdFinishBuffers (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_RUN IoRuns,
-    IN ULONG RunCount,
-    IN BOOLEAN FinalCleanup,
-    IN BOOLEAN SaveXABuffer
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIO_RUN IoRuns,
+    _In_ ULONG RunCount,
+    _In_ BOOLEAN FinalCleanup,
+    _In_ BOOLEAN SaveXABuffer
     )
 
 /*++
@@ -2260,27 +2285,11 @@ Return Value:
 
             if (!FinalCleanup) {
 
-                //
-                //  If we are shifting in the user's buffer then use
-                //  MoveMemory.
-                //
-
-                if (ThisIoRun->TransferMdl == IrpContext->Irp->MdlAddress) {
-
-                    RtlMoveMemory( ThisIoRun->UserBuffer,
-                                   Add2Ptr( ThisIoRun->TransferBuffer,
-                                            ThisIoRun->TransferBufferOffset,
-                                            PVOID ),
-                                   ThisIoRun->TransferByteCount );
-
-                } else {
-
-                    RtlCopyMemory( ThisIoRun->UserBuffer,
-                                   Add2Ptr( ThisIoRun->TransferBuffer,
-                                            ThisIoRun->TransferBufferOffset,
-                                            PVOID ),
-                                   ThisIoRun->TransferByteCount );
-                }
+                RtlCopyMemory( ThisIoRun->UserBuffer,
+                               Add2Ptr( ThisIoRun->TransferBuffer,
+                                        ThisIoRun->TransferBufferOffset,
+                                        PVOID ),
+                               ThisIoRun->TransferByteCount );
 
                 FlushIoBuffers = TRUE;
             }
@@ -2371,42 +2380,410 @@ Return Value:
     return FlushIoBuffers;
 }
 
-\f
-//
-//  Local support routine
-//
+//  Tell prefast this is a completion routine.
+IO_COMPLETION_ROUTINE CdSyncCompletionRoutine;
 
-VOID
-CdMultipleAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG RunCount,
-    IN PIO_RUN IoRuns
+NTSTATUS
+CdSyncCompletionRoutine (
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Contxt
     )
 
 /*++
 
 Routine Description:
 
-    This routine first does the initial setup required of a Master IRP that is
-    going to be completed using associated IRPs.  This routine should not
-    be used if only one async request is needed, instead the single read
-    async routines should be called.
+    Completion routine for synchronizing back to dispatch.
 
-    A context parameter is initialized, to serve as a communications area
-    between here and the common completion routine.
+Arguments:
 
-    Next this routine reads or writes one or more contiguous sectors from
-    a device asynchronously, and is used if there are multiple reads for a
-    master IRP.  A completion routine is used to synchronize with the
-    completion of all of the I/O requests started by calls to this routine.
+    Contxt - pointer to KEVENT.
 
-    Also, prior to calling this routine the caller must initialize the
-    IoStatus field in the Context, with the correct success status and byte
-    count which are expected if all of the parallel transfers complete
-    successfully.  After return this status will be unchanged if all requests
-    were, in fact, successful.  However, if one or more errors occur, the
-    IoStatus will be modified to reflect the error status and byte count
-    from the first run (by Vbo) which encountered an error.  I/O status
+Return Value:
+
+    STATUS_MORE_PROCESSING_REQUIRED
+
+--*/
+
+{
+    PKEVENT Event = (PKEVENT)Contxt;
+    _Analysis_assume_(Contxt != NULL);
+
+    UNREFERENCED_PARAMETER( Irp );
+    UNREFERENCED_PARAMETER( DeviceObject );
+
+    KeSetEvent( Event, 0, FALSE );
+
+    //
+    //  We don't want IO to get our IRP and free it.
+    //
+    
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+
+_Requires_lock_held_(_Global_critical_region_)
+VOID
+CdFreeDirCache (
+    _In_ PIRP_CONTEXT IrpContext
+    )
+
+/*++
+
+Routine Description:
+
+    Safely frees the sector cache buffer.
+
+Arguments:
+
+Return Value:
+
+    None.
+
+--*/
+
+{
+    PAGED_CODE();
+
+    if (NULL != IrpContext->Vcb->SectorCacheBuffer) {
+        
+        CdAcquireCacheForUpdate( IrpContext);
+        CdFreePool( &IrpContext->Vcb->SectorCacheBuffer);
+        CdReleaseCache( IrpContext);
+    }
+}
+
+_Requires_lock_held_(_Global_critical_region_)
+BOOLEAN
+CdReadDirDataThroughCache (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_RUN Run
+    )
+    
+/*++
+
+Routine Description:
+
+    Reads blocks through the sector cache. If the data is present, then it
+    is copied from memory.  If not present, one of the cache chunks will be
+    replaced with a chunk containing the requested region, and the data
+    copied from there.
+
+    Only intended for reading *directory* blocks, for the purpose of pre-caching
+    directory information, by reading a chunk of blocks which hopefully contains
+    other directory blocks, rather than just the (usually) single block requested.
+
+Arguments:
+
+    Run - description of extent required, and buffer to read into.
+
+Return Value:
+
+    None. Raises on error.
+
+--*/
+
+{
+    PVCB Vcb          = IrpContext->Vcb;
+    ULONG Lbn         = SectorsFromLlBytes( Run->DiskOffset);
+    ULONG Remaining   = SectorsFromBytes( Run->DiskByteCount);
+    PUCHAR UserBuffer = Run->TransferBuffer;
+
+    NTSTATUS Status;
+    ULONG Found;
+    ULONG BufferSectorOffset;
+    ULONG StartBlock;
+    ULONG EndBlock;
+    ULONG Blocks;
+
+    PIO_STACK_LOCATION IrpSp;
+    IO_STATUS_BLOCK Iosb;
+
+    PTRACK_DATA TrackData;
+
+#if DBG
+    BOOLEAN JustRead = FALSE;
+#endif
+
+    ULONG Index;
+    PCD_SECTOR_CACHE_CHUNK Buffer;
+    BOOLEAN Result = FALSE;
+
+    PAGED_CODE();
+
+    CdAcquireCacheForRead( IrpContext);
+
+    try {
+        
+        //
+        //  Check the cache hasn't gone away due to volume verify failure (which
+        //  is the *only* reason it'll go away).  If this is the case we raise 
+        //  the same error any I/O would return if the cache weren't here.
+        //
+        
+        if (NULL == Vcb->SectorCacheBuffer) {
+        
+            CdRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED);
+        }
+        
+        while (Remaining) {
+
+            Buffer = NULL;
+
+            //
+            //  Look to see if any portion is currently cached.
+            //
+            
+            for (Index = 0; Index < CD_SEC_CACHE_CHUNKS; Index++) {
+
+                if ((Vcb->SecCacheChunks[ Index].BaseLbn != -1) &&
+                    (Vcb->SecCacheChunks[ Index].BaseLbn <= Lbn) &&
+                    ((Vcb->SecCacheChunks[ Index].BaseLbn + CD_SEC_CHUNK_BLOCKS) > Lbn)) {
+
+                    Buffer = &Vcb->SecCacheChunks[ Index];
+                    break;
+                }
+            }
+
+            //
+            //  If we found any, copy it out and continue.
+            //
+
+            if (NULL != Buffer) {
+
+                BufferSectorOffset = Lbn - Buffer->BaseLbn;
+                Found = Min( CD_SEC_CHUNK_BLOCKS - BufferSectorOffset, Remaining);
+
+                RtlCopyMemory( UserBuffer, 
+                               Buffer->Buffer + BytesFromSectors( BufferSectorOffset), 
+                               BytesFromSectors( Found));
+
+                Remaining -= Found;
+                UserBuffer += BytesFromSectors( Found);
+                Lbn += Found;
+#if DBG
+                //
+                //  Update stats.  Don't count a hit if we've just read the data in.
+                //
+                
+                if (!JustRead) {
+                    
+                    InterlockedIncrement( (LONG*)&Vcb->SecCacheHits);
+                }
+                
+                JustRead = FALSE;
+#endif                
+                continue;
+            }
+
+            //
+            //  Missed the cache, so we need to read a new chunk.  Take the cache
+            //  resource exclusive while we do so.
+            //
+
+            CdReleaseCache( IrpContext);
+            CdAcquireCacheForUpdate( IrpContext);
+#if DBG            
+            Vcb->SecCacheMisses += 1;
+#endif
+            //
+            //  Select the chunk to replace and calculate the start block of the 
+            //  chunk to cache.  We cache blocks which start on Lbns aligned on 
+            //  multiples of chunk size, treating block 16 (VRS start) as block
+            //  zero.
+            //
+
+            Buffer = &Vcb->SecCacheChunks[ Vcb->SecCacheLRUChunkIndex];
+            
+            StartBlock = Lbn - ((Lbn - 16) % CD_SEC_CHUNK_BLOCKS);
+
+            //
+            //  Make sure we don't try and read past end of the last track.
+            //
+
+            TrackData = &Vcb->CdromToc->TrackData[(Vcb->CdromToc->LastTrack - Vcb->CdromToc->FirstTrack + 1)];
+
+            SwapCopyUchar4( &EndBlock, &TrackData->Address );
+
+            Blocks = EndBlock - StartBlock;
+
+            if (Blocks > CD_SEC_CHUNK_BLOCKS) {
+
+                Blocks = CD_SEC_CHUNK_BLOCKS;
+            }
+
+            if ((0 == Blocks) || (Lbn < 16)) {
+
+                CdRaiseStatus( IrpContext, STATUS_INVALID_PARAMETER);
+            }
+
+            //
+            //  Now build / send the read request.
+            //
+            
+            IoReuseIrp( Vcb->SectorCacheIrp, STATUS_SUCCESS);
+
+            KeClearEvent( &Vcb->SectorCacheEvent);
+            Vcb->SectorCacheIrp->Tail.Overlay.Thread = PsGetCurrentThread();
+            
+            //
+            // Get a pointer to the stack location of the first driver which will be
+            // invoked.  This is where the function codes and the parameters are set.
+            //
+            
+            IrpSp = IoGetNextIrpStackLocation( Vcb->SectorCacheIrp);
+            IrpSp->MajorFunction = (UCHAR) IRP_MJ_READ;
+
+            //
+            //  Build an MDL to describe the buffer.
+            //
+            
+            IoAllocateMdl( Buffer->Buffer,
+                           BytesFromSectors( Blocks), 
+                           FALSE, 
+                           FALSE, 
+                           Vcb->SectorCacheIrp);
+            
+            if (NULL == Vcb->SectorCacheIrp->MdlAddress)  {
+            
+                IrpContext->Irp->IoStatus.Information = 0;
+                CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES);
+            }
+            
+            //
+            //  We're reading/writing into the block cache (paged pool).  Lock the
+            //  pages and update the MDL with physical page information.
+            //
+        
+            try {
+            
+                MmProbeAndLockPages( Vcb->SectorCacheIrp->MdlAddress,
+                                     KernelMode,
+                                     (LOCK_OPERATION) IoWriteAccess );
+            } 
+#pragma warning(suppress: 6320)
+            except(EXCEPTION_EXECUTE_HANDLER) {
+        
+                IoFreeMdl( Vcb->SectorCacheIrp->MdlAddress );
+                Vcb->SectorCacheIrp->MdlAddress = NULL;
+            }
+        
+            if (NULL == Vcb->SectorCacheIrp->MdlAddress) {
+        
+                CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
+            }
+
+            //
+            //  Reset the BaseLbn as we can't trust this Buffer's data until the request
+            //  is successfully completed.
+            //
+
+            Buffer->BaseLbn = (ULONG)-1;
+
+            IrpSp->Parameters.Read.Length = BytesFromSectors( Blocks);
+            IrpSp->Parameters.Read.ByteOffset.QuadPart = LlBytesFromSectors( StartBlock);
+
+            IoSetCompletionRoutine( Vcb->SectorCacheIrp,
+                                    CdSyncCompletionRoutine,
+                                    &Vcb->SectorCacheEvent,
+                                    TRUE,
+                                    TRUE,
+                                    TRUE );
+            
+            Vcb->SectorCacheIrp->UserIosb = &Iosb;
+
+            Status = IoCallDriver( Vcb->TargetDeviceObject, Vcb->SectorCacheIrp );
+            
+            if (STATUS_PENDING == Status)  {
+
+
+                (VOID)KeWaitForSingleObject( &Vcb->SectorCacheEvent,
+                                       Executive,
+                                       KernelMode,
+                                       FALSE,
+                                       NULL );
+            
+                Status = Vcb->SectorCacheIrp->IoStatus.Status;
+            }
+
+            Vcb->SectorCacheIrp->UserIosb = NULL;
+
+            //
+            //  Unlock the pages and free the MDL.
+            //
+
+            MmUnlockPages( Vcb->SectorCacheIrp->MdlAddress );
+            IoFreeMdl( Vcb->SectorCacheIrp->MdlAddress );
+            Vcb->SectorCacheIrp->MdlAddress = NULL;
+
+            if (!NT_SUCCESS( Status )) {
+
+                try_leave( Status );
+            }
+
+            //
+            //  Update the buffer information, and drop the cache resource to shared
+            //  to allow in reads.
+            //
+
+            Buffer->BaseLbn = StartBlock;
+            Vcb->SecCacheLRUChunkIndex = (Vcb->SecCacheLRUChunkIndex + 1) % CD_SEC_CACHE_CHUNKS;
+            
+            CdConvertCacheToShared( IrpContext);        
+#if DBG
+            JustRead = TRUE;
+#endif
+        }
+
+        Result = TRUE;
+    }
+    finally {
+
+        CdReleaseCache( IrpContext);
+    }
+
+    return Result;
+}
+
+
+//
+//  Local support routine
+//
+
+_Requires_lock_held_(_Global_critical_region_)
+VOID
+CdMultipleAsync (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG RunCount,
+    _Inout_ PIO_RUN IoRuns
+    )
+
+/*++
+
+Routine Description:
+
+    This routine first does the initial setup required of a Master IRP that is
+    going to be completed using associated IRPs.  This routine should not
+    be used if only one async request is needed, instead the single read
+    async routines should be called.
+
+    A context parameter is initialized, to serve as a communications area
+    between here and the common completion routine.
+
+    Next this routine reads or writes one or more contiguous sectors from
+    a device asynchronously, and is used if there are multiple reads for a
+    master IRP.  A completion routine is used to synchronize with the
+    completion of all of the I/O requests started by calls to this routine.
+
+    Also, prior to calling this routine the caller must initialize the
+    IoStatus field in the Context, with the correct success status and byte
+    count which are expected if all of the parallel transfers complete
+    successfully.  After return this status will be unchanged if all requests
+    were, in fact, successful.  However, if one or more errors occur, the
+    IoStatus will be modified to reflect the error status and byte count
+    from the first run (by Vbo) which encountered an error.  I/O status
     from all subsequent runs will not be indicated.
 
 Arguments:
@@ -2430,6 +2807,7 @@ Return Value:
     PIRP Irp;
     PIRP MasterIrp;
     ULONG UnwindRunCount;
+    BOOLEAN UseSectorCache;
 
     PAGED_CODE();
 
@@ -2444,6 +2822,21 @@ Return Value:
         CompletionRoutine = CdMultiAsyncCompletionRoutine;
     }
 
+    //
+    //  For directories, use the sector cache.
+    //
+    
+    if ((SafeNodeType( Fcb) == CDFS_NTC_FCB_INDEX) &&
+        (NULL != Fcb->Vcb->SectorCacheBuffer) &&
+        (VcbMounted == IrpContext->Vcb->VcbCondition)) {
+
+        UseSectorCache = TRUE;
+    }
+    else {
+
+        UseSectorCache = FALSE;
+    }
+
     //
     //  Initialize some local variables.
     //
@@ -2451,7 +2844,7 @@ Return Value:
     MasterIrp = IrpContext->Irp;
 
     //
-    //  Iterate through the runs, doing everything that can fail.
+    //  Itterate through the runs, doing everything that can fail.
     //  We let the cleanup in CdFinishBuffers clean up on error.
     //
 
@@ -2459,6 +2852,21 @@ Return Value:
          UnwindRunCount < RunCount;
          UnwindRunCount += 1) {
 
+        if (UseSectorCache) {
+
+            if (!CdReadDirDataThroughCache( IrpContext, &IoRuns[ UnwindRunCount])) {
+
+                //
+                //  Turn off using directory cache and restart all over again.
+                //
+
+                UseSectorCache = FALSE;
+                UnwindRunCount = 0;
+            }
+
+            continue;
+        }
+
         //
         //  Create an associated IRP, making sure there is one stack entry for
         //  us, as well.
@@ -2536,6 +2944,21 @@ Return Value:
         IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].DiskOffset;
     }
 
+    //
+    //  If we used the cache, we're done.
+    //
+
+    if (UseSectorCache) {
+
+        if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
+
+            IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
+            KeSetEvent( &IrpContext->IoContext->SyncEvent, 0, FALSE );
+        }
+
+        return;
+    }
+    
     //
     //  We only need to set the associated IRP count in the master irp to
     //  make it a master IRP.  But we set the count to one more than our
@@ -2555,6 +2978,23 @@ Return Value:
 
     MasterIrp->AssociatedIrp.IrpCount = 1;
 
+    //
+    //  If we (FS) acquired locks, transition the lock owners to an object, since
+    //  when we return this thread could go away before request completion, and
+    //  the resource package may otherwise try to boost priority, etc.
+    //
+
+    if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ) &&
+        FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) {
+
+        NT_ASSERT( IrpContext->IoContext->ResourceThreadId == (ERESOURCE_THREAD)PsGetCurrentThread() );
+
+        IrpContext->IoContext->ResourceThreadId = ((ULONG_PTR)IrpContext->IoContext) | 3;
+
+        ExSetResourceOwnerPointer( IrpContext->IoContext->Resource,
+                                   (PVOID)IrpContext->IoContext->ResourceThreadId );
+    }
+
     //
     //  Now that all the dangerous work is done, issue the Io requests
     //
@@ -2566,16 +3006,17 @@ Return Value:
         Irp = IoRuns[UnwindRunCount].SavedIrp;
         IoRuns[UnwindRunCount].SavedIrp = NULL;
 
-        //
-        //  If IoCallDriver returns an error, it has completed the Irp
-        //  and the error will be caught by our completion routines
-        //  and dealt with as a normal IO error.
-        //
+        if (NULL != Irp) {
+            
+            //
+            //  If IoCallDriver returns an error, it has completed the Irp
+            //  and the error will be caught by our completion routines
+            //  and dealt with as a normal IO error.
+            //
 
-        (VOID) IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp );
+            (VOID) IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp );
+        }
     }
-
-    return;
 }
 
 \f
@@ -2585,11 +3026,11 @@ Return Value:
 
 VOID
 CdMultipleXAAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG RunCount,
-    IN PIO_RUN IoRuns,
-    IN PRAW_READ_INFO RawReads,
-    IN TRACK_MODE_TYPE TrackMode
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG RunCount,
+    _Inout_ PIO_RUN IoRuns,
+    _In_ PRAW_READ_INFO RawReads,
+    _In_ TRACK_MODE_TYPE TrackMode
     )
 
 /*++
@@ -2656,7 +3097,7 @@ Return Value:
     MasterIrp = IrpContext->Irp;
 
     //
-    //  Iterate through the runs, doing everything that can fail.
+    //  Itterate through the runs, doing everything that can fail.
     //  We let the cleanup in CdFinishBuffers clean up on error.
     //
 
@@ -2683,7 +3124,7 @@ Return Value:
         //  must be a multiple of sector size
         //
         
-        ASSERT( ThisIoRun->DiskByteCount && !SectorOffset(ThisIoRun->DiskByteCount));
+        NT_ASSERT( ThisIoRun->DiskByteCount && !SectorOffset(ThisIoRun->DiskByteCount));
 
         RawByteCount = SectorsFromBytes( ThisIoRun->DiskByteCount) * RAW_SECTOR_SIZE;
 
@@ -2809,11 +3250,12 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdSingleAsync (
-    IN PIRP_CONTEXT IrpContext,
-    IN LONGLONG ByteOffset,
-    IN ULONG ByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_RUN Run,
+    _In_ PFCB Fcb
     )
 
 /*++
@@ -2844,6 +3286,26 @@ Return Value:
 
     PAGED_CODE();
 
+    //
+    //  For directories, look in the sector cache,
+    //
+    
+    if ((SafeNodeType( Fcb) == CDFS_NTC_FCB_INDEX) &&
+        (NULL != Fcb->Vcb->SectorCacheBuffer) &&
+        (VcbMounted == IrpContext->Vcb->VcbCondition)) {
+
+        if (CdReadDirDataThroughCache( IrpContext, Run )) {
+
+            if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
+                
+                IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
+                KeSetEvent( &IrpContext->IoContext->SyncEvent, 0, FALSE );
+            }
+
+            return;
+        }
+    }
+
     //
     //  Set up things according to whether this is truely async.
     //
@@ -2855,6 +3317,22 @@ Return Value:
     } else {
 
         CompletionRoutine = CdSingleAsyncCompletionRoutine;
+
+        //
+        //  If we (FS) acquired locks, transition the lock owners to an object, since
+        //  when we return this thread could go away before request completion, and
+        //  the resource package may otherwise try to boost priority, etc.
+        //
+
+        if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) {
+        
+            NT_ASSERT( IrpContext->IoContext->ResourceThreadId == (ERESOURCE_THREAD)PsGetCurrentThread() );
+        
+            IrpContext->IoContext->ResourceThreadId = ((ULONG_PTR)IrpContext->IoContext) | 3;
+        
+            ExSetResourceOwnerPointer( IrpContext->IoContext->Resource,
+                                       (PVOID)IrpContext->IoContext->ResourceThreadId );
+        }
     }
 
     //
@@ -2879,9 +3357,9 @@ Return Value:
     //  Setup the Stack location to do a read from the disk driver.
     //
 
-    IrpSp->MajorFunction = IRP_MJ_READ;
-    IrpSp->Parameters.Read.Length = ByteCount;
-    IrpSp->Parameters.Read.ByteOffset.QuadPart = ByteOffset;
+    IrpSp->MajorFunction = IrpContext->MajorFunction;
+    IrpSp->Parameters.Read.Length = Run->DiskByteCount;
+    IrpSp->Parameters.Read.ByteOffset.QuadPart = Run->DiskOffset;
 
     //
     //  Issue the Io request
@@ -2894,12 +3372,6 @@ Return Value:
     //
 
     (VOID)IoCallDriver( IrpContext->Vcb->TargetDeviceObject, IrpContext->Irp );
-
-    //
-    //  And return to our caller
-    //
-
-    return;
 }
 
 \f
@@ -2909,7 +3381,7 @@ Return Value:
 
 VOID
 CdWaitSync (
-    IN PIRP_CONTEXT IrpContext
+    _In_ PIRP_CONTEXT IrpContext
     )
 
 /*++
@@ -2930,15 +3402,14 @@ Return Value:
 {
     PAGED_CODE();
 
-    KeWaitForSingleObject( &IrpContext->IoContext->SyncEvent,
+
+    (VOID)KeWaitForSingleObject( &IrpContext->IoContext->SyncEvent,
                            Executive,
                            KernelMode,
                            FALSE,
                            NULL );
 
     KeClearEvent( &IrpContext->IoContext->SyncEvent );
-
-    return;
 }
 
 \f
@@ -2947,11 +3418,10 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdMultiSyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Context
     )
 
 /*++
@@ -2992,6 +3462,7 @@ Return Value:
 
 {
     PCD_IO_CONTEXT IoContext = Context;
+    _Analysis_assume_(Context != NULL);
 
     AssertVerifyDeviceIrp( Irp );
 
@@ -3034,11 +3505,10 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdMultiAsyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Context
     )
 
 /*++
@@ -3072,11 +3542,11 @@ Return Value:
 
 {
     PCD_IO_CONTEXT IoContext = Context;
-    /* ReactOS Change: GCC Unused Variable */
-    //PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
-
+    _Analysis_assume_(Context != NULL);
     AssertVerifyDeviceIrp( Irp );
-    
+
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     //
     //  If we got an error (or verify required), remember it in the Irp
     //
@@ -3119,8 +3589,8 @@ Return Value:
         //  Now release the resource
         //
 
-        ExReleaseResourceForThreadLite( IoContext->Resource,
-                                    IoContext->ResourceThreadId );
+        _Analysis_assume_lock_held_(*IoContext->Resource);
+        ExReleaseResourceForThreadLite( IoContext->Resource, IoContext->ResourceThreadId );
 
         //
         //  and finally, free the context record.
@@ -3146,7 +3616,6 @@ Return Value:
         return STATUS_MORE_PROCESSING_REQUIRED;
     }
 
-    UNREFERENCED_PARAMETER( DeviceObject );
 }
 
 \f
@@ -3155,11 +3624,10 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdSingleSyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Context
     )
 
 /*++
@@ -3193,6 +3661,10 @@ Return Value:
 --*/
 
 {
+    _Analysis_assume_(Context != NULL);
+
+    UNREFERENCED_PARAMETER( DeviceObject );
+    
     AssertVerifyDeviceIrp( Irp );
     
     //
@@ -3215,11 +3687,10 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdSingleAsyncCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Context
     )
 
 /*++
@@ -3246,6 +3717,11 @@ Return Value:
 --*/
 
 {
+    PCD_IO_CONTEXT IoContext = Context;
+
+    UNREFERENCED_PARAMETER( DeviceObject );
+
+    _Analysis_assume_(IoContext != NULL);
     AssertVerifyDeviceIrp( Irp );
     
     //
@@ -3256,7 +3732,7 @@ Return Value:
 
     if (NT_SUCCESS( Irp->IoStatus.Status )) {
 
-        Irp->IoStatus.Information = ((PCD_IO_CONTEXT) Context)->RequestedByteCount;
+        Irp->IoStatus.Information = IoContext->RequestedByteCount;
     }
 
     //
@@ -3269,17 +3745,16 @@ Return Value:
     //  Now release the resource
     //
 
-    ExReleaseResourceForThreadLite( ((PCD_IO_CONTEXT) Context)->Resource,
-                                ((PCD_IO_CONTEXT) Context)->ResourceThreadId );
+    _Analysis_assume_lock_held_(*IoContext->Resource);
+    ExReleaseResourceForThreadLite( IoContext->Resource, IoContext->ResourceThreadId );
 
     //
     //  and finally, free the context record.
     //
 
-    CdFreeIoContext(  Context ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */
+    CdFreeIoContext( IoContext );
     return STATUS_SUCCESS;
 
-    UNREFERENCED_PARAMETER( DeviceObject );
 }
 
 \f
@@ -3287,13 +3762,15 @@ Return Value:
 //  Local support routine
 //
 
+_When_(SafeNodeType(Fcb) != CDFS_NTC_FCB_PATH_TABLE && StartingOffset == 0, _At_(ByteCount, _In_range_(>=, CdAudioDirentSize + sizeof(RAW_DIRENT))))
+_When_(SafeNodeType(Fcb) != CDFS_NTC_FCB_PATH_TABLE && StartingOffset != 0, _At_(ByteCount, _In_range_(>=, CdAudioDirentSize + SECTOR_SIZE)))
 VOID
 CdReadAudioSystemFile (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG StartingOffset,
-    IN ULONG ByteCount,
-    IN PVOID SystemBuffer
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG StartingOffset,
+    _In_ _In_range_(>=, CdAudioDirentSize) ULONG ByteCount,
+    _Out_writes_bytes_(ByteCount) PVOID SystemBuffer
     )
 
 /*++
@@ -3354,7 +3831,7 @@ Return Value:
         //  Sanity check that the offset is zero.
         //
 
-        ASSERT( StartingOffset == 0 );
+        NT_ASSERT( StartingOffset == 0 );
 
         //
         //  Store a pseudo path entry in our local buffer.
@@ -3543,20 +4020,13 @@ Return Value:
                                CdAudioFileNameLength );
 
                 //
-                //  Set the time stamp to be Jan 1, 1995
+                //  Set the time stamp to be Jan 1, 1995 00:00
                 //
 
                 RawDirent->RecordTime[0] = 95;
                 RawDirent->RecordTime[1] = 1;
                 RawDirent->RecordTime[2] = 1;
 
-                //
-                //  Now bias by the values in the TOC.
-                //
-
-                RawDirent->RecordTime[4] = ThisTrack->Address[1] % 60;
-                RawDirent->RecordTime[5] = ThisTrack->Address[2] % 60;
-
                 //
                 //  Put the track number into the file name.
                 //
@@ -3610,3 +4080,96 @@ Return Value:
     return;
 }
 
+
+NTSTATUS
+CdHijackIrpAndFlushDevice (
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PDEVICE_OBJECT TargetDeviceObject
+    )
+
+/*++
+
+Routine Description:
+
+    This routine is called when we need to send a flush to a device but
+    we don't have a flush Irp.  What this routine does is make a copy
+    of its current Irp stack location, but changes the Irp Major code
+    to a IRP_MJ_FLUSH_BUFFERS amd then send it down, but cut it off at
+    the knees in the completion routine, fix it up and return to the
+    user as if nothing had happened.
+
+Arguments:
+
+    Irp - The Irp to hijack
+
+    TargetDeviceObject - The device to send the request to.
+
+Return Value:
+
+    NTSTATUS - The Status from the flush in case anybody cares.
+
+--*/
+
+{
+    KEVENT Event;
+    NTSTATUS Status;
+    PIO_STACK_LOCATION NextIrpSp;
+
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( IrpContext );
+    
+    //
+    //  Get the next stack location, and copy over the stack location
+    //
+
+    NextIrpSp = IoGetNextIrpStackLocation( Irp );
+
+    *NextIrpSp = *IoGetCurrentIrpStackLocation( Irp );
+
+    NextIrpSp->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
+    NextIrpSp->MinorFunction = 0;
+
+    //
+    //  Set up the completion routine
+    //
+
+    KeInitializeEvent( &Event, NotificationEvent, FALSE );
+
+    IoSetCompletionRoutine( Irp,
+                            CdSyncCompletionRoutine,
+                            &Event,
+                            TRUE,
+                            TRUE,
+                            TRUE );
+
+    //
+    //  Send the request.
+    //
+
+    Status = IoCallDriver( TargetDeviceObject, Irp );
+
+    if (Status == STATUS_PENDING) {
+
+        (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
+
+        Status = Irp->IoStatus.Status;
+    }
+
+    //
+    //  If the driver doesn't support flushes, return SUCCESS.
+    //
+
+    if (Status == STATUS_INVALID_DEVICE_REQUEST) {
+
+        Status = STATUS_SUCCESS;
+    }
+
+    Irp->IoStatus.Status = 0;
+    Irp->IoStatus.Information = 0;
+
+    return Status;
+}
+
+
index 28cf0d5..71cfccb 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -26,41 +26,43 @@ Abstract:
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PFCB Fcb,
-    IN PCCB Ccb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PFCB Fcb,
+    _In_ PCCB Ccb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdNotifyChangeDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PCCB Ccb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PCCB Ccb
     );
 
 VOID
 CdInitializeEnumeration (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PFCB Fcb,
-    IN OUT PCCB Ccb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    OUT PBOOLEAN ReturnNextEntry,
-    OUT PBOOLEAN ReturnSingleEntry,
-    OUT PBOOLEAN InitialQuery
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PFCB Fcb,
+    _Inout_ PCCB Ccb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _Out_ PBOOLEAN ReturnNextEntry,
+    _Out_ PBOOLEAN ReturnSingleEntry,
+    _Out_ PBOOLEAN InitialQuery
     );
 
 BOOLEAN
 CdEnumerateIndex (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCCB Ccb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    IN BOOLEAN ReturnNextEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCCB Ccb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _In_ BOOLEAN ReturnNextEntry
     );
 
 #ifdef ALLOC_PRAGMA
@@ -72,10 +74,12 @@ CdEnumerateIndex (
 #endif
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonDirControl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -152,13 +156,14 @@ Return Value:
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PFCB Fcb,
-    IN PCCB Ccb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PFCB Fcb,
+    _In_ PCCB Ccb
     )
 
 /*++
@@ -197,9 +202,9 @@ Return Value:
     ULONG VersionStringBytes;
 
     FILE_ENUM_CONTEXT FileContext;
-    PDIRENT ThisDirent;
+    PDIRENT ThisDirent = NULL;
     BOOLEAN InitialQuery;
-    BOOLEAN ReturnNextEntry;
+    BOOLEAN ReturnNextEntry = FALSE;
     BOOLEAN ReturnSingleEntry;
     BOOLEAN Found;
     BOOLEAN DoCcbUpdate = FALSE;
@@ -209,7 +214,7 @@ Return Value:
 
     ULONG BaseLength;
 
-    PFILE_BOTH_DIR_INFORMATION DirInfo = NULL; /* ReactOS Change: GCC Uninit var */
+    PFILE_BOTH_DIR_INFORMATION DirInfo = NULL;
     PFILE_NAMES_INFORMATION NamesInfo;
     PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo;
     PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo;
@@ -287,7 +292,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Fcb is still good.
@@ -387,7 +392,7 @@ Return Value:
             //
             //  Here are the rules concerning filling up the buffer:
             //
-            //  1.  The Io system guarantees that there will always be
+            //  1.  The Io system garentees that there will always be
             //      enough room for at least one base record.
             //
             //  2.  If the full first record (including file name) cannot
@@ -499,7 +504,7 @@ Return Value:
             //  such trickery.
             //
             
-            _SEH2_TRY {
+            try {
             
                 //
                 //  Zero and initialize the base part of the current entry.
@@ -543,21 +548,16 @@ Return Value:
     
                         DirInfo->EndOfFile.QuadPart = DirInfo->AllocationSize.QuadPart = 0;
     
-                        SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY );
-    
+                        SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
+                        
                     } else {
     
                         DirInfo->EndOfFile.QuadPart = FileContext.FileSize;
                         DirInfo->AllocationSize.QuadPart = LlSectorAlign( FileContext.FileSize );
+                        
+                        SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_READONLY);
                     }
-    
-                    //
-                    //  All Cdrom files are readonly.  We also copy the existence
-                    //  bit to the hidden attribute.
-                    //
-    
-                    SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_READONLY );
-    
+
                     if (FlagOn( ThisDirent->DirentFlags,
                                 CD_ATTRIBUTE_HIDDEN )) {
     
@@ -579,9 +579,6 @@ Return Value:
                     NamesInfo->FileNameLength = FileNameBytes + SeparatorBytes + VersionStringBytes;
     
                     break;
-
-                /* ReactOS Change: GCC "enumeration value not handled in switch" */
-                default: break;
                 }
 
                 //
@@ -715,7 +712,8 @@ Return Value:
                 LastEntry = NextEntry;
                 NextEntry = QuadAlign( Information );
             
-            } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+#pragma warning(suppress: 6320)
+            } except (EXCEPTION_EXECUTE_HANDLER) {
 
                   //
                   //  We had a problem filling in the user's buffer, so stop and
@@ -724,16 +722,16 @@ Return Value:
                   //
                   
                   Information = 0;
-                  try_leave( Status = _SEH2_GetExceptionCode());
-            } _SEH2_END;
+                  try_leave( Status = GetExceptionCode());
+            }
         }
         
         DoCcbUpdate = TRUE;
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
-        //  Cleanup our search context - *before* acquiring the FCB mutex exclusive,
+        //  Cleanup our search context - *before* aquiring the FCB mutex exclusive,
         //  else can block on threads in cdcreateinternalstream/purge which 
         //  hold the FCB but are waiting for all maps in this stream to be released.
         //
@@ -741,7 +739,7 @@ Return Value:
         CdCleanupFileContext( IrpContext, &FileContext );
 
         //
-        //  Now we can safely acquire the FCB mutex if we need to.
+        //  Now we can safely aqure the FCB mutex if we need to.
         //
 
         if (DoCcbUpdate && !NT_ERROR( Status )) {
@@ -769,7 +767,7 @@ Return Value:
         //
 
         CdReleaseFile( IrpContext, Fcb );
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request here.
@@ -786,12 +784,13 @@ Return Value:
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdNotifyChangeDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PCCB Ccb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PCCB Ccb
     )
 
 /*++
@@ -837,7 +836,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Vcb.
@@ -862,14 +861,14 @@ Return Value:
                                         NULL,
                                         NULL );
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the Vcb.
         //
 
         CdReleaseVcb( IrpContext, IrpContext->Vcb );
-    } _SEH2_END;
+    }
 
     //
     //  Cleanup the IrpContext.
@@ -887,14 +886,14 @@ Return Value:
 
 VOID
 CdInitializeEnumeration (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIO_STACK_LOCATION IrpSp,
-    IN PFCB Fcb,
-    IN OUT PCCB Ccb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    OUT PBOOLEAN ReturnNextEntry,
-    OUT PBOOLEAN ReturnSingleEntry,
-    OUT PBOOLEAN InitialQuery
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PIO_STACK_LOCATION IrpSp,
+    _In_ PFCB Fcb,
+    _Inout_ PCCB Ccb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _Out_ PBOOLEAN ReturnNextEntry,
+    _Out_ PBOOLEAN ReturnSingleEntry,
+    _Out_ PBOOLEAN InitialQuery
     )
 
 /*++
@@ -949,6 +948,31 @@ Return Value:
 
     PAGED_CODE();
 
+    //
+    //  If the user has specified that the scan be restarted, and has specicified 
+    //  a new query pattern, reinitialize the CCB.
+    //
+
+    if (FlagOn( IrpSp->Flags, SL_RESTART_SCAN )) {
+
+        CdLockFcb( IrpContext, Fcb );
+
+        FileName = (PUNICODE_STRING) IrpSp->Parameters.QueryDirectory.FileName;
+        if (FileName && FileName->Length > 0) {
+
+            if (!FlagOn( Ccb->Flags, CCB_FLAG_ENUM_MATCH_ALL )) {
+
+                CdFreePool( &Ccb->SearchExpression.FileName.Buffer );
+            }
+
+            ClearFlag(Ccb->Flags, CCB_FLAG_ENUM_MATCH_ALL);
+            ClearFlag(Ccb->Flags, CCB_FLAG_ENUM_INITIALIZED);
+            ClearFlag(Ccb->Flags, CCB_FLAG_ENUM_NAME_EXP_HAS_WILD);
+        }
+
+        CdUnlockFcb( IrpContext, Fcb );
+    }
+
     //
     //  If this is the initial query then build a search expression from the input
     //  file name.
@@ -1049,8 +1073,8 @@ Return Value:
                 //
                 //  This should never fail.
                 //
-
-                ASSERT( Status == STATUS_SUCCESS );
+                __analysis_assert( Status == STATUS_SUCCESS );
+                NT_ASSERT( Status == STATUS_SUCCESS );
 
             } else {
 
@@ -1189,10 +1213,7 @@ Return Value:
     //  If there is no file object then create it now.
     //
 
-    if (Fcb->FileObject == NULL) {
-
-        CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
-    }
+    CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
 
     //
     //  Determine the offset in the stream to position the FileContext and
@@ -1330,10 +1351,10 @@ Return Value:
 
 BOOLEAN
 CdEnumerateIndex (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCCB Ccb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    IN BOOLEAN ReturnNextEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCCB Ccb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _In_ BOOLEAN ReturnNextEntry
     )
 
 /*++
@@ -1371,7 +1392,7 @@ Return Value:
     PAGED_CODE();
 
     //
-    //  Loop until we find a match or exhaust the directory.
+    //  Loop until we find a match or exaust the directory.
     //
 
     while (TRUE) {
index 6a652eb..b1667d3 100755 (executable)
@@ -65,7 +65,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -80,8 +80,8 @@ Abstract:
 //
 //  PRAW_DIRENT
 //  CdRawDirent (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PDIR_ENUM_CONTEXT DirContext
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PDIR_ENUM_CONTEXT DirContext
 //      );
 //
 
@@ -94,15 +94,15 @@ Abstract:
 
 ULONG
 CdCheckRawDirentBounds (
-    IN PIRP_CONTEXT IrpContext,
-    IN PDIRENT_ENUM_CONTEXT DirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PDIRENT_ENUM_CONTEXT DirContext
     );
 
 XA_EXTENT_TYPE
 CdCheckForXAExtent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRAW_DIRENT RawDirent,
-    IN OUT PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PRAW_DIRENT RawDirent,
+    _Inout_ PDIRENT Dirent
     );
 
 #ifdef ALLOC_PRAGMA
@@ -123,10 +123,10 @@ CdCheckForXAExtent (
 \f
 VOID
 CdLookupDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG DirentOffset,
-    OUT PDIRENT_ENUM_CONTEXT DirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG DirentOffset,
+    _Out_ PDIRENT_ENUM_CONTEXT DirContext
     )
 
 /*++
@@ -206,10 +206,10 @@ Return Value:
 \f
 BOOLEAN
 CdLookupNextDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PDIRENT_ENUM_CONTEXT CurrentDirContext,
-    OUT PDIRENT_ENUM_CONTEXT NextDirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PDIRENT_ENUM_CONTEXT CurrentDirContext,
+    _Inout_ PDIRENT_ENUM_CONTEXT NextDirContext
     )
 
 /*++
@@ -241,7 +241,7 @@ Arguments:
         find.  This may already point to a dirent so we need to check if
         we are in the same sector and unmap any buffer as necessary.
 
-        This dirent is left in an indeterminate state if we don't find a dirent.
+        This dirent is left in an indeterminant state if we don't find a dirent.
 
 Return Value:
 
@@ -390,13 +390,14 @@ Return Value:
     return FoundDirent;
 }
 
-\f
+
+_At_(Dirent->CdTime, _Post_notnull_)\f
 VOID
 CdUpdateDirentFromRawDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PDIRENT_ENUM_CONTEXT DirContext,
-    IN OUT PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PDIRENT_ENUM_CONTEXT DirContext,
+    _Inout_ PDIRENT Dirent
     )
 
 /*++
@@ -426,6 +427,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( Fcb );
+
     //
     //  Clear all of the current state flags except the flag indicating that
     //  we allocated a name string.
@@ -465,7 +468,7 @@ Return Value:
     //  Save a pointer to the time stamps.
     //
 
-    Dirent->CdTime = (PCHAR)RawDirent->RecordTime; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */
+    Dirent->CdTime = (PCHAR)RawDirent->RecordTime;
 
     //
     //  Copy the dirent flags.
@@ -501,7 +504,7 @@ Return Value:
     }
 
     Dirent->FileNameLen = RawDirent->FileIdLen;
-    Dirent->FileName = (PCHAR)RawDirent->FileId; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */
+    Dirent->FileName = (PCHAR)RawDirent->FileId;
 
     //
     //  If there are any remaining bytes at the end of the dirent then
@@ -529,9 +532,9 @@ Return Value:
 \f
 VOID
 CdUpdateDirentName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PDIRENT Dirent,
-    IN ULONG IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PDIRENT Dirent,
+    _In_ ULONG IgnoreCase
     )
 
 /*++
@@ -704,7 +707,8 @@ Return Value:
                                    Dirent->FileName,
                                    Dirent->FileNameLen );
 
-        ASSERT( Status == STATUS_SUCCESS );
+        __analysis_assert( Status == STATUS_SUCCESS );
+        NT_ASSERT( Status == STATUS_SUCCESS );
         Dirent->CdFileName.FileName.Length = (USHORT) Length;
 
     } else {
@@ -781,6 +785,11 @@ Return Value:
         Dirent->CdFileName.FileName.Length -= sizeof( WCHAR );
     }
 
+    if (!CdIsLegalName( IrpContext, &Dirent->CdFileName.FileName )) {
+
+        CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
+    }
+
     //
     //  If this an exact case operation then use the filename exactly.
     //
@@ -811,21 +820,21 @@ Return Value:
 }
 
 \f
-BOOLEAN
+_Success_(return != FALSE) BOOLEAN
 CdFindFile (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PFILE_ENUM_CONTEXT FileContext,
-    OUT PCD_NAME *MatchingName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext,
+    _Out_ PCD_NAME *MatchingName
     )
 
 /*++
 
 Routine Description:
 
-    This routine is called to search a directory for a file matching the input
+    This routine is called to search a dirctory for a file matching the input
     name.  This name has been upcased at this point if this a case-insensitive
     search.  The name has been separated into separate name and version strings.
     We look for an exact match in the name and only consider the version if
@@ -864,10 +873,7 @@ Return Value:
     //  Make sure there is a stream file for this Fcb.
     //
 
-    if (Fcb->FileObject == NULL) {
-
-        CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
-    }
+    CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
 
     //
     //  Check to see whether we need to check for a possible short name.
@@ -989,18 +995,18 @@ Return Value:
 \f
 BOOLEAN
 CdFindDirectory (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
 
 Routine Description:
 
-    This routine is called to search a directory for a directory matching the input
+    This routine is called to search a dirctory for a directory matching the input
     name.  This name has been upcased at this point if this a case-insensitive
     search.  We look for an exact match in the name and do not look for shortname
     equivalents.
@@ -1033,10 +1039,7 @@ Return Value:
     //  Make sure there is a stream file for this Fcb.
     //
 
-    if (Fcb->FileObject == NULL) {
-
-        CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
-    }
+    CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
 
     //
     //  Position ourselves at the first entry.
@@ -1100,14 +1103,15 @@ Return Value:
 }
 
 \f
+_At_(FileContext->ShortName.FileName.MaximumLength, _In_range_(>=, BYTE_COUNT_8_DOT_3))
 BOOLEAN
 CdFindFileByShortName (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN ULONG ShortNameDirentOffset,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ ULONG ShortNameDirentOffset,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
@@ -1153,10 +1157,7 @@ Return Value:
     //  Make sure there is a stream file for this Fcb.
     //
 
-    if (Fcb->FileObject == NULL) {
-
-        CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
-    }
+    CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
 
     //
     //  Position ourselves at the start of the directory and update
@@ -1272,9 +1273,9 @@ Return Value:
 \f
 BOOLEAN
 CdLookupNextInitialFileDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Inout_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
@@ -1283,7 +1284,7 @@ Routine Description:
 
     This routine is called to walk through the directory until we find the
     first possible dirent for file.  We are positioned at some point described
-    by the FileContext.  We will walk through any remaining dirents for the
+    by the FileContext.  We will walk through any remaing dirents for the
     current file until we find the first dirent for some subsequent file.
 
     We can be called when we have found just one dirent for a file or all
@@ -1423,9 +1424,9 @@ Return Value:
 \f
 VOID
 CdLookupLastFileDirent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
@@ -1457,9 +1458,9 @@ Return Value:
 --*/
 
 {
-    XA_EXTENT_TYPE ExtentType = 0; /* ReactOS Change: GCC Uninit var */
+    XA_EXTENT_TYPE ExtentType = Form1Data;
     PCOMPOUND_DIRENT CurrentCompoundDirent;
-    PDIRENT CurrentDirent;
+    PDIRENT CurrentDirent = NULL;
 
     BOOLEAN FirstPass = TRUE;
     BOOLEAN FoundDirent;
@@ -1633,8 +1634,8 @@ Return Value:
 \f
 VOID
 CdCleanupFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
@@ -1661,6 +1662,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Cleanup the individual compound dirents.
     //
@@ -1683,8 +1686,8 @@ Return Value:
 
 ULONG
 CdCheckRawDirentBounds (
-    IN PIRP_CONTEXT IrpContext,
-    IN PDIRENT_ENUM_CONTEXT DirContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PDIRENT_ENUM_CONTEXT DirContext
     )
 
 /*++
@@ -1718,12 +1721,14 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  We should always have at least a byte still available in the
     //  current buffer.
     //
 
-    ASSERT( (DirContext->DataLength - DirContext->SectorOffset) >= 1 );
+    NT_ASSERT( (DirContext->DataLength - DirContext->SectorOffset) >= 1 );
 
     //
     //  Get a pointer to the current dirent.
@@ -1783,9 +1788,9 @@ Return Value:
 
 XA_EXTENT_TYPE
 CdCheckForXAExtent (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRAW_DIRENT RawDirent,
-    IN OUT PDIRENT Dirent
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PRAW_DIRENT RawDirent,
+    _Inout_ PDIRENT Dirent
     )
 
 /*++
@@ -1815,6 +1820,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Check if there is enough space for the XA system use area.
     //
index 63bc236..0aecc39 100755 (executable)
@@ -1,4 +1,4 @@
-#include "cdprocs.h"
+#include "CdProcs.h"
 #include <stdio.h>
 
 #define doit(a,b) { printf("%s %04lx %4lx %s\n", #a, FIELD_OFFSET(a,b), sizeof(d.b), #b); }
@@ -127,7 +127,6 @@ main (argc, argv)
     printf("\n");
     {
         FCB_DATA d;
-        doit( FCB_DATA, Oplock );
         doit( FCB_DATA, FileLock );
     }
     printf("\n");
@@ -475,4 +474,3 @@ main (argc, argv)
         doit( SYSTEM_USE_XA, Reserved );
     }
 }
-
index ca22058..cd9f1af 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -28,67 +28,68 @@ Abstract:
 
 VOID
 CdQueryBasicInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_BASIC_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_BASIC_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 VOID
 CdQueryStandardInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_STANDARD_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_STANDARD_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 VOID
 CdQueryInternalInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_INTERNAL_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_INTERNAL_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 VOID
 CdQueryEaInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_EA_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_EA_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 VOID
 CdQueryPositionInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN OUT PFILE_POSITION_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFILE_POSITION_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 NTSTATUS
 CdQueryNameInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN OUT PFILE_NAME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFILE_NAME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryAlternateNameInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCCB Ccb,
-    IN OUT PFILE_NAME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCCB Ccb,
+    _Out_ PFILE_NAME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 VOID
 CdQueryNetworkInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 #ifdef ALLOC_PRAGMA
@@ -108,10 +109,11 @@ CdQueryNetworkInfo (
 #endif
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonQueryInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -165,7 +167,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We only support query on file and directory handles.
@@ -191,8 +193,8 @@ Return Value:
 
             if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) {
 
-                ASSERT( TypeOfOpen == UserDirectoryOpen );
-                CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
+                NT_ASSERT( TypeOfOpen == UserDirectoryOpen );
+                CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
             }
 
             //
@@ -325,7 +327,7 @@ Return Value:
 
         Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the file.
@@ -335,7 +337,7 @@ Return Value:
 
             CdReleaseFile( IrpContext, Fcb );
         }
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request if we didn't raise.
@@ -347,10 +349,11 @@ Return Value:
 }
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonSetInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -406,7 +409,7 @@ Return Value:
 
     CdAcquireFileShared( IrpContext, Fcb );
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Make sure the Fcb is in a usable condition.  This
@@ -445,10 +448,10 @@ Return Value:
         Status = STATUS_SUCCESS;
 
     try_exit: NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         CdReleaseFile( IrpContext, Fcb );
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request if there was no raise.
@@ -458,15 +461,17 @@ Return Value:
     return Status;
 }
 
-\f
+
+_Function_class_(FAST_IO_QUERY_BASIC_INFO)
+_IRQL_requires_same_\f
+_Success_(return != FALSE)
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastQueryBasicInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    IN OUT PFILE_BASIC_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ BOOLEAN Wait,
+    _Out_ PFILE_BASIC_INFORMATION Buffer,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -500,6 +505,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     ASSERT_FILE_OBJECT( FileObject );
 
     FsRtlEnterFileSystem();
@@ -536,7 +543,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Only deal with 'good' Fcb's.
@@ -566,25 +573,27 @@ Return Value:
             Result = TRUE;
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         ExReleaseResourceLite( Fcb->Resource );
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Result;
 }
 
-\f
+
+_Function_class_(FAST_IO_QUERY_STANDARD_INFO)
+_IRQL_requires_same_
+_Success_(return != FALSE)
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastQueryStdInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    IN OUT PFILE_STANDARD_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ BOOLEAN Wait,
+    _Out_ PFILE_STANDARD_INFORMATION Buffer,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -618,6 +627,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     ASSERT_FILE_OBJECT( FileObject );
 
     FsRtlEnterFileSystem();
@@ -654,7 +665,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Only deal with 'good' Fcb's.
@@ -694,25 +705,27 @@ Return Value:
             Result = TRUE;
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         ExReleaseResourceLite( Fcb->Resource );
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Result;
 }
 
-\f
+
+_Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO)
+_IRQL_requires_same_
+_Success_(return != FALSE)
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastQueryNetworkInfo (
-    IN PFILE_OBJECT FileObject,
-    IN BOOLEAN Wait,
-    OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ BOOLEAN Wait,
+    _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -746,6 +759,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     ASSERT_FILE_OBJECT( FileObject );
 
     FsRtlEnterFileSystem();
@@ -782,7 +797,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Only deal with 'good' Fcb's.
@@ -827,12 +842,12 @@ Return Value:
             Result = TRUE;
         }
 
-    } _SEH2_FINALLY {
+    } finally {
 
         ExReleaseResourceLite( Fcb->Resource );
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Result;
 }
@@ -844,10 +859,10 @@ Return Value:
 
 VOID
 CdQueryBasicInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_BASIC_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_BASIC_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -875,6 +890,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  We only support creation, last modify and last write times on Cdfs.
     //
@@ -903,10 +920,10 @@ Return Value:
 
 VOID
 CdQueryStandardInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_STANDARD_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_STANDARD_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 /*++
 
@@ -933,6 +950,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  There is only one link and delete is never pending on a Cdrom file.
     //
@@ -976,10 +995,10 @@ Return Value:
 
 VOID
 CdQueryInternalInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_INTERNAL_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_INTERNAL_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1007,6 +1026,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Index number is the file Id number in the Fcb.
     //
@@ -1024,10 +1045,10 @@ Return Value:
 
 VOID
 CdQueryEaInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_EA_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_EA_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1055,6 +1076,9 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    UNREFERENCED_PARAMETER( Fcb );
+
     //
     //  No Ea's on Cdfs volumes.
     //
@@ -1072,10 +1096,10 @@ Return Value:
 
 VOID
 CdQueryPositionInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN OUT PFILE_POSITION_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFILE_POSITION_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1103,6 +1127,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Get the current position found in the file object.
     //
@@ -1125,10 +1151,10 @@ Return Value:
 
 NTSTATUS
 CdQueryNameInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN OUT PFILE_NAME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFILE_NAME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1159,7 +1185,9 @@ Return Value:
 
     PAGED_CODE();
 
-    ASSERT(*Length >= sizeof(ULONG));
+    UNREFERENCED_PARAMETER( IrpContext );
+
+    NT_ASSERT(*Length >= sizeof(ULONG));
     
     //
     //  Simply copy the name in the file object to the user's buffer.
@@ -1197,13 +1225,14 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryAlternateNameInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCCB Ccb,
-    IN OUT PFILE_NAME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ PCCB Ccb,
+    _Out_ PFILE_NAME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1237,16 +1266,16 @@ Return Value:
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
-    DIRENT_ENUM_CONTEXT DirContext;
-    DIRENT Dirent;
+    DIRENT_ENUM_CONTEXT DirContext = {0};
+    DIRENT Dirent = {0};
 
     PUNICODE_STRING NameToUse;
     ULONG DirentOffset;
 
-    COMPOUND_PATH_ENTRY CompoundPathEntry;
+    COMPOUND_PATH_ENTRY CompoundPathEntry = {0};
     FILE_ENUM_CONTEXT FileContext;
 
-    PFCB ParentFcb;
+    PFCB ParentFcb = NULL;
     BOOLEAN ReleaseParentFcb = FALSE;
 
     BOOLEAN CleanupFileLookup = FALSE;
@@ -1278,20 +1307,13 @@ Return Value:
     //  Use a try-finally to cleanup the structures.
     //
 
-    _SEH2_TRY {
+    try {
 
         ParentFcb = Fcb->ParentFcb;
         CdAcquireFileShared( IrpContext, ParentFcb );
         ReleaseParentFcb = TRUE;
     
-        //
-        //  Do an unsafe test to see if we need to create a file object.
-        //
-
-        if (ParentFcb->FileObject == NULL) {
-
-            CdCreateInternalStream( IrpContext, ParentFcb->Vcb, ParentFcb );
-        }
+        CdVerifyOrCreateDirStreamFile( IrpContext, ParentFcb);
 
         if (CdFidIsDirectory( Fcb->FileId)) {
 
@@ -1396,7 +1418,7 @@ Return Value:
         RtlCopyMemory( Buffer->FileName, ShortNameBuffer, Buffer->FileNameLength );
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         if (CleanupFileLookup) {
 
@@ -1413,7 +1435,7 @@ Return Value:
 
             CdReleaseFile( IrpContext, ParentFcb );
         }
-    } _SEH2_END;
+    }
 
     //
     //  Reduce the available bytes by the amount stored into this buffer.
@@ -1434,10 +1456,10 @@ Return Value:
 
 VOID
 CdQueryNetworkInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -1465,6 +1487,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  We only support creation, last modify and last write times on Cdfs.
     //
index 00ab96b..1354bc1 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -33,14 +33,16 @@ Abstract:
 #pragma alloc_text(PAGE, CdSetFileObject)
 #endif
 
-\f
+
+_When_(TypeOfOpen == UnopenedFileObject, _At_(Fcb, _In_opt_))
+_When_(TypeOfOpen != UnopenedFileObject, _At_(Fcb, _In_))
 VOID
 CdSetFileObject (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    IN TYPE_OF_OPEN TypeOfOpen,
-    IN PFCB Fcb OPTIONAL,
-    IN PCCB Ccb OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFILE_OBJECT FileObject,
+    _In_ TYPE_OF_OPEN TypeOfOpen,
+    PFCB Fcb,
+    _In_opt_ PCCB Ccb
     )
 
 /*++
@@ -70,12 +72,14 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  We only have values 0 to 7 available so make sure we didn't
     //  inadvertantly add a new type.
     //
 
-    ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 );
+    NT_ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 );
 
     //
     //  Setting a file object to type UnopenedFileObject means just
@@ -94,7 +98,7 @@ Return Value:
     //  Check that the 3 low-order bits of the Ccb are clear.
     //
 
-    ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK ));
+    NT_ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK ));
 
     //
     //  We will or the type of open into the low order bits of FsContext2
@@ -105,7 +109,8 @@ Return Value:
     FileObject->FsContext = Fcb;
     FileObject->FsContext2 = Ccb;
 
-    SetFlag( (*(PULONG_PTR)&FileObject->FsContext2), TypeOfOpen ); /* ReactOS Change: GCC "invalid lvalue in assignment" */
+#pragma warning( suppress: 4213 )
+    SetFlag( ((ULONG_PTR) FileObject->FsContext2), TypeOfOpen );
 
     //
     //  Set the Vpb field in the file object.
@@ -117,13 +122,16 @@ Return Value:
 }
 
 
-\f
+_When_(return == UnopenedFileObject, _At_(*Fcb, _Post_null_))
+_When_(return != UnopenedFileObject, _At_(Fcb, _Outptr_))
+_When_(return == UnopenedFileObject, _At_(*Ccb, _Post_null_))
+_When_(return != UnopenedFileObject, _At_(Ccb, _Outptr_))
 TYPE_OF_OPEN
 CdDecodeFileObject (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFILE_OBJECT FileObject,
-    OUT PFCB *Fcb,
-    OUT PCCB *Ccb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFILE_OBJECT FileObject,
+    PFCB *Fcb,
+    PCCB *Ccb
     )
 
 /*++
@@ -152,6 +160,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  If this is an unopened file object then return NULL for the
     //  Fcb/Ccb.  Don't trust any other values in the file object.
@@ -175,8 +185,9 @@ Return Value:
 
         *Fcb = FileObject->FsContext;
         *Ccb = FileObject->FsContext2;
-
-        ClearFlag( (*(PULONG_PTR)Ccb), TYPE_OF_OPEN_MASK ); /* ReactOS Change: GCC "invalid lvalue in assignment" */
+        
+#pragma warning( suppress: 4213 )
+        ClearFlag( (ULONG_PTR) *Ccb, TYPE_OF_OPEN_MASK );
     }
 
     //
@@ -189,8 +200,8 @@ Return Value:
 \f
 TYPE_OF_OPEN
 CdFastDecodeFileObject (
-    IN PFILE_OBJECT FileObject,
-    OUT PFCB *Fcb
+    _In_ PFILE_OBJECT FileObject,
+    _Out_ PFCB *Fcb
     )
 
 /*++
index cfa3e8b..8a113f0 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -33,108 +33,124 @@ BOOLEAN CdNoJoliet = FALSE;
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdUserFsctl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 VOID
-CdReMountOldVcb(
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB OldVcb,
-    IN PVCB NewVcb,
-    IN PDEVICE_OBJECT DeviceObjectWeTalkTo
+CdReMountOldVcb (
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB OldVcb,
+    _Inout_ PVCB NewVcb,
+    _In_ PDEVICE_OBJECT DeviceObjectWeTalkTo
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdMountVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdVerifyVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOplockRequest (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdLockVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdUnlockVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdDismountVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
-    
-NTSTATUS /* ReactOS Change: Function did not have a type??? */
+
+NTSTATUS
 CdIsVolumeDirty (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 NTSTATUS
 CdIsVolumeMounted (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 NTSTATUS
 CdIsPathnameValid (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdInvalidateVolumes (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
+NTSTATUS
+CdAllowExtendedDasdIo (
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    );
+
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdScanForDismountedVcb (
-    IN PIRP_CONTEXT IrpContext
+    _Inout_ PIRP_CONTEXT IrpContext
     );
 
+_Success_(return != FALSE)
 BOOLEAN
 CdFindPrimaryVd (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PCHAR RawIsoVd,
-    IN ULONG BlockFactor,
-    IN BOOLEAN ReturnOnError,
-    IN BOOLEAN VerifyVolume
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _Out_writes_bytes_(SECTOR_SIZE) PCHAR RawIsoVd,
+    _In_ ULONG BlockFactor,
+    _In_ BOOLEAN ReturnOnError,
+    _In_ BOOLEAN VerifyVolume
     );
 
-BOOLEAN
+_Success_(return != FALSE) BOOLEAN
 CdIsRemount (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    OUT PVCB *OldVcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PVCB *OldVcb
     );
 
 VOID
 CdFindActiveVolDescriptor (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN OUT PCHAR RawIsoVd,
-    IN BOOLEAN VerifyVolume
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Inout_updates_bytes_(ROUND_TO_PAGES( SECTOR_SIZE )) PCHAR RawIsoVd,
+    _In_ BOOLEAN VerifyVolume
     );
 
 #ifdef ALLOC_PRAGMA
@@ -149,6 +165,7 @@ CdFindActiveVolDescriptor (
 #pragma alloc_text(PAGE, CdLockVolume)
 #pragma alloc_text(PAGE, CdMountVolume)
 #pragma alloc_text(PAGE, CdOplockRequest)
+#pragma alloc_text(PAGE, CdAllowExtendedDasdIo)
 #pragma alloc_text(PAGE, CdScanForDismountedVcb)
 #pragma alloc_text(PAGE, CdUnlockVolume)
 #pragma alloc_text(PAGE, CdUserFsctl)
@@ -160,11 +177,13 @@ CdFindActiveVolDescriptor (
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
+_Requires_lock_held_(Vcb->VcbResource)
 NTSTATUS
 CdLockVolumeInternal (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_OBJECT FileObject OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_opt_ PFILE_OBJECT FileObject
     )
 
 /*++
@@ -267,9 +286,9 @@ Return Value:
 \f
 NTSTATUS
 CdUnlockVolumeInternal (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_OBJECT FileObject OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_opt_ PFILE_OBJECT FileObject
     )
 
 /*++
@@ -299,6 +318,8 @@ Return Value:
     NTSTATUS Status = STATUS_NOT_LOCKED;
     KIRQL SavedIrql;
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Note that we check the VPB_LOCKED flag here rather than the Vcb
     //  lock flag.  The Vpb flag is only set for an explicit lock request,  not
@@ -322,10 +343,12 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonFsControl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -349,12 +372,6 @@ Return Value:
     NTSTATUS Status;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
 
-    //
-    //  Get a pointer to the current Irp stack location
-    //
-
-    IrpSp = IoGetCurrentIrpStackLocation( Irp );
-
     PAGED_CODE();
 
     //
@@ -395,10 +412,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdUserFsctl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 /*++
 
@@ -476,6 +494,10 @@ Return Value:
         Status = CdInvalidateVolumes( IrpContext, Irp );
         break;
 
+    case FSCTL_ALLOW_EXTENDED_DASD_IO:
+
+        Status = CdAllowExtendedDasdIo( IrpContext, Irp );
+        break;
 
     //
     //  We don't support any of the known or unknown requests.
@@ -493,19 +515,24 @@ Return Value:
 
 
 VOID
-CdReMountOldVcb(
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB OldVcb,
-    IN PVCB NewVcb,
-    IN PDEVICE_OBJECT DeviceObjectWeTalkTo
+CdReMountOldVcb (
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB OldVcb,
+    _Inout_ PVCB NewVcb,
+    _In_ PDEVICE_OBJECT DeviceObjectWeTalkTo
     )
 {
     KIRQL SavedIrql;
+    ULONG Index;
+    PUCHAR Buffer;
+
+    UNREFERENCED_PARAMETER( IrpContext );
     
     ObDereferenceObject( OldVcb->TargetDeviceObject );
 
     IoAcquireVpbSpinLock( &SavedIrql );
 
+#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
     NewVcb->Vpb->RealDevice->Vpb = OldVcb->Vpb;
     
     OldVcb->Vpb->RealDevice = NewVcb->Vpb->RealDevice;
@@ -516,6 +543,20 @@ CdReMountOldVcb(
 
     ClearFlag( OldVcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE);
 
+    Buffer = OldVcb->SectorCacheBuffer = NewVcb->SectorCacheBuffer;
+    NewVcb->SectorCacheBuffer = NULL;
+
+    if (NULL != Buffer) {
+        
+        for (Index = 0; Index < CD_SEC_CACHE_CHUNKS; Index++) {
+        
+            OldVcb->SecCacheChunks[ Index].Buffer = Buffer;
+            OldVcb->SecCacheChunks[ Index].BaseLbn = (ULONG)-1;
+        
+            Buffer += CD_SEC_CHUNK_BLOCKS * SECTOR_SIZE;
+        }
+    }
+
     IoReleaseVpbSpinLock( SavedIrql );
 }
 
@@ -524,10 +565,11 @@ CdReMountOldVcb(
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdMountVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -571,6 +613,7 @@ Return Value:
     PVOLUME_DEVICE_OBJECT VolDo = NULL;
     PVCB Vcb = NULL;
     PVCB OldVcb;
+    UCHAR StackSize;
     
     BOOLEAN FoundPvd = FALSE;
     BOOLEAN SetDoVerifyOnFail;
@@ -590,14 +633,15 @@ Return Value:
 
     PCHAR RawIsoVd = NULL;
 
-    PCDROM_TOC CdromToc = NULL;
+    PCDROM_TOC_LARGE CdromToc = NULL;
     ULONG TocLength = 0;
     ULONG TocTrackCount = 0;
     ULONG TocDiskFlags = 0;
     ULONG MediaChangeCount = 0;
 
-#ifdef __REACTOS__
-    DEVICE_TYPE FilesystemDeviceType;
+#ifdef CDFS_TELEMETRY_DATA
+    GUID VolumeGuid;
+    GUID VolumeCorrelationId = { 0 };
 #endif
 
     PAGED_CODE();
@@ -607,17 +651,17 @@ Return Value:
     //  always be waitable.
     //
 
-#ifdef __REACTOS__
-    if (IrpSp->DeviceObject == CdData.HddFileSystemDeviceObject) {
-        FilesystemDeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
-    } else {
-#endif
-    ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM );
-#ifdef __REACTOS__
-        FilesystemDeviceType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
-    }
+    NT_ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM );
+    NT_ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
+
+#ifdef CDFS_TELEMETRY_DATA
+    //
+    //  We don't want a bogus VolumeGuid to show up in our telemetry
+    //
+
+    RtlZeroMemory( &VolumeGuid, sizeof(GUID) );
+
 #endif
-    ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
 
     //
     //  Update the real device in the IrpContext from the Vpb.  There was no available
@@ -638,16 +682,22 @@ Return Value:
         return STATUS_UNRECOGNIZED_VOLUME;
     }
 
+    //
+    //  If we've shutdown disallow further mounts.
+    //
+
+    if (FlagOn( CdData.Flags, CD_FLAGS_SHUTDOWN )) {
+
+        CdCompleteRequest( IrpContext, Irp, STATUS_SYSTEM_SHUTDOWN );
+        return STATUS_SYSTEM_SHUTDOWN;
+    }
+
     //
     //  Do a CheckVerify here to lift the MediaChange ticker from the driver
     //
 
     Status = CdPerformDevIoCtrl( IrpContext,
-#ifndef __REACTOS__
                                  IOCTL_CDROM_CHECK_VERIFY,
-#else
-                                 (FilesystemDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ? IOCTL_DISK_CHECK_VERIFY : IOCTL_CDROM_CHECK_VERIFY),
-#endif
                                  DeviceObjectWeTalkTo,
                                  &MediaChangeCount,
                                  sizeof(ULONG),
@@ -676,11 +726,7 @@ Return Value:
     //
 
     Status = CdPerformDevIoCtrl( IrpContext,
-#ifndef __REACTOS__
                                  IOCTL_CDROM_GET_DRIVE_GEOMETRY,
-#else
-                                 (FilesystemDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ? IOCTL_DISK_GET_DRIVE_GEOMETRY : IOCTL_CDROM_GET_DRIVE_GEOMETRY),
-#endif
                                  DeviceObjectWeTalkTo,
                                  &DiskGeometry,
                                  sizeof( DISK_GEOMETRY ),
@@ -723,17 +769,17 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Allocate a buffer to query the TOC.
         //
 
         CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool,
-                                             sizeof( CDROM_TOC ),
+                                             sizeof( CDROM_TOC_LARGE ),
                                              TAG_CDROM_TOC );
 
-        RtlZeroMemory( CdromToc, sizeof( CDROM_TOC ));
+        RtlZeroMemory( CdromToc, sizeof( CDROM_TOC_LARGE ));
 
         //
         //  Do a quick check to see if there any Vcb's which can be removed.
@@ -748,11 +794,7 @@ Return Value:
         Status = IoCreateDevice( CdData.DriverObject,
                                  sizeof( VOLUME_DEVICE_OBJECT ) - sizeof( DEVICE_OBJECT ),
                                  NULL,
-#ifndef __REACTOS__
                                  FILE_DEVICE_CD_ROM_FILE_SYSTEM,
-#else
-                                 FilesystemDeviceType,
-#endif
                                  0,
                                  FALSE,
                                  (PDEVICE_OBJECT *) &VolDo );
@@ -775,6 +817,7 @@ Return Value:
         //
 
         ((PDEVICE_OBJECT) VolDo)->StackSize = (CCHAR) (DeviceObjectWeTalkTo->StackSize + 1);
+        StackSize = ((PDEVICE_OBJECT) VolDo)->StackSize;
 
         ClearFlag( VolDo->DeviceObject.Flags, DO_DEVICE_INITIALIZING );
 
@@ -805,21 +848,7 @@ Return Value:
 
         if (Status != STATUS_SUCCESS)  { 
 
-#ifdef __REACTOS__
-
-            //
-            // Don't bail out if that was a disk based ISO image, it is legit
-            //
-
-            if (FilesystemDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) {
-                CdFreePool( &CdromToc );
-                Status = STATUS_SUCCESS;
-            } else {
-#endif
             try_leave( Status ); 
-#ifdef __REACTOS__
-            }
-#endif
         }
 
         //
@@ -855,6 +884,39 @@ Return Value:
         Vpb = NULL;
         CdromToc = NULL;
 
+#ifdef CDFS_TELEMETRY_DATA
+
+        //
+        //  Initialize the volume guid.
+        //
+
+        if (NT_SUCCESS( IoVolumeDeviceToGuid( Vcb->TargetDeviceObject, &VolumeGuid ))) {
+
+            //
+            //  We got a GUID, set it in the Telemetry structure
+            //
+
+            RtlCopyMemory( &CdTelemetryData.VolumeGuid, &VolumeGuid, sizeof(GUID) );
+        }
+
+        //
+        // Initialize the correlation ID.
+        //
+
+        if (NT_SUCCESS( FsRtlVolumeDeviceToCorrelationId( Vcb->TargetDeviceObject, &VolumeCorrelationId ) )) {
+
+            //
+            // Stash a copy away in the VCB.
+            //
+
+            RtlCopyMemory( &Vcb->VolumeCorrelationId, &VolumeCorrelationId, sizeof( GUID ) );
+        }
+
+#endif // CDFS_TELEMETRY_DATA
+
+        // Lock object is acquired and released using internal state
+        _Analysis_suppress_lock_checking_(Vcb->VcbResource);
+        
         //
         //  Store the Vcb in the IrpContext as we didn't have one before.
         //
@@ -906,7 +968,7 @@ Return Value:
                 //  Since we're always last in the mount order,  we won't be preventing
                 //  any other FS from trying to mount the data track.  However if the 
                 //  data track was at the start of the disc,  then we abort,  to avoid
-                //  having to filter it from our synthesized directory listing later.  We
+                //  having to filter it from our synthesised directory listing later.  We
                 //  already filtered off any data track at the end.
                 //
 
@@ -951,6 +1013,52 @@ Return Value:
                                        FALSE);
         }
 
+        //
+        //  Allocate a block cache to speed directory operations. We can't
+        //  use the cache if there is any chance the volume has link blocks
+        //  in the data area (i.e. was packet written and then finalized to
+        //  Joliet/9660). So we simply only allow the cache to operate on 
+        //  media with a single track - since we're really targetting pressed
+        //  installation media here. We can't be more precise, since D/CD-ROM
+        //  drives don't support READ_TRACK_INFO, which is the only way for
+        //  certain to know whether or not a track was packet written.
+        //
+
+        if (!FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK) &&
+            ((Vcb->CdromToc->LastTrack - Vcb->CdromToc->FirstTrack) == 0)) {
+
+            ULONG Index;
+            PUCHAR Buffer;
+
+            Buffer = 
+            Vcb->SectorCacheBuffer = FsRtlAllocatePool( CdPagedPool, 
+                                                        CD_SEC_CACHE_CHUNKS *
+                                                        CD_SEC_CHUNK_BLOCKS * 
+                                                        SECTOR_SIZE);
+
+            for (Index = 0; Index < (ULONG)CD_SEC_CACHE_CHUNKS; Index++) {
+
+                Vcb->SecCacheChunks[ Index].Buffer = Buffer;
+                Vcb->SecCacheChunks[ Index].BaseLbn = (ULONG)-1;
+
+                Buffer += CD_SEC_CHUNK_BLOCKS * SECTOR_SIZE;
+            }
+
+            Vcb->SectorCacheIrp = IoAllocateIrp( StackSize, FALSE);
+
+            if (Vcb->SectorCacheIrp == NULL) {
+
+                try_leave( Status = STATUS_INSUFFICIENT_RESOURCES );
+            }
+            
+            IoInitializeIrp( Vcb->SectorCacheIrp, 
+                             IoSizeOfIrp( StackSize), 
+                             (CCHAR)StackSize);
+            
+            KeInitializeEvent( &Vcb->SectorCacheEvent, SynchronizationEvent, FALSE);
+            ExInitializeResourceLite( &Vcb->SectorCacheResource);
+        }
+
         //
         //  Check if this is a remount operation.  If so then clean up
         //  the data structures passed in and created here.
@@ -958,9 +1066,7 @@ Return Value:
 
         if (CdIsRemount( IrpContext, Vcb, &OldVcb )) {
 
-            //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */
-
-            ASSERT( NULL != OldVcb->SwapVpb );
+            NT_ASSERT( NULL != OldVcb->SwapVpb );
 
             //
             //  Link the old Vcb to point to the new device object that we
@@ -1047,7 +1153,7 @@ Return Value:
         //
 
         Vcb->VcbReference -= CDFS_RESIDUAL_REFERENCE;
-        ASSERT( Vcb->VcbReference == CDFS_RESIDUAL_REFERENCE );
+        NT_ASSERT( Vcb->VcbReference == CDFS_RESIDUAL_REFERENCE );
 
         ObDereferenceObject( Vcb->TargetDeviceObject );
 
@@ -1058,7 +1164,7 @@ Return Value:
 
         Status = STATUS_SUCCESS;
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Free the TOC buffer if not in the Vcb.
@@ -1082,7 +1188,7 @@ Return Value:
         //  If we are not mounting the device,  then set the verify bit again.
         //
         
-        if ((_SEH2_AbnormalTermination() || (Status != STATUS_SUCCESS)) && 
+        if ((AbnormalTermination() || (Status != STATUS_SUCCESS)) && 
             SetDoVerifyOnFail)  {
 
             CdMarkRealDevForVerify( IrpContext->RealDevice);
@@ -1119,7 +1225,7 @@ Return Value:
         //
 
         CdReleaseCdData( IrpContext );
-    } _SEH2_END;
+    }
 
     //
     //  Now send mount notification.
@@ -1131,6 +1237,16 @@ Return Value:
         ObDereferenceObject( FileObjectToNotify );
     }
 
+#ifdef CDFS_TELEMETRY_DATA
+
+    //
+    // Send Telemetry
+    //
+
+    CdTelemetryMountSafe( &VolumeCorrelationId, STATUS_SUCCESS, Vcb );
+
+#endif
+
     //
     //  Complete the request if no exception.
     //
@@ -1144,10 +1260,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdVerifyVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -1174,7 +1291,7 @@ Return Value:
 
     PCHAR RawIsoVd = NULL;
 
-    PCDROM_TOC CdromToc = NULL;
+    PCDROM_TOC_LARGE CdromToc = NULL;
     ULONG TocLength = 0;
     ULONG TocTrackCount = 0;
     ULONG TocDiskFlags = 0;
@@ -1196,7 +1313,7 @@ Return Value:
 
     ULONG Index;
 
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     PAGED_CODE();
 
@@ -1204,8 +1321,8 @@ Return Value:
     //  We check that we are talking to a Cdrom device.
     //
 
-    ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM );
-    ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
+    NT_ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM );
+    NT_ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ));
 
     //
     //  Update the real device in the IrpContext from the Vpb.  There was no available
@@ -1221,11 +1338,21 @@ Return Value:
 
     CdAcquireCdData( IrpContext );
 
-    _SEH2_TRY {
+    try {
 
         CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
         ReleaseVcb = TRUE;
 
+        //
+        //  Check to see if the volume is eligible for verification.
+        //
+
+        if ((Vcb->VcbCondition == VcbInvalid) ||
+            (Vcb->VcbCondition == VcbDismountInProgress)) {
+
+            try_return( Status = STATUS_WRONG_VOLUME );
+        }
+
         //
         //  Verify that there is a disk here.
         //
@@ -1276,10 +1403,10 @@ Return Value:
             //
 
             CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool,
-                                                 sizeof( CDROM_TOC ),
+                                                 sizeof( CDROM_TOC_LARGE ),
                                                  TAG_CDROM_TOC );
 
-            RtlZeroMemory( CdromToc, sizeof( CDROM_TOC ));
+            RtlZeroMemory( CdromToc, sizeof( CDROM_TOC_LARGE ));
 
             //
             //  Let's query for the Toc now and handle any error we get from this operation.
@@ -1414,8 +1541,8 @@ Return Value:
                         //  Compute the length of the volume name
                         //
 
-                        AnsiLabel.Buffer = (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ); /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
-                        AnsiLabel.MaximumLength = AnsiLabel.Length = VOLUME_ID_LENGTH;
+                        AnsiLabel.Buffer = (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState );
+                        AnsiLabel.MaximumLength = AnsiLabel.Length = (ULONG)VOLUME_ID_LENGTH;
 
                         UnicodeLabel.MaximumLength = VOLUME_ID_LENGTH * sizeof( WCHAR );
                         UnicodeLabel.Buffer = VolumeLabel;
@@ -1441,7 +1568,7 @@ Return Value:
                     } else {
 
                         CdConvertBigToLittleEndian( IrpContext,
-                                                    (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
+                                                    (PCHAR) CdRvdVolId( RawIsoVd, Vcb->VcbState ),
                                                     VOLUME_ID_LENGTH,
                                                     (PCHAR) VolumeLabel );
 
@@ -1515,12 +1642,20 @@ Return Value:
 
         CdUpdateMediaChangeCount( Vcb, MediaChangeCount);
 
+        //
+        //  If the volume was already unmounted, nothing more to do.
+        //
+        
+        if (Vcb->VcbCondition == VcbNotMounted) {
+        
+            Status = STATUS_WRONG_VOLUME;
+
         //
         //  If we got the wrong volume then free any remaining XA sector in
         //  the current Vcb.  Also mark the Vcb as not mounted.
         //
 
-        if (Status == STATUS_WRONG_VOLUME) {
+        } else if ((Vcb->VcbCondition == VcbMounted) && (Status == STATUS_WRONG_VOLUME)) {
 
             CdUpdateVcbCondition( Vcb, VcbNotMounted);
 
@@ -1531,6 +1666,8 @@ Return Value:
                 Vcb->XADiskOffset = 0;
             }
 
+            CdFreeDirCache( IrpContext);
+
             //
             //  Now, if there are no user handles to the volume, try to spark
             //  teardown by purging the volume.
@@ -1545,7 +1682,8 @@ Return Value:
             }
         }
 
-    } _SEH2_FINALLY {
+    } 
+    finally {
 
         //
         //  Free the TOC buffer if allocated.
@@ -1562,12 +1700,15 @@ Return Value:
         }
 
         if (ReleaseVcb) {
-            
+
             CdReleaseVcb( IrpContext, Vcb );
         }
+        else {
+            _Analysis_assume_lock_not_held_(Vcb->VcbResource);
+        }
 
         CdReleaseCdData( IrpContext );
-    } _SEH2_END;
+    }
 
     //
     //  Now send mount notification.
@@ -1592,10 +1733,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdOplockRequest (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -1616,7 +1758,7 @@ Return Value:
 --*/
 
 {
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     PFCB Fcb;
     PCCB Ccb;
 
@@ -1664,7 +1806,11 @@ Return Value:
 
             if (Fcb->FileLock != NULL) {
 
+#if (NTDDI_VERSION >= NTDDI_WIN7)
+                OplockCount = (ULONG) FsRtlAreThereCurrentOrInProgressFileLocks( Fcb->FileLock );
+#else
                 OplockCount = (ULONG) FsRtlAreThereCurrentFileLocks( Fcb->FileLock );
+#endif
             }
 
         } else {
@@ -1692,7 +1838,7 @@ Return Value:
     //  Use a try finally to free the Fcb.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Fcb.
@@ -1704,7 +1850,7 @@ Return Value:
         //  Call the FsRtl routine to grant/acknowledge oplock.
         //
 
-        Status = FsRtlOplockFsctrl( &Fcb->Oplock,
+        Status = FsRtlOplockFsctrl( CdGetFcbOplock(Fcb),
                                     Irp,
                                     OplockCount );
 
@@ -1722,14 +1868,14 @@ Return Value:
 
         Irp = NULL;
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release all of our resources
         //
 
         CdReleaseFcb( IrpContext, Fcb );
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request if there was no exception.
@@ -1744,10 +1890,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdLockVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -1768,7 +1915,7 @@ Return Value:
 --*/
 
 {
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
 
@@ -1804,7 +1951,7 @@ Return Value:
     Vcb = Fcb->Vcb;
     CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Vcb.
@@ -1814,7 +1961,7 @@ Return Value:
 
         Status = CdLockVolumeInternal( IrpContext, Vcb, IrpSp->FileObject );
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the Vcb.
@@ -1822,11 +1969,11 @@ Return Value:
 
         CdReleaseVcb( IrpContext, Vcb );
         
-        if (_SEH2_AbnormalTermination() || !NT_SUCCESS( Status )) {
+        if (AbnormalTermination() || !NT_SUCCESS( Status )) {
 
             FsRtlNotifyVolumeEvent( IrpSp->FileObject, FSRTL_VOLUME_LOCK_FAILED );
         }
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request if there haven't been any exceptions.
@@ -1841,10 +1988,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdUnlockVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -1908,7 +2056,7 @@ Return Value:
     CdReleaseVcb( IrpContext, Vcb );
 
     //
-    //  Send notification that the volume is available.
+    //  Send notification that the volume is avaliable.
     //
 
     if (NT_SUCCESS( Status )) {
@@ -1930,10 +2078,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdDismountVolume (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -1974,6 +2123,12 @@ Return Value:
 
     Vcb = Fcb->Vcb;
 
+    //
+    //  Send dismount notification.
+    //
+
+    FsRtlNotifyVolumeEvent( IrpSp->FileObject, FSRTL_VOLUME_DISMOUNT );
+
     //
     //  Make this request waitable.
     //
@@ -2011,11 +2166,14 @@ Return Value:
         
         if (Vcb->VcbCondition != VcbDismountInProgress) {
         
-            CdUpdateVcbCondition( Vcb, VcbInvalid);
+            CdUpdateVcbCondition( Vcb, VcbInvalid );
         }
+
+        SetFlag( Vcb->VcbState, VCB_STATE_DISMOUNTED );
         
         CdUnlockVcb( IrpContext, Vcb );
 
+        
         //
         //  Set flag to tell the close path that we want to force dismount
         //  the volume when this handle is closed.
@@ -2031,7 +2189,13 @@ Return Value:
     //
 
     CdReleaseVcb( IrpContext, Vcb );
-    CdReleaseCdData( IrpContext);
+    CdReleaseCdData( IrpContext );
+
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+
+    FsRtlDismountComplete( Vcb->TargetDeviceObject, Status );
+
+#endif
 
     //
     //  Complete the request if there haven't been any exceptions.
@@ -2045,10 +2209,11 @@ Return Value:
 //
 //  Local support routine
 //
-NTSTATUS /* ReactOS Change: Function did not have a type??? */
+
+NTSTATUS
 CdIsVolumeDirty (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -2075,7 +2240,9 @@ Return Value:
     PCCB Ccb;
 
     PULONG VolumeState;
-    
+
+    PAGED_CODE();
+
     //
     //  Get the current stack location and extract the output
     //  buffer information.
@@ -2146,8 +2313,8 @@ Return Value:
 
 NTSTATUS
 CdIsVolumeMounted (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -2207,8 +2374,8 @@ Return Value:
 
 NTSTATUS
 CdIsPathnameValid (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -2240,10 +2407,11 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdInvalidateVolumes (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -2286,12 +2454,7 @@ Return Value:
     //  We only allow the invalidate call to come in on our file system devices.
     //
     
-#ifndef __REACTOS__
     if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject)  {
-#else
-    if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject &&
-        IrpSp->DeviceObject != CdData.HddFileSystemDeviceObject)  {
-#endif
 
         CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
 
@@ -2314,7 +2477,8 @@ Return Value:
     //  Try to get a pointer to the device object from the handle passed in.
     //
 
-#if defined(_WIN64)
+#if defined(_WIN64) && BUILD_WOW64_ENABLED
+
     if (IoIs32bitProcess( Irp )) {
         
         if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( UINT32 )) {
@@ -2325,23 +2489,25 @@ Return Value:
 
         Handle = (HANDLE) LongToHandle( *((PUINT32) Irp->AssociatedIrp.SystemBuffer) );
     
-    } else {
+    } else
+
 #endif
+
+    {
         if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( HANDLE )) {
 
             CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
             return STATUS_INVALID_PARAMETER;
         }
+
         Handle = *((PHANDLE) Irp->AssociatedIrp.SystemBuffer);
-#if defined(_WIN64)
     }
-#endif
 
     Status = ObReferenceObjectByHandle( Handle,
                                         0,
                                         *IoFileObjectType,
                                         KernelMode,
-                                        (PVOID*)&FileToMarkBad, /* ReactOS Change: GCC "passing argument 5 of 'ObReferenceObjectByHandle' from incompatible pointer type" */
+                                        &FileToMarkBad,
                                         NULL );
 
     if (!NT_SUCCESS(Status)) {
@@ -2412,21 +2578,26 @@ Return Value:
             
             IoAcquireVpbSpinLock( &SavedIrql );
 
+#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
             if (DeviceToMarkBad->Vpb == Vcb->Vpb)  {
             
                 PVPB NewVpb = Vcb->SwapVpb;
 
-                ASSERT( FlagOn( Vcb->Vpb->Flags, VPB_MOUNTED));
-                ASSERT( NULL != NewVpb);
+                NT_ASSERT( FlagOn( Vcb->Vpb->Flags, VPB_MOUNTED));
+                NT_ASSERT( NULL != NewVpb);
 
                 RtlZeroMemory( NewVpb, sizeof( VPB ) );
 
                 NewVpb->Type = IO_TYPE_VPB;
                 NewVpb->Size = sizeof( VPB );
                 NewVpb->RealDevice = DeviceToMarkBad;
-                NewVpb->Flags = FlagOn( DeviceToMarkBad->Vpb->Flags, VPB_REMOVE_PENDING );
 
+#pragma prefast(push)
+#pragma prefast(disable: 28175, "this is a filesystem driver, touching the vpb is allowed")
+                NewVpb->Flags = FlagOn( DeviceToMarkBad->Vpb->Flags, VPB_REMOVE_PENDING );
                 DeviceToMarkBad->Vpb = NewVpb;
+#pragma prefast(pop)
+
                 Vcb->SwapVpb = NULL;
             }
 
@@ -2445,6 +2616,13 @@ Return Value:
 
             UnlockVcb = CdCheckForDismount( IrpContext, Vcb, FALSE );
 
+            //
+            //  prefast: if UnlockVcb is false, then the VCB was already deleted, so we better not touch the Vcb.
+            //           tell Prefast something nice so it stops complaining about us leaking it.
+            // 
+            
+            __analysis_assert( UnlockVcb == TRUE );            
+
             if (UnlockVcb)  {
 
                 CdReleaseVcb( IrpContext, Vcb);
@@ -2467,9 +2645,67 @@ Return Value:
 //  Local support routine
 //
 
+NTSTATUS
+CdAllowExtendedDasdIo (
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    )
+
+/*++
+
+Routine Description:
+
+    This routine marks the CCB to indicate that the handle
+    may be used to read past the end of the volume file.  The
+    handle must be a dasd handle.
+
+Arguments:
+
+    Irp - Supplies the Irp to process
+
+Return Value:
+
+    NTSTATUS - The return status for the operation
+
+--*/
+
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
+
+    PFCB Fcb;
+    PCCB Ccb;
+
+    PAGED_CODE();
+
+    //
+    //  Decode the file object, the only type of opens we accept are
+    //  user volume opens.
+    //
+
+    if (CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ) != UserVolumeOpen ) {
+
+        Status = STATUS_INVALID_PARAMETER;
+    }
+    else {
+
+        SetFlag( Ccb->Flags, CCB_FLAG_ALLOW_EXTENDED_DASD_IO );
+        Status = STATUS_SUCCESS;
+    }
+
+    CdCompleteRequest( IrpContext, Irp, Status );
+    return Status;
+}
+
+
+//
+//  Local support routine
+//
+
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdScanForDismountedVcb (
-    IN PIRP_CONTEXT IrpContext
+    _Inout_ PIRP_CONTEXT IrpContext
     )
 
 /*++
@@ -2530,15 +2766,15 @@ Return Value:
 //
 //  Local support routine
 //
-
+_Success_(return != FALSE)
 BOOLEAN
 CdFindPrimaryVd (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PCHAR RawIsoVd,
-    IN ULONG BlockFactor,
-    IN BOOLEAN ReturnOnError,
-    IN BOOLEAN VerifyVolume
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _Out_writes_bytes_(SECTOR_SIZE) PCHAR RawIsoVd,
+    _In_ ULONG BlockFactor,
+    _In_ BOOLEAN ReturnOnError,
+    _In_ BOOLEAN VerifyVolume
     )
 
 /*++
@@ -2581,7 +2817,7 @@ Return Value:
     ULONG BaseSector;
     ULONG SectorOffset;
 
-    PCDROM_TOC CdromToc;
+    PCDROM_TOC_LARGE CdromToc;
 
     ULONG VolumeFlags;
 
@@ -2598,7 +2834,7 @@ Return Value:
     //  and still have the disk work.  As this form of error worked in NT 4.0, and
     //  since these disks really do exist, I don't want to change them.
     //
-    //  If we wished to support all such media (we don't), it would be necessary
+    //  If we wished to support all such media (we don't), it would be neccesary
     //  to clear this flag on finding ISO or HSG descriptors below.
     //
 
@@ -2635,17 +2871,17 @@ Return Value:
             //  Check for whether this device supports XA and multi-session.
             //
 
-            _SEH2_TRY {
+            try {
 
                 //
                 //  Allocate a buffer for the last session information.
                 //
 
                 CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool,
-                                                     sizeof( CDROM_TOC ),
+                                                     sizeof( CDROM_TOC_LARGE ),
                                                      TAG_CDROM_TOC );
 
-                RtlZeroMemory( CdromToc, sizeof( CDROM_TOC ));
+                RtlZeroMemory( CdromToc, sizeof( CDROM_TOC_LARGE ));
 
                 //
                 //  Query the last session information from the driver.
@@ -2655,7 +2891,7 @@ Return Value:
                                              IOCTL_CDROM_GET_LAST_SESSION,
                                              Vcb->TargetDeviceObject,
                                              CdromToc,
-                                             sizeof( CDROM_TOC ),
+                                             sizeof( CDROM_TOC_LARGE ),
                                              FALSE,
                                              TRUE,
                                              NULL );
@@ -2687,8 +2923,8 @@ Return Value:
                     //  The track address is BigEndian, we need to flip the bytes.
                     //
 
-                    Source = (PCHAR) &CdromToc->TrackData[0].Address[3];/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
-                    Dest = (PCHAR) &BaseSector; /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
+                    Source = (PCHAR) &CdromToc->TrackData[0].Address[3];
+                    Dest = (PCHAR) &BaseSector;
 
                     do {
 
@@ -2713,10 +2949,10 @@ Return Value:
                     ThisPass += 1;
                 }
 
-            } _SEH2_FINALLY {
+            } finally {
 
                 if (CdromToc != NULL) { CdFreePool( &CdromToc ); }
-            } _SEH2_END;
+            }
         }
 
         //
@@ -2844,11 +3080,11 @@ Return Value:
 //  Local support routine
 //
 
-BOOLEAN
+_Success_(return != FALSE) BOOLEAN
 CdIsRemount (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    OUT PVCB *OldVcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PVCB *OldVcb
     )
 /*++
 
@@ -2904,6 +3140,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Check whether we are looking for a device only Mvcb.
     //
@@ -2959,17 +3197,21 @@ Return Value:
 
             //
             //  The current disk is not a raw disk.  Go ahead and compare
-            //  serial numbers and volume label.
+            //  serial numbers, volume label and TOC.
             //
 
-            } else if ((OldVpb->SerialNumber == Vpb->SerialNumber) &&
-                       (Vpb->VolumeLabelLength == OldVpb->VolumeLabelLength) &&
-                       (RtlEqualMemory( OldVpb->VolumeLabel,
+            } 
+            else if ((OldVpb->SerialNumber == Vpb->SerialNumber) &&
+                     (Vcb->TocLength == (*OldVcb)->TocLength) &&
+                     ((Vcb->TocLength == 0) || RtlEqualMemory( Vcb->CdromToc,
+                                                               (*OldVcb)->CdromToc,
+                                                               Vcb->TocLength )) &&
+                     (Vpb->VolumeLabelLength == OldVpb->VolumeLabelLength) &&
+                     (RtlEqualMemory( OldVpb->VolumeLabel,
                                         Vpb->VolumeLabel,
                                         Vpb->VolumeLabelLength ))) {
-
                 //
-                //  Remember the old mvcb.  Then set the return value to
+                //  Remember the old Vcb.  Then set the return value to
                 //  TRUE and break.
                 //
 
@@ -2989,10 +3231,10 @@ Return Value:
 
 VOID
 CdFindActiveVolDescriptor (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN OUT PCHAR RawIsoVd,
-    IN BOOLEAN VerifyVolume
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Inout_updates_bytes_(ROUND_TO_PAGES( SECTOR_SIZE )) PCHAR RawIsoVd,
+    _In_ BOOLEAN VerifyVolume
     )
 
 /*++
@@ -3145,7 +3387,7 @@ Return Value:
     //  Make sure the CD label will fit in the Vpb.
     //
 
-    ASSERT( VOLUME_ID_LENGTH * sizeof( WCHAR ) <= MAXIMUM_VOLUME_LABEL_LENGTH );
+    NT_ASSERT( VOLUME_ID_LENGTH * sizeof( WCHAR ) <= MAXIMUM_VOLUME_LABEL_LENGTH );
 
     //
     //  If this is not a Unicode label we must convert it to unicode.
@@ -3163,7 +3405,7 @@ Return Value:
         if (NT_SUCCESS( RtlOemToUnicodeN( &Vcb->Vpb->VolumeLabel[0],
                                           MAXIMUM_VOLUME_LABEL_LENGTH,
                                           &Length,
-                                          (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
+                                          (PCH)CdRvdVolId( RawIsoVd, Vcb->VcbState ),
                                           VOLUME_ID_LENGTH ))) {
 
             Vcb->Vpb->VolumeLabelLength = (USHORT) Length;
@@ -3176,7 +3418,7 @@ Return Value:
     } else {
 
         CdConvertBigToLittleEndian( IrpContext,
-                                    (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */
+                                    (PCHAR) CdRvdVolId( RawIsoVd, Vcb->VcbState ),
                                     VOLUME_ID_LENGTH,
                                     (PCHAR) Vcb->Vpb->VolumeLabel );
 
index da685e2..b38548d 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -25,7 +25,7 @@ Abstract:
 \f
 VOID
 CdFspDispatch (
-    IN PIRP_CONTEXT IrpContext
+    _In_ PVOID Context
     )
 
 /*++
@@ -48,7 +48,8 @@ Return Value:
 --*/
 
 {
-    THREAD_CONTEXT ThreadContext;
+    THREAD_CONTEXT ThreadContext = {0};
+    PIRP_CONTEXT IrpContext = Context;
     NTSTATUS Status;
 
     PIRP Irp = IrpContext->Irp;
@@ -94,7 +95,7 @@ Return Value:
 
         while (TRUE) {
 
-            _SEH2_TRY {
+            try {
 
                 //
                 //  Reinitialize for the next try at completing this
@@ -124,7 +125,7 @@ Return Value:
 
                 case IRP_MJ_CLOSE :
 
-                    ASSERT( FALSE );
+                    NT_ASSERT( FALSE );
                     break;
 
                 case IRP_MJ_READ :
@@ -174,7 +175,7 @@ Return Value:
 
                 case IRP_MJ_PNP :
 
-                    ASSERT( FALSE );
+                    NT_ASSERT( FALSE );
                     CdCommonPnp( IrpContext, Irp );
                     break;
 
@@ -184,10 +185,10 @@ Return Value:
                     CdCompleteRequest( IrpContext, Irp, Status );
                 }
 
-            } _SEH2_EXCEPT( CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
+            } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) {
 
-                Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
-            } _SEH2_END;
+                Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
+            }
 
             //
             //  Break out of the loop if we didn't get CANT_WAIT.
@@ -233,6 +234,12 @@ Return Value:
                 VolDo->OverflowQueueCount -= 1;
 
                 Entry = RemoveHeadList( &VolDo->OverflowQueue );
+
+            } else {
+
+                VolDo->PostedRequestCount -= 1;            
+
+                Entry = NULL;
             }
 
             KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );
@@ -242,7 +249,10 @@ Return Value:
             //  the Ex Worker thread.
             //
 
-            if (Entry == NULL) { break; }
+            if (Entry == NULL) { 
+
+                break; 
+            }
 
             //
             //  Extract the IrpContext , Irp, set wait to TRUE, and loop.
@@ -254,6 +264,7 @@ Return Value:
 
             Irp = IrpContext->Irp;
             IrpSp = IoGetCurrentIrpStackLocation( Irp );
+            __analysis_assert( IrpSp != 0 );
 
             continue;
         }
@@ -261,15 +272,6 @@ Return Value:
         break;
     }
 
-    //
-    //  Decrement the PostedRequestCount if there was a volume device object.
-    //
-
-    if (VolDo) {
-
-        InterlockedDecrement( &VolDo->PostedRequestCount );
-    }
-
     return;
 }
 
index 961c3be..edf0d07 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -33,8 +33,8 @@ Abstract:
 \f
 NTSTATUS
 CdCommonLockControl (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -86,10 +86,10 @@ Return Value:
     //  This call might post the irp for us.
     //
 
-    Status = FsRtlCheckOplock( &Fcb->Oplock,
+    Status = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
                                Irp,
                                IrpContext,
-                               (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
+                               CdOplockComplete,
                                NULL );
 
     //
@@ -138,17 +138,16 @@ Return Value:
 
 \f
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastLock (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN PLARGE_INTEGER Length,
-    PEPROCESS ProcessId,
-    ULONG Key,
-    BOOLEAN FailImmediately,
-    BOOLEAN ExclusiveLock,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PLARGE_INTEGER FileOffset,
+    _In_ PLARGE_INTEGER Length,
+    _In_ PEPROCESS ProcessId,
+    _In_ ULONG Key,
+    _In_ BOOLEAN FailImmediately,
+    _In_ BOOLEAN ExclusiveLock,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -192,6 +191,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+
     ASSERT_FILE_OBJECT( FileObject );
 
     IoStatus->Information = 0;
@@ -224,13 +225,13 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We check whether we can proceed based on the state of the file oplocks.
         //
 
-        if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
+        if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
 
             try_return( NOTHING );
         }
@@ -247,18 +248,19 @@ Return Value:
         //
         //  Now call the FsRtl routine to perform the lock request.
         //
-        /* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */
+
+#pragma prefast(suppress: 28159, "prefast thinks this is an obsolete routine, but it is ok for CDFS to use it")
         if ((Results = FsRtlFastLock( Fcb->FileLock,
-                                     FileObject,
-                                     FileOffset,
-                                     Length,
-                                     ProcessId,
-                                     Key,
-                                     FailImmediately,
-                                     ExclusiveLock,
-                                     IoStatus,
-                                     NULL,
-                                     FALSE ))) {
+                                      FileObject,
+                                      FileOffset,
+                                      Length,
+                                      ProcessId,
+                                      Key,
+                                      FailImmediately,
+                                      ExclusiveLock,
+                                      IoStatus,
+                                      NULL,
+                                      FALSE )) != FALSE) {
 
             //
             //  Set the flag indicating if Fast I/O is questionable.  We
@@ -275,25 +277,24 @@ Return Value:
         }
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Results;
 }
 
 \f
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastUnlockSingle (
-    IN PFILE_OBJECT FileObject,
-    IN PLARGE_INTEGER FileOffset,
-    IN PLARGE_INTEGER Length,
-    PEPROCESS ProcessId,
-    ULONG Key,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PLARGE_INTEGER FileOffset,
+    _In_ PLARGE_INTEGER Length,
+    _In_ PEPROCESS ProcessId,
+    _In_ ULONG Key,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -330,6 +331,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+    
     IoStatus->Information = 0;
 
     //
@@ -366,13 +369,13 @@ Return Value:
 
     FsRtlEnterFileSystem();
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We check whether we can proceed based on the state of the file oplocks.
         //
 
-        if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
+        if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
 
             try_return( NOTHING );
         }
@@ -416,22 +419,21 @@ Return Value:
         }
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Results;
 }
 
 \f
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastUnlockAll (
-    IN PFILE_OBJECT FileObject,
-    PEPROCESS ProcessId,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PEPROCESS ProcessId,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -462,6 +464,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+    
     IoStatus->Information = 0;
 
     //
@@ -498,13 +502,13 @@ Return Value:
 
     FsRtlEnterFileSystem();
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We check whether we can proceed based on the state of the file oplocks.
         //
 
-        if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
+        if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
 
             try_return( NOTHING );
         }
@@ -539,23 +543,22 @@ Return Value:
         CdUnlockFcb( IrpContext, Fcb );
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Results;
 }
 
 \f
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdFastUnlockAllByKey (
-    IN PFILE_OBJECT FileObject,
-    PVOID ProcessId,
-    ULONG Key,
-    OUT PIO_STATUS_BLOCK IoStatus,
-    IN PDEVICE_OBJECT DeviceObject
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PVOID ProcessId,
+    _In_ ULONG Key,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject
     )
 
 /*++
@@ -588,6 +591,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( DeviceObject );
+    
     IoStatus->Information = 0;
 
     //
@@ -624,13 +629,13 @@ Return Value:
 
     FsRtlEnterFileSystem();
 
-    _SEH2_TRY {
+    try {
 
         //
         //  We check whether we can proceed based on the state of the file oplocks.
         //
 
-        if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
+        if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
 
             try_return( NOTHING );
         }
@@ -666,10 +671,10 @@ Return Value:
         CdUnlockFcb( IrpContext, Fcb );
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         FsRtlExitFileSystem();
-    } _SEH2_END;
+    }
 
     return Results;
 }
index 08c9d62..dc3ed31 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -27,6 +27,7 @@ Abstract:
 #pragma alloc_text(PAGE, CdDissectName)
 #pragma alloc_text(PAGE, CdGenerate8dot3Name)
 #pragma alloc_text(PAGE, CdFullCompareNames)
+#pragma alloc_text(PAGE, CdIsLegalName)
 #pragma alloc_text(PAGE, CdIs8dot3Name)
 #pragma alloc_text(PAGE, CdIsNameInExpression)
 #pragma alloc_text(PAGE, CdShortNameDirentOffset)
@@ -34,10 +35,12 @@ Abstract:
 #endif
 
 \f
+_Post_satisfies_(_Old_(CdName->FileName.Length) >=
+                 CdName->FileName.Length + CdName->VersionString.Length)
 VOID
 CdConvertNameToCdName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PCD_NAME CdName
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PCD_NAME CdName
     )
 
 /*++
@@ -65,6 +68,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Look for a separator character.
     //
@@ -103,10 +108,10 @@ Return Value:
 \f
 VOID
 CdConvertBigToLittleEndian (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCHAR BigEndian,
-    IN ULONG ByteCount,
-    OUT PCHAR LittleEndian
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_reads_bytes_(ByteCount) PCHAR BigEndian,
+    _In_ ULONG ByteCount,
+    _Out_writes_bytes_(ByteCount) PCHAR LittleEndian
     )
 
 /*++
@@ -166,7 +171,10 @@ Return Value:
 
     while (RemainingByteCount != 0) {
 
+#pragma prefast(push)
+#pragma prefast(suppress:26014, "RemainingByteCount is even")
         *Destination = *Source;
+#pragma prefast(pop)
 
         Source += 2;
         Destination += 2;
@@ -180,9 +188,9 @@ Return Value:
 \f
 VOID
 CdUpcaseName (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_NAME Name,
-    IN OUT PCD_NAME UpcaseName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_NAME Name,
+    _Inout_ PCD_NAME UpcaseName
     )
 
 /*++
@@ -206,10 +214,11 @@ Return Value:
 
 {
     NTSTATUS Status;
-    //PVOID NewBuffer; /* ReactOS Change: GCC Uninitialized variable */
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  If the name structures are different then initialize the different components.
     //
@@ -242,6 +251,7 @@ Return Value:
             //  copy the data.
             //
 
+#pragma prefast( suppress:26015, "CD_NAME structures have two UNICODE_STRING structures pointing to the same allocation. there is no way to tell prefast this is the case and that the allocation is always big enough.");
             *(UpcaseName->VersionString.Buffer) = L';';
 
             UpcaseName->VersionString.Buffer += 1;
@@ -260,8 +270,9 @@ Return Value:
     //  This should never fail.
     //
 
-    ASSERT( Status == STATUS_SUCCESS );
-
+    NT_ASSERT( Status == STATUS_SUCCESS );
+    __analysis_assert( Status == STATUS_SUCCESS );
+                
     if (Name->VersionString.Length != 0) {
 
         Status = RtlUpcaseUnicodeString( &UpcaseName->VersionString,
@@ -272,7 +283,8 @@ Return Value:
         //  This should never fail.
         //
 
-        ASSERT( Status == STATUS_SUCCESS );
+        NT_ASSERT( Status == STATUS_SUCCESS );
+        __analysis_assert( Status == STATUS_SUCCESS );        
     }
 
     return;
@@ -281,9 +293,9 @@ Return Value:
 \f
 VOID
 CdDissectName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PUNICODE_STRING RemainingName,
-    OUT PUNICODE_STRING FinalName
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PUNICODE_STRING RemainingName,
+    _Out_ PUNICODE_STRING FinalName
     )
 
 /*++
@@ -312,6 +324,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Find the offset of the next component separators.
     //
@@ -353,10 +367,62 @@ Return Value:
 }
 
 \f
+BOOLEAN
+CdIsLegalName (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING FileName
+    )
+
+/*++
+
+Routine Description:
+
+    This routine checks if the name is a legal ISO 9660 name.
+
+Arguments:
+
+    FileName - String of bytes containing the name.
+
+Return Value:
+
+    BOOLEAN - TRUE if this name is a legal, FALSE otherwise.
+
+--*/
+
+{
+    PWCHAR Wchar;
+
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( IrpContext );
+
+    //
+    //  Check if name corresponds to a legal file name.
+    //
+
+    for (Wchar = FileName->Buffer;
+         Wchar < Add2Ptr( FileName->Buffer, FileName->Length, PWCHAR );
+         Wchar++) {
+
+        if ((*Wchar < 0xff) &&
+            !FsRtlIsAnsiCharacterLegalHpfs( *Wchar, FALSE ) &&
+            (*Wchar != L'"') &&
+            (*Wchar != L'<') &&
+            (*Wchar != L'>') &&
+            (*Wchar != L'|')) {
+
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+\f
 BOOLEAN
 CdIs8dot3Name (
-    IN PIRP_CONTEXT IrpContext,
-    IN UNICODE_STRING FileName
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ UNICODE_STRING FileName
     )
 
 /*++
@@ -378,7 +444,7 @@ Return Value:
 
 {
     CHAR DbcsNameBuffer[ BYTE_COUNT_8_DOT_3 ];
-    STRING DbcsName;
+    STRING DbcsName = {0};
 
     PWCHAR NextWchar;
     ULONG Count;
@@ -388,11 +454,13 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  The length must be less than 24 bytes.
     //
 
-    ASSERT( FileName.Length != 0 );
+    NT_ASSERT( FileName.Length != 0 );
     if (FileName.Length > BYTE_COUNT_8_DOT_3) {
 
         return FALSE;
@@ -474,11 +542,11 @@ Return Value:
 \f
 VOID
 CdGenerate8dot3Name (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING FileName,
-    IN ULONG DirentOffset,
-    OUT PWCHAR ShortFileName,
-    OUT PUSHORT ShortByteCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING FileName,
+    _In_ ULONG DirentOffset,
+    _Out_writes_bytes_to_(BYTE_COUNT_8_DOT_3, *ShortByteCount) PWCHAR ShortFileName,
+    _Out_ PUSHORT ShortByteCount
     )
 
 /*++
@@ -517,11 +585,12 @@ Return Value:
 
 --*/
 
-{
+{   
     NTSTATUS Status;
+    
     UNICODE_STRING ShortName;
     UNICODE_STRING BiasedShortName;
-    WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ];
+    WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ] = {0};
     WCHAR BiasedShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ];
 
     GENERATE_NAME_CONTEXT NameContext;
@@ -537,7 +606,7 @@ Return Value:
 
     BOOLEAN FoundTilde = FALSE;
 
-    OEM_STRING OemName;
+    OEM_STRING OemName = {0};
     USHORT OemNameOffset = 0;
     BOOLEAN OverflowBuffer = FALSE;
 
@@ -568,7 +637,7 @@ Return Value:
     //  into the name in order to reduce the chance of name conflicts.  We will use
     //  a tilde character followed by a character representation of the dirent offset.
     //  This will be the hexadecimal representation of the dirent offset in the directory.
-    //  It is actually this offset divided by 32 since we don't need the full
+    //  It is actuall this offset divided by 32 since we don't need the full
     //  granularity.
     //
 
@@ -592,9 +661,14 @@ Return Value:
     
     Status = RtlUnicodeStringToOemString(&OemName, &ShortName, TRUE);
 
-    if (!NT_SUCCESS( Status )) {
+    //
+    //  If this failed, bail out. Don't expect any problems other than no mem.
+    //
+    
+    if (!NT_SUCCESS( Status)) {
 
-        CdRaiseStatus( IrpContext, Status );
+        NT_ASSERT( STATUS_INSUFFICIENT_RESOURCES == Status);
+        CdRaiseStatus( IrpContext, Status);
     }
     
     Length = 0;
@@ -650,7 +724,7 @@ Return Value:
 
     //
     //  Figure out the maximum number of characters we can copy of the base
-    //  name.  We subtract the number of characters in the dirent string from 8.
+    //  name.  We subract the number of characters in the dirent string from 8.
     //  We will copy this many characters or stop when we reach a '.' character
     //  or a '~' character in the name.
     //
@@ -685,20 +759,23 @@ Return Value:
         // may use 2 bytes as DBCS characters.
         //
 
+#pragma prefast(push)
+#pragma prefast(suppress:26014, "OemNameOffset <= BaseNameOffset throughout this loop; OemName buffer previously allocated based on ShortName's length.")
         if (FsRtlIsLeadDbcsCharacter(OemName.Buffer[OemNameOffset])) {
+#pragma prefast(pop)
 
             OemNameOffset += 2;
+
+            if ((OemNameOffset + (BiasedShortName.Length / sizeof(WCHAR))) > 8)  {
+            
+                OverflowBuffer = TRUE;
+            }
         }
         else  {
         
             OemNameOffset++;
         }
 
-        if ((OemNameOffset + (BiasedShortName.Length / sizeof(WCHAR))) > 8)  {
-        
-            OverflowBuffer = TRUE;
-        }
-
         //
         //  Only copy the bytes if we still have space for the dirent string.
         //
@@ -719,9 +796,11 @@ Return Value:
     //  Now copy the dirent string into the biased name buffer.
     //
 
+#pragma prefast(push)
     RtlCopyMemory( NextWchar,
                    BiasedShortName.Buffer,
                    BiasedShortName.Length );
+#pragma prefast(pop)
 
     Length += BiasedShortName.Length;
     NextWchar += (BiasedShortName.Length / sizeof( WCHAR ));
@@ -744,18 +823,16 @@ Return Value:
     //
 
     *ShortByteCount = Length;
-
-    return;
 }
 
 \f
 BOOLEAN
 CdIsNameInExpression (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCD_NAME CurrentName,
-    IN PCD_NAME SearchExpression,
-    IN ULONG  WildcardFlags,
-    IN BOOLEAN CheckVersion
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCD_NAME CurrentName,
+    _In_ PCD_NAME SearchExpression,
+    _In_ ULONG  WildcardFlags,
+    _In_ BOOLEAN CheckVersion
     )
 
 /*++
@@ -791,6 +868,8 @@ Return Value:
     BOOLEAN Match = TRUE;
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  If there are wildcards in the expression then we call the
     //  appropriate FsRtlRoutine.
@@ -860,8 +939,8 @@ Return Value:
 \f
 ULONG
 CdShortNameDirentOffset (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING Name
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING Name
     )
 
 /*++
@@ -894,6 +973,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Walk through the name until we either reach the end of the name
     //  or find a tilde character.
@@ -967,9 +1048,9 @@ Return Value:
 
 FSRTL_COMPARISON_RESULT
 CdFullCompareNames (
-    IN PIRP_CONTEXT IrpContext,
-    IN PUNICODE_STRING NameA,
-    IN PUNICODE_STRING NameB
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PUNICODE_STRING NameA,
+    _In_ PUNICODE_STRING NameB
     )
 
 /*++
@@ -987,8 +1068,8 @@ Return Value:
 
     COMPARISON - returns
 
-        LessThan    if NameA < NameB lexicographically,
-        GreaterThan if NameA > NameB lexicographically,
+        LessThan    if NameA < NameB lexicalgraphically,
+        GreaterThan if NameA > NameB lexicalgraphically,
         EqualTo     if NameA is equal to NameB
 
 --*/
@@ -1000,6 +1081,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Figure out the minimum of the two lengths
     //
@@ -1016,7 +1099,7 @@ Return Value:
 
     //
     //  Loop through looking at all of the characters in both strings
-    //  testing for equality, less than, and greater than
+    //  testing for equalilty, less than, and greater than
     //
 
     i = RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength );
index b227332..41e2eef 100755 (executable)
@@ -19,7 +19,7 @@ Abstract:
 #ifndef _CDNODETYPE_
 #define _CDNODETYPE_
 
-typedef CSHORT NODE_TYPE_CODE;
+typedef USHORT NODE_TYPE_CODE;
 typedef NODE_TYPE_CODE *PNODE_TYPE_CODE;
 
 #define NTC_UNDEFINED                   ((NODE_TYPE_CODE)0x0000)
@@ -90,12 +90,15 @@ typedef CSHORT NODE_BYTE_SIZE;
 #define CDFS_BUG_CHECK_PNP               (0x00140000)
 #define CDFS_BUG_CHECK_PREFXSUP          (0x00150000)
 #define CDFS_BUG_CHECK_READ              (0x00160000)
-#define CDFS_BUG_CHECK_RESRCSUP          (0x00170000)
-#define CDFS_BUG_CHECK_STRUCSUP          (0x00180000)
-#define CDFS_BUG_CHECK_TIMESUP           (0x00190000)
-#define CDFS_BUG_CHECK_VERFYSUP          (0x001a0000)
-#define CDFS_BUG_CHECK_VOLINFO           (0x001b0000)
-#define CDFS_BUG_CHECK_WORKQUE           (0x001c0000)
+#define CDFS_BUG_CHECK_WRITE             (0x00170000)
+#define CDFS_BUG_CHECK_RESRCSUP          (0x00180000)
+#define CDFS_BUG_CHECK_STRUCSUP          (0x00190000)
+#define CDFS_BUG_CHECK_TIMESUP           (0x001a0000)
+#define CDFS_BUG_CHECK_VERFYSUP          (0x001b0000)
+#define CDFS_BUG_CHECK_VOLINFO           (0x001c0000)
+#define CDFS_BUG_CHECK_WORKQUE           (0x001d0000)
+#define CDFS_BUG_CHECK_SHUTDOWN          (0x001e0000)
+
 
 #define CdBugCheck(A,B,C) { KeBugCheckEx(CDFS_FILE_SYSTEM, BugCheckFileId | __LINE__, A, B, C ); }
 
index 2428c9d..bd5d1dc 100755 (executable)
@@ -22,7 +22,7 @@ Abstract:
     of the tree.  The children of a given directory will be grouped together.
 
     The directories are assigned ordinal numbers based on their position in
-    the path table.  The root directory is assigned ordinal value 1.
+    the path table.  The root dirctory is assigned ordinal value 1.
 
     Path table sectors:
 
@@ -73,7 +73,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -88,8 +88,8 @@ Abstract:
 //
 //  PRAW_PATH_ENTRY
 //  CdRawPathEntry (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PPATH_ENUM_CONTEXT PathContext
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PPATH_ENUM_CONTEXT PathContext
 //      );
 //
 
@@ -102,19 +102,20 @@ Abstract:
 
 VOID
 CdMapPathTableBlock (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG BaseOffset,
-    IN OUT PPATH_ENUM_CONTEXT PathContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG BaseOffset,
+    _Inout_ PPATH_ENUM_CONTEXT PathContext
     );
 
+_Success_(return != FALSE)
 BOOLEAN
 CdUpdatePathEntryFromRawPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG Ordinal,
-    IN BOOLEAN VerifyBounds,
-    IN PPATH_ENUM_CONTEXT PathContext,
-    OUT PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG Ordinal,
+    _In_ BOOLEAN VerifyBounds,
+    _In_ PPATH_ENUM_CONTEXT PathContext,
+    _Out_ PPATH_ENTRY PathEntry
     );
 
 #ifdef ALLOC_PRAGMA
@@ -129,11 +130,11 @@ CdUpdatePathEntryFromRawPathEntry (
 \f
 VOID
 CdLookupPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG PathEntryOffset,
-    IN ULONG Ordinal,
-    IN BOOLEAN VerifyBounds,
-    IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG PathEntryOffset,
+    _In_ ULONG Ordinal,
+    _In_ BOOLEAN VerifyBounds,
+    _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
     )
 
 /*++
@@ -204,9 +205,9 @@ Return Value:
 \f
 BOOLEAN
 CdLookupNextPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PPATH_ENUM_CONTEXT PathContext,
-    IN OUT PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PPATH_ENUM_CONTEXT PathContext,
+    _Inout_ PPATH_ENTRY PathEntry
     )
 
 /*++
@@ -296,14 +297,14 @@ Return Value:
                                               PathEntry );
 }
 
-\f
+_Success_(return != FALSE)\f
 BOOLEAN
 CdFindPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB ParentFcb,
-    IN PCD_NAME DirName,
-    IN BOOLEAN IgnoreCase,
-    IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB ParentFcb,
+    _In_ PCD_NAME DirName,
+    _In_ BOOLEAN IgnoreCase,
+    _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
     )
 
 /*++
@@ -481,10 +482,10 @@ Return Value:
 
 VOID
 CdMapPathTableBlock (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN LONGLONG BaseOffset,
-    IN OUT PPATH_ENUM_CONTEXT PathContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ LONGLONG BaseOffset,
+    _Inout_ PPATH_ENUM_CONTEXT PathContext
     )
 
 /*++
@@ -493,7 +494,7 @@ Routine Description:
 
     This routine is called to map (or allocate and copy) the next
     data block in the path table.  We check if the next block will
-    span a view boundary and allocate an auxiliary buffer in that case.
+    span a view boundary and allocate an auxilary buffer in that case.
 
 Arguments:
 
@@ -519,9 +520,11 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Map the new block and set the enumeration context to this
-    //  point.  Allocate an auxiliary buffer if necessary.
+    //  point.  Allocate an auxilary buffer if necessary.
     //
 
     CurrentLength = 2 * SECTOR_SIZE;
@@ -564,7 +567,7 @@ Return Value:
         (FlagOn( ((ULONG) BaseOffset), VACB_MAPPING_MASK ) == LAST_VACB_SECTOR_OFFSET )) {
 
         //
-        //  Map each sector individually and store into an auxiliary
+        //  Map each sector individually and store into an auxilary
         //  buffer.
         //
 
@@ -605,7 +608,7 @@ Return Value:
 
         //
         //  There is a slight chance that we have allocated an
-        //  auxiliary buffer on the previous sector.
+        //  auxilary buffer on the previous sector.
         //
 
         if (PathContext->AllocatedData) {
@@ -629,14 +632,14 @@ Return Value:
 //
 //  Local support routine
 //
-
+_Success_(return != FALSE)
 BOOLEAN
 CdUpdatePathEntryFromRawPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN ULONG Ordinal,
-    IN BOOLEAN VerifyBounds,
-    IN PPATH_ENUM_CONTEXT PathContext,
-    OUT PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ ULONG Ordinal,
+    _In_ BOOLEAN VerifyBounds,
+    _In_ PPATH_ENUM_CONTEXT PathContext,
+    _Out_ PPATH_ENTRY PathEntry
     )
 
 /*++
@@ -764,7 +767,7 @@ Return Value:
 
     PathEntry->PathEntryLength = WordAlign( PathEntry->PathEntryLength );
 
-    PathEntry->DirName = (PCHAR)RawPathEntry->DirId; /* ReactOS Change: GCC "assignment makes pointer from integer without a cast" */
+    PathEntry->DirName = (PCHAR)RawPathEntry->DirId;
 
     return TRUE;
 }
@@ -776,9 +779,9 @@ Return Value:
 
 VOID
 CdUpdatePathEntryName (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PPATH_ENTRY PathEntry,
-    IN BOOLEAN IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PPATH_ENTRY PathEntry,
+    _In_ BOOLEAN IgnoreCase
     )
 
 /*++
@@ -789,7 +792,7 @@ Routine Description:
     path entry.  If this is a Joliet name then we will make sure we have
     an allocated buffer and need to convert from big endian to little
     endian.  We also correctly update the case name.  If this operation is ignore
-    case then we need an auxiliary buffer for the name.
+    case then we need an auxilary buffer for the name.
 
     For an Ansi disk we can use the name from the disk for the exact case.  We only
     need to allocate a buffer for the ignore case name.  The on-disk representation of
@@ -828,7 +831,7 @@ Return Value:
         //  There should be no allocated buffers.
         //
 
-        ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ));
+        NT_ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ));
 
         //
         //  Now use one of the hard coded directory names.
@@ -931,7 +934,8 @@ Return Value:
                                    PathEntry->DirName,
                                    PathEntry->DirNameLen );
 
-        ASSERT( Status == STATUS_SUCCESS );
+        NT_ASSERT( Status == STATUS_SUCCESS );
+        __analysis_assert( Status == STATUS_SUCCESS );        
         PathEntry->CdDirName.FileName.Length = (USHORT) Length;
 
     } else {
index 596ac28..b3237df 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -22,40 +22,50 @@ Abstract:
 
 #define BugCheckFileId                   (CDFS_BUG_CHECK_PNP)
 
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpQueryRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpSurpriseRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     );
 
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpCancelRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     );
 
+//  Tell prefast this is a completion routine.
+IO_COMPLETION_ROUTINE CdPnpCompletionRoutine;
+
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdPnpCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Contxt
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ PIRP Irp,
+    _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
     );
 
 #ifdef ALLOC_PRAGMA
@@ -66,11 +76,11 @@ CdPnpCompletionRoutine (
 #pragma alloc_text(PAGE, CdPnpSurpriseRemove)
 #endif
 
-
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonPnp (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -91,7 +101,7 @@ Return Value:
 --*/
 
 {
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN PassThrough = FALSE;
     
     PIO_STACK_LOCATION IrpSp;
@@ -99,6 +109,11 @@ Return Value:
     PVOLUME_DEVICE_OBJECT OurDeviceObject;
     PVCB Vcb;
 
+    PAGED_CODE();
+
+    // Global lock object is acquired based on internal book-keeping
+    _Analysis_suppress_lock_checking_(CdData.DataResource);
+
     //
     //  Get the current Irp stack location.
     //
@@ -126,7 +141,8 @@ Return Value:
     //  object.  If it isn't, we need to get out before we try to reference some
     //  field that takes us past the end of an ordinary device object.    
     //
-    
+
+#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the size member is allowed")
     if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) ||
         NodeType( &OurDeviceObject->Vcb ) != CDFS_NTC_VCB) {
         
@@ -215,12 +231,13 @@ Return Value:
     return Status;
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpQueryRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -251,6 +268,8 @@ Return Value:
     KEVENT Event;
     BOOLEAN VcbPresent = TRUE;
 
+    PAGED_CODE();
+
     ASSERT_EXCLUSIVE_CDDATA;
 
     //
@@ -326,7 +345,7 @@ Return Value:
 
         if (Status == STATUS_PENDING) {
 
-            KeWaitForSingleObject( &Event,
+            (VOID)KeWaitForSingleObject( &Event,
                                    Executive,
                                    KernelMode,
                                    FALSE,
@@ -343,7 +362,7 @@ Return Value:
         //  Since we were able to lock the volume, we are guaranteed to
         //  move this volume into dismount state and disconnect it from
         //  the underlying storage stack.  The force on our part is actually
-        //  unnecessary, though complete.
+        //  unnecesary, though complete.
         //
         //  What is not strictly guaranteed, though, is that the closes
         //  for the metadata streams take effect synchronously underneath
@@ -355,7 +374,7 @@ Return Value:
             
             VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE );
     
-            ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress );
+            NT_ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress );
         }
 
         //
@@ -372,7 +391,7 @@ Return Value:
         //
         //  The reason this is the case is that handles/fileobjects place a reference
         //  on the device objects they overly.  In the filesystem case, these references
-        //  are on our target devices.  PnP correctly thinks that if references remain
+        //  are on our target devices.  PnP correcly thinks that if references remain
         //  on the device objects in the stack that someone has a handle, and that this
         //  counts as a reason to not succeed the query - even though every interrogated
         //  driver thinks that it is OK.
@@ -392,11 +411,14 @@ Return Value:
 
         CdReleaseVcb( IrpContext, Vcb );
     }
+    else {
+        _Analysis_assume_lock_not_held_(Vcb->VcbResource);
+    }
 
     CdReleaseCdData( IrpContext );
     
     //
-    //  Cleanup our IrpContext and complete the IRP if necessary.
+    //  Cleanup our IrpContext and complete the IRP if neccesary.
     //
 
     CdCompleteRequest( IrpContext, Irp, Status );
@@ -404,12 +426,13 @@ Return Value:
     return Status;
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -438,6 +461,8 @@ Return Value:
     KEVENT Event;
     BOOLEAN VcbPresent = TRUE;
 
+    PAGED_CODE();
+
     ASSERT_EXCLUSIVE_CDDATA;
 
     //
@@ -447,7 +472,7 @@ Return Value:
     //  (the only case in which this will be the first warning).
     //
     //  Note that it is entirely unlikely that we will be around
-    //  for a REMOVE in the first two cases, as we try to initiate
+    //  for a REMOVE in the first two cases, as we try to intiate
     //  dismount.
     //
     
@@ -516,7 +541,7 @@ Return Value:
 
     if (Status == STATUS_PENDING) {
 
-        KeWaitForSingleObject( &Event,
+        (VOID)KeWaitForSingleObject( &Event,
                                Executive,
                                KernelMode,
                                FALSE,
@@ -528,7 +553,7 @@ Return Value:
     //
     //  Now make our dismount happen.  This may not vaporize the
     //  Vcb, of course, since there could be any number of handles
-    //  outstanding if we were not preceded by a QUERY.
+    //  outstanding if we were not preceeded by a QUERY.
     //
     //  PnP will take care of disconnecting this stack if we
     //  couldn't get off of it immediately.
@@ -545,6 +570,9 @@ Return Value:
 
         CdReleaseVcb( IrpContext, Vcb );
     }
+    else {
+        _Analysis_assume_lock_not_held_(Vcb->VcbResource);
+    }
 
     CdReleaseCdData( IrpContext );
     
@@ -557,12 +585,13 @@ Return Value:
     return Status;
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpSurpriseRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -597,6 +626,8 @@ Return Value:
     KEVENT Event;
     BOOLEAN VcbPresent = TRUE;
 
+    PAGED_CODE();
+
     ASSERT_EXCLUSIVE_CDDATA;
     
     //
@@ -654,7 +685,7 @@ Return Value:
 
     if (Status == STATUS_PENDING) {
 
-        KeWaitForSingleObject( &Event,
+        (VOID)KeWaitForSingleObject( &Event,
                                Executive,
                                KernelMode,
                                FALSE,
@@ -680,6 +711,9 @@ Return Value:
 
         CdReleaseVcb( IrpContext, Vcb );
     }
+    else {
+        _Analysis_assume_lock_not_held_(Vcb->VcbResource);
+    }
 
     CdReleaseCdData( IrpContext );
     
@@ -692,12 +726,13 @@ Return Value:
     return Status;
 }
 
-
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_nonreentrant_lock_(CdData.DataResource)
 NTSTATUS
 CdPnpCancelRemove (
-    PIRP_CONTEXT IrpContext,
-    PIRP Irp,
-    PVCB Vcb
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -724,6 +759,8 @@ Return Value:
 {
     NTSTATUS Status;
 
+    PAGED_CODE();
+
     ASSERT_EXCLUSIVE_CDDATA;
 
     //
@@ -775,20 +812,21 @@ Return Value:
 //
 
 NTSTATUS
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdPnpCompletionRoutine (
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Contxt
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ PIRP Irp,
+    _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
     )
 {
     PKEVENT Event = (PKEVENT) Contxt;
+    _Analysis_assume_(Contxt != NULL);
 
     KeSetEvent( Event, 0, FALSE );
 
     return STATUS_MORE_PROCESSING_REQUIRED;
 
     UNREFERENCED_PARAMETER( DeviceObject );
+    UNREFERENCED_PARAMETER( Irp );
     UNREFERENCED_PARAMETER( Contxt );
 }
 
index 75d6b02..6a7b6c5 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -27,16 +27,16 @@ Abstract:
 
 PNAME_LINK
 CdFindNameLink (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRTL_SPLAY_LINKS *RootNode,
-    IN PUNICODE_STRING Name
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PRTL_SPLAY_LINKS *RootNode,
+    _In_ PUNICODE_STRING Name
     );
 
 BOOLEAN
 CdInsertNameLink (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRTL_SPLAY_LINKS *RootNode,
-    IN PNAME_LINK NameLink
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PRTL_SPLAY_LINKS *RootNode,
+    _In_ PNAME_LINK NameLink
     );
 
 #ifdef ALLOC_PRAGMA
@@ -50,12 +50,12 @@ CdInsertNameLink (
 \f
 VOID
 CdInsertPrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PCD_NAME Name,
-    IN BOOLEAN IgnoreCase,
-    IN BOOLEAN ShortNameMatch,
-    IN PFCB ParentFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ PCD_NAME Name,
+    _In_ BOOLEAN IgnoreCase,
+    _In_ BOOLEAN ShortNameMatch,
+    _Inout_ PFCB ParentFcb
     )
 
 /*++
@@ -205,8 +205,8 @@ Return Value:
 \f
 VOID
 CdRemovePrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb
     )
 
 /*++
@@ -228,7 +228,9 @@ Return Value:
 
 {
     PAGED_CODE();
-
+    
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Start with the short name prefix entry.
     //
@@ -281,12 +283,14 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdFindPrefix (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PFCB *CurrentFcb,
-    IN OUT PUNICODE_STRING RemainingName,
-    IN BOOLEAN IgnoreCase
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB *CurrentFcb,
+    _Inout_ PUNICODE_STRING RemainingName,
+    _In_ BOOLEAN IgnoreCase
     )
 
 /*++
@@ -459,9 +463,9 @@ Return Value:
 
 PNAME_LINK
 CdFindNameLink (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRTL_SPLAY_LINKS *RootNode,
-    IN PUNICODE_STRING Name
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PRTL_SPLAY_LINKS *RootNode,
+    _In_ PUNICODE_STRING Name
     )
 
 /*++
@@ -562,9 +566,9 @@ Return Value:
 
 BOOLEAN
 CdInsertNameLink (
-    IN PIRP_CONTEXT IrpContext,
-    IN PRTL_SPLAY_LINKS *RootNode,
-    IN PNAME_LINK NameLink
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PRTL_SPLAY_LINKS *RootNode,
+    _In_ PNAME_LINK NameLink
     )
 
 /*++
index b32b13b..43e8f9c 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -25,8 +25,8 @@ Abstract:
 //
 //  VOID
 //  SafeZeroMemory (
-//      IN PUCHAR At,
-//      IN ULONG ByteCount
+//      _Out_ PUCHAR At,
+//      _In_ ULONG ByteCount
 //      );
 //
 
@@ -35,11 +35,12 @@ Abstract:
 //
 
 #define SafeZeroMemory(IC,AT,BYTE_COUNT) {                  \
-    _SEH2_TRY {                                             \
+    try {                                                   \
         RtlZeroMemory( (AT), (BYTE_COUNT) );                \
-    } _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER ) {           \
+__pragma(warning(suppress: 6320))                           \
+    } except( EXCEPTION_EXECUTE_HANDLER ) {                 \
          CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER );   \
-    } _SEH2_END;                                            \
+    }                                                       \
 }
 
 //
@@ -53,10 +54,12 @@ Abstract:
 #endif
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonRead (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -79,7 +82,7 @@ Return Value:
 --*/
 
 {
-    NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Uninit var */
+    NTSTATUS Status = STATUS_SUCCESS;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
 
     TYPE_OF_OPEN TypeOfOpen;
@@ -103,7 +106,7 @@ Return Value:
     BOOLEAN ReleaseFile = TRUE;
 
     CD_IO_CONTEXT LocalIoContext;
-
+    
     PAGED_CODE();
 
     //
@@ -123,6 +126,9 @@ Return Value:
 
     TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
 
+    // Internal lock object is acquired if return status is STATUS_PENDING
+    _Analysis_suppress_lock_checking_(Fcb->Resource);
+
     if ((TypeOfOpen == UnopenedFileObject) ||
         (TypeOfOpen == UserDirectoryOpen)) {
 
@@ -180,7 +186,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Fcb.  Allow reads if this is a DASD handle that is 
@@ -222,11 +228,11 @@ Return Value:
             //  based on the state of the file oplocks.
             //
 
-            Status = FsRtlCheckOplock( &Fcb->Oplock,
+            Status = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
                                        Irp,
                                        IrpContext,
-                                       (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
-                                       (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */
+                                       CdOplockComplete,
+                                       CdPrePostIrp );
 
             //
             //  If the result is not STATUS_SUCCESS then the Irp was completed
@@ -250,22 +256,31 @@ Return Value:
         }
 
         //
-        //  Complete the request if it begins beyond the end of file.
+        //  Check request beyond end of file if this is not a read on a volume
+        //  handle marked for extended DASD IO.
         //
 
-        if (StartingOffset >= Fcb->FileSize.QuadPart) {
+        if ((TypeOfOpen != UserVolumeOpen) ||
+            (!FlagOn( Ccb->Flags, CCB_FLAG_ALLOW_EXTENDED_DASD_IO ))) {
 
-            try_return( Status = STATUS_END_OF_FILE );
-        }
+            //
+            //  Complete the request if it begins beyond the end of file.
+            //
 
-        //
-        //  Truncate the read if it extends beyond the end of the file.
-        //
+            if (StartingOffset >= Fcb->FileSize.QuadPart) {
 
-        if (ByteRange > Fcb->FileSize.QuadPart) {
+                try_return( Status = STATUS_END_OF_FILE );
+            }
+
+            //
+            //  Truncate the read if it extends beyond the end of the file.
+            //
 
-            ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
-            ByteRange = Fcb->FileSize.QuadPart;
+            if (ByteRange > Fcb->FileSize.QuadPart) {
+
+                ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
+                ByteRange = Fcb->FileSize.QuadPart;
+            }
         }
 
         //
@@ -515,7 +530,7 @@ Return Value:
         }
 
     try_exit:  NOTHING;
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the Fcb.
@@ -525,7 +540,7 @@ Return Value:
 
             CdReleaseFile( IrpContext, Fcb );
         }
-    } _SEH2_END;
+    }
 
     //
     //  Post the request if we got CANT_WAIT.
@@ -548,3 +563,4 @@ Return Value:
 }
 
 
+
index 6622405..86b2b91 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -23,7 +23,7 @@ Abstract:
 
 #ifdef ALLOC_PRAGMA
 #pragma alloc_text(PAGE, CdAcquireForCache)
-#pragma alloc_text(PAGE, CdAcquireForCreateSection)
+#pragma alloc_text(PAGE, CdFilterCallbackAcquireForCreateSection)
 #pragma alloc_text(PAGE, CdAcquireResource)
 #pragma alloc_text(PAGE, CdNoopAcquire)
 #pragma alloc_text(PAGE, CdNoopRelease)
@@ -32,12 +32,18 @@ Abstract:
 #endif
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
+_When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
+_When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
+_When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
+_When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
 BOOLEAN
 CdAcquireResource (
-    IN PIRP_CONTEXT IrpContext,
-    IN PERESOURCE Resource,
-    IN BOOLEAN IgnoreWait,
-    IN TYPE_OF_ACQUIRE Type
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PERESOURCE Resource,
+    _In_ BOOLEAN IgnoreWait,
+    _In_ TYPE_OF_ACQUIRE Type
     )
 
 /*++
@@ -89,27 +95,28 @@ Return Value:
 
     switch (Type) {
         case AcquireExclusive:
-        
+
+#pragma prefast( suppress:28137, "prefast believes Wait should be a constant, but this is ok for CDFS" )
             Acquired = ExAcquireResourceExclusiveLite( Resource, Wait );
             break;
 
         case AcquireShared:
-            
+
             Acquired = ExAcquireResourceSharedLite( Resource, Wait );
             break;
 
         case AcquireSharedStarveExclusive:
-            
+
             Acquired = ExAcquireSharedStarveExclusive( Resource, Wait );
             break;
 
         default:
-               Acquired = FALSE;
-            ASSERT( FALSE );
+            Acquired = FALSE;
+            NT_ASSERT( FALSE );
     }
 
     //
-    //  If not acquired and the user didn't specify IgnoreWait then
+    //  If not acquired and the user didn't specifiy IgnoreWait then
     //  raise CANT_WAIT.
     //
 
@@ -122,11 +129,13 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
+_When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdAcquireForCache (
-    IN PFCB Fcb,
-    IN BOOLEAN Wait
+    _Inout_ PFCB Fcb,
+    _In_ BOOLEAN Wait
     )
 
 /*++
@@ -152,17 +161,18 @@ Return Value:
 {
     PAGED_CODE();
 
-    ASSERT(IoGetTopLevelIrp() == NULL);
+    NT_ASSERT(IoGetTopLevelIrp() == NULL);
     IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
 
     return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
 }
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
+_Releases_lock_(*Fcb->Resource)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdReleaseFromCache (
-    IN PFCB Fcb
+    _Inout_ PFCB Fcb
     )
 
 /*++
@@ -187,7 +197,7 @@ Return Value:
 {
     PAGED_CODE();
 
-    ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
+    NT_ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
     IoSetTopLevelIrp( NULL );
     
     ExReleaseResourceLite( Fcb->Resource );
@@ -195,10 +205,9 @@ Return Value:
 
 \f
 BOOLEAN
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdNoopAcquire (
-    IN PVOID Fcb,
-    IN BOOLEAN Wait
+    _In_ PVOID Fcb,
+    _In_ BOOLEAN Wait
     )
 
 /*++
@@ -222,14 +231,17 @@ Return Value:
 
 {
     PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( Fcb );
+    UNREFERENCED_PARAMETER( Wait );
+    
     return TRUE;
 }
 
 \f
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdNoopRelease (
-    IN PVOID Fcb
+    _In_ PVOID Fcb
     )
 
 /*++
@@ -251,13 +263,17 @@ Return Value:
 
 {
     PAGED_CODE();
+
+    UNREFERENCED_PARAMETER( Fcb );
 }
 
 \f
-VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
-CdAcquireForCreateSection (
-    IN PFILE_OBJECT FileObject
+
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdFilterCallbackAcquireForCreateSection (
+    _In_ PFS_FILTER_CALLBACK_DATA CallbackData,
+    _Unreferenced_parameter_ PVOID *CompletionContext
     )
 
 /*++
@@ -268,24 +284,41 @@ Routine Description:
 
 Arguments:
 
-    FileObject - File object for a Cdfs stream.
+    FS_FILTER_CALLBACK_DATA - Filter based callback data that provides the file object we
+                              want to acquire.
+
+    CompletionContext - Ignored.
 
 Return Value:
 
-    None
+    On success we return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
+
+    If SyncType is SyncTypeCreateSection, we return a status that indicates there are no
+    writers to this file.
 
 --*/
 
 {
-    PAGED_CODE();
+    PFILE_OBJECT FileObject;
+
 
+    PAGED_CODE();
     
+    NT_ASSERT( CallbackData->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION );
+    NT_ASSERT( CallbackData->SizeOfFsFilterCallbackData == sizeof(FS_FILTER_CALLBACK_DATA) );
+
+    //
+    //  Get the file object from the callback data.
+    //
+
+    FileObject = CallbackData->FileObject;
+
     //
     //  Get the Fcb resource exclusively.
     //
 
     ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource,
-                                TRUE );
+                                    TRUE );
                                 
     //
     //  Take the File resource shared.  We need this later on when MM calls 
@@ -299,13 +332,31 @@ Return Value:
 
     ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource,
                                     TRUE );
+
+    //
+    //  CDFS is a read-only file system, so we can always indicate no writers.
+    //  We only do this for create section synchronization.  For others we
+    //  return the generic success STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
+    //
+
+    if (CallbackData->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection) {
+
+        return STATUS_FILE_LOCKED_WITH_ONLY_READERS;
+
+    } else {
+
+        return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY;
+    }
+
+    UNREFERENCED_PARAMETER( CompletionContext );
 }
 
 \f
+_Function_class_(FAST_IO_RELEASE_FILE)
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdReleaseForCreateSection (
-    IN PFILE_OBJECT FileObject
+    _In_ PFILE_OBJECT FileObject
     )
 
 /*++
diff --git a/drivers/filesystems/cdfs_new/shutdown.c b/drivers/filesystems/cdfs_new/shutdown.c
new file mode 100644 (file)
index 0000000..ca42635
--- /dev/null
@@ -0,0 +1,175 @@
+/*++
+
+Copyright (c) 1997-2006 Microsoft Corporation
+
+Module Name:
+
+    Shutdown.c
+
+Abstract:
+
+    This module implements the shutdown routine for CDFS called by
+    the dispatch driver.
+
+
+--*/
+
+#include "CdProcs.h"
+
+//
+//  The Bug check file id for this module
+//
+
+#define BugCheckFileId                   (CDFS_BUG_CHECK_SHUTDOWN)
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, CdCommonShutdown)
+#endif
+
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdCommonShutdown (
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    )
+
+/*++
+
+Routine Description:
+
+    This is the common routine for handling shutdown operation called
+    by both the fsd and fsp threads
+
+Arguments:
+
+    Irp - Supplies the Irp to process
+
+Return Value:
+
+    NTSTATUS - The return status for the operation
+
+--*/
+
+{
+    KEVENT Event;
+    PLIST_ENTRY Links;
+    PVCB Vcb;
+    PIRP NewIrp;
+    IO_STATUS_BLOCK Iosb;
+    BOOLEAN VcbPresent;
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+    //
+    //  Make sure we don't get any pop-ups.
+    //
+
+    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS );
+
+    //
+    //  Initialize an event for doing calls down to
+    //  our target device objects.
+    //
+
+    KeInitializeEvent( &Event, NotificationEvent, FALSE );
+
+    //
+    //  Indicate that shutdown has started.
+    //
+
+    SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN );
+
+    //
+    //  Get everyone else out of the way
+    //
+
+    CdAcquireCdData( IrpContext );
+
+    //
+    //  Now walk through all the mounted Vcb's and shutdown the target
+    //  device objects.
+    //
+
+    Links = CdData.VcbQueue.Flink;
+
+    while (Links != &CdData.VcbQueue) {
+
+        Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks );
+
+        //
+        //  Move to the next link now since the current Vcb may be deleted.
+        //
+
+        Links = Links->Flink;
+
+        //
+        //  If we have already been called before for this volume
+        //  (and yes this does happen), skip this volume as no writes
+        //  have been allowed since the first shutdown.
+        //
+
+        if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) ||
+            (Vcb->VcbCondition != VcbMounted)) {
+
+            continue;
+        }
+
+        CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
+
+        CdPurgeVolume( IrpContext, Vcb, FALSE );
+
+        //
+        //  Build an irp for this volume stack - our own irp is probably too small and
+        //  each stack may have a different stack size.
+        //
+
+        NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
+                                               Vcb->TargetDeviceObject,
+                                               NULL,
+                                               0,
+                                               NULL,
+                                               &Event,
+                                               &Iosb );
+
+        if (NewIrp != NULL) {
+
+            Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp );
+
+            if (Status == STATUS_PENDING) {
+
+                (VOID)KeWaitForSingleObject( &Event,
+                                             Executive,
+                                             KernelMode,
+                                             FALSE,
+                                             NULL );
+            }
+
+            KeClearEvent( &Event );
+        }
+
+        SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN );
+
+        //
+        //  Attempt to punch the volume down.
+        //
+
+        VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE );
+
+        if (VcbPresent) {
+
+            CdReleaseVcb( IrpContext, Vcb );
+        }
+    }
+
+
+    CdReleaseCdData( IrpContext );
+
+    IoUnregisterFileSystem( CdData.FileSystemDeviceObject );
+    IoDeleteDevice( CdData.FileSystemDeviceObject );
+
+    CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
+    return STATUS_SUCCESS;
+}
+
+
index 7ab3b2a..5f354ac 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -29,46 +29,46 @@ Abstract:
 //
 //  PFCB
 //  CdAllocateFcbData (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdDeallocateFcbData (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  PFCB
 //  CdAllocateFcbIndex (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdDeallocateFcbIndex (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB Fcb
 //      );
 //
 //  PFCB_NONPAGED
 //  CdAllocateFcbNonpaged (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdDeallocateFcbNonpaged (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB_NONPAGED FcbNonpaged
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PFCB_NONPAGED FcbNonpaged
 //      );
 //
 //  PCCB
 //  CdAllocateCcb (
-//      IN PIRP_CONTEXT IrpContext
+//      _In_ PIRP_CONTEXT IrpContext
 //      );
 //
 //  VOID
 //  CdDeallocateCcb (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PCCB Ccb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _Inout_ PCCB Ccb
 //      );
 //
 
@@ -114,14 +114,14 @@ typedef struct _FCB_TABLE_ELEMENT {
 //
 //  VOID
 //  CdInsertFcbTable (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PFCB Fcb
 //      );
 //
 //  VOID
 //  CdDeleteFcbTable (
-//      IN PIRP_CONTEXT IrpContext,
-//      IN PFCB Fcb
+//      _In_ PIRP_CONTEXT IrpContext,
+//      _In_ PFCB Fcb
 //      );
 //
 
@@ -148,44 +148,53 @@ typedef struct _FCB_TABLE_ELEMENT {
 
 VOID
 CdDeleteFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb
     );
 
 PFCB_NONPAGED
 CdCreateFcbNonpaged (
-    IN PIRP_CONTEXT IrpContext
+    _In_ PIRP_CONTEXT IrpContext
     );
 
 VOID
 CdDeleteFcbNonpaged (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB_NONPAGED FcbNonpaged
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB_NONPAGED FcbNonpaged
     );
 
+//  Inform prefast that this is a compare routine.
+RTL_GENERIC_COMPARE_ROUTINE CdFcbTableCompare;
+
 RTL_GENERIC_COMPARE_RESULTS
 CdFcbTableCompare (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN PVOID Fid1,
-    IN PVOID Fid2
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ PVOID Fid1,
+    _In_ PVOID Fid2
     );
 
+//  Inform prefast that this is an alloc reoutine.
+RTL_GENERIC_ALLOCATE_ROUTINE CdAllocateFcbTable;
+
 PVOID
 CdAllocateFcbTable (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN CLONG ByteSize
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ CLONG ByteSize
     );
 
+//  Inform prefast that this is a free reoutine.
+RTL_GENERIC_FREE_ROUTINE CdDeallocateFcbTable;
+
 VOID
 CdDeallocateFcbTable (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN PVOID Buffer
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer
     );
 
 ULONG
 CdTocSerial (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCDROM_TOC CdromToc
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCDROM_TOC_LARGE CdromToc
     );
 
 #ifdef ALLOC_PRAGMA
@@ -215,19 +224,28 @@ CdTocSerial (
 #pragma alloc_text(PAGE, CdUpdateVcbFromVolDescriptor)
 #endif
 
+//
+//  Some static names for volume streams
+//
+
+UNICODE_STRING CdInternalStreamNames[] = {
+        { 24, 24, L"$PATH_TABLE$"},
+        { 2,  2,  L"\\"}
+};
+
 \f
 VOID
 CdInitializeVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb,
-    IN PDEVICE_OBJECT TargetDeviceObject,
-    IN PVPB Vpb,
-    IN PCDROM_TOC CdromToc,
-    IN ULONG TocLength,
-    IN ULONG TocTrackCount,
-    IN ULONG TocDiskFlags,
-    IN ULONG BlockFactor,
-    IN ULONG MediaChangeCount
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_ __drv_aliasesMem  PDEVICE_OBJECT TargetDeviceObject,
+    _In_ __drv_aliasesMem PVPB Vpb,
+    _In_ __drv_aliasesMem PCDROM_TOC_LARGE CdromToc,
+    _In_ ULONG TocLength,
+    _In_ ULONG TocTrackCount,
+    _In_ ULONG TocDiskFlags,
+    _In_ ULONG BlockFactor,
+    _In_ ULONG MediaChangeCount
     )
 
 /*++
@@ -271,6 +289,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  We start by first zeroing out all of the VCB, this will guarantee
     //  that any stale data is wiped clean.
@@ -298,19 +318,19 @@ Return Value:
     //  uninitialize the notify structures before returning.
     //
     
-    _SEH2_TRY  {
+    try  {
 
-        Vcb->SwapVpb = FsRtlAllocatePoolWithTag( NonPagedPool,
+        Vcb->SwapVpb = FsRtlAllocatePoolWithTag( CdNonPagedPool,
                                                  sizeof( VPB ),
                                                  TAG_VPB );
     }
-    _SEH2_FINALLY {
+    finally {
 
-        if (_SEH2_AbnormalTermination())  {
+        if (AbnormalTermination())  {
         
             FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
         }
-    } _SEH2_END;
+    }
 
     //
     //  Nothing beyond this point should raise.
@@ -368,7 +388,7 @@ Return Value:
     CdUpdateVcbCondition( Vcb, VcbMountInProgress);
 
     //
-    //  Reference the Vcb for two reasons.  The first is a reference
+    //  Refererence the Vcb for two reasons.  The first is a reference
     //  that prevents the Vcb from going away on the last close unless
     //  dismount has already occurred.  The second is to make sure
     //  we don't go into the dismount path on any error during mount
@@ -411,9 +431,9 @@ Return Value:
 \f
 VOID
 CdUpdateVcbFromVolDescriptor (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb,
-    IN PCHAR RawIsoVd OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_reads_bytes_opt_(SECTOR_SIZE) PCHAR RawIsoVd
     )
 
 /*++
@@ -438,7 +458,6 @@ Return Value:
 --*/
 
 {
-    //ULONG Shift; /* ReactOS Change: GCC Unused variable */
     ULONG StartingBlock;
     ULONG ByteCount;
 
@@ -456,7 +475,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Copy the block size and compute the various block masks.
@@ -495,7 +514,7 @@ Return Value:
         if (ARGUMENT_PRESENT( RawIsoVd )) {
 
             //
-            //  Create the path table Fcb and reference it and the Vcb.
+            //  Create the path table Fcb and refererence it and the Vcb.
             //
 
             CdLockVcb( IrpContext, Vcb );
@@ -553,7 +572,7 @@ Return Value:
 
             SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED );
 
-            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb );
+            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb, &CdInternalStreamNames[0]);
 
             //
             //  Create the root index and reference it in the Vcb.
@@ -599,7 +618,7 @@ Return Value:
             //  Create the stream file for the root directory.
             //
 
-            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb );
+            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb, &CdInternalStreamNames[1] );
 
             //
             //  Now do the volume dasd Fcb.  Create this and reference it in the
@@ -686,7 +705,7 @@ Return Value:
             ULONG RootDirectorySize;
 
             //
-            //  Create the path table Fcb and reference it and the Vcb.
+            //  Create the path table Fcb and refererence it and the Vcb.
             //
 
             CdLockVcb( IrpContext, Vcb );
@@ -723,7 +742,7 @@ Return Value:
 
             SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED );
 
-            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb );
+            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb, &CdInternalStreamNames[0]);
 
             //
             //  Create the root index and reference it in the Vcb.
@@ -781,7 +800,7 @@ Return Value:
             //  Create the stream file for the root directory.
             //
 
-            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb );
+            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb, &CdInternalStreamNames[1] );
 
             //
             //  Now do the volume dasd Fcb.  Create this and reference it in the
@@ -843,17 +862,17 @@ Return Value:
             SetFlag( Vcb->VcbState, VCB_STATE_ISO );
         }
         
-    } _SEH2_FINALLY {
+    } finally {
 
         if (UnlockVcb) { CdUnlockVcb( IrpContext, Vcb ); }
-    } _SEH2_END;
+    }
 }
 
 \f
 VOID
 CdDeleteVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN OUT PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -862,7 +881,7 @@ Routine Description:
 
     This routine is called to delete a Vcb which failed mount or has been
     dismounted.  The dismount code should have already removed all of the
-    open Fcb's.  We do nothing here but clean up other auxiliary structures.
+    open Fcb's.  We do nothing here but clean up other auxilary structures.
 
 Arguments:
 
@@ -879,24 +898,20 @@ Return Value:
 
     ASSERT_EXCLUSIVE_CDDATA;
     ASSERT_EXCLUSIVE_VCB( Vcb );
-
+    
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Chuck the backpocket Vpb we kept just in case.
     //
 
-    if (Vcb->SwapVpb) {
-
-        CdFreePool( &Vcb->SwapVpb );
-    }
+    CdFreePool( &Vcb->SwapVpb );
     
     //
     //  If there is a Vpb then we must delete it ourselves.
     //
 
-    if (Vcb->Vpb != NULL) {
-
-        CdFreePool( &Vcb->Vpb );
-    }
+    CdFreePool( &Vcb->Vpb );
 
     //
     //  Dereference our target if we haven't already done so.
@@ -908,12 +923,18 @@ Return Value:
     }
 
     //
-    //  Delete the XA Sector if allocated.
+    //  Delete the XA Sector and sector cache buffer if allocated.
     //
 
-    if (Vcb->XASector != NULL) {
+    CdFreePool( &Vcb->XASector );
+    CdFreePool( &Vcb->SectorCacheBuffer);
+
+    if (Vcb->SectorCacheIrp != NULL) {
 
-        CdFreePool( &Vcb->XASector );
+        IoFreeIrp( Vcb->SectorCacheIrp);
+        Vcb->SectorCacheIrp = NULL;
+
+        ExDeleteResourceLite( &Vcb->SectorCacheResource);
     }
 
     //
@@ -933,10 +954,7 @@ Return Value:
     //  Delete the TOC if present.
     //
 
-    if (Vcb->CdromToc != NULL) {
-
-        CdFreePool( &Vcb->CdromToc );
-    }
+    CdFreePool( &Vcb->CdromToc );
 
     //
     //  Uninitialize the notify structures.
@@ -950,7 +968,7 @@ Return Value:
     //
     //  Now delete the volume device object.
     //
-
+#pragma prefast( suppress: __WARNING_BUFFER_UNDERFLOW, "This is ok, the Vcb is embedded in our volume device object, and that is what we are really deleting." )
     IoDeleteDevice( (PDEVICE_OBJECT) CONTAINING_RECORD( Vcb,
                                                         VOLUME_DEVICE_OBJECT,
                                                         Vcb ));
@@ -961,10 +979,10 @@ Return Value:
 \f
 PFCB
 CdCreateFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN FILE_ID FileId,
-    IN NODE_TYPE_CODE NodeTypeCode,
-    OUT PBOOLEAN FcbExisted OPTIONAL
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ FILE_ID FileId,
+    _In_ NODE_TYPE_CODE NodeTypeCode,
+    _Out_opt_ PBOOLEAN FcbExisted
     )
 
 /*++
@@ -1051,6 +1069,7 @@ Return Value:
 
         default:
 
+#pragma prefast( suppress: __WARNING_USE_OTHER_FUNCTION, "This is a bug." )   
             CdBugCheck( 0, 0, 0 );
         }
 
@@ -1091,6 +1110,12 @@ Return Value:
         ExInitializeFastMutex( &NewFcb->FcbNonpaged->AdvancedFcbHeaderMutex );
         FsRtlSetupAdvancedHeader( &NewFcb->Header, 
                                   &NewFcb->FcbNonpaged->AdvancedFcbHeaderMutex );
+
+        if (NodeTypeCode == CDFS_NTC_FCB_DATA) {
+
+            FsRtlInitializeOplock( CdGetFcbOplock(NewFcb) );
+        }
+
     } else {
 
         *FcbExisted = TRUE;
@@ -1102,10 +1127,10 @@ Return Value:
 \f
 VOID
 CdInitializeFcbFromPathEntry (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFCB ParentFcb OPTIONAL,
-    IN PPATH_ENTRY PathEntry
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_opt_ PFCB ParentFcb,
+    _In_ PPATH_ENTRY PathEntry
     )
 
 /*++
@@ -1167,8 +1192,7 @@ Return Value:
     //  State flags for this Fcb.
     //
 
-    SetFlag( Fcb->FileAttributes,
-             FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY );
+    SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY );
 
     //
     //  Link into the other in-memory structures and into the Fcb table.
@@ -1192,10 +1216,10 @@ Return Value:
 \f
 VOID
 CdInitializeFcbFromFileContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN PFCB ParentFcb,
-    IN PFILE_ENUM_CONTEXT FileContext
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ PFCB ParentFcb,
+    _In_ PFILE_ENUM_CONTEXT FileContext
     )
 
 /*++
@@ -1238,7 +1262,7 @@ Return Value:
 
     CdLockFcb( IrpContext, Fcb );
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Initialize the common header in the Fcb.  The node type is already
@@ -1361,10 +1385,10 @@ Return Value:
         CdInsertFcbTable( IrpContext, Fcb );
         SetFlag( Fcb->FcbState, FCB_STATE_IN_FCB_TABLE );
 
-    } _SEH2_FINALLY {
+    } finally {
 
         CdUnlockFcb( IrpContext, Fcb );
-    } _SEH2_END;
+    }
 
     return;
 }
@@ -1372,9 +1396,9 @@ Return Value:
 \f
 PCCB
 CdCreateCcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb,
-    IN ULONG Flags
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb,
+    _In_ ULONG Flags
     )
 
 /*++
@@ -1399,6 +1423,8 @@ Return Value:
     PCCB NewCcb;
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Allocate and initialize the structure.
     //
@@ -1427,8 +1453,8 @@ Return Value:
 \f
 VOID
 CdDeleteCcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCCB Ccb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ __drv_freesMem( Pool ) PCCB Ccb
     )
 /*++
 
@@ -1449,6 +1475,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     if (Ccb->SearchExpression.FileName.Buffer != NULL) {
 
         CdFreePool( &Ccb->SearchExpression.FileName.Buffer );
@@ -1459,11 +1487,13 @@ Return Value:
 }
 
 \f
+_When_(RaiseOnError || return, _At_(Fcb->FileLock, _Post_notnull_))
+_When_(RaiseOnError, _At_(IrpContext, _Pre_notnull_))
 BOOLEAN
 CdCreateFileLock (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PFCB Fcb,
-    IN BOOLEAN RaiseOnError
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB Fcb,
+    _In_ BOOLEAN RaiseOnError
     )
 
 /*++
@@ -1520,7 +1550,7 @@ Return Value:
          
         if (RaiseOnError) {
 
-            ASSERT( ARGUMENT_PRESENT( IrpContext ));
+            NT_ASSERT( ARGUMENT_PRESENT( IrpContext ));
 
             CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
         }
@@ -1532,10 +1562,10 @@ Return Value:
 }
 
 \f
-PIRP_CONTEXT
+_Ret_valid_ PIRP_CONTEXT
 CdCreateIrpContext (
-    IN PIRP Irp,
-    IN BOOLEAN Wait
+    _In_ PIRP Irp,
+    _In_ BOOLEAN Wait
     )
 
 /*++
@@ -1570,12 +1600,7 @@ Return Value:
     //  occur in the context of fileobjects (i.e., mount).
     //
 
-#ifndef __REACTOS__
     if (IrpSp->DeviceObject == CdData.FileSystemDeviceObject) {
-#else
-    if (IrpSp->DeviceObject == CdData.FileSystemDeviceObject ||
-        IrpSp->DeviceObject == CdData.HddFileSystemDeviceObject) {
-#endif
 
         if (IrpSp->FileObject != NULL &&
             IrpSp->MajorFunction != IRP_MJ_CREATE &&
@@ -1585,7 +1610,7 @@ Return Value:
             ExRaiseStatus( STATUS_INVALID_DEVICE_REQUEST );
         }
 
-        ASSERT( IrpSp->FileObject != NULL ||
+        NT_ASSERT( IrpSp->FileObject != NULL ||
                 
                 (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
                  IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST &&
@@ -1619,7 +1644,7 @@ Return Value:
         //  We didn't get it from our private list so allocate it from pool.
         //
 
-        NewIrpContext = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof( IRP_CONTEXT ), TAG_IRP_CONTEXT );
+        NewIrpContext = FsRtlAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT ), TAG_IRP_CONTEXT );
     }
 
     RtlZeroMemory( NewIrpContext, sizeof( IRP_CONTEXT ));
@@ -1653,12 +1678,7 @@ Return Value:
     //  the Vcb field.
     //
 
-#ifndef __REACTOS__
     if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject) {
-#else
-    if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject &&
-        IrpSp->DeviceObject != CdData.HddFileSystemDeviceObject) {
-#endif
 
         NewIrpContext->Vcb =  &((PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject)->Vcb;
     
@@ -1694,8 +1714,8 @@ Return Value:
 \f
 VOID
 CdCleanupIrpContext (
-    IN PIRP_CONTEXT IrpContext,
-    IN BOOLEAN Post
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ BOOLEAN Post
     )
 
 /*++
@@ -1704,7 +1724,7 @@ Routine Description:
 
     This routine is called to cleanup and possibly deallocate the Irp Context.
     If the request is being posted or this Irp Context is possibly on the
-    stack then we only cleanup any auxiliary structures.
+    stack then we only cleanup any auxilary structures.
 
 Arguments:
 
@@ -1800,8 +1820,8 @@ Return Value:
 \f
 VOID
 CdInitializeStackIrpContext (
-    OUT PIRP_CONTEXT IrpContext,
-    IN PIRP_CONTEXT_LITE IrpContextLite
+    _Out_ PIRP_CONTEXT IrpContext,
+    _In_ PIRP_CONTEXT_LITE IrpContextLite
     )
 
 /*++
@@ -1874,11 +1894,13 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 VOID
 CdTeardownStructures (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB StartingFcb,
-    OUT PBOOLEAN RemovedStartingFcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PFCB StartingFcb,
+    _Out_ PBOOLEAN RemovedStartingFcb
     )
 
 /*++
@@ -1937,7 +1959,7 @@ Return Value:
     //  Use a try-finally to safely clear the top-level field.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Loop until we find an Fcb we can't remove.
@@ -2041,7 +2063,7 @@ Return Value:
 
         } while (CurrentFcb != NULL);
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the current Fcb if we have acquired it.
@@ -2057,7 +2079,7 @@ Return Value:
         //
 
         ClearFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN );
-    } _SEH2_END;
+    }
 
     *RemovedStartingFcb = (CurrentFcb != StartingFcb);
     return;
@@ -2066,9 +2088,9 @@ Return Value:
 \f
 PFCB
 CdLookupFcbTable (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN FILE_ID FileId
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ FILE_ID FileId
     )
 
 /*++
@@ -2114,9 +2136,9 @@ Return Value:
 \f
 PFCB
 CdGetNextFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PVOID *RestartKey
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _In_ PVOID *RestartKey
     )
 
 /*++
@@ -2145,6 +2167,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     Fcb = (PFCB) RtlEnumerateGenericTableWithoutSplaying( &Vcb->FcbTable, RestartKey );
 
     if (Fcb != NULL) {
@@ -2158,12 +2182,12 @@ Return Value:
 \f
 NTSTATUS
 CdProcessToc (
-    IN PIRP_CONTEXT IrpContext,
-    IN PDEVICE_OBJECT TargetDeviceObject,
-    IN PCDROM_TOC CdromToc,
-    IN OUT PULONG Length,
-    OUT PULONG TrackCount,
-    OUT PULONG DiskFlags
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PDEVICE_OBJECT TargetDeviceObject,
+    _In_ PCDROM_TOC_LARGE CdromToc,
+    _Inout_ PULONG Length,
+    _Out_ PULONG TrackCount,
+    _Inout_ PULONG DiskFlags
     )
 
 /*++
@@ -2196,10 +2220,13 @@ Return Value:
 {
     NTSTATUS Status;
     IO_STATUS_BLOCK Iosb;
+    CDROM_READ_TOC_EX Command;
 
     ULONG CurrentTrack;
     ULONG LocalTrackCount;
     ULONG LocalTocLength;
+    ULONG Address = 0;
+    BOOLEAN UseReadToc = FALSE;
 
     union {
 
@@ -2212,24 +2239,47 @@ Return Value:
 
     PAGED_CODE();
 
+    //
+    //  Zero the command block.  This conveniently corresponds to an
+    //  LBA mode READ_TOC request.
+    //
+    
+    RtlZeroMemory( &Command, sizeof( Command));
+
+RetryReadToc:
+
     //
     //  Go ahead and read the table of contents
     //
 
-    Status = CdPerformDevIoCtrl( IrpContext,
-                                 IOCTL_CDROM_READ_TOC,
-                                 TargetDeviceObject,
-                                 CdromToc,
-                                 sizeof( CDROM_TOC ),
-                                 FALSE,
-                                 TRUE,
-                                 &Iosb );
+    Status = CdPerformDevIoCtrlEx( IrpContext,
+                                   UseReadToc ? IOCTL_CDROM_READ_TOC : IOCTL_CDROM_READ_TOC_EX,
+                                   TargetDeviceObject,
+                                   &Command,
+                                   sizeof( Command ),
+                                   CdromToc,
+                                   sizeof( CDROM_TOC_LARGE ),
+                                   FALSE,
+                                   TRUE,
+                                   &Iosb );
 
     //
     //  Nothing to process if this request fails.
     //
 
-    if (Status != STATUS_SUCCESS) {
+    if (!NT_SUCCESS( Status )) {
+
+        //
+        //  If the underlying device does not support READ_TOC_EX, try the old method.
+        //
+
+        if (!UseReadToc &&
+            ((Status == STATUS_INVALID_DEVICE_REQUEST) ||
+             (Status == STATUS_INVALID_PARAMETER))) {
+
+            UseReadToc = TRUE;
+            goto RetryReadToc;
+        }
 
         return Status;
     }
@@ -2290,21 +2340,13 @@ Return Value:
                 CdromToc->LastTrack -= 1;
 
                 //
-                //  Knock 2.5 minutes off the current track to
-                //  hide the final leadin.
+                //  Knock 2.5 minutes off the current track to hide the final leadin.
+                //  2.5 min = 150 sec = (x 75) 11250 frames (sectors).
                 //
-
-                Track->Address[1] -= 2;
-                Track->Address[2] += 30;
-
-                if (Track->Address[2] < 60) {
-
-                    Track->Address[1] -= 1;
-
-                } else {
-
-                    Track->Address[2] -= 60;
-                }
+                
+                SwapCopyUchar4( &Address, &Track->Address);
+                Address -= 11250;
+                SwapCopyUchar4( &Track->Address, &Address);
 
                 Track->TrackNumber = TOC_LAST_TRACK;
 
@@ -2362,8 +2404,8 @@ Return Value:
 
 VOID
 CdDeleteFcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB Fcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb
     )
 
 /*++
@@ -2371,12 +2413,12 @@ CdDeleteFcb (
 Routine Description:
 
     This routine is called to cleanup and deallocate an Fcb.  We know there
-    are no references remaining.  We cleanup any auxiliary structures and
+    are no references remaining.  We cleanup any auxilary structures and
     deallocate this Fcb.
 
 Arguments:
 
-    Fcb - This is the Fcb to deallocate.
+    Fcb - This is the Fcb to deallcoate.
 
 Return Value:
 
@@ -2392,8 +2434,8 @@ Return Value:
     //  Sanity check the counts.
     //
 
-    ASSERT( Fcb->FcbCleanup == 0 );
-    ASSERT( Fcb->FcbReference == 0 );
+    NT_ASSERT( Fcb->FcbCleanup == 0 );
+    NT_ASSERT( Fcb->FcbReference == 0 );
 
     //
     //  Release any Filter Context structures associated with this FCB
@@ -2437,8 +2479,8 @@ Return Value:
     case CDFS_NTC_FCB_PATH_TABLE:
     case CDFS_NTC_FCB_INDEX:
 
-        ASSERT( Fcb->FileObject == NULL );
-        ASSERT( IsListEmpty( &Fcb->FcbQueue ));
+        NT_ASSERT( Fcb->FileObject == NULL );
+        NT_ASSERT( IsListEmpty( &Fcb->FcbQueue ));
 
         if (Fcb == Fcb->Vcb->RootIndexFcb) {
 
@@ -2461,7 +2503,7 @@ Return Value:
             FsRtlFreeFileLock( Fcb->FileLock );
         }
 
-        FsRtlUninitializeOplock( &Fcb->Oplock );
+        FsRtlUninitializeOplock( CdGetFcbOplock(Fcb) );
 
         if (Fcb == Fcb->Vcb->VolumeDasdFcb) {
 
@@ -2479,8 +2521,8 @@ Return Value:
 
     if (Vcb != NULL) {
 
-        InterlockedDecrement( &Vcb->VcbReference );
-        InterlockedDecrement( &Vcb->VcbUserReference );
+        InterlockedDecrement( (LONG*)&Vcb->VcbReference );
+        InterlockedDecrement( (LONG*)&Vcb->VcbUserReference );
     }
 
     return;
@@ -2493,7 +2535,7 @@ Return Value:
 
 PFCB_NONPAGED
 CdCreateFcbNonpaged (
-    IN PIRP_CONTEXT IrpContext
+    _In_ PIRP_CONTEXT IrpContext
     )
 
 /*++
@@ -2515,7 +2557,9 @@ Return Value:
     PFCB_NONPAGED FcbNonpaged;
 
     PAGED_CODE();
-
+    
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Allocate the non-paged pool and initialize the various
     //  synchronization objects.
@@ -2544,8 +2588,8 @@ Return Value:
 
 VOID
 CdDeleteFcbNonpaged (
-    IN PIRP_CONTEXT IrpContext,
-    IN PFCB_NONPAGED FcbNonpaged
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB_NONPAGED FcbNonpaged
     )
 
 /*++
@@ -2566,7 +2610,9 @@ Return Value:
 
 {
     PAGED_CODE();
-
+    
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     ExDeleteResourceLite( &FcbNonpaged->FcbResource );
 
     CdDeallocateFcbNonpaged( IrpContext, FcbNonpaged );
@@ -2581,9 +2627,9 @@ Return Value:
 
 RTL_GENERIC_COMPARE_RESULTS
 CdFcbTableCompare (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN PVOID Fid1,
-    IN PVOID Fid2
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ PVOID Fid1,
+    _In_ PVOID Fid2
     )
 
 /*++
@@ -2638,8 +2684,8 @@ Return Value:
 
 PVOID
 CdAllocateFcbTable (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN CLONG ByteSize
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ CLONG ByteSize
     )
 
 /*++
@@ -2662,6 +2708,8 @@ Return Value:
 
 {
     PAGED_CODE();
+    
+    UNREFERENCED_PARAMETER( FcbTable );
 
     return( FsRtlAllocatePoolWithTag( CdPagedPool, ByteSize, TAG_FCB_TABLE ));
 }
@@ -2670,13 +2718,11 @@ Return Value:
 //
 //  Local support routine
 //
-
 VOID
 CdDeallocateFcbTable (
-    IN PRTL_GENERIC_TABLE FcbTable,
-    IN PVOID Buffer
+    _In_ PRTL_GENERIC_TABLE FcbTable,
+    _In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer
     )
-
 /*++
 
 Routine Description:
@@ -2710,8 +2756,8 @@ Return Value:
 
 ULONG
 CdTocSerial (
-    IN PIRP_CONTEXT IrpContext,
-    IN PCDROM_TOC CdromToc
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PCDROM_TOC_LARGE CdromToc
     )
 
 /*++
@@ -2741,9 +2787,13 @@ Return Value:
     ULONG SerialNumber = 0;
     PTRACK_DATA ThisTrack;
     PTRACK_DATA LastTrack;
+    ULONG Address;
+    ULONG MsfAddress = 0;   // satisfy PREFIX
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+    
     //
     //  Check if there are two tracks or fewer.
     //
@@ -2753,21 +2803,23 @@ Return Value:
 
     if (CdromToc->LastTrack - CdromToc->FirstTrack <= 1) {
 
-        SerialNumber = (((LastTrack->Address[1] * 60) + LastTrack->Address[2]) * 75) + LastTrack->Address[3];
-
-        SerialNumber -= (((ThisTrack->Address[1] * 60) + ThisTrack->Address[2]) * 75) + ThisTrack->Address[3];
+        SwapCopyUchar4( &Address, LastTrack->Address);
+        CdLbnToMmSsFf( Address, (PUCHAR)&SerialNumber);
     }
+    else {
 
-    //
-    //  Now find the starting offset of each track and add to the serial number.
-    //
-
-    while (ThisTrack != LastTrack) {
+        //
+        //  Add the starting offset of each track and add to the serial number.
+        //
 
-        SerialNumber += (ThisTrack->Address[1] << 16);
-        SerialNumber += (ThisTrack->Address[2] << 8);
-        SerialNumber += ThisTrack->Address[3];
-        ThisTrack += 1;
+        while (ThisTrack != LastTrack) {
+            
+            SwapCopyUchar4( &Address, ThisTrack->Address);
+            CdLbnToMmSsFf( Address, (PUCHAR)&MsfAddress);
+            
+            SerialNumber += MsfAddress;
+            ThisTrack += 1;
+        }
     }
 
     return SerialNumber;
index fc130d8..015b367 100755 (executable)
@@ -13,7 +13,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -26,12 +26,12 @@ Abstract:
 #pragma alloc_text(PAGE, CdVerifyVcb)
 #endif
 
-
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdPerformVerify (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp,
-    IN PDEVICE_OBJECT DeviceToVerify
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp,
+    _In_ PDEVICE_OBJECT DeviceToVerify
     )
 
 /*++
@@ -92,7 +92,7 @@ Return Value:
     Vcb = &CONTAINING_RECORD( IrpSp->DeviceObject,
                               VOLUME_DEVICE_OBJECT,
                               DeviceObject )->Vcb;
-    _SEH2_TRY {
+    try {
 
         //
         //  Send down the verify FSCTL.  Note that this is sent to the
@@ -206,26 +206,28 @@ Return Value:
             Status = CdFsdPostRequest( IrpContext, Irp );
         }
 
-    } _SEH2_EXCEPT(CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
+    } except(CdExceptionFilter( IrpContext, GetExceptionInformation() )) {
 
         //
         //  We had some trouble trying to perform the verify or raised
         //  an error ourselves.  So we'll abort the I/O request with
-        //  the error status that we get back from the exception code.
+        //  the error status that we get back from the execption code.
         //
 
-        Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
-    } _SEH2_END;
+        Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
+    }
 
     return Status;
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdCheckForDismount (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN BOOLEAN Force
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb,
+    _In_ BOOLEAN Force
     )
 
 /*++
@@ -345,14 +347,17 @@ Return Value:
 
         CdReleaseVcb( IrpContext, Vcb );
     }
+    else {
+        _Analysis_assume_lock_not_held_(Vcb->VcbResource);
+    }
 
     return VcbPresent;
 }
 
 
 BOOLEAN
-CdMarkDevForVerifyIfVcbMounted(
-    IN PVCB Vcb
+CdMarkDevForVerifyIfVcbMounted (
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -378,7 +383,8 @@ Return Value:
     KIRQL SavedIrql;
 
     IoAcquireVpbSpinLock( &SavedIrql );
-    
+
+#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
     if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb)  {
 
         CdMarkRealDevForVerify( Vcb->Vpb->RealDevice);
@@ -401,8 +407,8 @@ Return Value:
 
 VOID
 CdVerifyVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -431,7 +437,6 @@ Return Value:
     ULONG MediaChangeCount = 0;
     BOOLEAN ForceVerify = FALSE;
     BOOLEAN DevMarkedForVerify;
-    //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */
 
     PAGED_CODE();
 
@@ -444,17 +449,24 @@ Return Value:
         ((Vcb->VcbCondition == VcbDismountInProgress) && 
          (IrpContext->MajorFunction != IRP_MJ_CREATE))) {
 
-        CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+        if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
+
+            CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
+
+        } else {
+
+            CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+        }
     }
     
-    if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ))  {
-        
-        //
-        //  Capture the real device verify state.
-        //
+    //
+    //  Capture the real device verify state.
+    //
+    
+    DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice);
+    
+    if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ) && !DevMarkedForVerify) {
         
-        DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice);
-
         //
         //  If the media is removable and the verify volume flag in the
         //  device object is not set then we want to ping the device
@@ -534,7 +546,7 @@ Return Value:
         //  since they were directed at the 'drive',  not our volume.
         //
 
-        if (NT_SUCCESS( Status) && !ForceVerify && 
+        if (NT_SUCCESS( Status) && !ForceVerify && !DevMarkedForVerify &&
             (IrpContext->MajorFunction == IRP_MJ_CREATE))  {
 
             PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
@@ -548,18 +560,20 @@ Return Value:
             //  it would have been caught and set by the first set of checks.
             //
         }
+    }
 
-        //
-        //  Raise the verify / error if necessary.
-        //
-        
-        if (ForceVerify || !NT_SUCCESS( Status)) {
-
-            IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
-                                          Vcb->Vpb->RealDevice );
-           
-            CdRaiseStatus( IrpContext, ForceVerify ? STATUS_VERIFY_REQUIRED : Status);
-        }
+    //
+    //  Raise the verify / error if neccessary.
+    //
+    
+    if (ForceVerify || DevMarkedForVerify || !NT_SUCCESS( Status)) {
+    
+        IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
+                                      Vcb->Vpb->RealDevice );
+       
+        CdRaiseStatus( IrpContext, (ForceVerify || DevMarkedForVerify) 
+                                   ? STATUS_VERIFY_REQUIRED 
+                                   : Status);
     }
 
     //
@@ -577,21 +591,25 @@ Return Value:
         break;
 
     case VcbInvalid:
-    case VcbDismountInProgress :
+    case VcbDismountInProgress:
+
+        if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
+
+            CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
 
-        CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+        } else {
+
+            CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+        }
         break;
-        
-    /* ReactOS Change: GCC "enumeration value not handled in switch" */
-    default: break;
     }
 }
 
 
 BOOLEAN
 CdVerifyFcbOperation (
-    IN PIRP_CONTEXT IrpContext OPTIONAL,
-    IN PFCB Fcb
+    _In_opt_ PIRP_CONTEXT IrpContext,
+    _In_ PFCB Fcb
     )
 
 /*++
@@ -616,7 +634,6 @@ Return Value:
 --*/
 
 {
-    //NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Unused variable */
     PVCB Vcb = Fcb->Vcb;
     PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice;
     PIRP Irp;
@@ -668,7 +685,14 @@ Return Value:
 
         if (ARGUMENT_PRESENT( IrpContext )) {
 
-            CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+            if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
+
+                CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
+
+            } else {
+            
+                CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
+            }
         }
 
         return FALSE;
@@ -715,23 +739,22 @@ Return Value:
 
     } else if (Vcb->VcbCondition == VcbNotMounted) {
 
-        if (ARGUMENT_PRESENT( IrpContext )) {
-
-            IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
-            CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
-        }
+        IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
+        CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
 
-        return FALSE;
+//        return FALSE; // unreachable code
     }
 
     return TRUE;
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 BOOLEAN
 CdDismountVcb (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb
+    _In_ PIRP_CONTEXT IrpContext,
+    _Inout_ PVCB Vcb
     )
 
 /*++
@@ -772,7 +795,7 @@ Return Value:
     //  We should only take this path once.
     //
 
-    ASSERT( Vcb->VcbCondition != VcbDismountInProgress );
+    NT_ASSERT( Vcb->VcbCondition != VcbDismountInProgress );
 
     //
     //  Mark the Vcb as DismountInProgress.
@@ -858,6 +881,7 @@ Return Value:
     //  mount request.
     //
 
+#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
     if (OldVpb->RealDevice->Vpb == OldVpb) {
 
         //
@@ -868,13 +892,16 @@ Return Value:
 
         if (!FinalReference) {
 
-            ASSERT( Vcb->SwapVpb != NULL );
+            NT_ASSERT( Vcb->SwapVpb != NULL );
 
             Vcb->SwapVpb->Type = IO_TYPE_VPB;
             Vcb->SwapVpb->Size = sizeof( VPB );
-            Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
 
+#pragma prefast(push)
+#pragma prefast(disable: 28175, "this is a filesystem driver, touching the vpb is allowed")
+            Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
             Vcb->SwapVpb->RealDevice->Vpb = Vcb->SwapVpb;
+#pragma prefast(pop)
 
             Vcb->SwapVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING );
 
index b215fe0..6640fd8 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -26,36 +26,45 @@ Abstract:
 //  Local support routines
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryFsVolumeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_VOLUME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 NTSTATUS
 CdQueryFsSizeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_SIZE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_SIZE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 NTSTATUS
 CdQueryFsDeviceInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_DEVICE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 NTSTATUS
 CdQueryFsAttributeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
+    _Inout_ PULONG Length
+    );
+
+NTSTATUS
+CdQueryFsSectorSizeInfo (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     );
 
 #ifdef ALLOC_PRAGMA
@@ -64,13 +73,15 @@ CdQueryFsAttributeInfo (
 #pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
 #pragma alloc_text(PAGE, CdQueryFsSizeInfo)
 #pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
+#pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
 #endif
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdCommonQueryVolInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -130,7 +141,7 @@ Return Value:
     //  Use a try-finally to facilitate cleanup.
     //
 
-    _SEH2_TRY {
+    try {
 
         //
         //  Verify the Vcb.
@@ -166,25 +177,29 @@ Return Value:
 
             Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
             break;
-                
-        /* ReactOS Change: GCC "enumeration value not handled in switch" */
-        default: break;
+
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+        case FileFsSectorSizeInformation:
+
+            Status = CdQueryFsSectorSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
+            break;
+#endif
         }
-        
+
         //
         //  Set the information field to the number of bytes actually filled in
         //
 
         Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
 
-    } _SEH2_FINALLY {
+    } finally {
 
         //
         //  Release the Vcb.
         //
 
         CdReleaseVcb( IrpContext, Fcb->Vcb );
-    } _SEH2_END;
+    }
 
     //
     //  Complete the request if we didn't raise.
@@ -200,12 +215,13 @@ Return Value:
 //  Local support routine
 //
 
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdQueryFsVolumeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_VOLUME_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -222,7 +238,7 @@ Arguments:
         is to be returned
 
     Length - Supplies the length of the buffer in byte.  This variable
-        upon return receives the remaining bytes free in the buffer
+        upon return recieves the remaining bytes free in the buffer
 
 Return Value:
 
@@ -237,6 +253,8 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Fill in the data from the Vcb.
     //
@@ -292,10 +310,10 @@ Return Value:
 
 NTSTATUS
 CdQueryFsSizeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_SIZE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_SIZE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -312,7 +330,7 @@ Arguments:
         is to be returned
 
     Length - Supplies the length of the buffer in byte.  This variable
-        upon return receives the remaining bytes free in the buffer
+        upon return recieves the remaining bytes free in the buffer
 
 Return Value:
 
@@ -323,6 +341,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Fill in the output buffer.
     //
@@ -353,10 +373,10 @@ Return Value:
 
 NTSTATUS
 CdQueryFsDeviceInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_DEVICE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -373,7 +393,7 @@ Arguments:
         is to be returned
 
     Length - Supplies the length of the buffer in byte.  This variable
-        upon return receives the remaining bytes free in the buffer
+        upon return recieves the remaining bytes free in the buffer
 
 Return Value:
 
@@ -384,6 +404,8 @@ Return Value:
 {
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( IrpContext );
+
     //
     //  Update the output buffer.
     //
@@ -411,10 +433,10 @@ Return Value:
 
 NTSTATUS
 CdQueryFsAttributeInfo (
-    IN PIRP_CONTEXT IrpContext,
-    IN PVCB Vcb,
-    IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
-    IN OUT PULONG Length
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
+    _Inout_ PULONG Length
     )
 
 /*++
@@ -431,7 +453,7 @@ Arguments:
         is to be returned
 
     Length - Supplies the length of the buffer in byte.  This variable
-        upon return receives the remaining bytes free in the buffer
+        upon return recieves the remaining bytes free in the buffer
 
 Return Value:
 
@@ -446,12 +468,15 @@ Return Value:
 
     PAGED_CODE();
 
+    UNREFERENCED_PARAMETER( Vcb );
+
     //
     //  Fill out the fixed portion of the buffer.
     //
 
     Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
-                                  FILE_READ_ONLY_VOLUME;
+                                   FILE_READ_ONLY_VOLUME |
+                                   FILE_SUPPORTS_OPEN_BY_FILE_ID;
 
     if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
 
@@ -503,3 +528,71 @@ Return Value:
     return Status;
 }
 
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+
+NTSTATUS
+CdQueryFsSectorSizeInfo (
+    _In_ PIRP_CONTEXT IrpContext,
+    _In_ PVCB Vcb,
+    _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
+    _Inout_ PULONG Length
+    )
+
+/*++
+
+Routine Description:
+
+    This routine implements the query sector size information call
+    This operation will work on any handle and requires no privilege.
+
+Arguments:
+
+    Vcb - Supplies the Vcb being queried
+
+    Buffer - Supplies a pointer to the output buffer where the information
+        is to be returned
+
+    Length - Supplies the length of the buffer in byte.  This variable
+        upon return receives the remaining bytes free in the buffer
+
+Return Value:
+
+    NTSTATUS - Returns the status for the query
+
+--*/
+
+{
+    NTSTATUS Status;
+
+    PAGED_CODE();
+    UNREFERENCED_PARAMETER( IrpContext );
+
+    //
+    //  Sufficient buffer size is guaranteed by the I/O manager or the
+    //  originating kernel mode driver.
+    //
+
+    ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
+    _Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
+
+    //
+    //  Retrieve the sector size information
+    //
+
+    Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
+                                            Buffer );
+
+    //
+    //  Adjust the length variable
+    //
+
+    if (NT_SUCCESS( Status )) {
+
+        *Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
+    }
+
+    return Status;
+}
+
+#endif
+
index f242c8c..ee54882 100755 (executable)
@@ -14,7 +14,7 @@ Abstract:
 
 --*/
 
-#include "cdprocs.h"
+#include "CdProcs.h"
 
 //
 //  The Bug check file id for this module
@@ -35,8 +35,8 @@ Abstract:
 
 VOID
 CdAddToWorkque (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     );
 
 #ifdef ALLOC_PRAGMA
@@ -46,10 +46,11 @@ CdAddToWorkque (
 #endif
 
 \f
+_Requires_lock_held_(_Global_critical_region_)
 NTSTATUS
 CdFsdPostRequest (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -96,18 +97,19 @@ Return Value:
 }
 
 \f
+    
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdPrePostIrp (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
 
 Routine Description:
 
-    This routine performs any necessary work before STATUS_PENDING is
+    This routine performs any neccessary work before STATUS_PENDING is
     returned with the Fsd thread.  This routine is called within the
     filesystem and by the oplock package.
 
@@ -155,6 +157,7 @@ Return Value:
 
             if (!RemovedFcb) {
 
+                _Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
                 CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
             }
 
@@ -165,7 +168,7 @@ Return Value:
         break;
 
     //
-    //  We need to lock the user's buffer, unless this is an MDL-read,
+    //  We need to lock the user's buffer, unless this is an MDL read/write,
     //  in which case there is no user buffer.
     //
 
@@ -173,7 +176,16 @@ Return Value:
 
         if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
 
-            CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length );
+            CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoWriteAccess );
+        }
+
+        break;
+
+    case IRP_MJ_WRITE :
+
+        if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
+
+            CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoReadAccess );
         }
 
         break;
@@ -186,7 +198,7 @@ Return Value:
 
         if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
 
-            CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length );
+            CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length, IoWriteAccess );
         }
 
         break;
@@ -209,11 +221,12 @@ Return Value:
 }
 
 \f
+
+_Requires_lock_held_(_Global_critical_region_)
 VOID
-NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
 CdOplockComplete (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
@@ -272,6 +285,7 @@ Return Value:
 
                 if (!RemovedFcb) {
 
+                    _Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
                     CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
                 }
 
@@ -307,15 +321,15 @@ Return Value:
 
 VOID
 CdAddToWorkque (
-    IN PIRP_CONTEXT IrpContext,
-    IN PIRP Irp
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
     )
 
 /*++
 
 Routine Description:
 
-    This routine is called to actually store the posted Irp to the Fsp
+    This routine is called to acually store the posted Irp to the Fsp
     workque.
 
 Arguments:
@@ -387,10 +401,12 @@ Return Value:
     //  Send it off.....
     //
 
+#pragma prefast(suppress:28155, "the function prototype is correct")
     ExInitializeWorkItem( &IrpContext->WorkQueueItem,
-                          (PVOID)CdFspDispatch,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
+                          CdFspDispatch,
                           IrpContext );
 
+#pragma prefast(suppress: 28159, "prefast believes this routine is obsolete, but it is ok for CDFS to continue using it")
     ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue );
 
     return;
diff --git a/drivers/filesystems/cdfs_new/write.c b/drivers/filesystems/cdfs_new/write.c
new file mode 100644 (file)
index 0000000..36a41a7
--- /dev/null
@@ -0,0 +1,381 @@
+/*++
+
+Copyright (c) 1989-2000 Microsoft Corporation
+
+Module Name:
+
+    Write.c
+
+Abstract:
+
+    This module implements the File Write routine for Write called by the
+    Fsd/Fsp dispatch drivers.
+
+
+--*/
+
+#include "CdProcs.h"
+
+//
+//  The Bug check file id for this module
+//
+
+#define BugCheckFileId                   (CDFS_BUG_CHECK_WRITE)
+
+//
+//  VOID
+//  SafeZeroMemory (
+//      _Out_ PUCHAR At,
+//      _In_ ULONG ByteCount
+//      );
+//
+
+//
+//  This macro just puts a nice little try-except around RtlZeroMemory
+//
+
+#define SafeZeroMemory(IC,AT,BYTE_COUNT) {                  \
+    try {                                                   \
+        RtlZeroMemory( (AT), (BYTE_COUNT) );                \
+__pragma(warning(suppress: 6320))                           \
+    } except( EXCEPTION_EXECUTE_HANDLER ) {                 \
+         CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER );   \
+    }                                                       \
+}
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, CdCommonWrite)
+#endif
+
+\f
+_Requires_lock_held_(_Global_critical_region_)
+NTSTATUS
+CdCommonWrite (
+    _Inout_ PIRP_CONTEXT IrpContext,
+    _Inout_ PIRP Irp
+    )
+
+/*++
+
+Routine Description:
+
+    This is the common entry point for NtWriteFile calls.  For synchronous requests,
+    CommonWrite will complete the request in the current thread.  If not
+    synchronous the request will be passed to the Fsp if there is a need to
+    block.
+
+Arguments:
+
+    Irp - Supplies the Irp to process
+
+Return Value:
+
+    NTSTATUS - The result of this operation.
+
+--*/
+
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
+
+    TYPE_OF_OPEN TypeOfOpen;
+    PFCB Fcb;
+    PCCB Ccb;
+
+    BOOLEAN Wait;
+    ULONG SynchronousIo;
+    PVOID UserBuffer;
+
+    LONGLONG StartingOffset;
+    LONGLONG ByteRange;
+    ULONG ByteCount;
+    ULONG WriteByteCount;
+    ULONG OriginalByteCount;
+
+    BOOLEAN ReleaseFile = TRUE;
+
+    CD_IO_CONTEXT LocalIoContext;
+
+    PAGED_CODE();
+
+    //
+    //  If this is a zero length write then return SUCCESS immediately.
+    //
+
+    if (IrpSp->Parameters.Write.Length == 0) {
+
+        CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
+        return STATUS_SUCCESS;
+    }
+
+    //
+    //  Decode the file object and verify we support write on this.  It
+    //  must be a volume file.
+    //
+
+    TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
+
+    // Internal lock object is acquired if return status is STATUS_PENDING
+    _Analysis_suppress_lock_checking_(Fcb->Resource);
+
+    if (TypeOfOpen != UserVolumeOpen) {
+
+        CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
+        return STATUS_INVALID_DEVICE_REQUEST;
+    }
+
+    //
+    //  Examine our input parameters to determine if this is noncached and/or
+    //  a paging io operation.
+    //
+
+    Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
+    SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO );
+
+
+    //
+    //  Extract the range of the Io.
+    //
+
+    StartingOffset = IrpSp->Parameters.Write.ByteOffset.QuadPart;
+    OriginalByteCount = ByteCount = IrpSp->Parameters.Write.Length;
+
+    ByteRange = StartingOffset + ByteCount;
+
+    //
+    //  Acquire the file shared to perform the write.
+    //
+
+    CdAcquireFileShared( IrpContext, Fcb );
+
+    //
+    //  Use a try-finally to facilitate cleanup.
+    //
+
+    try {
+
+        //
+        //  Verify the Fcb.  Allow writes if this is a DASD handle that is 
+        //  dismounting the volume.
+        //
+
+        if (!FlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE ))  {
+
+            CdVerifyFcbOperation( IrpContext, Fcb );
+        }
+
+        if (!FlagOn( Ccb->Flags, CCB_FLAG_ALLOW_EXTENDED_DASD_IO )) {
+
+            //
+            //  Complete the request if it begins beyond the end of file.
+            //
+
+            if (StartingOffset >= Fcb->FileSize.QuadPart) {
+
+                try_return( Status = STATUS_END_OF_FILE );
+            }
+
+            //
+            //  Truncate the write if it extends beyond the end of the file.
+            //
+
+            if (ByteRange > Fcb->FileSize.QuadPart) {
+
+                ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
+                ByteRange = Fcb->FileSize.QuadPart;
+            }
+        }
+
+        //
+        //  If we have an unaligned transfer then post this request if
+        //  we can't wait.  Unaligned means that the starting offset
+        //  is not on a sector boundary or the write is not integral
+        //  sectors.
+        //
+
+        WriteByteCount = BlockAlign( Fcb->Vcb, ByteCount );
+
+        if (SectorOffset( StartingOffset ) ||
+            SectorOffset( WriteByteCount ) ||
+            (WriteByteCount > OriginalByteCount)) {
+
+            if (!Wait) {
+
+                CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
+            }
+
+            //
+            //  Make sure we don't overwrite the buffer.
+            //
+
+            WriteByteCount = ByteCount;
+        }
+
+        //
+        //  Initialize the IoContext for the write.
+        //  If there is a context pointer, we need to make sure it was
+        //  allocated and not a stale stack pointer.
+        //
+
+        if (IrpContext->IoContext == NULL ||
+            !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {
+
+            //
+            //  If we can wait, use the context on the stack.  Otherwise
+            //  we need to allocate one.
+            //
+
+            if (Wait) {
+
+                IrpContext->IoContext = &LocalIoContext;
+                ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
+
+            } else {
+
+                IrpContext->IoContext = CdAllocateIoContext();
+                SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
+            }
+        }
+
+        RtlZeroMemory( IrpContext->IoContext, sizeof( CD_IO_CONTEXT ) );
+
+        //
+        //  Store whether we allocated this context structure in the structure
+        //  itself.
+        //
+
+        IrpContext->IoContext->AllocatedContext =
+            BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
+
+        if (Wait) {
+
+            KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
+                               NotificationEvent,
+                               FALSE );
+
+        } else {
+
+            IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread();
+            IrpContext->IoContext->Resource = Fcb->Resource;
+            IrpContext->IoContext->RequestedByteCount = ByteCount;
+        }
+
+        Irp->IoStatus.Information = WriteByteCount;
+
+        //
+        //  Set the FO_MODIFIED flag here to trigger a verify when this
+        //  handle is closed.  Note that we can err on the conservative
+        //  side with no problem, i.e. if we accidently do an extra
+        //  verify there is no problem.
+        //
+
+        SetFlag( IrpSp->FileObject->Flags, FO_FILE_MODIFIED );
+
+        //
+        //  Dasd access is always non-cached. Call the Dasd write routine to
+        //  perform the actual write.
+        //
+
+        Status = CdVolumeDasdWrite( IrpContext, Fcb, StartingOffset, WriteByteCount );
+
+        //
+        //  Don't complete this request now if STATUS_PENDING was returned.
+        //
+
+        if (Status == STATUS_PENDING) {
+
+            Irp = NULL;
+            ReleaseFile = FALSE;
+
+        //
+        //  Test is we should zero part of the buffer or update the
+        //  synchronous file position.
+        //
+
+        } else {
+
+            //
+            //  Convert any unknown error code to IO_ERROR.
+            //
+
+            if (!NT_SUCCESS( Status )) {
+
+                //
+                //  Set the information field to zero.
+                //
+
+                Irp->IoStatus.Information = 0;
+
+                //
+                //  Raise if this is a user induced error.
+                //
+
+                if (IoIsErrorUserInduced( Status )) {
+
+                    CdRaiseStatus( IrpContext, Status );
+                }
+
+                Status = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR );
+
+            //
+            //  Check if there is any portion of the user's buffer to zero.
+            //
+
+            } else if (WriteByteCount != ByteCount) {
+
+                CdMapUserBuffer( IrpContext, &UserBuffer );
+                
+                SafeZeroMemory( IrpContext,
+                                Add2Ptr( UserBuffer,
+                                         ByteCount,
+                                         PVOID ),
+                                WriteByteCount - ByteCount );
+
+                Irp->IoStatus.Information = ByteCount;
+            }
+
+            //
+            //  Update the file position if this is a synchronous request.
+            //
+
+            if (SynchronousIo && NT_SUCCESS( Status )) {
+
+                IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
+            }
+        }
+
+    try_exit:  NOTHING;
+    } finally {
+
+        //
+        //  Release the Fcb.
+        //
+
+        if (ReleaseFile) {
+
+            CdReleaseFile( IrpContext, Fcb );
+        }
+    }
+
+    //
+    //  Post the request if we got CANT_WAIT.
+    //
+
+    if (Status == STATUS_CANT_WAIT) {
+
+        Status = CdFsdPostRequest( IrpContext, Irp );
+
+    //
+    //  Otherwise complete the request.
+    //
+
+    } else {
+
+        CdCompleteRequest( IrpContext, Irp, Status );
+    }
+
+    return Status;
+}
+
+