[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.
     //
diff --g