ReactOS 0.4.16-dev-87-g3dfbe52
create.c File Reference
#include "vfat.h"
#include <debug.h>
Include dependency graph for create.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
 
NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Parent, PUNICODE_STRING FileToFindU, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
 
static NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING PathNameU, PFILE_OBJECT FileObject, ULONG RequestedDisposition, ULONG RequestedOptions, PVFATFCB *ParentFcb)
 
static NTSTATUS VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file create.c.

Function Documentation

◆ FindFile()

NTSTATUS FindFile ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  Parent,
PUNICODE_STRING  FileToFindU,
PVFAT_DIRENTRY_CONTEXT  DirContext,
BOOLEAN  First 
)

Definition at line 83 of file create.c.

89{
90 PWCHAR PathNameBuffer;
91 USHORT PathNameBufferLength;
94 PVOID Page;
95 PVFATFCB rcFcb;
97 UNICODE_STRING PathNameU;
98 UNICODE_STRING FileToFindUpcase;
99 BOOLEAN WildCard;
100 BOOLEAN IsFatX = vfatVolumeIsFatX(DeviceExt);
101
102 DPRINT("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
103 Parent, FileToFindU, DirContext->DirIndex);
104 DPRINT("FindFile: Path %wZ\n",&Parent->PathNameU);
105
106 PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
107 PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength + sizeof(WCHAR), TAG_NAME);
108 if (!PathNameBuffer)
109 {
111 }
112
113 PathNameU.Buffer = PathNameBuffer;
114 PathNameU.Length = 0;
115 PathNameU.MaximumLength = PathNameBufferLength;
116
117 DirContext->LongNameU.Length = 0;
118 DirContext->ShortNameU.Length = 0;
119
120 WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
121
122 if (WildCard == FALSE)
123 {
124 /* if there is no '*?' in the search name, than look first for an existing fcb */
125 RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
126 if (!vfatFCBIsRoot(Parent))
127 {
128 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
129 PathNameU.Length += sizeof(WCHAR);
130 }
131 RtlAppendUnicodeStringToString(&PathNameU, FileToFindU);
132 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
133 rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
134 if (rcFcb)
135 {
136 ULONG startIndex = rcFcb->startIndex;
137 if (IsFatX && !vfatFCBIsRoot(Parent))
138 {
139 startIndex += 2;
140 }
141 if(startIndex >= DirContext->DirIndex)
142 {
143 RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
144 RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
145 RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
146 DirContext->StartIndex = rcFcb->startIndex;
147 DirContext->DirIndex = rcFcb->dirIndex;
148 DPRINT("FindFile: new Name %wZ, DirIndex %u (%u)\n",
149 &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
151 }
152 else
153 {
154 DPRINT("FCB not found for %wZ\n", &PathNameU);
156 }
157 vfatReleaseFCB(DeviceExt, rcFcb);
158 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
159 return Status;
160 }
161 }
162
163 /* FsRtlIsNameInExpression need the searched string to be upcase,
164 * even if IgnoreCase is specified */
165 Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
166 if (!NT_SUCCESS(Status))
167 {
168 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
169 return Status;
170 }
171
172 while (TRUE)
173 {
175 First = FALSE;
177 {
178 break;
179 }
180 if (ENTRY_VOLUME(IsFatX, &DirContext->DirEntry))
181 {
183 continue;
184 }
185 if (DirContext->LongNameU.Length == 0 ||
186 DirContext->ShortNameU.Length == 0)
187 {
188 DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
190 {
191 ASSERT(DirContext->LongNameU.Length != 0 &&
192 DirContext->ShortNameU.Length != 0);
193 }
195 continue;
196 }
197 if (WildCard)
198 {
199 Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
200 FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
201 }
202 else
203 {
204 Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
205 FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
206 }
207
208 if (Found)
209 {
210 if (WildCard)
211 {
212 RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
213 if (!vfatFCBIsRoot(Parent))
214 {
215 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
216 PathNameU.Length += sizeof(WCHAR);
217 }
218 RtlAppendUnicodeStringToString(&PathNameU, &DirContext->LongNameU);
219 PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
220 rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
221 if (rcFcb != NULL)
222 {
223 RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
224 vfatReleaseFCB(DeviceExt, rcFcb);
225 }
226 }
227 DPRINT("%u\n", DirContext->LongNameU.Length);
228 DPRINT("FindFile: new Name %wZ, DirIndex %u\n",
229 &DirContext->LongNameU, DirContext->DirIndex);
230
231 if (Context)
232 {
234 }
235 RtlFreeUnicodeString(&FileToFindUpcase);
236 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
237 return STATUS_SUCCESS;
238 }
240 }
241
242 if (Context)
243 {
245 }
246
247 RtlFreeUnicodeString(&FileToFindUpcase);
248 ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
249 return Status;
250}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:425
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define NonPagedPool
Definition: env_spec_w32.h:307
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
ULONG Flags
Definition: vfat.h:413
ULONG DirIndex
Definition: ntfs.h:533
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: vfat.h:448
ULONG dirIndex
Definition: vfat.h:502
UNICODE_STRING ShortNameU
Definition: vfat.h:466
ULONG startIndex
Definition: vfat.h:505
DIR_ENTRY entry
Definition: vfat.h:457
UNICODE_STRING LongNameU
Definition: vfat.h:463
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: vfat.h:225
#define ENTRY_VOLUME(IsFatX, DirEntry)
Definition: vfat.h:206
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407
FORCEINLINE NTSTATUS VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt, PVOID *pContext, PVOID *pPage, struct _VFATFCB *pDirFcb, struct _VFAT_DIRENTRY_CONTEXT *DirContext, BOOLEAN First)
Definition: vfat.h:397
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
#define TAG_NAME
Definition: vfat.h:553
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ vfat8Dot3ToString()

VOID vfat8Dot3ToString ( PFAT_DIR_ENTRY  pEntry,
PUNICODE_STRING  NameU 
)

Definition at line 19 of file create.c.

22{
23 OEM_STRING StringA;
25 CHAR cString[12];
26
27 RtlCopyMemory(cString, pEntry->ShortName, 11);
28 cString[11] = 0;
29 if (cString[0] == 0x05)
30 {
31 cString[0] = 0xe5;
32 }
33
34 StringA.Buffer = cString;
35 for (StringA.Length = 0;
36 StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
37 StringA.Length++);
38 StringA.MaximumLength = StringA.Length;
39
40 RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
41
43 {
44 RtlDowncaseUnicodeString(NameU, NameU, FALSE);
45 }
46
47 if (cString[8] != ' ')
48 {
49 Length = NameU->Length;
50 NameU->Buffer += Length / sizeof(WCHAR);
52 {
53 Length += sizeof(WCHAR);
54 NameU->Buffer[0] = L'.';
55 NameU->Buffer++;
56 }
57 NameU->Length = 0;
58 NameU->MaximumLength -= Length;
59
60 StringA.Buffer = &cString[8];
61 for (StringA.Length = 0;
62 StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
63 StringA.Length++);
64 StringA.MaximumLength = StringA.Length;
65 RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
67 {
68 RtlDowncaseUnicodeString(NameU, NameU, FALSE);
69 }
70 NameU->Buffer -= Length / sizeof(WCHAR);
71 NameU->Length += Length;
72 NameU->MaximumLength += Length;
73 }
74
75 NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
76 DPRINT("'%wZ'\n", NameU);
77}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
STRING OEM_STRING
Definition: umtypes.h:203
#define VFAT_CASE_LOWER_EXT
Definition: vfat.h:201
#define FAT_ENTRY_VOLUME(DirEntry)
Definition: vfat.h:212
#define VFAT_CASE_LOWER_BASE
Definition: vfat.h:200
char CHAR
Definition: xmlstorage.h:175

Referenced by FATGetNextDirEntry(), and ReadVolumeLabel().

◆ VfatCreate()

NTSTATUS VfatCreate ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1070 of file create.c.

1072{
1074
1075 ASSERT(IrpContext);
1076
1077 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
1078 {
1079 /* DeviceObject represents FileSystem instead of logical volume */
1080 DPRINT ("FsdCreate called with file system\n");
1081 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
1082 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1083
1084 return STATUS_SUCCESS;
1085 }
1086
1087 IrpContext->Irp->IoStatus.Information = 0;
1089 Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
1091
1092 if (NT_SUCCESS(Status))
1093 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1094
1095 return Status;
1096}
static NTSTATUS VfatCreateFile(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: create.c:404
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define FILE_OPENED
Definition: nt_native.h:769
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
ERESOURCE DirResource
Definition: ntfs.h:103
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
CCHAR PriorityBoost
Definition: vfat.h:594
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
IO_STATUS_BLOCK IoStatus
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

Referenced by VfatDispatchRequest().

◆ VfatCreateFile()

static NTSTATUS VfatCreateFile ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 404 of file create.c.

407{
411 PDEVICE_EXTENSION DeviceExt;
412 ULONG RequestedDisposition, RequestedOptions;
413 PVFATFCB pFcb = NULL;
415 PVFATCCB pCcb = NULL;
416 PWCHAR c, last;
417 BOOLEAN PagingFileCreate;
418 BOOLEAN Dots;
419 BOOLEAN OpenTargetDir;
420 BOOLEAN TrailingBackslash;
421 UNICODE_STRING FileNameU;
422 UNICODE_STRING PathNameU;
424
425 /* Unpack the various parameters. */
427 RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
428 RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
429 PagingFileCreate = BooleanFlagOn(Stack->Flags, SL_OPEN_PAGING_FILE);
430 OpenTargetDir = BooleanFlagOn(Stack->Flags, SL_OPEN_TARGET_DIRECTORY);
431
432 FileObject = Stack->FileObject;
433 DeviceExt = DeviceObject->DeviceExtension;
434
435 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID))
436 {
438 }
439
440 /* Check their validity. */
441 if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
442 RequestedDisposition == FILE_SUPERSEDE)
443 {
445 }
446
447 if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
448 BooleanFlagOn(RequestedOptions, FILE_NON_DIRECTORY_FILE))
449 {
451 }
452
453 /* Deny create if the volume is locked */
454 if (BooleanFlagOn(DeviceExt->Flags, VCB_VOLUME_LOCKED))
455 {
457 }
458
459 /* This a open operation for the volume itself */
460 if (FileObject->FileName.Length == 0 &&
461 (FileObject->RelatedFileObject == NULL ||
462 FileObject->RelatedFileObject->FsContext2 != NULL ||
463 FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb))
464 {
465 DPRINT("Volume opening\n");
466
467 if (RequestedDisposition != FILE_OPEN &&
468 RequestedDisposition != FILE_OPEN_IF)
469 {
471 }
472
473 if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
474 (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 == NULL || FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb))
475 {
477 }
478
479 if (OpenTargetDir)
480 {
482 }
483
484 if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
485 {
487 }
488
489 vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
490
491 pFcb = DeviceExt->VolumeFcb;
492
493 if (pFcb->OpenHandleCount == 0)
494 {
495 IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
496 Stack->Parameters.Create.ShareAccess,
498 &pFcb->FCBShareAccess);
499 }
500 else
501 {
502 Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
503 Stack->Parameters.Create.ShareAccess,
505 &pFcb->FCBShareAccess,
506 TRUE);
507 if (!NT_SUCCESS(Status))
508 {
509 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
510 return Status;
511 }
512 }
513
514 vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
515 DeviceExt->OpenHandleCount++;
516 pFcb->OpenHandleCount++;
517 vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
518
519 Irp->IoStatus.Information = FILE_OPENED;
520 return STATUS_SUCCESS;
521 }
522
523 if (FileObject->RelatedFileObject != NULL &&
524 FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb)
525 {
526 ASSERT(FileObject->FileName.Length != 0);
528 }
529
530 /* Check for illegal characters and illegal dot sequences in the file name */
531 PathNameU = FileObject->FileName;
532 c = PathNameU.Buffer + PathNameU.Length / sizeof(WCHAR);
533 last = c - 1;
534
535 Dots = TRUE;
536 while (c-- > PathNameU.Buffer)
537 {
538 if (*c == L'\\' || c == PathNameU.Buffer)
539 {
540 if (Dots && last > c)
541 {
543 }
544 if (*c == L'\\' && (c - 1) > PathNameU.Buffer &&
545 *(c - 1) == L'\\')
546 {
548 }
549
550 last = c - 1;
551 Dots = TRUE;
552 }
553 else if (*c != L'.')
554 {
555 Dots = FALSE;
556 }
557
558 if (*c != '\\' && vfatIsLongIllegal(*c))
559 {
561 }
562 }
563
564 /* Check if we try to open target directory of root dir */
565 if (OpenTargetDir && FileObject->RelatedFileObject == NULL && PathNameU.Length == sizeof(WCHAR) &&
566 PathNameU.Buffer[0] == L'\\')
567 {
569 }
570
571 if (FileObject->RelatedFileObject && PathNameU.Length >= sizeof(WCHAR) && PathNameU.Buffer[0] == L'\\')
572 {
574 }
575
576 TrailingBackslash = FALSE;
577 if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
578 {
579 PathNameU.Length -= sizeof(WCHAR);
580 TrailingBackslash = TRUE;
581 }
582
583 if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
584 {
586 }
587
588 /* Try opening the file. */
589 if (!OpenTargetDir)
590 {
591 vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
592
593 Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, RequestedOptions, &ParentFcb);
594 }
595 else
596 {
597 PVFATFCB TargetFcb;
599
600 vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
601
602 ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL;
603 if (ParentFcb)
604 {
605 vfatGrabFCB(DeviceExt, ParentFcb);
606 }
607
608 Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
609 if (NT_SUCCESS(Status))
610 {
611 vfatReleaseFCB(DeviceExt, TargetFcb);
612 Irp->IoStatus.Information = FILE_EXISTS;
613 }
614 else
615 {
616 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
617 }
618
619 idx = FileObject->FileName.Length / sizeof(WCHAR) - 1;
620
621 /* Skip trailing \ - if any */
622 if (PathNameU.Buffer[idx] == L'\\')
623 {
624 --idx;
625 PathNameU.Length -= sizeof(WCHAR);
626 }
627
628 /* Get file name */
629 while (idx >= 0 && PathNameU.Buffer[idx] != L'\\')
630 {
631 --idx;
632 }
633
634 if (idx > 0 || PathNameU.Buffer[0] == L'\\')
635 {
636 /* We don't want to include / in the name */
637 FileNameLen = PathNameU.Length - ((idx + 1) * sizeof(WCHAR));
638
639 /* Update FO just to keep file name */
640 /* Skip first slash */
641 ++idx;
642 FileObject->FileName.Length = FileNameLen;
643 RtlMoveMemory(&PathNameU.Buffer[0], &PathNameU.Buffer[idx], FileObject->FileName.Length);
644#if 0
645 /* Terminate the string at the last backslash */
646 PathNameU.Buffer[idx + 1] = UNICODE_NULL;
647 PathNameU.Length = (idx + 1) * sizeof(WCHAR);
648 PathNameU.MaximumLength = PathNameU.Length + sizeof(WCHAR);
649
650 /* Update the file object as well */
651 FileObject->FileName.Length = PathNameU.Length;
652 FileObject->FileName.MaximumLength = PathNameU.MaximumLength;
653#endif
654 }
655 else
656 {
657 /* This is a relative open and we have only the filename, so open the parent directory
658 * It is in RelatedFileObject
659 */
660 ASSERT(FileObject->RelatedFileObject != NULL);
661
662 /* No need to modify the FO, it already has the name */
663 }
664
665 /* We're done with opening! */
666 if (ParentFcb != NULL)
667 {
669 }
670
671 if (NT_SUCCESS(Status))
672 {
673 pFcb = FileObject->FsContext;
674 ASSERT(pFcb == ParentFcb);
675
676 if (pFcb->OpenHandleCount == 0)
677 {
678 IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
679 Stack->Parameters.Create.ShareAccess,
681 &pFcb->FCBShareAccess);
682 }
683 else
684 {
685 Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
686 Stack->Parameters.Create.ShareAccess,
688 &pFcb->FCBShareAccess,
689 FALSE);
690 if (!NT_SUCCESS(Status))
691 {
692 VfatCloseFile(DeviceExt, FileObject);
693 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
694 return Status;
695 }
696 }
697
698 pCcb = FileObject->FsContext2;
699 if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
700 {
701 pCcb->Flags |= CCB_DELETE_ON_CLOSE;
702 }
703
704 pFcb->OpenHandleCount++;
705 DeviceExt->OpenHandleCount++;
706 }
707 else if (ParentFcb != NULL)
708 {
709 vfatReleaseFCB(DeviceExt, ParentFcb);
710 }
711
712 if (NT_SUCCESS(Status))
713 {
714 vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
715 }
716 else
717 {
718 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
719 }
720
721 return Status;
722 }
723
724 /*
725 * If the directory containing the file to open doesn't exist then
726 * fail immediately
727 */
733 {
734 if (ParentFcb)
735 {
736 vfatReleaseFCB(DeviceExt, ParentFcb);
737 }
738 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
739 return Status;
740 }
741
742 if (!NT_SUCCESS(Status) && ParentFcb == NULL)
743 {
744 DPRINT1("VfatOpenFile failed for '%wZ', status %x\n", &PathNameU, Status);
745 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
746 return Status;
747 }
748
749 Attributes = (Stack->Parameters.Create.FileAttributes & (FILE_ATTRIBUTE_ARCHIVE |
754
755 /* If the file open failed then create the required file */
756 if (!NT_SUCCESS (Status))
757 {
758 if (RequestedDisposition == FILE_CREATE ||
759 RequestedDisposition == FILE_OPEN_IF ||
760 RequestedDisposition == FILE_OVERWRITE_IF ||
761 RequestedDisposition == FILE_SUPERSEDE)
762 {
763 if (!BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE))
764 {
765 if (TrailingBackslash)
766 {
767 vfatReleaseFCB(DeviceExt, ParentFcb);
768 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
770 }
772 }
773 vfatSplitPathName(&PathNameU, NULL, &FileNameU);
774
775 if (IsDotOrDotDot(&FileNameU))
776 {
777 vfatReleaseFCB(DeviceExt, ParentFcb);
778 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
780 }
781 Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
783 vfatReleaseFCB(DeviceExt, ParentFcb);
784 if (NT_SUCCESS(Status))
785 {
786 Status = vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
787 if (!NT_SUCCESS(Status))
788 {
789 vfatReleaseFCB(DeviceExt, pFcb);
790 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
791 return Status;
792 }
793
794 Irp->IoStatus.Information = FILE_CREATED;
796 pFcb,
797 DeviceExt,
798 &Irp->Overlay.AllocationSize);
800 Irp->AssociatedIrp.SystemBuffer,
801 Stack->Parameters.Create.EaLength);
802
803 if (PagingFileCreate)
804 {
805 pFcb->Flags |= FCB_IS_PAGE_FILE;
806 SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE);
807 }
808 }
809 else
810 {
811 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
812 return Status;
813 }
814 }
815 else
816 {
817 vfatReleaseFCB(DeviceExt, ParentFcb);
818 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
819 return Status;
820 }
821 }
822 else
823 {
824 if (ParentFcb)
825 {
826 vfatReleaseFCB(DeviceExt, ParentFcb);
827 }
828
829 pFcb = FileObject->FsContext;
830
831 /* Otherwise fail if the caller wanted to create a new file */
832 if (RequestedDisposition == FILE_CREATE)
833 {
834 VfatCloseFile(DeviceExt, FileObject);
835 if (TrailingBackslash && !vfatFCBIsDirectory(pFcb))
836 {
837 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
839 }
840 Irp->IoStatus.Information = FILE_EXISTS;
841 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
843 }
844
845 if (pFcb->OpenHandleCount != 0)
846 {
847 Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
848 Stack->Parameters.Create.ShareAccess,
850 &pFcb->FCBShareAccess,
851 FALSE);
852 if (!NT_SUCCESS(Status))
853 {
854 VfatCloseFile(DeviceExt, FileObject);
855 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
856 return Status;
857 }
858 }
859
860 /*
861 * Check the file has the requested attributes
862 */
863 if (BooleanFlagOn(RequestedOptions, FILE_NON_DIRECTORY_FILE) &&
864 vfatFCBIsDirectory(pFcb))
865 {
866 VfatCloseFile (DeviceExt, FileObject);
867 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
869 }
870 if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
871 !vfatFCBIsDirectory(pFcb))
872 {
873 VfatCloseFile (DeviceExt, FileObject);
874 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
876 }
877 if (TrailingBackslash && !vfatFCBIsDirectory(pFcb))
878 {
879 VfatCloseFile (DeviceExt, FileObject);
880 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
882 }
883#ifndef USE_ROS_CC_AND_FS
884 if (!vfatFCBIsDirectory(pFcb))
885 {
886 if (BooleanFlagOn(Stack->Parameters.Create.SecurityContext->DesiredAccess, FILE_WRITE_DATA) ||
887 RequestedDisposition == FILE_OVERWRITE ||
888 RequestedDisposition == FILE_OVERWRITE_IF ||
889 (RequestedOptions & FILE_DELETE_ON_CLOSE))
890 {
891 if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite))
892 {
893 DPRINT1("%wZ\n", &pFcb->PathNameU);
894 DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA,
895 RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF);
896 VfatCloseFile (DeviceExt, FileObject);
897 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
898 return (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE)) ? STATUS_CANNOT_DELETE
900 }
901 }
902 }
903#endif
904 if (PagingFileCreate)
905 {
906 /* FIXME:
907 * Do more checking for page files. It is possible,
908 * that the file was opened and closed previously
909 * as a normal cached file. In this case, the cache
910 * manager has referenced the fileobject and the fcb
911 * is held in memory. Try to remove the fileobject
912 * from cache manager and use the fcb.
913 */
914 if (pFcb->RefCount > 1)
915 {
917 {
918 VfatCloseFile(DeviceExt, FileObject);
919 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
921 }
922 }
923 else
924 {
925 pFcb->Flags |= FCB_IS_PAGE_FILE;
926 SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE);
927 }
928 }
929 else
930 {
932 {
933 VfatCloseFile(DeviceExt, FileObject);
934 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
936 }
937 }
938
939 if (RequestedDisposition == FILE_OVERWRITE ||
940 RequestedDisposition == FILE_OVERWRITE_IF ||
941 RequestedDisposition == FILE_SUPERSEDE)
942 {
945 {
946 VfatCloseFile(DeviceExt, FileObject);
947 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
949 }
950
951 if (!vfatFCBIsDirectory(pFcb))
952 {
953 LARGE_INTEGER SystemTime;
954
955 if (RequestedDisposition == FILE_SUPERSEDE)
956 {
957 *pFcb->Attributes = Attributes;
958 }
959 else
960 {
961 *pFcb->Attributes |= Attributes;
962 }
964
965 KeQuerySystemTime(&SystemTime);
966 if (vfatVolumeIsFatX(DeviceExt))
967 {
969 &SystemTime, &pFcb->entry.FatX.UpdateDate,
970 &pFcb->entry.FatX.UpdateTime);
971 }
972 else
973 {
975 &SystemTime, &pFcb->entry.Fat.UpdateDate,
976 &pFcb->entry.Fat.UpdateTime);
977 }
978
979 VfatUpdateEntry(DeviceExt, pFcb);
980 }
981
984 pFcb,
985 DeviceExt,
986 &Irp->Overlay.AllocationSize);
988 if (!NT_SUCCESS (Status))
989 {
990 VfatCloseFile(DeviceExt, FileObject);
991 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
992 return Status;
993 }
994 }
995
996 if (RequestedDisposition == FILE_SUPERSEDE)
997 {
998 Irp->IoStatus.Information = FILE_SUPERSEDED;
999 }
1000 else if (RequestedDisposition == FILE_OVERWRITE ||
1001 RequestedDisposition == FILE_OVERWRITE_IF)
1002 {
1003 Irp->IoStatus.Information = FILE_OVERWRITTEN;
1004 }
1005 else
1006 {
1007 Irp->IoStatus.Information = FILE_OPENED;
1008 }
1009 }
1010
1011 if (pFcb->OpenHandleCount == 0)
1012 {
1013 IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
1014 Stack->Parameters.Create.ShareAccess,
1015 FileObject,
1016 &pFcb->FCBShareAccess);
1017 }
1018 else
1019 {
1021 &pFcb->FCBShareAccess);
1022 }
1023
1024 pCcb = FileObject->FsContext2;
1025 if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
1026 {
1027 pCcb->Flags |= CCB_DELETE_ON_CLOSE;
1028 }
1029
1030 if (Irp->IoStatus.Information == FILE_CREATED)
1031 {
1032 vfatReportChange(DeviceExt,
1033 pFcb,
1034 (vfatFCBIsDirectory(pFcb) ?
1037 }
1038 else if (Irp->IoStatus.Information == FILE_OVERWRITTEN ||
1039 Irp->IoStatus.Information == FILE_SUPERSEDED)
1040 {
1041 vfatReportChange(DeviceExt,
1042 pFcb,
1045 }
1046
1047 pFcb->OpenHandleCount++;
1048 DeviceExt->OpenHandleCount++;
1049
1050 /* FIXME : test write access if requested */
1051
1052 /* FIXME: That is broken, we cannot reach this code path with failure */
1054 if (NT_SUCCESS(Status))
1055 {
1056 vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
1057 }
1058 else
1059 {
1060 vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
1061 }
1062
1063 return Status;
1064}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
Dirent FileNameLen
Definition: dirsup.c:506
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:115
unsigned int idx
Definition: utils.c:41
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:159
static NTSTATUS VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING PathNameU, PFILE_OBJECT FileObject, ULONG RequestedDisposition, ULONG RequestedOptions, PVFATFCB *ParentFcb)
Definition: create.c:257
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:52
NTSTATUS VfatSetExtendedAttributes(PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength)
Definition: ea.c:18
BOOLEAN vfatIsLongIllegal(WCHAR c)
Definition: string.c:21
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:28
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:789
#define CCB_DELETE_ON_CLOSE
Definition: ext2fs.h:1035
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
if(dx< 0)
Definition: linetemp.h:194
static UINT UINT last
Definition: font.c:45
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_CREATED
Definition: nt_native.h:770
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_EXISTS
Definition: nt_native.h:772
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define UNICODE_NULL
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3517
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3390
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3351
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
long LONG
Definition: pedump.c:60
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
unsigned short UpdateDate
Definition: vfat.h:127
unsigned short UpdateTime
Definition: vfat.h:126
unsigned short UpdateDate
Definition: vfat.h:177
unsigned short UpdateTime
Definition: vfat.h:176
Definition: vfat.h:537
ULONG Flags
Definition: vfat.h:539
ULONG Flags
Definition: vfat.h:496
UNICODE_STRING PathNameU
Definition: vfat.h:472
PUCHAR Attributes
Definition: vfat.h:460
ERESOURCE MainResource
Definition: vfat.h:452
SHARE_ACCESS FCBShareAccess
Definition: vfat.h:508
ULONG OpenHandleCount
Definition: vfat.h:511
LONG RefCount
Definition: vfat.h:481
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: vfat.h:451
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
#define vfatAddToStat(Vcb, Stat, Inc)
Definition: vfat.h:671
#define VCB_IS_SYS_OR_HAS_PAGE
Definition: vfat.h:243
FORCEINLINE NTSTATUS VfatAddEntry(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING NameU, struct _VFATFCB **Fcb, struct _VFATFCB *ParentFcb, ULONG RequestedOptions, UCHAR ReqAttr, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:375
#define FCB_IS_PAGE_FILE
Definition: vfat.h:436
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:658
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:54
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:754
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:883
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1211
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_NOTIFY_CHANGE_FILE_NAME
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818
#define FILE_ACTION_ADDED
#define FILE_NOTIFY_CHANGE_DIR_NAME

Referenced by VfatCreate().

◆ VfatOpenFile()

static NTSTATUS VfatOpenFile ( PDEVICE_EXTENSION  DeviceExt,
PUNICODE_STRING  PathNameU,
PFILE_OBJECT  FileObject,
ULONG  RequestedDisposition,
ULONG  RequestedOptions,
PVFATFCB ParentFcb 
)
static

Definition at line 257 of file create.c.

264{
267
268 DPRINT("VfatOpenFile(%p, '%wZ', %p, %p)\n", DeviceExt, PathNameU, FileObject, ParentFcb);
269
270 if (FileObject->RelatedFileObject)
271 {
272 DPRINT("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
273
274 *ParentFcb = FileObject->RelatedFileObject->FsContext;
275 }
276 else
277 {
278 *ParentFcb = NULL;
279 }
280
281 if (!DeviceExt->FatInfo.FixedMedia)
282 {
283 Status = VfatBlockDeviceIoControl(DeviceExt->StorageDevice,
285 NULL,
286 0,
287 NULL,
288 0,
289 FALSE);
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT("Status %lx\n", Status);
293 *ParentFcb = NULL;
294 return Status;
295 }
296 }
297
298 if (*ParentFcb)
299 {
300 vfatGrabFCB(DeviceExt, *ParentFcb);
301 }
302
303 /* try first to find an existing FCB in memory */
304 DPRINT("Checking for existing FCB in memory\n");
305
306 Status = vfatGetFCBForFile(DeviceExt, ParentFcb, &Fcb, PathNameU);
307 if (!NT_SUCCESS(Status))
308 {
309 DPRINT ("Could not make a new FCB, status: %x\n", Status);
310 return Status;
311 }
312
313 /* Fail, if we try to overwrite an existing directory */
314 if ((!BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) && vfatFCBIsDirectory(Fcb)) &&
315 (RequestedDisposition == FILE_OVERWRITE ||
316 RequestedDisposition == FILE_OVERWRITE_IF ||
317 RequestedDisposition == FILE_SUPERSEDE))
318 {
319 vfatReleaseFCB(DeviceExt, Fcb);
321 }
322
324 {
325 vfatReleaseFCB(DeviceExt, Fcb);
327 }
328
329 /* Fail, if we try to overwrite a read-only file */
330 if (vfatFCBIsReadOnly(Fcb) &&
331 (RequestedDisposition == FILE_OVERWRITE ||
332 RequestedDisposition == FILE_OVERWRITE_IF))
333 {
334 vfatReleaseFCB(DeviceExt, Fcb);
336 }
337
338 if (vfatFCBIsReadOnly(Fcb) &&
339 (RequestedOptions & FILE_DELETE_ON_CLOSE))
340 {
341 vfatReleaseFCB(DeviceExt, Fcb);
343 }
344
345 if ((vfatFCBIsRoot(Fcb) || IsDotOrDotDot(&Fcb->LongNameU)) &&
346 BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
347 {
348 // we cannot delete a '.', '..' or the root directory
349 vfatReleaseFCB(DeviceExt, Fcb);
351 }
352
353 /* If that one was marked for closing, remove it */
355 {
356 BOOLEAN ConcurrentDeletion;
357 PVFAT_CLOSE_CONTEXT CloseContext;
358
359 /* Get the context */
360 CloseContext = Fcb->CloseContext;
361 /* Is someone already taking over? */
362 if (CloseContext != NULL)
363 {
364 ConcurrentDeletion = FALSE;
365 /* Lock list */
367 /* Check whether it was already removed, if not, do it */
368 if (!IsListEmpty(&CloseContext->CloseListEntry))
369 {
370 RemoveEntryList(&CloseContext->CloseListEntry);
372 ConcurrentDeletion = TRUE;
373 }
375
376 /* It's not delayed anymore! */
378 /* Release the extra reference (would have been removed by IRP_MJ_CLOSE) */
379 vfatReleaseFCB(DeviceExt, Fcb);
380 Fcb->CloseContext = NULL;
381 /* If no concurrent deletion, free work item */
382 if (!ConcurrentDeletion)
383 {
384 ExFreeToPagedLookasideList(&VfatGlobalData->CloseContextLookasideList, CloseContext);
385 }
386 }
387
388 DPRINT("Reusing delayed close FCB for %wZ\n", &Fcb->PathNameU);
389 }
390
391 DPRINT("Attaching FCB to fileObject\n");
393 if (!NT_SUCCESS(Status))
394 {
395 vfatReleaseFCB(DeviceExt, Fcb);
396 }
397 return Status;
398}
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
PAGED_LOOKASIDE_LIST CloseContextLookasideList
Definition: vfat.h:420
FAST_MUTEX CloseMutex
Definition: vfat.h:423
ULONG CloseCount
Definition: vfat.h:424
ULONG Flags
Definition: ntfs.h:536
LIST_ENTRY CloseListEntry
Definition: vfat.h:620
#define FCB_DELAYED_CLOSE
Definition: vfat.h:439
FORCEINLINE BOOLEAN vfatFCBIsReadOnly(PVFATFCB FCB)
Definition: vfat.h:644
NTSTATUS VfatBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG OutputBufferSize, IN BOOLEAN Override)
Definition: blockdev.c:430

Referenced by VfatCreateFile().