23#define BugCheckFileId (FAT_BUG_CHECK_CREATE)
29#define Dbg (DEBUG_TRACE_CREATE)
36#define CollectCreateHitStatistics(VCB) { \
37 PFILE_SYSTEM_STATISTICS Stats = &(VCB)->Statistics[KeGetCurrentProcessorNumber() % FatData.NumberProcessors]; \
38 Stats->Fat.CreateHits += 1; \
41#define CollectCreateStatistics(VCB,STATUS) { \
42 PFILE_SYSTEM_STATISTICS Stats = &(VCB)->Statistics[KeGetCurrentProcessorNumber() % FatData.NumberProcessors]; \
43 if ((STATUS) == STATUS_SUCCESS) { \
44 Stats->Fat.SuccessfulCreates += 1; \
46 Stats->Fat.FailedCreates += 1; \
120FatOpenTargetDirectory (
133FatOpenExistingDirectory (
182FatCreateNewDirectory (
227FatSupersedeOrOverwriteFile (
254#pragma alloc_text(PAGE, FatCheckShareAccess)
255#pragma alloc_text(PAGE, FatCheckSystemSecurityAccess)
256#pragma alloc_text(PAGE, FatCommonCreate)
258#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
259#pragma alloc_text(PAGE, FatCommonCreateOnNewStack)
260#pragma alloc_text(PAGE, FatCommonCreateCallout)
263#pragma alloc_text(PAGE, FatCreateNewDirectory)
264#pragma alloc_text(PAGE, FatCreateNewFile)
265#pragma alloc_text(PAGE, FatFsdCreate)
266#pragma alloc_text(PAGE, FatOpenExistingDcb)
267#pragma alloc_text(PAGE, FatOpenExistingDirectory)
268#pragma alloc_text(PAGE, FatOpenExistingFcb)
269#pragma alloc_text(PAGE, FatOpenExistingFile)
270#pragma alloc_text(PAGE, FatOpenRootDcb)
271#pragma alloc_text(PAGE, FatOpenTargetDirectory)
272#pragma alloc_text(PAGE, FatOpenVolume)
273#pragma alloc_text(PAGE, FatSupersedeOrOverwriteFile)
274#pragma alloc_text(PAGE, FatSetFullNameInFcb)
349#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
350 Status = FatCommonCreateOnNewStack( IrpContext,
Irp );
352 Status = FatCommonCreate( IrpContext,
Irp );
365 ExceptionCompletedIrp =
TRUE;
397#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
400FatCommonCreateCallout (
434 CalloutParameters->IrpStatus = FatCommonCreate( CalloutParameters->Create.IrpContext,
435 CalloutParameters->Create.Irp );
451FatCommonCreateOnNewStack (
488 CalloutParameters.
Create.IrpContext = IrpContext;
498 status = KeExpandKernelStackAndCalloutEx( FatCommonCreateCallout,
591 BOOLEAN NoIntermediateBuffering;
630 ULONG MatchFlags = 0;
653 DebugTrace( 0,
Dbg,
"->AllocationSize.LowPart = %08lx\n",
Irp->Overlay.AllocationSize.LowPart );
654 DebugTrace( 0,
Dbg,
"->AllocationSize.HighPart = %08lx\n",
Irp->Overlay.AllocationSize.HighPart );
655 DebugTrace( 0,
Dbg,
"->SystemBuffer = %p\n",
Irp->AssociatedIrp.SystemBuffer );
685 DebugTrace(-1,
Dbg,
"FatCommonCreate -> STATUS_OBJECT_NAME_INVALID\n", 0);
698 RelatedFileObject =
FileObject->RelatedFileObject;
712 if ( RelatedFileObject !=
NULL ) {
756#if (NTDDI_VERSION >= NTDDI_WIN7)
784 if (
Irp->Overlay.AllocationSize.HighPart != 0 ||
787 DebugTrace(-1,
Dbg,
"FatCommonCreate -> STATUS_INVALID_PARAMETER\n", 0);
814#pragma prefast( suppress:28159, "this is a serious programming error if it happens" )
829 OemFinalName.Length = 0;
830 OemFinalName.MaximumLength =
sizeof( OemBuffer);
831 OemFinalName.Buffer = (
PCHAR)OemBuffer;
833 UpcasedFinalName.
Length = 0;
835 UpcasedFinalName.
Buffer = UpcasedBuffer;
838 Lfn.MaximumLength =
sizeof( LfnBuffer);
880 Vcb->Vpb->RealDevice );
907 if (RelatedFileObject ==
NULL ||
921 DebugTrace(0,
Dbg,
"Cannot open volume as a directory\n", 0);
930 if (OpenTargetDirectory) {
946 Irp->IoStatus.Information =
Iosb.Information;
957 if (RelatedFileObject !=
NULL) {
1000 FatVerifyFcb( IrpContext, RelatedDcb );
1018 if (NonDirectoryFile) {
1020 DebugTrace(0,
Dbg,
"Cannot open root directory as a file\n", 0);
1029 if (OpenTargetDirectory) {
1047 Iosb = FatOpenRootDcb( IrpContext,
1054 Irp->IoStatus.Information =
Iosb.Information;
1081 TrailingBackslash =
TRUE;
1085 TrailingBackslash =
FALSE;
1096 FatSetFullFileNameInFcb( IrpContext,
ParentDcb );
1128 &NextRemainingPart );
1136 if (((NextRemainingPart.
Length != 0) && (NextRemainingPart.
Buffer[0] ==
L'\\')) ||
1164 OemFinalName.Length = 0;
1208 if (NextFcb !=
NULL) {
1213 if ((NextFcb ==
NULL) ||
1215 (NextRemainingPart.
Length == 0)) {
1237 FatVerifyFcb( IrpContext,
Fcb );
1253 if (IsPagingFile && FirstLoop &&
1325 if (OpenTargetDirectory) {
1329 Iosb = FatOpenTargetDirectory( IrpContext,
1336 Irp->IoStatus.Information =
Iosb.Information;
1352 if (NonDirectoryFile) {
1363 Iosb = FatOpenExistingDcb( IrpContext,
1379 Irp->IoStatus.Information =
Iosb.Information;
1416 if ( TrailingBackslash ) {
1422 Iosb = FatOpenExistingFcb( IrpContext,
1452 Irp->IoStatus.Information =
Iosb.Information;
1469#pragma prefast( suppress:28159, "this is a serious corruption if it happens" )
1624 FatLocateDirent( IrpContext,
1706 if (OpenTargetDirectory) {
1708 Iosb = FatOpenTargetDirectory( IrpContext,
1716 Irp->IoStatus.Information =
Iosb.Information;
1740 if (NonDirectoryFile) {
1749 Iosb = FatOpenExistingDirectory( IrpContext,
1767 Irp->IoStatus.Information =
Iosb.Information;
1785 if ( TrailingBackslash ) {
1790 Iosb = FatOpenExistingFile( IrpContext,
1823 Irp->IoStatus.Information =
Iosb.Information;
1851 OemFinalName.Length = 0;
1881 Vcb->Vpb->RealDevice );
1893 if (TemporaryFile) {
1898 Iosb = FatCreateNewDirectory( IrpContext,
1914 Irp->IoStatus.Information =
Iosb.Information;
1920 if ( TrailingBackslash ) {
1939 Vcb->Vpb->RealDevice );
1947 Iosb = FatCreateNewFile( IrpContext,
1977 Irp->IoStatus.Information =
Iosb.Information;
2008#if (NTDDI_VERSION >= NTDDI_WIN7)
2025 IrpContext->OriginatingIrp,
2062 SavedFlags = IrpContext->Flags;
2069 if ((FinalDcb !=
NULL) &&
2077 DirectoryFileObject = FinalDcb->
Specific.
Dcb.DirectoryFile;
2086 IrpContext->Flags = SavedFlags;
2120 if (!OplockPostIrp) {
2167 FatTruncateFileAllocation( IrpContext, LocalFcb, 0 );
2169 FatDeleteDirent( IrpContext, LocalFcb,
NULL,
TRUE );
2190 DirectoryFileObject = LocalFcb->
Specific.
Dcb.DirectoryFile;
2237#pragma prefast( suppress:28112, "this should be safe" )
2259#pragma prefast( suppress:28112, "this should be safe" )
2370#if (NTDDI_VERSION >= NTDDI_VISTA)
2379 FsRtlAreVolumeStartupApplicationsComplete()) {
2401 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
2413 if (
Vcb->OpenFileCount != 0) {
2420 if (
Vcb->ReadOnlyCount !=
Vcb->OpenFileCount) {
2432 UnwindVolumeLock =
TRUE;
2438 CleanedVolume =
TRUE;
2449 CleanedVolume =
TRUE;
2457 if (CleanedVolume &&
2488 if (
Vcb->DirectAccessOpenCount > 0) {
2504 &
Vcb->ShareAccess );
2507 UnwindShareAccess =
TRUE;
2519 FileObject->SectionObjectPointer = &
Vcb->SectionObjectPointers;
2521 Vcb->DirectAccessOpenCount += 1;
2522 Vcb->OpenFileCount += 1;
2524 UnwindCounts =
TRUE;
2534 Vcb->Vpb->RealDevice,
2538 IrpContext->OriginatingIrp->RequestorMode ));
2564 Vcb->DirectAccessOpenCount -= 1;
2565 Vcb->OpenFileCount -= 1;
2570 if (UnwindVolumeLock) {
Vcb->VcbState &= ~VCB_STATE_FLAG_LOCKED; }
2642 RootDcb =
Vcb->RootDcb;
2649 (
VOID)FatAcquireExclusiveFcb( IrpContext, RootDcb );
2650 RootDcbAcquired =
TRUE;
2697 UnwindShareAccess =
TRUE;
2711 Vcb->OpenFileCount += 1;
2713 UnwindCounts =
TRUE;
2736 Vcb->OpenFileCount -= 1;
2743 if (RootDcbAcquired) {
2821#if (NTDDI_VERSION <= NTDDI_WIN7)
2836 (
VOID)FatAcquireExclusiveFcb( IrpContext,
Dcb );
2842 *OplockPostIrp =
FALSE;
2856#if (NTDDI_VERSION >= NTDDI_WIN8)
2864 IrpContext->OriginatingIrp,
2893 FatGetDirentFromFcbOrDcb( IrpContext,
2899 FatGetNeedEaCount( IrpContext,
2925 Dcb->DirentFatFlags,
2937 if (
Dcb->OpenCount > 0) {
2944#if (NTDDI_VERSION >= NTDDI_WIN8)
2959 IrpContext->OriginatingIrp,
2973 *OplockPostIrp =
TRUE;
2980 }
else if (!
NT_SUCCESS( OplockBreakStatus )) {
2982 Iosb.Status = OplockBreakStatus;
3016#if (NTDDI_VERSION >= NTDDI_WIN8)
3024 if (
Dcb->UncleanCount != 0) {
3027 IrpContext->OriginatingIrp,
3040 *OplockPostIrp =
TRUE;
3054 IrpContext->OriginatingIrp,
3055 (
Dcb->UncleanCount + 1) );
3080 if (
Dcb->OpenCount > 0) {
3092 UnwindShareAccess =
TRUE;
3104 Dcb->UncleanCount += 1;
3105 Dcb->OpenCount += 1;
3106 Vcb->OpenFileCount += 1;
3168 DebugTrace(-1,
Dbg,
"FatOpenExistingDcb -> Iosb.Status = %08lx\n",
Iosb.Status);
3278 (
VOID)FatAcquireExclusiveFcb( IrpContext,
Fcb );
3284 *OplockPostIrp =
FALSE;
3286#if (NTDDI_VERSION >= NTDDI_WIN7)
3294 IrpContext->OriginatingIrp,
3321 IrpContext->OriginatingIrp,
3333 *OplockPostIrp =
TRUE;
3413 DebugTrace(0,
Dbg,
"The hidden and/or system bits do not match\n", 0);
3433 Vcb->Vpb->RealDevice );
3452#if (NTDDI_VERSION >= NTDDI_WIN7)
3467 IrpContext->OriginatingIrp,
3481 *OplockPostIrp =
TRUE;
3488 }
else if (!
NT_SUCCESS( OplockBreakStatus )) {
3490 Iosb.Status = OplockBreakStatus;
3538 IrpContext->OriginatingIrp,
3551 *OplockPostIrp =
TRUE;
3565 IrpContext->OriginatingIrp,
3601 DecrementFcbOpenCount =
TRUE;
3604 MmFlushForWrite )) {
3672 FatGetDirentFromFcbOrDcb( IrpContext,
3678 FatGetNeedEaCount( IrpContext,
3725 DebugTrace(0,
Dbg,
"Doing supersede/overwrite operation\n", 0);
3732 OldStatus =
Iosb.Status;
3747 Iosb = FatSupersedeOrOverwriteFile( IrpContext,
3759 Iosb.Status = OldStatus;
3770#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
3797#pragma prefast( suppress:28931, "it needs to be there for debug assert" );
3817 UnwindShareAccess =
TRUE;
3830 Vcb->OpenFileCount += 1;
3864 IrpContext->OriginatingIrp->RequestorMode ))) {
3893 if (DecrementFcbOpenCount) {
3902 FcbAcquired =
FALSE;
3911 DebugTrace(-1,
Dbg,
"FatOpenExistingFcb -> Iosb.Status = %08lx\n",
Iosb.Status);
3923FatOpenTargetDirectory (
3980 (
VOID)FatAcquireExclusiveFcb( IrpContext,
Dcb );
3992 if (
Dcb->OpenCount > 0) {
4011 UnwindShareAccess =
TRUE;
4023 Dcb->UncleanCount += 1;
4024 Dcb->OpenCount += 1;
4025 Dcb->Vcb->OpenFileCount += 1;
4118 DebugTrace(-1,
Dbg,
"FatOpenTargetDirectory -> Iosb.Status = %08lx\n",
Iosb.Status);
4133#pragma warning(suppress:6101)
4135FatOpenExistingDirectory (
4217#if (NTDDI_VERSION <= NTDDI_WIN7)
4237 FatGetNeedEaCount( IrpContext,
4280#if (NTDDI_VERSION >= NTDDI_WIN8)
4288 IrpContext->OriginatingIrp,
4304 IrpContext->OriginatingIrp,
4305 ((*Dcb)->UncleanCount + 1) );
4340 (*Dcb)->UncleanCount += 1;
4341 (*Dcb)->OpenCount += 1;
4383 (*Dcb)->UncleanCount -= 1;
4384 (*Dcb)->OpenCount -= 1;
4385 Vcb->OpenFileCount -= 1;
4412FatOpenExistingFile (
4516#if (NTDDI_VERSION < NTDDI_WIN7)
4590 DebugTrace(0,
Dbg,
"The hidden and/or system bits do not match\n", 0);
4592 if ( !IsPagingFile ) {
4613 Vcb->Vpb->RealDevice );
4638 (*Fcb)->Header.ValidDataLength.LowPart = (*Fcb)->Header.FileSize.LowPart;
4647 FatLookupFileAllocationSize( IrpContext, *
Fcb );
4650#if (NTDDI_VERSION >= NTDDI_WIN7)
4658 IrpContext->OriginatingIrp,
4674 IrpContext->OriginatingIrp,
4675 ((*Fcb)->UncleanCount + 1) );
4712 FatGetNeedEaCount( IrpContext,
4732 FileObject->SectionObjectPointer = &(*Fcb)->NonPaged->SectionObjectPointers;
4742 DebugTrace(0,
Dbg,
"Doing supersede/overwrite operation\n", 0);
4753 Iosb = FatSupersedeOrOverwriteFile( IrpContext,
4769#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
4795 (*Fcb)->UncleanCount += 1;
4796 (*Fcb)->OpenCount += 1;
4798 (*Fcb)->NonCachedUncleanCount += 1;
4800 Vcb->OpenFileCount += 1;
4839 IrpContext->OriginatingIrp->RequestorMode ))) {
4859 (*Fcb)->UncleanCount -= 1;
4860 (*Fcb)->OpenCount -= 1;
4862 (*Fcb)->NonCachedUncleanCount -= 1;
4864 Vcb->OpenFileCount -= 1;
4868 if (UnwindFcb !=
NULL) {
4879 DebugTrace(-1,
Dbg,
"FatOpenExistingFile -> Iosb.Status = %08lx\n",
Iosb.Status);
4892FatCreateNewDirectory (