ReactOS  0.4.15-dev-1377-ga59cecd
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 31 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 101 of file create.c.

107 {
108  PWCHAR PathNameBuffer;
109  USHORT PathNameBufferLength;
111  PVOID Context = NULL;
112  PVOID Page;
113  PVFATFCB rcFcb;
114  BOOLEAN Found;
115  UNICODE_STRING PathNameU;
116  UNICODE_STRING FileToFindUpcase;
117  BOOLEAN WildCard;
118  BOOLEAN IsFatX = vfatVolumeIsFatX(DeviceExt);
119 
120  DPRINT("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
121  Parent, FileToFindU, DirContext->DirIndex);
122  DPRINT("FindFile: Path %wZ\n",&Parent->PathNameU);
123 
124  PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
125  PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength + sizeof(WCHAR), TAG_NAME);
126  if (!PathNameBuffer)
127  {
129  }
130 
131  PathNameU.Buffer = PathNameBuffer;
132  PathNameU.Length = 0;
133  PathNameU.MaximumLength = PathNameBufferLength;
134 
135  DirContext->LongNameU.Length = 0;
136  DirContext->ShortNameU.Length = 0;
137 
138  WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
139 
140  if (WildCard == FALSE)
141  {
142  /* if there is no '*?' in the search name, than look first for an existing fcb */
143  RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
144  if (!vfatFCBIsRoot(Parent))
145  {
146  PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
147  PathNameU.Length += sizeof(WCHAR);
148  }
149  RtlAppendUnicodeStringToString(&PathNameU, FileToFindU);
150  PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
151  rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
152  if (rcFcb)
153  {
154  ULONG startIndex = rcFcb->startIndex;
155  if (IsFatX && !vfatFCBIsRoot(Parent))
156  {
157  startIndex += 2;
158  }
159  if(startIndex >= DirContext->DirIndex)
160  {
161  RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
162  RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
163  RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
164  DirContext->StartIndex = rcFcb->startIndex;
165  DirContext->DirIndex = rcFcb->dirIndex;
166  DPRINT("FindFile: new Name %wZ, DirIndex %u (%u)\n",
167  &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
169  }
170  else
171  {
172  DPRINT("FCB not found for %wZ\n", &PathNameU);
174  }
175  vfatReleaseFCB(DeviceExt, rcFcb);
176  ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
177  return Status;
178  }
179  }
180 
181  /* FsRtlIsNameInExpression need the searched string to be upcase,
182  * even if IgnoreCase is specified */
183  Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
184  if (!NT_SUCCESS(Status))
185  {
186  ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
187  return Status;
188  }
189 
190  while (TRUE)
191  {
192  Status = VfatGetNextDirEntry(DeviceExt, &Context, &Page, Parent, DirContext, First);
193  First = FALSE;
195  {
196  break;
197  }
198  if (ENTRY_VOLUME(IsFatX, &DirContext->DirEntry))
199  {
200  DirContext->DirIndex++;
201  continue;
202  }
203  if (DirContext->LongNameU.Length == 0 ||
204  DirContext->ShortNameU.Length == 0)
205  {
206  DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
208  {
209  ASSERT(DirContext->LongNameU.Length != 0 &&
210  DirContext->ShortNameU.Length != 0);
211  }
212  DirContext->DirIndex++;
213  continue;
214  }
215  if (WildCard)
216  {
217  Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
218  FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
219  }
220  else
221  {
222  Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
223  FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
224  }
225 
226  if (Found)
227  {
228  if (WildCard)
229  {
230  RtlCopyUnicodeString(&PathNameU, &Parent->PathNameU);
231  if (!vfatFCBIsRoot(Parent))
232  {
233  PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = L'\\';
234  PathNameU.Length += sizeof(WCHAR);
235  }
236  RtlAppendUnicodeStringToString(&PathNameU, &DirContext->LongNameU);
237  PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
238  rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
239  if (rcFcb != NULL)
240  {
241  RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
242  vfatReleaseFCB(DeviceExt, rcFcb);
243  }
244  }
245  DPRINT("%u\n", DirContext->LongNameU.Length);
246  DPRINT("FindFile: new Name %wZ, DirIndex %u\n",
247  &DirContext->LongNameU, DirContext->DirIndex);
248 
249  if (Context)
250  {
252  }
253  RtlFreeUnicodeString(&FileToFindUpcase);
254  ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
255  return STATUS_SUCCESS;
256  }
257  DirContext->DirIndex++;
258  }
259 
260  if (Context)
261  {
263  }
264 
265  RtlFreeUnicodeString(&FileToFindUpcase);
266  ExFreePoolWithTag(PathNameBuffer, TAG_NAME);
267  return Status;
268 }
#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
Iosb Status
Definition: create.c:4287
#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:529
UNICODE_STRING LongNameU
Definition: vfat.h:463
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:294
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:728
uint16_t * PWCHAR
Definition: typedefs.h:56
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 FALSE
Definition: types.h:117
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
return Found
Definition: dirsup.c:1270
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:45
__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)
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
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 VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
DIR_ENTRY entry
Definition: vfat.h:457
unsigned short USHORT
Definition: pedump.c:61
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
#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
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ vfat8Dot3ToString()

VOID vfat8Dot3ToString ( PFAT_DIR_ENTRY  pEntry,
PUNICODE_STRING  NameU 
)

Definition at line 37 of file create.c.

40 {
41  OEM_STRING StringA;
42  USHORT Length;
43  CHAR cString[12];
44 
45  RtlCopyMemory(cString, pEntry->ShortName, 11);
46  cString[11] = 0;
47  if (cString[0] == 0x05)
48  {
49  cString[0] = 0xe5;
50  }
51 
52  StringA.Buffer = cString;
53  for (StringA.Length = 0;
54  StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
55  StringA.Length++);
56  StringA.MaximumLength = StringA.Length;
57 
58  RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
59 
61  {
62  RtlDowncaseUnicodeString(NameU, NameU, FALSE);
63  }
64 
65  if (cString[8] != ' ')
66  {
67  Length = NameU->Length;
68  NameU->Buffer += Length / sizeof(WCHAR);
70  {
71  Length += sizeof(WCHAR);
72  NameU->Buffer[0] = L'.';
73  NameU->Buffer++;
74  }
75  NameU->Length = 0;
76  NameU->MaximumLength -= Length;
77 
78  StringA.Buffer = &cString[8];
79  for (StringA.Length = 0;
80  StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
81  StringA.Length++);
82  StringA.MaximumLength = StringA.Length;
83  RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
85  {
86  RtlDowncaseUnicodeString(NameU, NameU, FALSE);
87  }
88  NameU->Buffer -= Length / sizeof(WCHAR);
89  NameU->Length += Length;
90  NameU->MaximumLength += Length;
91  }
92 
93  NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
94  DPRINT("'%wZ'\n", NameU);
95 }
_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 FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
__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
static const WCHAR L[]
Definition: oid.c:1250
#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
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by FATGetNextDirEntry(), and ReadVolumeLabel().

◆ VfatCreate()

NTSTATUS VfatCreate ( PVFAT_IRP_CONTEXT  IrpContext)

Definition at line 1088 of file create.c.

1090 {
1091  NTSTATUS Status;
1092 
1093  ASSERT(IrpContext);
1094 
1095  if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
1096  {
1097  /* DeviceObject represents FileSystem instead of logical volume */
1098  DPRINT ("FsdCreate called with file system\n");
1099  IrpContext->Irp->IoStatus.Information = FILE_OPENED;
1100  IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1101 
1102  return STATUS_SUCCESS;
1103  }
1104 
1105  IrpContext->Irp->IoStatus.Information = 0;
1106  ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
1107  Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
1108  ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
1109 
1110  if (NT_SUCCESS(Status))
1111  IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1112 
1113  return Status;
1114 }
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
Iosb Status
Definition: create.c:4287
#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:583
void DPRINT(...)
Definition: polytest.cpp:61
Status
Definition: gdiplustypes.h:24
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define STATUS_SUCCESS
Definition: shellext.h:65
static NTSTATUS VfatCreateFile(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: create.c:422

Referenced by VfatDispatchRequest().

◆ VfatCreateFile()

static NTSTATUS VfatCreateFile ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 422 of file create.c.

425 {
429  PDEVICE_EXTENSION DeviceExt;
430  ULONG RequestedDisposition, RequestedOptions;
431  PVFATFCB pFcb = NULL;
433  PVFATCCB pCcb = NULL;
434  PWCHAR c, last;
435  BOOLEAN PagingFileCreate;
436  BOOLEAN Dots;
437  BOOLEAN OpenTargetDir;
438  BOOLEAN TrailingBackslash;
439  UNICODE_STRING FileNameU;
440  UNICODE_STRING PathNameU;
442 
443  /* Unpack the various parameters. */
445  RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
446  RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
447  PagingFileCreate = BooleanFlagOn(Stack->Flags, SL_OPEN_PAGING_FILE);
448  OpenTargetDir = BooleanFlagOn(Stack->Flags, SL_OPEN_TARGET_DIRECTORY);
449 
450  FileObject = Stack->FileObject;
451  DeviceExt = DeviceObject->DeviceExtension;
452 
453  if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID))
454  {
455  return STATUS_NOT_IMPLEMENTED;
456  }
457 
458  /* Check their validity. */
459  if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
460  RequestedDisposition == FILE_SUPERSEDE)
461  {
463  }
464 
465  if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
466  BooleanFlagOn(RequestedOptions, FILE_NON_DIRECTORY_FILE))
467  {
469  }
470 
471  /* Deny create if the volume is locked */
472  if (BooleanFlagOn(DeviceExt->Flags, VCB_VOLUME_LOCKED))
473  {
474  return STATUS_ACCESS_DENIED;
475  }
476 
477  /* This a open operation for the volume itself */
478  if (FileObject->FileName.Length == 0 &&
479  (FileObject->RelatedFileObject == NULL ||
480  FileObject->RelatedFileObject->FsContext2 != NULL ||
481  FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb))
482  {
483  DPRINT("Volume opening\n");
484 
485  if (RequestedDisposition != FILE_OPEN &&
486  RequestedDisposition != FILE_OPEN_IF)
487  {
488  return STATUS_ACCESS_DENIED;
489  }
490 
491  if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
492  (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 == NULL || FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb))
493  {
494  return STATUS_NOT_A_DIRECTORY;
495  }
496 
497  if (OpenTargetDir)
498  {
500  }
501 
502  if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
503  {
504  return STATUS_CANNOT_DELETE;
505  }
506 
507  vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
508 
509  pFcb = DeviceExt->VolumeFcb;
510 
511  if (pFcb->OpenHandleCount == 0)
512  {
513  IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
514  Stack->Parameters.Create.ShareAccess,
515  FileObject,
516  &pFcb->FCBShareAccess);
517  }
518  else
519  {
520  Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
521  Stack->Parameters.Create.ShareAccess,
522  FileObject,
523  &pFcb->FCBShareAccess,
524  TRUE);
525  if (!NT_SUCCESS(Status))
526  {
527  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
528  return Status;
529  }
530  }
531 
532  vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
533  DeviceExt->OpenHandleCount++;
534  pFcb->OpenHandleCount++;
535  vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
536 
537  Irp->IoStatus.Information = FILE_OPENED;
538  return STATUS_SUCCESS;
539  }
540 
541  if (FileObject->RelatedFileObject != NULL &&
542  FileObject->RelatedFileObject->FsContext == DeviceExt->VolumeFcb)
543  {
544  ASSERT(FileObject->FileName.Length != 0);
546  }
547 
548  /* Check for illegal characters and illegal dot sequences in the file name */
549  PathNameU = FileObject->FileName;
550  c = PathNameU.Buffer + PathNameU.Length / sizeof(WCHAR);
551  last = c - 1;
552 
553  Dots = TRUE;
554  while (c-- > PathNameU.Buffer)
555  {
556  if (*c == L'\\' || c == PathNameU.Buffer)
557  {
558  if (Dots && last > c)
559  {
561  }
562  if (*c == L'\\' && (c - 1) > PathNameU.Buffer &&
563  *(c - 1) == L'\\')
564  {
566  }
567 
568  last = c - 1;
569  Dots = TRUE;
570  }
571  else if (*c != L'.')
572  {
573  Dots = FALSE;
574  }
575 
576  if (*c != '\\' && vfatIsLongIllegal(*c))
577  {
579  }
580  }
581 
582  /* Check if we try to open target directory of root dir */
583  if (OpenTargetDir && FileObject->RelatedFileObject == NULL && PathNameU.Length == sizeof(WCHAR) &&
584  PathNameU.Buffer[0] == L'\\')
585  {
587  }
588 
589  if (FileObject->RelatedFileObject && PathNameU.Length >= sizeof(WCHAR) && PathNameU.Buffer[0] == L'\\')
590  {
592  }
593 
594  TrailingBackslash = FALSE;
595  if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
596  {
597  PathNameU.Length -= sizeof(WCHAR);
598  TrailingBackslash = TRUE;
599  }
600 
601  if (PathNameU.Length > sizeof(WCHAR) && PathNameU.Buffer[PathNameU.Length/sizeof(WCHAR)-1] == L'\\')
602  {
604  }
605 
606  /* Try opening the file. */
607  if (!OpenTargetDir)
608  {
609  vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
610 
611  Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, RequestedOptions, &ParentFcb);
612  }
613  else
614  {
615  PVFATFCB TargetFcb;
617 
618  vfatAddToStat(DeviceExt, Fat.CreateHits, 1);
619 
620  ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL;
621  if (ParentFcb)
622  {
623  vfatGrabFCB(DeviceExt, ParentFcb);
624  }
625 
626  Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
627  if (NT_SUCCESS(Status))
628  {
629  vfatReleaseFCB(DeviceExt, TargetFcb);
630  Irp->IoStatus.Information = FILE_EXISTS;
631  }
632  else
633  {
634  Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
635  }
636 
637  idx = FileObject->FileName.Length / sizeof(WCHAR) - 1;
638 
639  /* Skip trailing \ - if any */
640  if (PathNameU.Buffer[idx] == L'\\')
641  {
642  --idx;
643  PathNameU.Length -= sizeof(WCHAR);
644  }
645 
646  /* Get file name */
647  while (idx >= 0 && PathNameU.Buffer[idx] != L'\\')
648  {
649  --idx;
650  }
651 
652  if (idx > 0 || PathNameU.Buffer[0] == L'\\')
653  {
654  /* We don't want to include / in the name */
655  FileNameLen = PathNameU.Length - ((idx + 1) * sizeof(WCHAR));
656 
657  /* Update FO just to keep file name */
658  /* Skip first slash */
659  ++idx;
660  FileObject->FileName.Length = FileNameLen;
661  RtlMoveMemory(&PathNameU.Buffer[0], &PathNameU.Buffer[idx], FileObject->FileName.Length);
662 #if 0
663  /* Terminate the string at the last backslash */
664  PathNameU.Buffer[idx + 1] = UNICODE_NULL;
665  PathNameU.Length = (idx + 1) * sizeof(WCHAR);
666  PathNameU.MaximumLength = PathNameU.Length + sizeof(WCHAR);
667 
668  /* Update the file object as well */
669  FileObject->FileName.Length = PathNameU.Length;
670  FileObject->FileName.MaximumLength = PathNameU.MaximumLength;
671 #endif
672  }
673  else
674  {
675  /* This is a relative open and we have only the filename, so open the parent directory
676  * It is in RelatedFileObject
677  */
678  ASSERT(FileObject->RelatedFileObject != NULL);
679 
680  /* No need to modify the FO, it already has the name */
681  }
682 
683  /* We're done with opening! */
684  if (ParentFcb != NULL)
685  {
687  }
688 
689  if (NT_SUCCESS(Status))
690  {
691  pFcb = FileObject->FsContext;
692  ASSERT(pFcb == ParentFcb);
693 
694  if (pFcb->OpenHandleCount == 0)
695  {
696  IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
697  Stack->Parameters.Create.ShareAccess,
698  FileObject,
699  &pFcb->FCBShareAccess);
700  }
701  else
702  {
703  Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
704  Stack->Parameters.Create.ShareAccess,
705  FileObject,
706  &pFcb->FCBShareAccess,
707  FALSE);
708  if (!NT_SUCCESS(Status))
709  {
710  VfatCloseFile(DeviceExt, FileObject);
711  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
712  return Status;
713  }
714  }
715 
716  pCcb = FileObject->FsContext2;
717  if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
718  {
719  pCcb->Flags |= CCB_DELETE_ON_CLOSE;
720  }
721 
722  pFcb->OpenHandleCount++;
723  DeviceExt->OpenHandleCount++;
724  }
725  else if (ParentFcb != NULL)
726  {
727  vfatReleaseFCB(DeviceExt, ParentFcb);
728  }
729 
730  if (NT_SUCCESS(Status))
731  {
732  vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
733  }
734  else
735  {
736  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
737  }
738 
739  return Status;
740  }
741 
742  /*
743  * If the directory containing the file to open doesn't exist then
744  * fail immediately
745  */
751  {
752  if (ParentFcb)
753  {
754  vfatReleaseFCB(DeviceExt, ParentFcb);
755  }
756  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
757  return Status;
758  }
759 
760  if (!NT_SUCCESS(Status) && ParentFcb == NULL)
761  {
762  DPRINT1("VfatOpenFile failed for '%wZ', status %x\n", &PathNameU, Status);
763  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
764  return Status;
765  }
766 
767  Attributes = (Stack->Parameters.Create.FileAttributes & (FILE_ATTRIBUTE_ARCHIVE |
772 
773  /* If the file open failed then create the required file */
774  if (!NT_SUCCESS (Status))
775  {
776  if (RequestedDisposition == FILE_CREATE ||
777  RequestedDisposition == FILE_OPEN_IF ||
778  RequestedDisposition == FILE_OVERWRITE_IF ||
779  RequestedDisposition == FILE_SUPERSEDE)
780  {
781  if (!BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE))
782  {
783  if (TrailingBackslash)
784  {
785  vfatReleaseFCB(DeviceExt, ParentFcb);
786  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
788  }
790  }
791  vfatSplitPathName(&PathNameU, NULL, &FileNameU);
792 
793  if (IsDotOrDotDot(&FileNameU))
794  {
795  vfatReleaseFCB(DeviceExt, ParentFcb);
796  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
798  }
799  Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
800  Attributes, NULL);
801  vfatReleaseFCB(DeviceExt, ParentFcb);
802  if (NT_SUCCESS(Status))
803  {
804  Status = vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
805  if (!NT_SUCCESS(Status))
806  {
807  vfatReleaseFCB(DeviceExt, pFcb);
808  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
809  return Status;
810  }
811 
812  Irp->IoStatus.Information = FILE_CREATED;
814  pFcb,
815  DeviceExt,
816  &Irp->Overlay.AllocationSize);
818  Irp->AssociatedIrp.SystemBuffer,
819  Stack->Parameters.Create.EaLength);
820 
821  if (PagingFileCreate)
822  {
823  pFcb->Flags |= FCB_IS_PAGE_FILE;
824  SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE);
825  }
826  }
827  else
828  {
829  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
830  return Status;
831  }
832  }
833  else
834  {
835  vfatReleaseFCB(DeviceExt, ParentFcb);
836  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
837  return Status;
838  }
839  }
840  else
841  {
842  if (ParentFcb)
843  {
844  vfatReleaseFCB(DeviceExt, ParentFcb);
845  }
846 
847  pFcb = FileObject->FsContext;
848 
849  /* Otherwise fail if the caller wanted to create a new file */
850  if (RequestedDisposition == FILE_CREATE)
851  {
852  VfatCloseFile(DeviceExt, FileObject);
853  if (TrailingBackslash && !vfatFCBIsDirectory(pFcb))
854  {
855  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
857  }
858  Irp->IoStatus.Information = FILE_EXISTS;
859  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
861  }
862 
863  if (pFcb->OpenHandleCount != 0)
864  {
865  Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
866  Stack->Parameters.Create.ShareAccess,
867  FileObject,
868  &pFcb->FCBShareAccess,
869  FALSE);
870  if (!NT_SUCCESS(Status))
871  {
872  VfatCloseFile(DeviceExt, FileObject);
873  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
874  return Status;
875  }
876  }
877 
878  /*
879  * Check the file has the requested attributes
880  */
881  if (BooleanFlagOn(RequestedOptions, FILE_NON_DIRECTORY_FILE) &&
882  vfatFCBIsDirectory(pFcb))
883  {
884  VfatCloseFile (DeviceExt, FileObject);
885  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
887  }
888  if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) &&
889  !vfatFCBIsDirectory(pFcb))
890  {
891  VfatCloseFile (DeviceExt, FileObject);
892  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
893  return STATUS_NOT_A_DIRECTORY;
894  }
895  if (TrailingBackslash && !vfatFCBIsDirectory(pFcb))
896  {
897  VfatCloseFile (DeviceExt, FileObject);
898  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
900  }
901 #ifndef USE_ROS_CC_AND_FS
902  if (!vfatFCBIsDirectory(pFcb))
903  {
904  if (BooleanFlagOn(Stack->Parameters.Create.SecurityContext->DesiredAccess, FILE_WRITE_DATA) ||
905  RequestedDisposition == FILE_OVERWRITE ||
906  RequestedDisposition == FILE_OVERWRITE_IF ||
907  (RequestedOptions & FILE_DELETE_ON_CLOSE))
908  {
909  if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite))
910  {
911  DPRINT1("%wZ\n", &pFcb->PathNameU);
912  DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA,
913  RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF);
914  VfatCloseFile (DeviceExt, FileObject);
915  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
916  return (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE)) ? STATUS_CANNOT_DELETE
918  }
919  }
920  }
921 #endif
922  if (PagingFileCreate)
923  {
924  /* FIXME:
925  * Do more checking for page files. It is possible,
926  * that the file was opened and closed previously
927  * as a normal cached file. In this case, the cache
928  * manager has referenced the fileobject and the fcb
929  * is held in memory. Try to remove the fileobject
930  * from cache manager and use the fcb.
931  */
932  if (pFcb->RefCount > 1)
933  {
935  {
936  VfatCloseFile(DeviceExt, FileObject);
937  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
939  }
940  }
941  else
942  {
943  pFcb->Flags |= FCB_IS_PAGE_FILE;
944  SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE);
945  }
946  }
947  else
948  {
950  {
951  VfatCloseFile(DeviceExt, FileObject);
952  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
954  }
955  }
956 
957  if (RequestedDisposition == FILE_OVERWRITE ||
958  RequestedDisposition == FILE_OVERWRITE_IF ||
959  RequestedDisposition == FILE_SUPERSEDE)
960  {
963  {
964  VfatCloseFile(DeviceExt, FileObject);
965  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
966  return STATUS_ACCESS_DENIED;
967  }
968 
969  if (!vfatFCBIsDirectory(pFcb))
970  {
971  LARGE_INTEGER SystemTime;
972 
973  if (RequestedDisposition == FILE_SUPERSEDE)
974  {
975  *pFcb->Attributes = Attributes;
976  }
977  else
978  {
979  *pFcb->Attributes |= Attributes;
980  }
982 
983  KeQuerySystemTime(&SystemTime);
984  if (vfatVolumeIsFatX(DeviceExt))
985  {
986  FsdSystemTimeToDosDateTime(DeviceExt,
987  &SystemTime, &pFcb->entry.FatX.UpdateDate,
988  &pFcb->entry.FatX.UpdateTime);
989  }
990  else
991  {
992  FsdSystemTimeToDosDateTime(DeviceExt,
993  &SystemTime, &pFcb->entry.Fat.UpdateDate,
994  &pFcb->entry.Fat.UpdateTime);
995  }
996 
997  VfatUpdateEntry(DeviceExt, pFcb);
998  }
999 
1002  pFcb,
1003  DeviceExt,
1004  &Irp->Overlay.AllocationSize);
1006  if (!NT_SUCCESS (Status))
1007  {
1008  VfatCloseFile(DeviceExt, FileObject);
1009  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
1010  return Status;
1011  }
1012  }
1013 
1014  if (RequestedDisposition == FILE_SUPERSEDE)
1015  {
1016  Irp->IoStatus.Information = FILE_SUPERSEDED;
1017  }
1018  else if (RequestedDisposition == FILE_OVERWRITE ||
1019  RequestedDisposition == FILE_OVERWRITE_IF)
1020  {
1021  Irp->IoStatus.Information = FILE_OVERWRITTEN;
1022  }
1023  else
1024  {
1025  Irp->IoStatus.Information = FILE_OPENED;
1026  }
1027  }
1028 
1029  if (pFcb->OpenHandleCount == 0)
1030  {
1031  IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
1032  Stack->Parameters.Create.ShareAccess,
1033  FileObject,
1034  &pFcb->FCBShareAccess);
1035  }
1036  else
1037  {
1039  &pFcb->FCBShareAccess);
1040  }
1041 
1042  pCcb = FileObject->FsContext2;
1043  if (BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
1044  {
1045  pCcb->Flags |= CCB_DELETE_ON_CLOSE;
1046  }
1047 
1048  if (Irp->IoStatus.Information == FILE_CREATED)
1049  {
1050  vfatReportChange(DeviceExt,
1051  pFcb,
1052  (vfatFCBIsDirectory(pFcb) ?
1055  }
1056  else if (Irp->IoStatus.Information == FILE_OVERWRITTEN ||
1057  Irp->IoStatus.Information == FILE_SUPERSEDED)
1058  {
1059  vfatReportChange(DeviceExt,
1060  pFcb,
1063  }
1064 
1065  pFcb->OpenHandleCount++;
1066  DeviceExt->OpenHandleCount++;
1067 
1068  /* FIXME : test write access if requested */
1069 
1070  /* FIXME: That is broken, we cannot reach this code path with failure */
1072  if (NT_SUCCESS(Status))
1073  {
1074  vfatAddToStat(DeviceExt, Fat.SuccessfulCreates, 1);
1075  }
1076  else
1077  {
1078  vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
1079  }
1080 
1081  return Status;
1082 }
#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
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1213
#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
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:160
#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
Iosb Status
Definition: create.c:4287
POINT last
Definition: font.c:46
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1797
#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
if(OpenRequiringOplock &&(Iosb.Status==STATUS_SUCCESS))
Definition: create.c:4300
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:755
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
#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
NTSTATUS VfatSetExtendedAttributes(PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength)
Definition: ea.c:36
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
#define FILE_NOTIFY_CHANGE_DIR_NAME
#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 STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:53
#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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
#define FILE_ACTION_MODIFIED
unsigned int idx
Definition: utils.c:41
ULONG Flags
Definition: vfat.h:496
SHARE_ACCESS FCBShareAccess
Definition: vfat.h:508
unsigned char BOOLEAN
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
void DPRINT(...)
Definition: polytest.cpp:61
#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
Dirent FileNameLen
Definition: dirsup.c:506
#define ASSERT(a)
Definition: mode.c:45
__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:4796
#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:1978
_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
static const WCHAR L[]
Definition: oid.c:1250
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:30
#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:2789
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:1798
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:658
#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
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define NULL
Definition: types.h:112
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
BOOLEAN vfatIsLongIllegal(WCHAR c)
Definition: string.c:23
UNICODE_STRING PathNameU
Definition: vfat.h:472
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:117
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:302
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
static NTSTATUS VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING PathNameU, PFILE_OBJECT FileObject, ULONG RequestedDisposition, ULONG RequestedOptions, PVFATFCB *ParentFcb)
Definition: create.c:275
unsigned short UpdateDate
Definition: vfat.h:127
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:884
ULONG OpenHandleCount
Definition: vfat.h:511
unsigned short UpdateTime
Definition: vfat.h:176
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:55
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 275 of file create.c.

282 {
283  PVFATFCB Fcb;
285 
286  DPRINT("VfatOpenFile(%p, '%wZ', %p, %p)\n", DeviceExt, PathNameU, FileObject, ParentFcb);
287 
288  if (FileObject->RelatedFileObject)
289  {
290  DPRINT("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
291 
292  *ParentFcb = FileObject->RelatedFileObject->FsContext;
293  }
294  else
295  {
296  *ParentFcb = NULL;
297  }
298 
299  if (!DeviceExt->FatInfo.FixedMedia)
300  {
301  Status = VfatBlockDeviceIoControl(DeviceExt->StorageDevice,
303  NULL,
304  0,
305  NULL,
306  0,
307  FALSE);
308  if (!NT_SUCCESS(Status))
309  {
310  DPRINT("Status %lx\n", Status);
311  *ParentFcb = NULL;
312  return Status;
313  }
314  }
315 
316  if (*ParentFcb)
317  {
318  vfatGrabFCB(DeviceExt, *ParentFcb);
319  }
320 
321  /* try first to find an existing FCB in memory */
322  DPRINT("Checking for existing FCB in memory\n");
323 
324  Status = vfatGetFCBForFile(DeviceExt, ParentFcb, &Fcb, PathNameU);
325  if (!NT_SUCCESS(Status))
326  {
327  DPRINT ("Could not make a new FCB, status: %x\n", Status);
328  return Status;
329  }
330 
331  /* Fail, if we try to overwrite an existing directory */
332  if ((!BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE) && vfatFCBIsDirectory(Fcb)) &&
333  (RequestedDisposition == FILE_OVERWRITE ||
334  RequestedDisposition == FILE_OVERWRITE_IF ||
335  RequestedDisposition == FILE_SUPERSEDE))
336  {
337  vfatReleaseFCB(DeviceExt, Fcb);
339  }
340 
342  {
343  vfatReleaseFCB(DeviceExt, Fcb);
344  return STATUS_DELETE_PENDING;
345  }
346 
347  /* Fail, if we try to overwrite a read-only file */
348  if (vfatFCBIsReadOnly(Fcb) &&
349  (RequestedDisposition == FILE_OVERWRITE ||
350  RequestedDisposition == FILE_OVERWRITE_IF))
351  {
352  vfatReleaseFCB(DeviceExt, Fcb);
353  return STATUS_ACCESS_DENIED;
354  }
355 
356  if (vfatFCBIsReadOnly(Fcb) &&
357  (RequestedOptions & FILE_DELETE_ON_CLOSE))
358  {
359  vfatReleaseFCB(DeviceExt, Fcb);
360  return STATUS_CANNOT_DELETE;
361  }
362 
363  if ((vfatFCBIsRoot(Fcb) || IsDotOrDotDot(&Fcb->LongNameU)) &&
364  BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
365  {
366  // we cannot delete a '.', '..' or the root directory
367  vfatReleaseFCB(DeviceExt, Fcb);
368  return STATUS_CANNOT_DELETE;
369  }
370 
371  /* If that one was marked for closing, remove it */
373  {
374  BOOLEAN ConcurrentDeletion;
375  PVFAT_CLOSE_CONTEXT CloseContext;
376 
377  /* Get the context */
378  CloseContext = Fcb->CloseContext;
379  /* Is someone already taking over? */
380  if (CloseContext != NULL)
381  {
382  ConcurrentDeletion = FALSE;
383  /* Lock list */
385  /* Check whether it was already removed, if not, do it */
386  if (!IsListEmpty(&CloseContext->CloseListEntry))
387  {
388  RemoveEntryList(&CloseContext->CloseListEntry);
390  ConcurrentDeletion = TRUE;
391  }
393 
394  /* It's not delayed anymore! */
396  /* Release the extra reference (would have been removed by IRP_MJ_CLOSE) */
397  vfatReleaseFCB(DeviceExt, Fcb);
398  Fcb->CloseContext = NULL;
399  /* If no concurrent deletion, free work item */
400  if (!ConcurrentDeletion)
401  {
402  ExFreeToPagedLookasideList(&VfatGlobalData->CloseContextLookasideList, CloseContext);
403  }
404  }
405 
406  DPRINT("Reusing delayed close FCB for %wZ\n", &Fcb->PathNameU);
407  }
408 
409  DPRINT("Attaching FCB to fileObject\n");
411  if (!NT_SUCCESS(Status))
412  {
413  vfatReleaseFCB(DeviceExt, Fcb);
414  }
415  return Status;
416 }
#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
Iosb Status
Definition: create.c:4287
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:755
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
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:294
#define FILE_OVERWRITE
Definition: from_kernel.h:57
_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
void DPRINT(...)
Definition: polytest.cpp:61
_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:532
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:30
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define FCB_DELAYED_CLOSE
Definition: vfat.h:439
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
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:432
#define NULL
Definition: types.h:112
ULONG CloseCount
Definition: vfat.h:424
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:302
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:884
_In_ PFCB Fcb
Definition: cdprocs.h:159
PAGED_LOOKASIDE_LIST CloseContextLookasideList
Definition: vfat.h:420

Referenced by VfatCreateFile().