ReactOS  0.4.15-dev-5455-g015cd25
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;
93  PVOID Context = NULL;
94  PVOID Page;
95  PVFATFCB rcFcb;
96  BOOLEAN Found;
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  {
182  DirContext->DirIndex++;
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  }
194  DirContext->DirIndex++;
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  }
239  DirContext->DirIndex++;
240  }
241 
242  if (Context)
243  {
245  }
246 
247  RtlFreeUnicodeString(&FileToFindUpcase);
248  ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
249  return Status;
250 }
#define TAG_NAME
Definition: vfat.h:553
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
UNICODE_STRING ShortNameU
Definition: vfat.h:466
Definition: vfat.h:447
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG dirIndex
Definition: vfat.h:502
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
ULONG DirIndex
Definition: ntfs.h:533
UNICODE_STRING LongNameU
Definition: vfat.h:463
uint16_t * PWCHAR
Definition: typedefs.h:56
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
#define ENTRY_VOLUME(IsFatX, DirEntry)
Definition: vfat.h:206
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
WCHAR First[]
Definition: FormatMessage.c:11
#define L(x)
Definition: ntvdm.h:50
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1295
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
return Found
Definition: dirsup.c:1270
Iosb Status
Definition: create.c:4287
ULONG startIndex
Definition: vfat.h:505
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:424
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
FORCEINLINE NTSTATUS VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt, PVOID *pContext, PVOID *pPage, struct _VFATFCB *pDirFcb, struct _VFAT_DIRENTRY_CONTEXT *DirContext, BOOLEAN First)
Definition: vfat.h:397
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407
DIR_ENTRY entry
Definition: vfat.h:457
unsigned short USHORT
Definition: pedump.c:61
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
Definition: vfat.h:224
#define NULL
Definition: types.h:112
ULONG Flags
Definition: vfat.h:413
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
#define DPRINT1
Definition: precomp.h:8
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ vfat8Dot3ToString()

VOID vfat8Dot3ToString ( PFAT_DIR_ENTRY  pEntry,
PUNICODE_STRING  NameU 
)

Definition at line 19 of file create.c.

22 {
23  OEM_STRING StringA;
24  USHORT Length;
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 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
char CHAR
Definition: xmlstorage.h:175
STRING OEM_STRING
Definition: umtypes.h:203
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define FAT_ENTRY_VOLUME(DirEntry)
Definition: vfat.h:212
#define VFAT_CASE_LOWER_BASE
Definition: vfat.h:200
#define VFAT_CASE_LOWER_EXT
Definition: vfat.h:201
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned short USHORT
Definition: pedump.c:61
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DPRINT
Definition: sndvol32.h:71
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by FATGetNextDirEntry(), and ReadVolumeLabel().

◆ VfatCreate()

NTSTATUS VfatCreate ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1070 of file create.c.

1072 {
1073  NTSTATUS Status;
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;
1088  ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
1089  Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
1090  ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
1091 
1092  if (NT_SUCCESS(Status))
1093  IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1094 
1095  return Status;
1096 }
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
IO_STATUS_BLOCK IoStatus
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
CCHAR PriorityBoost
Definition: vfat.h:594
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
Iosb Status
Definition: create.c:4287
Status
Definition: gdiplustypes.h:24
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
static NTSTATUS VfatCreateFile(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: create.c:404
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

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  {
437  return STATUS_NOT_IMPLEMENTED;
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  {
456  return STATUS_ACCESS_DENIED;
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  {
470  return STATUS_ACCESS_DENIED;
471  }
472 
473  if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
474  (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 == NULL || FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb))
475  {
476  return STATUS_NOT_A_DIRECTORY;
477  }
478 
479  if (OpenTargetDir)
480  {
482  }
483 
484  if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
485  {
486  return STATUS_CANNOT_DELETE;
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,
497  FileObject,
498  &pFcb->FCBShareAccess);
499  }
500  else
501  {
502  Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
503  Stack->Parameters.Create.ShareAccess,
504  FileObject,
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,
680  FileObject,
681  &pFcb->FCBShareAccess);
682  }
683  else
684  {
685  Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
686  Stack->Parameters.Create.ShareAccess,
687  FileObject,
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,
782  Attributes, NULL);
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,
849  FileObject,
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);
875  return STATUS_NOT_A_DIRECTORY;
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);
948  return STATUS_ACCESS_DENIED;
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  {
968  FsdSystemTimeToDosDateTime(DeviceExt,
969  &SystemTime, &pFcb->entry.FatX.UpdateDate,
970  &pFcb->entry.FatX.UpdateTime);
971  }
972  else
973  {
974  FsdSystemTimeToDosDateTime(DeviceExt,
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 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
unsigned short UpdateTime
Definition: vfat.h:126
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define FILE_EXISTS
Definition: nt_native.h:772
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: vfat.h:451
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:52
#define FILE_OPEN_IF
Definition: from_kernel.h:56
unsigned short UpdateDate
Definition: vfat.h:177
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define CCB_DELETE_ON_CLOSE
Definition: ext2fs.h:1026
Definition: vfat.h:447
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: vfat.h:536
POINT last
Definition: font.c:46
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:28
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_SUPERSEDED
Definition: nt_native.h:768
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:883
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define vfatAddToStat(Vcb, Stat, Inc)
Definition: vfat.h:671
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_NOTIFY_CHANGE_FILE_NAME
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3516
uint16_t * PWCHAR
Definition: typedefs.h:56
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
#define FILE_NOTIFY_CHANGE_DIR_NAME
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
LONG RefCount
Definition: vfat.h:481
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
return STATUS_NOT_IMPLEMENTED
#define L(x)
Definition: ntvdm.h:50
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
ULONG Flags
Definition: vfat.h:539
#define FILE_ACTION_MODIFIED
unsigned int idx
Definition: utils.c:41
ULONG Flags
Definition: vfat.h:496
SHARE_ACCESS FCBShareAccess
Definition: vfat.h:508
static NTSTATUS VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING PathNameU, PFILE_OBJECT FileObject, ULONG RequestedDisposition, ULONG RequestedOptions, PVFATFCB *ParentFcb)
Definition: create.c:257
unsigned char BOOLEAN
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
Iosb Status
Definition: create.c:4287
#define FILE_WRITE_DATA
Definition: nt_native.h:631
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1211
BOOLEAN vfatIsLongIllegal(WCHAR c)
Definition: string.c:21
Dirent FileNameLen
Definition: dirsup.c:506
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4257
#define FCB_IS_PAGE_FILE
Definition: vfat.h:436
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
const GLubyte * c
Definition: glext.h:8905
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_OPEN
Definition: from_kernel.h:54
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3389
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
DIR_ENTRY entry
Definition: vfat.h:457
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PUCHAR Attributes
Definition: vfat.h:460
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:658
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:754
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define VCB_IS_SYS_OR_HAS_PAGE
Definition: vfat.h:243
if(OpenRequiringOplock &&(Iosb.Status==STATUS_SUCCESS))
Definition: create.c:4300
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define NULL
Definition: types.h:112
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:54
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:159
ERESOURCE MainResource
Definition: vfat.h:452
#define FILE_CREATED
Definition: nt_native.h:770
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:780
#define FILE_ACTION_ADDED
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING PathNameU
Definition: vfat.h:472
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:115
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
NTSTATUS VfatSetExtendedAttributes(PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength)
Definition: ea.c:18
unsigned short UpdateDate
Definition: vfat.h:127
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
#define DPRINT
Definition: sndvol32.h:71
ULONG OpenHandleCount
Definition: vfat.h:511
unsigned short UpdateTime
Definition: vfat.h:176
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3350
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

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 {
265  PVFATFCB Fcb;
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);
326  return STATUS_DELETE_PENDING;
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);
335  return STATUS_ACCESS_DENIED;
336  }
337 
338  if (vfatFCBIsReadOnly(Fcb) &&
339  (RequestedOptions & FILE_DELETE_ON_CLOSE))
340  {
341  vfatReleaseFCB(DeviceExt, Fcb);
342  return STATUS_CANNOT_DELETE;
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);
350  return STATUS_CANNOT_DELETE;
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 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
LIST_ENTRY CloseListEntry
Definition: vfat.h:620
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
FAST_MUTEX CloseMutex
Definition: vfat.h:423
Definition: vfat.h:447
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:28
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:883
#define FILE_OVERWRITE
Definition: from_kernel.h:57
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE BOOLEAN vfatFCBIsReadOnly(PVFATFCB FCB)
Definition: vfat.h:644
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
Iosb Status
Definition: create.c:4287
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
ULONG Flags
Definition: ntfs.h:536
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
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
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define FCB_DELAYED_CLOSE
Definition: vfat.h:439
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:754
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
#define NULL
Definition: types.h:112
ULONG CloseCount
Definition: vfat.h:424
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
PAGED_LOOKASIDE_LIST CloseContextLookasideList
Definition: vfat.h:420

Referenced by VfatCreateFile().