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; \ 120 FatOpenTargetDirectory (
133 FatOpenExistingDirectory (
155 FatOpenExistingFile (
182 FatCreateNewDirectory (
227 FatSupersedeOrOverwriteFile (
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) 400 FatCommonCreateCallout (
434 CalloutParameters->IrpStatus = FatCommonCreate( CalloutParameters->Create.IrpContext,
435 CalloutParameters->Create.Irp );
451 FatCommonCreateOnNewStack (
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);
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;
1893 if (TemporaryFile) {
1898 Iosb = FatCreateNewDirectory( IrpContext,
1914 Irp->IoStatus.Information =
Iosb.Information;
1920 if ( TrailingBackslash ) {
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) {
2507 UnwindShareAccess =
TRUE;
2519 FileObject->SectionObjectPointer = &
Vcb->SectionObjectPointers;
2521 Vcb->DirectAccessOpenCount += 1;
2522 Vcb->OpenFileCount += 1;
2524 UnwindCounts =
TRUE;
2538 IrpContext->OriginatingIrp->RequestorMode ));
2564 Vcb->DirectAccessOpenCount -= 1;
2565 Vcb->OpenFileCount -= 1;
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) {
2761 FatOpenExistingDcb (
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);
3181 FatOpenExistingFcb (
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);
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);
3923 FatOpenTargetDirectory (
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) // bug in PREFast means the _Success_ annotation is not correctly applied 4135 FatOpenExistingDirectory (
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;
4399 DebugTrace(-1,
Dbg,
"FatOpenExistingDirectory -> Iosb.Status = %08lx\n",
Iosb.Status);
4412 FatOpenExistingFile (
4516 #if (NTDDI_VERSION < NTDDI_WIN7) 4590 DebugTrace(0,
Dbg,
"The hidden and/or system bits do not match\n", 0);
4592 if ( !IsPagingFile ) {
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);
4892 FatCreateNewDirectory (
4969 ULONG ShortDirentByteOffset;
4977 ULONG BytesInFirstPage = 0;
4978 ULONG DirentsInFirstPage = 0;
4982 ULONG SecondPageOffset;
4989 UCHAR ShortNameBuffer[12];
4991 #if (NTDDI_VERSION <= NTDDI_WIN7) 5016 DebugTrace(-1,
Dbg,
"FatCreateNewDirectory -> Iosb.Status = %08lx\n",
Iosb.Status);
5033 FatSelectNames( IrpContext,
5066 FatPrepareWriteDirectoryFile( IrpContext,
5098 DirentsInFirstPage = BytesInFirstPage /
sizeof(
DIRENT);
5100 FatPrepareWriteDirectoryFile( IrpContext,
5108 (
PVOID *)&SecondPageDirent,
5116 FirstPageDirent =
Dirent;
5122 DirentFromPool =
TRUE;
5154 if (DirentFromPool) {
5159 Dirent + DirentsInFirstPage,
5162 ShortDirent = SecondPageDirent + (
DirentsNeeded - DirentsInFirstPage) - 1;
5173 ShortDirentByteOffset,
5177 #if (NTDDI_VERSION >= NTDDI_WIN8) 5191 IrpContext->OriginatingIrp,
5207 IrpContext->OriginatingIrp,
5208 (
Dcb->UncleanCount + 1) );