[CDFS_NEW] Replace old driver with a Ms-PL licensed version straight out of the driver samples github repository.

This commit is contained in:
David Quintana 2017-11-23 21:02:16 +01:00 committed by Pierre Schweitzer
parent 87d276f05d
commit fd34548263
38 changed files with 5298 additions and 2802 deletions

View 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)

View file

@ -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.

View file

@ -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
_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:
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:
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:
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:
}
_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:
}
_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:
//
// 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 );
//

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -36,9 +36,10 @@ Abstract:
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:
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;
}
NTSTATUS
CdCompleteMdl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -434,11 +459,13 @@ Return Value:
}
_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 );
}

View file

@ -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
// );
//

View file

@ -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
_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:
}
_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:
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:
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;
}
_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:
ULONG
CdSerial32 (
IN PCHAR Buffer,
IN ULONG ByteCount
_In_reads_bytes_(ByteCount) PCHAR Buffer,
_In_ ULONG ByteCount
)
/*++

View file

@ -94,82 +94,77 @@ extern LONG CdXAFileHeader[];
extern LONG CdAudioPlayHeader[];
extern LONG CdXAAudioPhileHeader[];
#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
//
// 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

View 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>

View file

@ -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.
//
#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.")
RtlInitUnicodeString( &UnicodeString, L"\\CdfsHdd" );
Status = IoCreateDevice( DriverObject,
0,
&UnicodeString,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&HddFileSystemDeviceObject );
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,15 +184,17 @@ 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);
#ifdef CDFS_TELEMETRY_DATA
//
// Initialize Telemetry
//
CdInitializeTelemetry();
#endif
//
@ -217,51 +204,10 @@ Return Value:
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.
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
CdCompleteRequest( NULL, Irp, 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
}
//
@ -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;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
#include "cdprocs.h"

View file

@ -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;
#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)
//
@ -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;
//
// 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;
//
// 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_

View file

@ -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;
}
}
//

View file

@ -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);
}
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
)
/*++

View file

@ -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
_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)
}
@ -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) {

View file

@ -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 (
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
)
{

File diff suppressed because it is too large Load diff

View file

@ -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
_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) {

View file

@ -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 (
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:
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;
}
_At_(Dirent->CdTime, _Post_notnull_)
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:
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:
}
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:
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:
}
_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:
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:
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:
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.
//

View file

@ -1,4 +1,4 @@
#include "cdprocs.h"
#include "CdProcs.h"
#include <stdio.h>
#define doit(a,b) { printf("%s %04lx %4lx %s\n", #a, FIELD_OFFSET(a,b), sizeof(d.b), #b); }
@ -127,7 +127,6 @@ main (argc, argv)
printf("\n");
{
FCB_DATA d;
doit( FCB_DATA, Oplock );
doit( FCB_DATA, FileLock );
}
printf("\n");
@ -475,4 +474,3 @@ main (argc, argv)
doit( SYSTEM_USE_XA, Reserved );
}
}

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -28,67 +28,68 @@ Abstract:
VOID
CdQueryBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_BASIC_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_BASIC_INFORMATION Buffer,
_Inout_ PULONG Length
);
VOID
CdQueryStandardInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_STANDARD_INFORMATION Buffer,
_Inout_ PULONG Length
);
VOID
CdQueryInternalInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_INTERNAL_INFORMATION Buffer,
_Inout_ PULONG Length
);
VOID
CdQueryEaInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_EA_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_EA_INFORMATION Buffer,
_Inout_ PULONG Length
);
VOID
CdQueryPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_POSITION_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFILE_OBJECT FileObject,
_Out_ PFILE_POSITION_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFILE_OBJECT FileObject,
_Out_ PFILE_NAME_INFORMATION Buffer,
_Inout_ PULONG Length
);
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryAlternateNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCCB Ccb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_In_ PCCB Ccb,
_Out_ PFILE_NAME_INFORMATION Buffer,
_Inout_ PULONG Length
);
VOID
CdQueryNetworkInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
_Inout_ PULONG Length
);
#ifdef ALLOC_PRAGMA
@ -108,10 +109,11 @@ CdQueryNetworkInfo (
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonQueryInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -165,7 +167,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// We only support query on file and directory handles.
@ -191,8 +193,8 @@ Return Value:
if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) {
ASSERT( TypeOfOpen == UserDirectoryOpen );
CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
NT_ASSERT( TypeOfOpen == UserDirectoryOpen );
CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
}
//
@ -325,7 +327,7 @@ Return Value:
Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
} _SEH2_FINALLY {
} finally {
//
// Release the file.
@ -335,7 +337,7 @@ Return Value:
CdReleaseFile( IrpContext, Fcb );
}
} _SEH2_END;
}
//
// Complete the request if we didn't raise.
@ -347,10 +349,11 @@ Return Value:
}
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonSetInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -406,7 +409,7 @@ Return Value:
CdAcquireFileShared( IrpContext, Fcb );
_SEH2_TRY {
try {
//
// Make sure the Fcb is in a usable condition. This
@ -445,10 +448,10 @@ Return Value:
Status = STATUS_SUCCESS;
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
CdReleaseFile( IrpContext, Fcb );
} _SEH2_END;
}
//
// Complete the request if there was no raise.
@ -458,15 +461,17 @@ Return Value:
return Status;
}
_Function_class_(FAST_IO_QUERY_BASIC_INFO)
_IRQL_requires_same_
_Success_(return != FALSE)
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastQueryBasicInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_BASIC_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -500,6 +505,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
ASSERT_FILE_OBJECT( FileObject );
FsRtlEnterFileSystem();
@ -536,7 +543,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// Only deal with 'good' Fcb's.
@ -566,25 +573,27 @@ Return Value:
Result = TRUE;
}
} _SEH2_FINALLY {
} finally {
ExReleaseResourceLite( Fcb->Resource );
FsRtlExitFileSystem();
} _SEH2_END;
}
return Result;
}
_Function_class_(FAST_IO_QUERY_STANDARD_INFO)
_IRQL_requires_same_
_Success_(return != FALSE)
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastQueryStdInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_STANDARD_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -618,6 +627,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
ASSERT_FILE_OBJECT( FileObject );
FsRtlEnterFileSystem();
@ -654,7 +665,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// Only deal with 'good' Fcb's.
@ -694,25 +705,27 @@ Return Value:
Result = TRUE;
}
} _SEH2_FINALLY {
} finally {
ExReleaseResourceLite( Fcb->Resource );
FsRtlExitFileSystem();
} _SEH2_END;
}
return Result;
}
_Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO)
_IRQL_requires_same_
_Success_(return != FALSE)
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastQueryNetworkInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -746,6 +759,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
ASSERT_FILE_OBJECT( FileObject );
FsRtlEnterFileSystem();
@ -782,7 +797,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// Only deal with 'good' Fcb's.
@ -827,12 +842,12 @@ Return Value:
Result = TRUE;
}
} _SEH2_FINALLY {
} finally {
ExReleaseResourceLite( Fcb->Resource );
FsRtlExitFileSystem();
} _SEH2_END;
}
return Result;
}
@ -844,10 +859,10 @@ Return Value:
VOID
CdQueryBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_BASIC_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_BASIC_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -875,6 +890,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// We only support creation, last modify and last write times on Cdfs.
//
@ -903,10 +920,10 @@ Return Value:
VOID
CdQueryStandardInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_STANDARD_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -933,6 +950,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// There is only one link and delete is never pending on a Cdrom file.
//
@ -976,10 +995,10 @@ Return Value:
VOID
CdQueryInternalInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_INTERNAL_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1007,6 +1026,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Index number is the file Id number in the Fcb.
//
@ -1024,10 +1045,10 @@ Return Value:
VOID
CdQueryEaInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_EA_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_EA_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1055,6 +1076,9 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
UNREFERENCED_PARAMETER( Fcb );
//
// No Ea's on Cdfs volumes.
//
@ -1072,10 +1096,10 @@ Return Value:
VOID
CdQueryPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_POSITION_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFILE_OBJECT FileObject,
_Out_ PFILE_POSITION_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1103,6 +1127,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Get the current position found in the file object.
//
@ -1125,10 +1151,10 @@ Return Value:
NTSTATUS
CdQueryNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFILE_OBJECT FileObject,
_Out_ PFILE_NAME_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1159,7 +1185,9 @@ Return Value:
PAGED_CODE();
ASSERT(*Length >= sizeof(ULONG));
UNREFERENCED_PARAMETER( IrpContext );
NT_ASSERT(*Length >= sizeof(ULONG));
//
// Simply copy the name in the file object to the user's buffer.
@ -1197,13 +1225,14 @@ Return Value:
// Local support routine
//
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryAlternateNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCCB Ccb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_In_ PCCB Ccb,
_Out_ PFILE_NAME_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1237,16 +1266,16 @@ Return Value:
{
NTSTATUS Status = STATUS_SUCCESS;
DIRENT_ENUM_CONTEXT DirContext;
DIRENT Dirent;
DIRENT_ENUM_CONTEXT DirContext = {0};
DIRENT Dirent = {0};
PUNICODE_STRING NameToUse;
ULONG DirentOffset;
COMPOUND_PATH_ENTRY CompoundPathEntry;
COMPOUND_PATH_ENTRY CompoundPathEntry = {0};
FILE_ENUM_CONTEXT FileContext;
PFCB ParentFcb;
PFCB ParentFcb = NULL;
BOOLEAN ReleaseParentFcb = FALSE;
BOOLEAN CleanupFileLookup = FALSE;
@ -1278,20 +1307,13 @@ Return Value:
// Use a try-finally to cleanup the structures.
//
_SEH2_TRY {
try {
ParentFcb = Fcb->ParentFcb;
CdAcquireFileShared( IrpContext, ParentFcb );
ReleaseParentFcb = TRUE;
//
// Do an unsafe test to see if we need to create a file object.
//
if (ParentFcb->FileObject == NULL) {
CdCreateInternalStream( IrpContext, ParentFcb->Vcb, ParentFcb );
}
CdVerifyOrCreateDirStreamFile( IrpContext, ParentFcb);
if (CdFidIsDirectory( Fcb->FileId)) {
@ -1396,7 +1418,7 @@ Return Value:
RtlCopyMemory( Buffer->FileName, ShortNameBuffer, Buffer->FileNameLength );
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
if (CleanupFileLookup) {
@ -1413,7 +1435,7 @@ Return Value:
CdReleaseFile( IrpContext, ParentFcb );
}
} _SEH2_END;
}
//
// Reduce the available bytes by the amount stored into this buffer.
@ -1434,10 +1456,10 @@ Return Value:
VOID
CdQueryNetworkInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -1465,6 +1487,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// We only support creation, last modify and last write times on Cdfs.
//

View file

@ -13,7 +13,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -33,14 +33,16 @@ Abstract:
#pragma alloc_text(PAGE, CdSetFileObject)
#endif
_When_(TypeOfOpen == UnopenedFileObject, _At_(Fcb, _In_opt_))
_When_(TypeOfOpen != UnopenedFileObject, _At_(Fcb, _In_))
VOID
CdSetFileObject (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN TYPE_OF_OPEN TypeOfOpen,
IN PFCB Fcb OPTIONAL,
IN PCCB Ccb OPTIONAL
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PFILE_OBJECT FileObject,
_In_ TYPE_OF_OPEN TypeOfOpen,
PFCB Fcb,
_In_opt_ PCCB Ccb
)
/*++
@ -70,12 +72,14 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// We only have values 0 to 7 available so make sure we didn't
// inadvertantly add a new type.
//
ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 );
NT_ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 );
//
// Setting a file object to type UnopenedFileObject means just
@ -94,7 +98,7 @@ Return Value:
// Check that the 3 low-order bits of the Ccb are clear.
//
ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK ));
NT_ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK ));
//
// We will or the type of open into the low order bits of FsContext2
@ -105,7 +109,8 @@ Return Value:
FileObject->FsContext = Fcb;
FileObject->FsContext2 = Ccb;
SetFlag( (*(PULONG_PTR)&FileObject->FsContext2), TypeOfOpen ); /* ReactOS Change: GCC "invalid lvalue in assignment" */
#pragma warning( suppress: 4213 )
SetFlag( ((ULONG_PTR) FileObject->FsContext2), TypeOfOpen );
//
// Set the Vpb field in the file object.
@ -117,13 +122,16 @@ Return Value:
}
_When_(return == UnopenedFileObject, _At_(*Fcb, _Post_null_))
_When_(return != UnopenedFileObject, _At_(Fcb, _Outptr_))
_When_(return == UnopenedFileObject, _At_(*Ccb, _Post_null_))
_When_(return != UnopenedFileObject, _At_(Ccb, _Outptr_))
TYPE_OF_OPEN
CdDecodeFileObject (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
OUT PFCB *Fcb,
OUT PCCB *Ccb
_In_ PIRP_CONTEXT IrpContext,
_In_ PFILE_OBJECT FileObject,
PFCB *Fcb,
PCCB *Ccb
)
/*++
@ -152,6 +160,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// If this is an unopened file object then return NULL for the
// Fcb/Ccb. Don't trust any other values in the file object.
@ -175,8 +185,9 @@ Return Value:
*Fcb = FileObject->FsContext;
*Ccb = FileObject->FsContext2;
ClearFlag( (*(PULONG_PTR)Ccb), TYPE_OF_OPEN_MASK ); /* ReactOS Change: GCC "invalid lvalue in assignment" */
#pragma warning( suppress: 4213 )
ClearFlag( (ULONG_PTR) *Ccb, TYPE_OF_OPEN_MASK );
}
//
@ -189,8 +200,8 @@ Return Value:
TYPE_OF_OPEN
CdFastDecodeFileObject (
IN PFILE_OBJECT FileObject,
OUT PFCB *Fcb
_In_ PFILE_OBJECT FileObject,
_Out_ PFCB *Fcb
)
/*++

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -25,7 +25,7 @@ Abstract:
VOID
CdFspDispatch (
IN PIRP_CONTEXT IrpContext
_In_ PVOID Context
)
/*++
@ -48,7 +48,8 @@ Return Value:
--*/
{
THREAD_CONTEXT ThreadContext;
THREAD_CONTEXT ThreadContext = {0};
PIRP_CONTEXT IrpContext = Context;
NTSTATUS Status;
PIRP Irp = IrpContext->Irp;
@ -94,7 +95,7 @@ Return Value:
while (TRUE) {
_SEH2_TRY {
try {
//
// Reinitialize for the next try at completing this
@ -124,7 +125,7 @@ Return Value:
case IRP_MJ_CLOSE :
ASSERT( FALSE );
NT_ASSERT( FALSE );
break;
case IRP_MJ_READ :
@ -174,7 +175,7 @@ Return Value:
case IRP_MJ_PNP :
ASSERT( FALSE );
NT_ASSERT( FALSE );
CdCommonPnp( IrpContext, Irp );
break;
@ -184,10 +185,10 @@ Return Value:
CdCompleteRequest( IrpContext, Irp, Status );
}
} _SEH2_EXCEPT( CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
} except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) {
Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
} _SEH2_END;
Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
}
//
// Break out of the loop if we didn't get CANT_WAIT.
@ -233,6 +234,12 @@ Return Value:
VolDo->OverflowQueueCount -= 1;
Entry = RemoveHeadList( &VolDo->OverflowQueue );
} else {
VolDo->PostedRequestCount -= 1;
Entry = NULL;
}
KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );
@ -242,7 +249,10 @@ Return Value:
// the Ex Worker thread.
//
if (Entry == NULL) { break; }
if (Entry == NULL) {
break;
}
//
// Extract the IrpContext , Irp, set wait to TRUE, and loop.
@ -254,6 +264,7 @@ Return Value:
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation( Irp );
__analysis_assert( IrpSp != 0 );
continue;
}
@ -261,15 +272,6 @@ Return Value:
break;
}
//
// Decrement the PostedRequestCount if there was a volume device object.
//
if (VolDo) {
InterlockedDecrement( &VolDo->PostedRequestCount );
}
return;
}

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -33,8 +33,8 @@ Abstract:
NTSTATUS
CdCommonLockControl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -86,10 +86,10 @@ Return Value:
// This call might post the irp for us.
//
Status = FsRtlCheckOplock( &Fcb->Oplock,
Status = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
Irp,
IrpContext,
(PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
CdOplockComplete,
NULL );
//
@ -138,17 +138,16 @@ Return Value:
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastLock (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
PEPROCESS ProcessId,
ULONG Key,
BOOLEAN FailImmediately,
BOOLEAN ExclusiveLock,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PLARGE_INTEGER Length,
_In_ PEPROCESS ProcessId,
_In_ ULONG Key,
_In_ BOOLEAN FailImmediately,
_In_ BOOLEAN ExclusiveLock,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -192,6 +191,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
ASSERT_FILE_OBJECT( FileObject );
IoStatus->Information = 0;
@ -224,13 +225,13 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// We check whether we can proceed based on the state of the file oplocks.
//
if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
try_return( NOTHING );
}
@ -247,18 +248,19 @@ Return Value:
//
// Now call the FsRtl routine to perform the lock request.
//
/* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */
#pragma prefast(suppress: 28159, "prefast thinks this is an obsolete routine, but it is ok for CDFS to use it")
if ((Results = FsRtlFastLock( Fcb->FileLock,
FileObject,
FileOffset,
Length,
ProcessId,
Key,
FailImmediately,
ExclusiveLock,
IoStatus,
NULL,
FALSE ))) {
FileObject,
FileOffset,
Length,
ProcessId,
Key,
FailImmediately,
ExclusiveLock,
IoStatus,
NULL,
FALSE )) != FALSE) {
//
// Set the flag indicating if Fast I/O is questionable. We
@ -275,25 +277,24 @@ Return Value:
}
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
FsRtlExitFileSystem();
} _SEH2_END;
}
return Results;
}
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastUnlockSingle (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
PEPROCESS ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PLARGE_INTEGER Length,
_In_ PEPROCESS ProcessId,
_In_ ULONG Key,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -330,6 +331,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
IoStatus->Information = 0;
//
@ -366,13 +369,13 @@ Return Value:
FsRtlEnterFileSystem();
_SEH2_TRY {
try {
//
// We check whether we can proceed based on the state of the file oplocks.
//
if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
try_return( NOTHING );
}
@ -416,22 +419,21 @@ Return Value:
}
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
FsRtlExitFileSystem();
} _SEH2_END;
}
return Results;
}
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastUnlockAll (
IN PFILE_OBJECT FileObject,
PEPROCESS ProcessId,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ PEPROCESS ProcessId,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -462,6 +464,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
IoStatus->Information = 0;
//
@ -498,13 +502,13 @@ Return Value:
FsRtlEnterFileSystem();
_SEH2_TRY {
try {
//
// We check whether we can proceed based on the state of the file oplocks.
//
if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
try_return( NOTHING );
}
@ -539,23 +543,22 @@ Return Value:
CdUnlockFcb( IrpContext, Fcb );
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
FsRtlExitFileSystem();
} _SEH2_END;
}
return Results;
}
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdFastUnlockAllByKey (
IN PFILE_OBJECT FileObject,
PVOID ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
_In_ PFILE_OBJECT FileObject,
_In_ PVOID ProcessId,
_In_ ULONG Key,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
)
/*++
@ -588,6 +591,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
IoStatus->Information = 0;
//
@ -624,13 +629,13 @@ Return Value:
FsRtlEnterFileSystem();
_SEH2_TRY {
try {
//
// We check whether we can proceed based on the state of the file oplocks.
//
if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
try_return( NOTHING );
}
@ -666,10 +671,10 @@ Return Value:
CdUnlockFcb( IrpContext, Fcb );
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
FsRtlExitFileSystem();
} _SEH2_END;
}
return Results;
}

View file

@ -13,7 +13,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -27,6 +27,7 @@ Abstract:
#pragma alloc_text(PAGE, CdDissectName)
#pragma alloc_text(PAGE, CdGenerate8dot3Name)
#pragma alloc_text(PAGE, CdFullCompareNames)
#pragma alloc_text(PAGE, CdIsLegalName)
#pragma alloc_text(PAGE, CdIs8dot3Name)
#pragma alloc_text(PAGE, CdIsNameInExpression)
#pragma alloc_text(PAGE, CdShortNameDirentOffset)
@ -34,10 +35,12 @@ Abstract:
#endif
_Post_satisfies_(_Old_(CdName->FileName.Length) >=
CdName->FileName.Length + CdName->VersionString.Length)
VOID
CdConvertNameToCdName (
IN PIRP_CONTEXT IrpContext,
IN OUT PCD_NAME CdName
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PCD_NAME CdName
)
/*++
@ -65,6 +68,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Look for a separator character.
//
@ -103,10 +108,10 @@ Return Value:
VOID
CdConvertBigToLittleEndian (
IN PIRP_CONTEXT IrpContext,
IN PCHAR BigEndian,
IN ULONG ByteCount,
OUT PCHAR LittleEndian
_In_ PIRP_CONTEXT IrpContext,
_In_reads_bytes_(ByteCount) PCHAR BigEndian,
_In_ ULONG ByteCount,
_Out_writes_bytes_(ByteCount) PCHAR LittleEndian
)
/*++
@ -166,7 +171,10 @@ Return Value:
while (RemainingByteCount != 0) {
#pragma prefast(push)
#pragma prefast(suppress:26014, "RemainingByteCount is even")
*Destination = *Source;
#pragma prefast(pop)
Source += 2;
Destination += 2;
@ -180,9 +188,9 @@ Return Value:
VOID
CdUpcaseName (
IN PIRP_CONTEXT IrpContext,
IN PCD_NAME Name,
IN OUT PCD_NAME UpcaseName
_In_ PIRP_CONTEXT IrpContext,
_In_ PCD_NAME Name,
_Inout_ PCD_NAME UpcaseName
)
/*++
@ -206,10 +214,11 @@ Return Value:
{
NTSTATUS Status;
//PVOID NewBuffer; /* ReactOS Change: GCC Uninitialized variable */
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// If the name structures are different then initialize the different components.
//
@ -242,6 +251,7 @@ Return Value:
// copy the data.
//
#pragma prefast( suppress:26015, "CD_NAME structures have two UNICODE_STRING structures pointing to the same allocation. there is no way to tell prefast this is the case and that the allocation is always big enough.");
*(UpcaseName->VersionString.Buffer) = L';';
UpcaseName->VersionString.Buffer += 1;
@ -260,8 +270,9 @@ Return Value:
// This should never fail.
//
ASSERT( Status == STATUS_SUCCESS );
NT_ASSERT( Status == STATUS_SUCCESS );
__analysis_assert( Status == STATUS_SUCCESS );
if (Name->VersionString.Length != 0) {
Status = RtlUpcaseUnicodeString( &UpcaseName->VersionString,
@ -272,7 +283,8 @@ Return Value:
// This should never fail.
//
ASSERT( Status == STATUS_SUCCESS );
NT_ASSERT( Status == STATUS_SUCCESS );
__analysis_assert( Status == STATUS_SUCCESS );
}
return;
@ -281,9 +293,9 @@ Return Value:
VOID
CdDissectName (
IN PIRP_CONTEXT IrpContext,
IN OUT PUNICODE_STRING RemainingName,
OUT PUNICODE_STRING FinalName
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PUNICODE_STRING RemainingName,
_Out_ PUNICODE_STRING FinalName
)
/*++
@ -312,6 +324,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Find the offset of the next component separators.
//
@ -352,11 +366,63 @@ Return Value:
return;
}
BOOLEAN
CdIsLegalName (
_In_ PIRP_CONTEXT IrpContext,
_In_ PUNICODE_STRING FileName
)
/*++
Routine Description:
This routine checks if the name is a legal ISO 9660 name.
Arguments:
FileName - String of bytes containing the name.
Return Value:
BOOLEAN - TRUE if this name is a legal, FALSE otherwise.
--*/
{
PWCHAR Wchar;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Check if name corresponds to a legal file name.
//
for (Wchar = FileName->Buffer;
Wchar < Add2Ptr( FileName->Buffer, FileName->Length, PWCHAR );
Wchar++) {
if ((*Wchar < 0xff) &&
!FsRtlIsAnsiCharacterLegalHpfs( *Wchar, FALSE ) &&
(*Wchar != L'"') &&
(*Wchar != L'<') &&
(*Wchar != L'>') &&
(*Wchar != L'|')) {
return FALSE;
}
}
return TRUE;
}
BOOLEAN
CdIs8dot3Name (
IN PIRP_CONTEXT IrpContext,
IN UNICODE_STRING FileName
_In_ PIRP_CONTEXT IrpContext,
_In_ UNICODE_STRING FileName
)
/*++
@ -378,7 +444,7 @@ Return Value:
{
CHAR DbcsNameBuffer[ BYTE_COUNT_8_DOT_3 ];
STRING DbcsName;
STRING DbcsName = {0};
PWCHAR NextWchar;
ULONG Count;
@ -388,11 +454,13 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// The length must be less than 24 bytes.
//
ASSERT( FileName.Length != 0 );
NT_ASSERT( FileName.Length != 0 );
if (FileName.Length > BYTE_COUNT_8_DOT_3) {
return FALSE;
@ -474,11 +542,11 @@ Return Value:
VOID
CdGenerate8dot3Name (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING FileName,
IN ULONG DirentOffset,
OUT PWCHAR ShortFileName,
OUT PUSHORT ShortByteCount
_In_ PIRP_CONTEXT IrpContext,
_In_ PUNICODE_STRING FileName,
_In_ ULONG DirentOffset,
_Out_writes_bytes_to_(BYTE_COUNT_8_DOT_3, *ShortByteCount) PWCHAR ShortFileName,
_Out_ PUSHORT ShortByteCount
)
/*++
@ -517,11 +585,12 @@ Return Value:
--*/
{
{
NTSTATUS Status;
UNICODE_STRING ShortName;
UNICODE_STRING BiasedShortName;
WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ];
WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ] = {0};
WCHAR BiasedShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ];
GENERATE_NAME_CONTEXT NameContext;
@ -537,7 +606,7 @@ Return Value:
BOOLEAN FoundTilde = FALSE;
OEM_STRING OemName;
OEM_STRING OemName = {0};
USHORT OemNameOffset = 0;
BOOLEAN OverflowBuffer = FALSE;
@ -568,7 +637,7 @@ Return Value:
// into the name in order to reduce the chance of name conflicts. We will use
// a tilde character followed by a character representation of the dirent offset.
// This will be the hexadecimal representation of the dirent offset in the directory.
// It is actually this offset divided by 32 since we don't need the full
// It is actuall this offset divided by 32 since we don't need the full
// granularity.
//
@ -592,9 +661,14 @@ Return Value:
Status = RtlUnicodeStringToOemString(&OemName, &ShortName, TRUE);
if (!NT_SUCCESS( Status )) {
//
// If this failed, bail out. Don't expect any problems other than no mem.
//
if (!NT_SUCCESS( Status)) {
CdRaiseStatus( IrpContext, Status );
NT_ASSERT( STATUS_INSUFFICIENT_RESOURCES == Status);
CdRaiseStatus( IrpContext, Status);
}
Length = 0;
@ -650,7 +724,7 @@ Return Value:
//
// Figure out the maximum number of characters we can copy of the base
// name. We subtract the number of characters in the dirent string from 8.
// name. We subract the number of characters in the dirent string from 8.
// We will copy this many characters or stop when we reach a '.' character
// or a '~' character in the name.
//
@ -685,20 +759,23 @@ Return Value:
// may use 2 bytes as DBCS characters.
//
#pragma prefast(push)
#pragma prefast(suppress:26014, "OemNameOffset <= BaseNameOffset throughout this loop; OemName buffer previously allocated based on ShortName's length.")
if (FsRtlIsLeadDbcsCharacter(OemName.Buffer[OemNameOffset])) {
#pragma prefast(pop)
OemNameOffset += 2;
if ((OemNameOffset + (BiasedShortName.Length / sizeof(WCHAR))) > 8) {
OverflowBuffer = TRUE;
}
}
else {
OemNameOffset++;
}
if ((OemNameOffset + (BiasedShortName.Length / sizeof(WCHAR))) > 8) {
OverflowBuffer = TRUE;
}
//
// Only copy the bytes if we still have space for the dirent string.
//
@ -719,9 +796,11 @@ Return Value:
// Now copy the dirent string into the biased name buffer.
//
#pragma prefast(push)
RtlCopyMemory( NextWchar,
BiasedShortName.Buffer,
BiasedShortName.Length );
#pragma prefast(pop)
Length += BiasedShortName.Length;
NextWchar += (BiasedShortName.Length / sizeof( WCHAR ));
@ -744,18 +823,16 @@ Return Value:
//
*ShortByteCount = Length;
return;
}
BOOLEAN
CdIsNameInExpression (
IN PIRP_CONTEXT IrpContext,
IN PCD_NAME CurrentName,
IN PCD_NAME SearchExpression,
IN ULONG WildcardFlags,
IN BOOLEAN CheckVersion
_In_ PIRP_CONTEXT IrpContext,
_In_ PCD_NAME CurrentName,
_In_ PCD_NAME SearchExpression,
_In_ ULONG WildcardFlags,
_In_ BOOLEAN CheckVersion
)
/*++
@ -791,6 +868,8 @@ Return Value:
BOOLEAN Match = TRUE;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// If there are wildcards in the expression then we call the
// appropriate FsRtlRoutine.
@ -860,8 +939,8 @@ Return Value:
ULONG
CdShortNameDirentOffset (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING Name
_In_ PIRP_CONTEXT IrpContext,
_In_ PUNICODE_STRING Name
)
/*++
@ -894,6 +973,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Walk through the name until we either reach the end of the name
// or find a tilde character.
@ -967,9 +1048,9 @@ Return Value:
FSRTL_COMPARISON_RESULT
CdFullCompareNames (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING NameA,
IN PUNICODE_STRING NameB
_In_ PIRP_CONTEXT IrpContext,
_In_ PUNICODE_STRING NameA,
_In_ PUNICODE_STRING NameB
)
/*++
@ -987,8 +1068,8 @@ Return Value:
COMPARISON - returns
LessThan if NameA < NameB lexicographically,
GreaterThan if NameA > NameB lexicographically,
LessThan if NameA < NameB lexicalgraphically,
GreaterThan if NameA > NameB lexicalgraphically,
EqualTo if NameA is equal to NameB
--*/
@ -1000,6 +1081,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Figure out the minimum of the two lengths
//
@ -1016,7 +1099,7 @@ Return Value:
//
// Loop through looking at all of the characters in both strings
// testing for equality, less than, and greater than
// testing for equalilty, less than, and greater than
//
i = RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength );

View file

@ -19,7 +19,7 @@ Abstract:
#ifndef _CDNODETYPE_
#define _CDNODETYPE_
typedef CSHORT NODE_TYPE_CODE;
typedef USHORT NODE_TYPE_CODE;
typedef NODE_TYPE_CODE *PNODE_TYPE_CODE;
#define NTC_UNDEFINED ((NODE_TYPE_CODE)0x0000)
@ -90,12 +90,15 @@ typedef CSHORT NODE_BYTE_SIZE;
#define CDFS_BUG_CHECK_PNP (0x00140000)
#define CDFS_BUG_CHECK_PREFXSUP (0x00150000)
#define CDFS_BUG_CHECK_READ (0x00160000)
#define CDFS_BUG_CHECK_RESRCSUP (0x00170000)
#define CDFS_BUG_CHECK_STRUCSUP (0x00180000)
#define CDFS_BUG_CHECK_TIMESUP (0x00190000)
#define CDFS_BUG_CHECK_VERFYSUP (0x001a0000)
#define CDFS_BUG_CHECK_VOLINFO (0x001b0000)
#define CDFS_BUG_CHECK_WORKQUE (0x001c0000)
#define CDFS_BUG_CHECK_WRITE (0x00170000)
#define CDFS_BUG_CHECK_RESRCSUP (0x00180000)
#define CDFS_BUG_CHECK_STRUCSUP (0x00190000)
#define CDFS_BUG_CHECK_TIMESUP (0x001a0000)
#define CDFS_BUG_CHECK_VERFYSUP (0x001b0000)
#define CDFS_BUG_CHECK_VOLINFO (0x001c0000)
#define CDFS_BUG_CHECK_WORKQUE (0x001d0000)
#define CDFS_BUG_CHECK_SHUTDOWN (0x001e0000)
#define CdBugCheck(A,B,C) { KeBugCheckEx(CDFS_FILE_SYSTEM, BugCheckFileId | __LINE__, A, B, C ); }

View file

@ -22,7 +22,7 @@ Abstract:
of the tree. The children of a given directory will be grouped together.
The directories are assigned ordinal numbers based on their position in
the path table. The root directory is assigned ordinal value 1.
the path table. The root dirctory is assigned ordinal value 1.
Path table sectors:
@ -73,7 +73,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -88,8 +88,8 @@ Abstract:
//
// PRAW_PATH_ENTRY
// CdRawPathEntry (
// IN PIRP_CONTEXT IrpContext,
// IN PPATH_ENUM_CONTEXT PathContext
// _In_ PIRP_CONTEXT IrpContext,
// _In_ PPATH_ENUM_CONTEXT PathContext
// );
//
@ -102,19 +102,20 @@ Abstract:
VOID
CdMapPathTableBlock (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG BaseOffset,
IN OUT PPATH_ENUM_CONTEXT PathContext
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_In_ LONGLONG BaseOffset,
_Inout_ PPATH_ENUM_CONTEXT PathContext
);
_Success_(return != FALSE)
BOOLEAN
CdUpdatePathEntryFromRawPathEntry (
IN PIRP_CONTEXT IrpContext,
IN ULONG Ordinal,
IN BOOLEAN VerifyBounds,
IN PPATH_ENUM_CONTEXT PathContext,
OUT PPATH_ENTRY PathEntry
_In_ PIRP_CONTEXT IrpContext,
_In_ ULONG Ordinal,
_In_ BOOLEAN VerifyBounds,
_In_ PPATH_ENUM_CONTEXT PathContext,
_Out_ PPATH_ENTRY PathEntry
);
#ifdef ALLOC_PRAGMA
@ -129,11 +130,11 @@ CdUpdatePathEntryFromRawPathEntry (
VOID
CdLookupPathEntry (
IN PIRP_CONTEXT IrpContext,
IN ULONG PathEntryOffset,
IN ULONG Ordinal,
IN BOOLEAN VerifyBounds,
IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
_In_ PIRP_CONTEXT IrpContext,
_In_ ULONG PathEntryOffset,
_In_ ULONG Ordinal,
_In_ BOOLEAN VerifyBounds,
_Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
)
/*++
@ -204,9 +205,9 @@ Return Value:
BOOLEAN
CdLookupNextPathEntry (
IN PIRP_CONTEXT IrpContext,
IN OUT PPATH_ENUM_CONTEXT PathContext,
IN OUT PPATH_ENTRY PathEntry
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PPATH_ENUM_CONTEXT PathContext,
_Inout_ PPATH_ENTRY PathEntry
)
/*++
@ -296,14 +297,14 @@ Return Value:
PathEntry );
}
_Success_(return != FALSE)
BOOLEAN
CdFindPathEntry (
IN PIRP_CONTEXT IrpContext,
IN PFCB ParentFcb,
IN PCD_NAME DirName,
IN BOOLEAN IgnoreCase,
IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB ParentFcb,
_In_ PCD_NAME DirName,
_In_ BOOLEAN IgnoreCase,
_Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
)
/*++
@ -481,10 +482,10 @@ Return Value:
VOID
CdMapPathTableBlock (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG BaseOffset,
IN OUT PPATH_ENUM_CONTEXT PathContext
_In_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb,
_In_ LONGLONG BaseOffset,
_Inout_ PPATH_ENUM_CONTEXT PathContext
)
/*++
@ -493,7 +494,7 @@ Routine Description:
This routine is called to map (or allocate and copy) the next
data block in the path table. We check if the next block will
span a view boundary and allocate an auxiliary buffer in that case.
span a view boundary and allocate an auxilary buffer in that case.
Arguments:
@ -519,9 +520,11 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Map the new block and set the enumeration context to this
// point. Allocate an auxiliary buffer if necessary.
// point. Allocate an auxilary buffer if necessary.
//
CurrentLength = 2 * SECTOR_SIZE;
@ -564,7 +567,7 @@ Return Value:
(FlagOn( ((ULONG) BaseOffset), VACB_MAPPING_MASK ) == LAST_VACB_SECTOR_OFFSET )) {
//
// Map each sector individually and store into an auxiliary
// Map each sector individually and store into an auxilary
// buffer.
//
@ -605,7 +608,7 @@ Return Value:
//
// There is a slight chance that we have allocated an
// auxiliary buffer on the previous sector.
// auxilary buffer on the previous sector.
//
if (PathContext->AllocatedData) {
@ -629,14 +632,14 @@ Return Value:
//
// Local support routine
//
_Success_(return != FALSE)
BOOLEAN
CdUpdatePathEntryFromRawPathEntry (
IN PIRP_CONTEXT IrpContext,
IN ULONG Ordinal,
IN BOOLEAN VerifyBounds,
IN PPATH_ENUM_CONTEXT PathContext,
OUT PPATH_ENTRY PathEntry
_In_ PIRP_CONTEXT IrpContext,
_In_ ULONG Ordinal,
_In_ BOOLEAN VerifyBounds,
_In_ PPATH_ENUM_CONTEXT PathContext,
_Out_ PPATH_ENTRY PathEntry
)
/*++
@ -764,7 +767,7 @@ Return Value:
PathEntry->PathEntryLength = WordAlign( PathEntry->PathEntryLength );
PathEntry->DirName = (PCHAR)RawPathEntry->DirId; /* ReactOS Change: GCC "assignment makes pointer from integer without a cast" */
PathEntry->DirName = (PCHAR)RawPathEntry->DirId;
return TRUE;
}
@ -776,9 +779,9 @@ Return Value:
VOID
CdUpdatePathEntryName (
IN PIRP_CONTEXT IrpContext,
IN OUT PPATH_ENTRY PathEntry,
IN BOOLEAN IgnoreCase
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PPATH_ENTRY PathEntry,
_In_ BOOLEAN IgnoreCase
)
/*++
@ -789,7 +792,7 @@ Routine Description:
path entry. If this is a Joliet name then we will make sure we have
an allocated buffer and need to convert from big endian to little
endian. We also correctly update the case name. If this operation is ignore
case then we need an auxiliary buffer for the name.
case then we need an auxilary buffer for the name.
For an Ansi disk we can use the name from the disk for the exact case. We only
need to allocate a buffer for the ignore case name. The on-disk representation of
@ -828,7 +831,7 @@ Return Value:
// There should be no allocated buffers.
//
ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ));
NT_ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ));
//
// Now use one of the hard coded directory names.
@ -931,7 +934,8 @@ Return Value:
PathEntry->DirName,
PathEntry->DirNameLen );
ASSERT( Status == STATUS_SUCCESS );
NT_ASSERT( Status == STATUS_SUCCESS );
__analysis_assert( Status == STATUS_SUCCESS );
PathEntry->CdDirName.FileName.Length = (USHORT) Length;
} else {

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -22,40 +22,50 @@ Abstract:
#define BugCheckFileId (CDFS_BUG_CHECK_PNP)
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpQueryRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
);
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
);
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpSurpriseRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
);
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpCancelRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
);
// Tell prefast this is a completion routine.
IO_COMPLETION_ROUTINE CdPnpCompletionRoutine;
NTSTATUS
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdPnpCompletionRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
);
#ifdef ALLOC_PRAGMA
@ -66,11 +76,11 @@ CdPnpCompletionRoutine (
#pragma alloc_text(PAGE, CdPnpSurpriseRemove)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonPnp (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -91,7 +101,7 @@ Return Value:
--*/
{
NTSTATUS Status;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN PassThrough = FALSE;
PIO_STACK_LOCATION IrpSp;
@ -99,6 +109,11 @@ Return Value:
PVOLUME_DEVICE_OBJECT OurDeviceObject;
PVCB Vcb;
PAGED_CODE();
// Global lock object is acquired based on internal book-keeping
_Analysis_suppress_lock_checking_(CdData.DataResource);
//
// Get the current Irp stack location.
//
@ -126,7 +141,8 @@ Return Value:
// object. If it isn't, we need to get out before we try to reference some
// field that takes us past the end of an ordinary device object.
//
#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the size member is allowed")
if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) ||
NodeType( &OurDeviceObject->Vcb ) != CDFS_NTC_VCB) {
@ -215,12 +231,13 @@ Return Value:
return Status;
}
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpQueryRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
)
/*++
@ -251,6 +268,8 @@ Return Value:
KEVENT Event;
BOOLEAN VcbPresent = TRUE;
PAGED_CODE();
ASSERT_EXCLUSIVE_CDDATA;
//
@ -326,7 +345,7 @@ Return Value:
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event,
(VOID)KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
@ -343,7 +362,7 @@ Return Value:
// Since we were able to lock the volume, we are guaranteed to
// move this volume into dismount state and disconnect it from
// the underlying storage stack. The force on our part is actually
// unnecessary, though complete.
// unnecesary, though complete.
//
// What is not strictly guaranteed, though, is that the closes
// for the metadata streams take effect synchronously underneath
@ -355,7 +374,7 @@ Return Value:
VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE );
ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress );
NT_ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress );
}
//
@ -372,7 +391,7 @@ Return Value:
//
// The reason this is the case is that handles/fileobjects place a reference
// on the device objects they overly. In the filesystem case, these references
// are on our target devices. PnP correctly thinks that if references remain
// are on our target devices. PnP correcly thinks that if references remain
// on the device objects in the stack that someone has a handle, and that this
// counts as a reason to not succeed the query - even though every interrogated
// driver thinks that it is OK.
@ -392,11 +411,14 @@ Return Value:
CdReleaseVcb( IrpContext, Vcb );
}
else {
_Analysis_assume_lock_not_held_(Vcb->VcbResource);
}
CdReleaseCdData( IrpContext );
//
// Cleanup our IrpContext and complete the IRP if necessary.
// Cleanup our IrpContext and complete the IRP if neccesary.
//
CdCompleteRequest( IrpContext, Irp, Status );
@ -404,12 +426,13 @@ Return Value:
return Status;
}
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
)
/*++
@ -438,6 +461,8 @@ Return Value:
KEVENT Event;
BOOLEAN VcbPresent = TRUE;
PAGED_CODE();
ASSERT_EXCLUSIVE_CDDATA;
//
@ -447,7 +472,7 @@ Return Value:
// (the only case in which this will be the first warning).
//
// Note that it is entirely unlikely that we will be around
// for a REMOVE in the first two cases, as we try to initiate
// for a REMOVE in the first two cases, as we try to intiate
// dismount.
//
@ -516,7 +541,7 @@ Return Value:
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event,
(VOID)KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
@ -528,7 +553,7 @@ Return Value:
//
// Now make our dismount happen. This may not vaporize the
// Vcb, of course, since there could be any number of handles
// outstanding if we were not preceded by a QUERY.
// outstanding if we were not preceeded by a QUERY.
//
// PnP will take care of disconnecting this stack if we
// couldn't get off of it immediately.
@ -545,6 +570,9 @@ Return Value:
CdReleaseVcb( IrpContext, Vcb );
}
else {
_Analysis_assume_lock_not_held_(Vcb->VcbResource);
}
CdReleaseCdData( IrpContext );
@ -557,12 +585,13 @@ Return Value:
return Status;
}
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpSurpriseRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
)
/*++
@ -597,6 +626,8 @@ Return Value:
KEVENT Event;
BOOLEAN VcbPresent = TRUE;
PAGED_CODE();
ASSERT_EXCLUSIVE_CDDATA;
//
@ -654,7 +685,7 @@ Return Value:
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event,
(VOID)KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
@ -680,6 +711,9 @@ Return Value:
CdReleaseVcb( IrpContext, Vcb );
}
else {
_Analysis_assume_lock_not_held_(Vcb->VcbResource);
}
CdReleaseCdData( IrpContext );
@ -692,12 +726,13 @@ Return Value:
return Status;
}
_Requires_lock_held_(_Global_critical_region_)
_Releases_nonreentrant_lock_(CdData.DataResource)
NTSTATUS
CdPnpCancelRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_Inout_ PVCB Vcb
)
/*++
@ -724,6 +759,8 @@ Return Value:
{
NTSTATUS Status;
PAGED_CODE();
ASSERT_EXCLUSIVE_CDDATA;
//
@ -775,20 +812,21 @@ Return Value:
//
NTSTATUS
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdPnpCompletionRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
)
{
PKEVENT Event = (PKEVENT) Contxt;
_Analysis_assume_(Contxt != NULL);
KeSetEvent( Event, 0, FALSE );
return STATUS_MORE_PROCESSING_REQUIRED;
UNREFERENCED_PARAMETER( DeviceObject );
UNREFERENCED_PARAMETER( Irp );
UNREFERENCED_PARAMETER( Contxt );
}

View file

@ -13,7 +13,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -27,16 +27,16 @@ Abstract:
PNAME_LINK
CdFindNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PUNICODE_STRING Name
_In_ PIRP_CONTEXT IrpContext,
_In_ PRTL_SPLAY_LINKS *RootNode,
_In_ PUNICODE_STRING Name
);
BOOLEAN
CdInsertNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PNAME_LINK NameLink
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PRTL_SPLAY_LINKS *RootNode,
_In_ PNAME_LINK NameLink
);
#ifdef ALLOC_PRAGMA
@ -50,12 +50,12 @@ CdInsertNameLink (
VOID
CdInsertPrefix (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN BOOLEAN ShortNameMatch,
IN PFCB ParentFcb
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PFCB Fcb,
_In_ PCD_NAME Name,
_In_ BOOLEAN IgnoreCase,
_In_ BOOLEAN ShortNameMatch,
_Inout_ PFCB ParentFcb
)
/*++
@ -205,8 +205,8 @@ Return Value:
VOID
CdRemovePrefix (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PFCB Fcb
)
/*++
@ -228,7 +228,9 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Start with the short name prefix entry.
//
@ -281,12 +283,14 @@ Return Value:
}
_Requires_lock_held_(_Global_critical_region_)
VOID
CdFindPrefix (
IN PIRP_CONTEXT IrpContext,
IN OUT PFCB *CurrentFcb,
IN OUT PUNICODE_STRING RemainingName,
IN BOOLEAN IgnoreCase
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PFCB *CurrentFcb,
_Inout_ PUNICODE_STRING RemainingName,
_In_ BOOLEAN IgnoreCase
)
/*++
@ -459,9 +463,9 @@ Return Value:
PNAME_LINK
CdFindNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PUNICODE_STRING Name
_In_ PIRP_CONTEXT IrpContext,
_In_ PRTL_SPLAY_LINKS *RootNode,
_In_ PUNICODE_STRING Name
)
/*++
@ -562,9 +566,9 @@ Return Value:
BOOLEAN
CdInsertNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PNAME_LINK NameLink
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PRTL_SPLAY_LINKS *RootNode,
_In_ PNAME_LINK NameLink
)
/*++

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -25,8 +25,8 @@ Abstract:
//
// VOID
// SafeZeroMemory (
// IN PUCHAR At,
// IN ULONG ByteCount
// _Out_ PUCHAR At,
// _In_ ULONG ByteCount
// );
//
@ -35,11 +35,12 @@ Abstract:
//
#define SafeZeroMemory(IC,AT,BYTE_COUNT) { \
_SEH2_TRY { \
try { \
RtlZeroMemory( (AT), (BYTE_COUNT) ); \
} _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { \
__pragma(warning(suppress: 6320)) \
} except( EXCEPTION_EXECUTE_HANDLER ) { \
CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \
} _SEH2_END; \
} \
}
//
@ -53,10 +54,12 @@ Abstract:
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonRead (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -79,7 +82,7 @@ Return Value:
--*/
{
NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Uninit var */
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
TYPE_OF_OPEN TypeOfOpen;
@ -103,7 +106,7 @@ Return Value:
BOOLEAN ReleaseFile = TRUE;
CD_IO_CONTEXT LocalIoContext;
PAGED_CODE();
//
@ -123,6 +126,9 @@ Return Value:
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
// Internal lock object is acquired if return status is STATUS_PENDING
_Analysis_suppress_lock_checking_(Fcb->Resource);
if ((TypeOfOpen == UnopenedFileObject) ||
(TypeOfOpen == UserDirectoryOpen)) {
@ -180,7 +186,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// Verify the Fcb. Allow reads if this is a DASD handle that is
@ -222,11 +228,11 @@ Return Value:
// based on the state of the file oplocks.
//
Status = FsRtlCheckOplock( &Fcb->Oplock,
Status = FsRtlCheckOplock( CdGetFcbOplock(Fcb),
Irp,
IrpContext,
(PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
(PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */
CdOplockComplete,
CdPrePostIrp );
//
// If the result is not STATUS_SUCCESS then the Irp was completed
@ -250,22 +256,31 @@ Return Value:
}
//
// Complete the request if it begins beyond the end of file.
// Check request beyond end of file if this is not a read on a volume
// handle marked for extended DASD IO.
//
if (StartingOffset >= Fcb->FileSize.QuadPart) {
if ((TypeOfOpen != UserVolumeOpen) ||
(!FlagOn( Ccb->Flags, CCB_FLAG_ALLOW_EXTENDED_DASD_IO ))) {
try_return( Status = STATUS_END_OF_FILE );
}
//
// Complete the request if it begins beyond the end of file.
//
//
// Truncate the read if it extends beyond the end of the file.
//
if (StartingOffset >= Fcb->FileSize.QuadPart) {
if (ByteRange > Fcb->FileSize.QuadPart) {
try_return( Status = STATUS_END_OF_FILE );
}
ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
ByteRange = Fcb->FileSize.QuadPart;
//
// Truncate the read if it extends beyond the end of the file.
//
if (ByteRange > Fcb->FileSize.QuadPart) {
ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
ByteRange = Fcb->FileSize.QuadPart;
}
}
//
@ -515,7 +530,7 @@ Return Value:
}
try_exit: NOTHING;
} _SEH2_FINALLY {
} finally {
//
// Release the Fcb.
@ -525,7 +540,7 @@ Return Value:
CdReleaseFile( IrpContext, Fcb );
}
} _SEH2_END;
}
//
// Post the request if we got CANT_WAIT.
@ -548,3 +563,4 @@ Return Value:
}

View file

@ -13,7 +13,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -23,7 +23,7 @@ Abstract:
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdAcquireForCache)
#pragma alloc_text(PAGE, CdAcquireForCreateSection)
#pragma alloc_text(PAGE, CdFilterCallbackAcquireForCreateSection)
#pragma alloc_text(PAGE, CdAcquireResource)
#pragma alloc_text(PAGE, CdNoopAcquire)
#pragma alloc_text(PAGE, CdNoopRelease)
@ -32,12 +32,18 @@ Abstract:
#endif
_Requires_lock_held_(_Global_critical_region_)
_When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
_When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
_When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
_When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
BOOLEAN
CdAcquireResource (
IN PIRP_CONTEXT IrpContext,
IN PERESOURCE Resource,
IN BOOLEAN IgnoreWait,
IN TYPE_OF_ACQUIRE Type
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PERESOURCE Resource,
_In_ BOOLEAN IgnoreWait,
_In_ TYPE_OF_ACQUIRE Type
)
/*++
@ -89,27 +95,28 @@ Return Value:
switch (Type) {
case AcquireExclusive:
#pragma prefast( suppress:28137, "prefast believes Wait should be a constant, but this is ok for CDFS" )
Acquired = ExAcquireResourceExclusiveLite( Resource, Wait );
break;
case AcquireShared:
Acquired = ExAcquireResourceSharedLite( Resource, Wait );
break;
case AcquireSharedStarveExclusive:
Acquired = ExAcquireSharedStarveExclusive( Resource, Wait );
break;
default:
Acquired = FALSE;
ASSERT( FALSE );
Acquired = FALSE;
NT_ASSERT( FALSE );
}
//
// If not acquired and the user didn't specify IgnoreWait then
// If not acquired and the user didn't specifiy IgnoreWait then
// raise CANT_WAIT.
//
@ -122,11 +129,13 @@ Return Value:
}
_Requires_lock_held_(_Global_critical_region_)
_When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdAcquireForCache (
IN PFCB Fcb,
IN BOOLEAN Wait
_Inout_ PFCB Fcb,
_In_ BOOLEAN Wait
)
/*++
@ -152,17 +161,18 @@ Return Value:
{
PAGED_CODE();
ASSERT(IoGetTopLevelIrp() == NULL);
NT_ASSERT(IoGetTopLevelIrp() == NULL);
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
}
_Requires_lock_held_(_Global_critical_region_)
_Releases_lock_(*Fcb->Resource)
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdReleaseFromCache (
IN PFCB Fcb
_Inout_ PFCB Fcb
)
/*++
@ -187,7 +197,7 @@ Return Value:
{
PAGED_CODE();
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
NT_ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
IoSetTopLevelIrp( NULL );
ExReleaseResourceLite( Fcb->Resource );
@ -195,10 +205,9 @@ Return Value:
BOOLEAN
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdNoopAcquire (
IN PVOID Fcb,
IN BOOLEAN Wait
_In_ PVOID Fcb,
_In_ BOOLEAN Wait
)
/*++
@ -222,14 +231,17 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( Fcb );
UNREFERENCED_PARAMETER( Wait );
return TRUE;
}
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdNoopRelease (
IN PVOID Fcb
_In_ PVOID Fcb
)
/*++
@ -251,13 +263,17 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( Fcb );
}
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdAcquireForCreateSection (
IN PFILE_OBJECT FileObject
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdFilterCallbackAcquireForCreateSection (
_In_ PFS_FILTER_CALLBACK_DATA CallbackData,
_Unreferenced_parameter_ PVOID *CompletionContext
)
/*++
@ -268,24 +284,41 @@ Routine Description:
Arguments:
FileObject - File object for a Cdfs stream.
FS_FILTER_CALLBACK_DATA - Filter based callback data that provides the file object we
want to acquire.
CompletionContext - Ignored.
Return Value:
None
On success we return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
If SyncType is SyncTypeCreateSection, we return a status that indicates there are no
writers to this file.
--*/
{
PAGED_CODE();
PFILE_OBJECT FileObject;
PAGED_CODE();
NT_ASSERT( CallbackData->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION );
NT_ASSERT( CallbackData->SizeOfFsFilterCallbackData == sizeof(FS_FILTER_CALLBACK_DATA) );
//
// Get the file object from the callback data.
//
FileObject = CallbackData->FileObject;
//
// Get the Fcb resource exclusively.
//
ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource,
TRUE );
TRUE );
//
// Take the File resource shared. We need this later on when MM calls
@ -299,13 +332,31 @@ Return Value:
ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource,
TRUE );
//
// CDFS is a read-only file system, so we can always indicate no writers.
// We only do this for create section synchronization. For others we
// return the generic success STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
//
if (CallbackData->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection) {
return STATUS_FILE_LOCKED_WITH_ONLY_READERS;
} else {
return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY;
}
UNREFERENCED_PARAMETER( CompletionContext );
}
_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
)
/*++

View file

@ -0,0 +1,175 @@
/*++
Copyright (c) 1997-2006 Microsoft Corporation
Module Name:
Shutdown.c
Abstract:
This module implements the shutdown routine for CDFS called by
the dispatch driver.
--*/
#include "CdProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (CDFS_BUG_CHECK_SHUTDOWN)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdCommonShutdown)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonShutdown (
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
Routine Description:
This is the common routine for handling shutdown operation called
by both the fsd and fsp threads
Arguments:
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - The return status for the operation
--*/
{
KEVENT Event;
PLIST_ENTRY Links;
PVCB Vcb;
PIRP NewIrp;
IO_STATUS_BLOCK Iosb;
BOOLEAN VcbPresent;
NTSTATUS Status;
PAGED_CODE();
//
// Make sure we don't get any pop-ups.
//
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS );
//
// Initialize an event for doing calls down to
// our target device objects.
//
KeInitializeEvent( &Event, NotificationEvent, FALSE );
//
// Indicate that shutdown has started.
//
SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN );
//
// Get everyone else out of the way
//
CdAcquireCdData( IrpContext );
//
// Now walk through all the mounted Vcb's and shutdown the target
// device objects.
//
Links = CdData.VcbQueue.Flink;
while (Links != &CdData.VcbQueue) {
Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks );
//
// Move to the next link now since the current Vcb may be deleted.
//
Links = Links->Flink;
//
// If we have already been called before for this volume
// (and yes this does happen), skip this volume as no writes
// have been allowed since the first shutdown.
//
if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) ||
(Vcb->VcbCondition != VcbMounted)) {
continue;
}
CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
CdPurgeVolume( IrpContext, Vcb, FALSE );
//
// Build an irp for this volume stack - our own irp is probably too small and
// each stack may have a different stack size.
//
NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
Vcb->TargetDeviceObject,
NULL,
0,
NULL,
&Event,
&Iosb );
if (NewIrp != NULL) {
Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp );
if (Status == STATUS_PENDING) {
(VOID)KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
NULL );
}
KeClearEvent( &Event );
}
SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN );
//
// Attempt to punch the volume down.
//
VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE );
if (VcbPresent) {
CdReleaseVcb( IrpContext, Vcb );
}
}
CdReleaseCdData( IrpContext );
IoUnregisterFileSystem( CdData.FileSystemDeviceObject );
IoDeleteDevice( CdData.FileSystemDeviceObject );
CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -26,12 +26,12 @@ Abstract:
#pragma alloc_text(PAGE, CdVerifyVcb)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdPerformVerify (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PDEVICE_OBJECT DeviceToVerify
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp,
_In_ PDEVICE_OBJECT DeviceToVerify
)
/*++
@ -92,7 +92,7 @@ Return Value:
Vcb = &CONTAINING_RECORD( IrpSp->DeviceObject,
VOLUME_DEVICE_OBJECT,
DeviceObject )->Vcb;
_SEH2_TRY {
try {
//
// Send down the verify FSCTL. Note that this is sent to the
@ -206,26 +206,28 @@ Return Value:
Status = CdFsdPostRequest( IrpContext, Irp );
}
} _SEH2_EXCEPT(CdExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
} except(CdExceptionFilter( IrpContext, GetExceptionInformation() )) {
//
// We had some trouble trying to perform the verify or raised
// an error ourselves. So we'll abort the I/O request with
// the error status that we get back from the exception code.
// the error status that we get back from the execption code.
//
Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
} _SEH2_END;
Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
}
return Status;
}
_Requires_lock_held_(_Global_critical_region_)
BOOLEAN
CdCheckForDismount (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN BOOLEAN Force
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PVCB Vcb,
_In_ BOOLEAN Force
)
/*++
@ -345,14 +347,17 @@ Return Value:
CdReleaseVcb( IrpContext, Vcb );
}
else {
_Analysis_assume_lock_not_held_(Vcb->VcbResource);
}
return VcbPresent;
}
BOOLEAN
CdMarkDevForVerifyIfVcbMounted(
IN PVCB Vcb
CdMarkDevForVerifyIfVcbMounted (
_Inout_ PVCB Vcb
)
/*++
@ -378,7 +383,8 @@ Return Value:
KIRQL SavedIrql;
IoAcquireVpbSpinLock( &SavedIrql );
#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb) {
CdMarkRealDevForVerify( Vcb->Vpb->RealDevice);
@ -401,8 +407,8 @@ Return Value:
VOID
CdVerifyVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PVCB Vcb
)
/*++
@ -431,7 +437,6 @@ Return Value:
ULONG MediaChangeCount = 0;
BOOLEAN ForceVerify = FALSE;
BOOLEAN DevMarkedForVerify;
//KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */
PAGED_CODE();
@ -444,17 +449,24 @@ Return Value:
((Vcb->VcbCondition == VcbDismountInProgress) &&
(IrpContext->MajorFunction != IRP_MJ_CREATE))) {
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
} else {
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
}
}
if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA )) {
//
// Capture the real device verify state.
//
DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice);
if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ) && !DevMarkedForVerify) {
//
// Capture the real device verify state.
//
DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice);
//
// If the media is removable and the verify volume flag in the
// device object is not set then we want to ping the device
@ -534,7 +546,7 @@ Return Value:
// since they were directed at the 'drive', not our volume.
//
if (NT_SUCCESS( Status) && !ForceVerify &&
if (NT_SUCCESS( Status) && !ForceVerify && !DevMarkedForVerify &&
(IrpContext->MajorFunction == IRP_MJ_CREATE)) {
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
@ -548,18 +560,20 @@ Return Value:
// it would have been caught and set by the first set of checks.
//
}
}
//
// Raise the verify / error if necessary.
//
if (ForceVerify || !NT_SUCCESS( Status)) {
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
Vcb->Vpb->RealDevice );
CdRaiseStatus( IrpContext, ForceVerify ? STATUS_VERIFY_REQUIRED : Status);
}
//
// Raise the verify / error if neccessary.
//
if (ForceVerify || DevMarkedForVerify || !NT_SUCCESS( Status)) {
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
Vcb->Vpb->RealDevice );
CdRaiseStatus( IrpContext, (ForceVerify || DevMarkedForVerify)
? STATUS_VERIFY_REQUIRED
: Status);
}
//
@ -577,21 +591,25 @@ Return Value:
break;
case VcbInvalid:
case VcbDismountInProgress :
case VcbDismountInProgress:
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
} else {
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
}
break;
/* ReactOS Change: GCC "enumeration value not handled in switch" */
default: break;
}
}
BOOLEAN
CdVerifyFcbOperation (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PFCB Fcb
_In_opt_ PIRP_CONTEXT IrpContext,
_In_ PFCB Fcb
)
/*++
@ -616,7 +634,6 @@ Return Value:
--*/
{
//NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Unused variable */
PVCB Vcb = Fcb->Vcb;
PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice;
PIRP Irp;
@ -668,7 +685,14 @@ Return Value:
if (ARGUMENT_PRESENT( IrpContext )) {
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
CdRaiseStatus( IrpContext, STATUS_VOLUME_DISMOUNTED );
} else {
CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
}
}
return FALSE;
@ -715,23 +739,22 @@ Return Value:
} else if (Vcb->VcbCondition == VcbNotMounted) {
if (ARGUMENT_PRESENT( IrpContext )) {
IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
}
return FALSE;
// return FALSE; // unreachable code
}
return TRUE;
}
_Requires_lock_held_(_Global_critical_region_)
BOOLEAN
CdDismountVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
_In_ PIRP_CONTEXT IrpContext,
_Inout_ PVCB Vcb
)
/*++
@ -772,7 +795,7 @@ Return Value:
// We should only take this path once.
//
ASSERT( Vcb->VcbCondition != VcbDismountInProgress );
NT_ASSERT( Vcb->VcbCondition != VcbDismountInProgress );
//
// Mark the Vcb as DismountInProgress.
@ -858,6 +881,7 @@ Return Value:
// mount request.
//
#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
if (OldVpb->RealDevice->Vpb == OldVpb) {
//
@ -868,13 +892,16 @@ Return Value:
if (!FinalReference) {
ASSERT( Vcb->SwapVpb != NULL );
NT_ASSERT( Vcb->SwapVpb != NULL );
Vcb->SwapVpb->Type = IO_TYPE_VPB;
Vcb->SwapVpb->Size = sizeof( VPB );
Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
#pragma prefast(push)
#pragma prefast(disable: 28175, "this is a filesystem driver, touching the vpb is allowed")
Vcb->SwapVpb->RealDevice = OldVpb->RealDevice;
Vcb->SwapVpb->RealDevice->Vpb = Vcb->SwapVpb;
#pragma prefast(pop)
Vcb->SwapVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING );

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -26,36 +26,45 @@ Abstract:
// Local support routines
//
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryFsVolumeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsSizeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsDeviceInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsAttributeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsSectorSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
);
#ifdef ALLOC_PRAGMA
@ -64,13 +73,15 @@ CdQueryFsAttributeInfo (
#pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
#pragma alloc_text(PAGE, CdQueryFsSizeInfo)
#pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
#pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonQueryVolInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -130,7 +141,7 @@ Return Value:
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
try {
//
// Verify the Vcb.
@ -166,25 +177,29 @@ Return Value:
Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
/* ReactOS Change: GCC "enumeration value not handled in switch" */
default: break;
#if (NTDDI_VERSION >= NTDDI_WIN8)
case FileFsSectorSizeInformation:
Status = CdQueryFsSectorSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
#endif
}
//
// Set the information field to the number of bytes actually filled in
//
Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
} _SEH2_FINALLY {
} finally {
//
// Release the Vcb.
//
CdReleaseVcb( IrpContext, Fcb->Vcb );
} _SEH2_END;
}
//
// Complete the request if we didn't raise.
@ -200,12 +215,13 @@ Return Value:
// Local support routine
//
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryFsVolumeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -222,7 +238,7 @@ Arguments:
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
upon return recieves the remaining bytes free in the buffer
Return Value:
@ -237,6 +253,8 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Fill in the data from the Vcb.
//
@ -292,10 +310,10 @@ Return Value:
NTSTATUS
CdQueryFsSizeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -312,7 +330,7 @@ Arguments:
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
upon return recieves the remaining bytes free in the buffer
Return Value:
@ -323,6 +341,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Fill in the output buffer.
//
@ -353,10 +373,10 @@ Return Value:
NTSTATUS
CdQueryFsDeviceInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -373,7 +393,7 @@ Arguments:
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
upon return recieves the remaining bytes free in the buffer
Return Value:
@ -384,6 +404,8 @@ Return Value:
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Update the output buffer.
//
@ -411,10 +433,10 @@ Return Value:
NTSTATUS
CdQueryFsAttributeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN OUT PULONG Length
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
@ -431,7 +453,7 @@ Arguments:
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
upon return recieves the remaining bytes free in the buffer
Return Value:
@ -446,12 +468,15 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( Vcb );
//
// Fill out the fixed portion of the buffer.
//
Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
FILE_READ_ONLY_VOLUME;
FILE_READ_ONLY_VOLUME |
FILE_SUPPORTS_OPEN_BY_FILE_ID;
if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
@ -503,3 +528,71 @@ Return Value:
return Status;
}
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSTATUS
CdQueryFsSectorSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query sector size information call
This operation will work on any handle and requires no privilege.
Arguments:
Vcb - Supplies the Vcb being queried
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
NTSTATUS Status;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Sufficient buffer size is guaranteed by the I/O manager or the
// originating kernel mode driver.
//
ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
_Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
//
// Retrieve the sector size information
//
Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
Buffer );
//
// Adjust the length variable
//
if (NT_SUCCESS( Status )) {
*Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
}
return Status;
}
#endif

View file

@ -14,7 +14,7 @@ Abstract:
--*/
#include "cdprocs.h"
#include "CdProcs.h"
//
// The Bug check file id for this module
@ -35,8 +35,8 @@ Abstract:
VOID
CdAddToWorkque (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
);
#ifdef ALLOC_PRAGMA
@ -46,10 +46,11 @@ CdAddToWorkque (
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdFsdPostRequest (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -96,18 +97,19 @@ Return Value:
}
_Requires_lock_held_(_Global_critical_region_)
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdPrePostIrp (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
Routine Description:
This routine performs any necessary work before STATUS_PENDING is
This routine performs any neccessary work before STATUS_PENDING is
returned with the Fsd thread. This routine is called within the
filesystem and by the oplock package.
@ -155,6 +157,7 @@ Return Value:
if (!RemovedFcb) {
_Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
}
@ -165,7 +168,7 @@ Return Value:
break;
//
// We need to lock the user's buffer, unless this is an MDL-read,
// We need to lock the user's buffer, unless this is an MDL read/write,
// in which case there is no user buffer.
//
@ -173,7 +176,16 @@ Return Value:
if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length );
CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoWriteAccess );
}
break;
case IRP_MJ_WRITE :
if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoReadAccess );
}
break;
@ -186,7 +198,7 @@ Return Value:
if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length );
CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length, IoWriteAccess );
}
break;
@ -209,11 +221,12 @@ Return Value:
}
_Requires_lock_held_(_Global_critical_region_)
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdOplockComplete (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
@ -272,6 +285,7 @@ Return Value:
if (!RemovedFcb) {
_Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
}
@ -307,15 +321,15 @@ Return Value:
VOID
CdAddToWorkque (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
Routine Description:
This routine is called to actually store the posted Irp to the Fsp
This routine is called to acually store the posted Irp to the Fsp
workque.
Arguments:
@ -387,10 +401,12 @@ Return Value:
// Send it off.....
//
#pragma prefast(suppress:28155, "the function prototype is correct")
ExInitializeWorkItem( &IrpContext->WorkQueueItem,
(PVOID)CdFspDispatch,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
CdFspDispatch,
IrpContext );
#pragma prefast(suppress: 28159, "prefast believes this routine is obsolete, but it is ok for CDFS to continue using it")
ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue );
return;

View file

@ -0,0 +1,381 @@
/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
Write.c
Abstract:
This module implements the File Write routine for Write called by the
Fsd/Fsp dispatch drivers.
--*/
#include "CdProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (CDFS_BUG_CHECK_WRITE)
//
// VOID
// SafeZeroMemory (
// _Out_ PUCHAR At,
// _In_ ULONG ByteCount
// );
//
//
// This macro just puts a nice little try-except around RtlZeroMemory
//
#define SafeZeroMemory(IC,AT,BYTE_COUNT) { \
try { \
RtlZeroMemory( (AT), (BYTE_COUNT) ); \
__pragma(warning(suppress: 6320)) \
} except( EXCEPTION_EXECUTE_HANDLER ) { \
CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \
} \
}
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdCommonWrite)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonWrite (
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
Routine Description:
This is the common entry point for NtWriteFile calls. For synchronous requests,
CommonWrite will complete the request in the current thread. If not
synchronous the request will be passed to the Fsp if there is a need to
block.
Arguments:
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - The result of this operation.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
TYPE_OF_OPEN TypeOfOpen;
PFCB Fcb;
PCCB Ccb;
BOOLEAN Wait;
ULONG SynchronousIo;
PVOID UserBuffer;
LONGLONG StartingOffset;
LONGLONG ByteRange;
ULONG ByteCount;
ULONG WriteByteCount;
ULONG OriginalByteCount;
BOOLEAN ReleaseFile = TRUE;
CD_IO_CONTEXT LocalIoContext;
PAGED_CODE();
//
// If this is a zero length write then return SUCCESS immediately.
//
if (IrpSp->Parameters.Write.Length == 0) {
CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}
//
// Decode the file object and verify we support write on this. It
// must be a volume file.
//
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
// Internal lock object is acquired if return status is STATUS_PENDING
_Analysis_suppress_lock_checking_(Fcb->Resource);
if (TypeOfOpen != UserVolumeOpen) {
CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
return STATUS_INVALID_DEVICE_REQUEST;
}
//
// Examine our input parameters to determine if this is noncached and/or
// a paging io operation.
//
Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO );
//
// Extract the range of the Io.
//
StartingOffset = IrpSp->Parameters.Write.ByteOffset.QuadPart;
OriginalByteCount = ByteCount = IrpSp->Parameters.Write.Length;
ByteRange = StartingOffset + ByteCount;
//
// Acquire the file shared to perform the write.
//
CdAcquireFileShared( IrpContext, Fcb );
//
// Use a try-finally to facilitate cleanup.
//
try {
//
// Verify the Fcb. Allow writes if this is a DASD handle that is
// dismounting the volume.
//
if (!FlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE )) {
CdVerifyFcbOperation( IrpContext, Fcb );
}
if (!FlagOn( Ccb->Flags, CCB_FLAG_ALLOW_EXTENDED_DASD_IO )) {
//
// Complete the request if it begins beyond the end of file.
//
if (StartingOffset >= Fcb->FileSize.QuadPart) {
try_return( Status = STATUS_END_OF_FILE );
}
//
// Truncate the write if it extends beyond the end of the file.
//
if (ByteRange > Fcb->FileSize.QuadPart) {
ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
ByteRange = Fcb->FileSize.QuadPart;
}
}
//
// If we have an unaligned transfer then post this request if
// we can't wait. Unaligned means that the starting offset
// is not on a sector boundary or the write is not integral
// sectors.
//
WriteByteCount = BlockAlign( Fcb->Vcb, ByteCount );
if (SectorOffset( StartingOffset ) ||
SectorOffset( WriteByteCount ) ||
(WriteByteCount > OriginalByteCount)) {
if (!Wait) {
CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
}
//
// Make sure we don't overwrite the buffer.
//
WriteByteCount = ByteCount;
}
//
// Initialize the IoContext for the write.
// If there is a context pointer, we need to make sure it was
// allocated and not a stale stack pointer.
//
if (IrpContext->IoContext == NULL ||
!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {
//
// If we can wait, use the context on the stack. Otherwise
// we need to allocate one.
//
if (Wait) {
IrpContext->IoContext = &LocalIoContext;
ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
} else {
IrpContext->IoContext = CdAllocateIoContext();
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
}
}
RtlZeroMemory( IrpContext->IoContext, sizeof( CD_IO_CONTEXT ) );
//
// Store whether we allocated this context structure in the structure
// itself.
//
IrpContext->IoContext->AllocatedContext =
BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
if (Wait) {
KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
NotificationEvent,
FALSE );
} else {
IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread();
IrpContext->IoContext->Resource = Fcb->Resource;
IrpContext->IoContext->RequestedByteCount = ByteCount;
}
Irp->IoStatus.Information = WriteByteCount;
//
// Set the FO_MODIFIED flag here to trigger a verify when this
// handle is closed. Note that we can err on the conservative
// side with no problem, i.e. if we accidently do an extra
// verify there is no problem.
//
SetFlag( IrpSp->FileObject->Flags, FO_FILE_MODIFIED );
//
// Dasd access is always non-cached. Call the Dasd write routine to
// perform the actual write.
//
Status = CdVolumeDasdWrite( IrpContext, Fcb, StartingOffset, WriteByteCount );
//
// Don't complete this request now if STATUS_PENDING was returned.
//
if (Status == STATUS_PENDING) {
Irp = NULL;
ReleaseFile = FALSE;
//
// Test is we should zero part of the buffer or update the
// synchronous file position.
//
} else {
//
// Convert any unknown error code to IO_ERROR.
//
if (!NT_SUCCESS( Status )) {
//
// Set the information field to zero.
//
Irp->IoStatus.Information = 0;
//
// Raise if this is a user induced error.
//
if (IoIsErrorUserInduced( Status )) {
CdRaiseStatus( IrpContext, Status );
}
Status = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR );
//
// Check if there is any portion of the user's buffer to zero.
//
} else if (WriteByteCount != ByteCount) {
CdMapUserBuffer( IrpContext, &UserBuffer );
SafeZeroMemory( IrpContext,
Add2Ptr( UserBuffer,
ByteCount,
PVOID ),
WriteByteCount - ByteCount );
Irp->IoStatus.Information = ByteCount;
}
//
// Update the file position if this is a synchronous request.
//
if (SynchronousIo && NT_SUCCESS( Status )) {
IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
}
}
try_exit: NOTHING;
} finally {
//
// Release the Fcb.
//
if (ReleaseFile) {
CdReleaseFile( IrpContext, Fcb );
}
}
//
// Post the request if we got CANT_WAIT.
//
if (Status == STATUS_CANT_WAIT) {
Status = CdFsdPostRequest( IrpContext, Irp );
//
// Otherwise complete the request.
//
} else {
CdCompleteRequest( IrpContext, Irp, Status );
}
return Status;
}