ReactOS  0.4.15-dev-1377-ga59cecd
finfo.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: drivers/filesystems/fastfat/finfo.c
5  * PURPOSE: VFAT Filesystem
6  * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
7  * Herve Poussineau (reactos@poussine.freesurf.fr)
8  * Pierre Schweitzer (pierre@reactos.org)
9  *
10  */
11 
12 /* INCLUDES *****************************************************************/
13 
14 #include "vfat.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #define NASSERTS_RENAME
20 
21 /* GLOBALS ******************************************************************/
22 
24 {
25  "??????",
26  "FileDirectoryInformation",
27  "FileFullDirectoryInformation",
28  "FileBothDirectoryInformation",
29  "FileBasicInformation",
30  "FileStandardInformation",
31  "FileInternalInformation",
32  "FileEaInformation",
33  "FileAccessInformation",
34  "FileNameInformation",
35  "FileRenameInformation",
36  "FileLinkInformation",
37  "FileNamesInformation",
38  "FileDispositionInformation",
39  "FilePositionInformation",
40  "FileFullEaInformation",
41  "FileModeInformation",
42  "FileAlignmentInformation",
43  "FileAllInformation",
44  "FileAllocationInformation",
45  "FileEndOfFileInformation",
46  "FileAlternateNameInformation",
47  "FileStreamInformation",
48  "FilePipeInformation",
49  "FilePipeLocalInformation",
50  "FilePipeRemoteInformation",
51  "FileMailslotQueryInformation",
52  "FileMailslotSetInformation",
53  "FileCompressionInformation",
54  "FileObjectIdInformation",
55  "FileCompletionInformation",
56  "FileMoveClusterInformation",
57  "FileQuotaInformation",
58  "FileReparsePointInformation",
59  "FileNetworkOpenInformation",
60  "FileAttributeTagInformation",
61  "FileTrackingInformation",
62  "FileIdBothDirectoryInformation",
63  "FileIdFullDirectoryInformation",
64  "FileValidDataLengthInformation",
65  "FileShortNameInformation",
66  "FileMaximumInformation"
67 };
68 
69 /* FUNCTIONS ****************************************************************/
70 
71 /*
72  * FUNCTION: Retrieve the standard file information
73  */
76  PVFATFCB FCB,
77  PFILE_STANDARD_INFORMATION StandardInfo,
79 {
82 
83  /* PRECONDITION */
84  ASSERT(StandardInfo != NULL);
85  ASSERT(FCB != NULL);
86 
88  {
89  StandardInfo->AllocationSize.QuadPart = 0;
90  StandardInfo->EndOfFile.QuadPart = 0;
91  StandardInfo->Directory = TRUE;
92  }
93  else
94  {
95  StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
96  StandardInfo->EndOfFile = FCB->RFCB.FileSize;
97  StandardInfo->Directory = FALSE;
98  }
99  StandardInfo->NumberOfLinks = 1;
101 
103  return STATUS_SUCCESS;
104 }
105 
106 static
107 NTSTATUS
110  PFILE_POSITION_INFORMATION PositionInfo)
111 {
112  DPRINT("FsdSetPositionInformation()\n");
113 
114  DPRINT("PositionInfo %p\n", PositionInfo);
115  DPRINT("Setting position %u\n", PositionInfo->CurrentByteOffset.u.LowPart);
116 
117  FileObject->CurrentByteOffset.QuadPart =
118  PositionInfo->CurrentByteOffset.QuadPart;
119 
120  return STATUS_SUCCESS;
121 }
122 
123 static
124 NTSTATUS
127  PVFATFCB FCB,
128  PDEVICE_EXTENSION DeviceExt,
129  PFILE_POSITION_INFORMATION PositionInfo,
131 {
134  UNREFERENCED_PARAMETER(DeviceExt);
135 
136  DPRINT("VfatGetPositionInformation()\n");
137 
139  return STATUS_BUFFER_OVERFLOW;
140 
141  PositionInfo->CurrentByteOffset.QuadPart =
142  FileObject->CurrentByteOffset.QuadPart;
143 
144  DPRINT("Getting position %I64x\n",
145  PositionInfo->CurrentByteOffset.QuadPart);
146 
148  return STATUS_SUCCESS;
149 }
150 
151 static
152 NTSTATUS
155  PVFATFCB FCB,
156  PDEVICE_EXTENSION DeviceExt,
157  PFILE_BASIC_INFORMATION BasicInfo)
158 {
160 
161  DPRINT("VfatSetBasicInformation()\n");
162 
163  ASSERT(NULL != FileObject);
164  ASSERT(NULL != FCB);
165  ASSERT(NULL != DeviceExt);
166  ASSERT(NULL != BasicInfo);
167  /* Check volume label bit */
168  ASSERT(0 == (*FCB->Attributes & _A_VOLID));
169 
170  NotifyFilter = 0;
171 
172  if (BasicInfo->FileAttributes != 0)
173  {
175 
181 
182  if (vfatFCBIsDirectory(FCB))
183  {
185  {
186  DPRINT("Setting temporary attribute on a directory!\n");
188  }
189 
191  }
192  else
193  {
195  {
196  DPRINT("Setting directory attribute on a file!\n");
198  }
199  }
200 
201  if (Attributes != *FCB->Attributes)
202  {
203  *FCB->Attributes = Attributes;
204  DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
206  }
207  }
208 
209  if (vfatVolumeIsFatX(DeviceExt))
210  {
211  if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
212  {
213  FsdSystemTimeToDosDateTime(DeviceExt,
214  &BasicInfo->CreationTime,
215  &FCB->entry.FatX.CreationDate,
216  &FCB->entry.FatX.CreationTime);
218  }
219 
220  if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
221  {
222  FsdSystemTimeToDosDateTime(DeviceExt,
223  &BasicInfo->LastAccessTime,
224  &FCB->entry.FatX.AccessDate,
225  &FCB->entry.FatX.AccessTime);
227  }
228 
229  if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
230  {
231  FsdSystemTimeToDosDateTime(DeviceExt,
232  &BasicInfo->LastWriteTime,
233  &FCB->entry.FatX.UpdateDate,
234  &FCB->entry.FatX.UpdateTime);
236  }
237  }
238  else
239  {
240  if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
241  {
242  FsdSystemTimeToDosDateTime(DeviceExt,
243  &BasicInfo->CreationTime,
244  &FCB->entry.Fat.CreationDate,
245  &FCB->entry.Fat.CreationTime);
247  }
248 
249  if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
250  {
251  FsdSystemTimeToDosDateTime(DeviceExt,
252  &BasicInfo->LastAccessTime,
253  &FCB->entry.Fat.AccessDate,
254  NULL);
256  }
257 
258  if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
259  {
260  FsdSystemTimeToDosDateTime(DeviceExt,
261  &BasicInfo->LastWriteTime,
262  &FCB->entry.Fat.UpdateDate,
263  &FCB->entry.Fat.UpdateTime);
265  }
266  }
267 
268  VfatUpdateEntry(DeviceExt, FCB);
269 
270  if (NotifyFilter != 0)
271  {
272  vfatReportChange(DeviceExt,
273  FCB,
274  NotifyFilter,
276  }
277 
278  return STATUS_SUCCESS;
279 }
280 
281 NTSTATUS
284  PVFATFCB FCB,
285  PDEVICE_EXTENSION DeviceExt,
286  PFILE_BASIC_INFORMATION BasicInfo,
288 {
290 
291  DPRINT("VfatGetBasicInformation()\n");
292 
293  if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
294  return STATUS_BUFFER_OVERFLOW;
295 
296  RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
297 
298  if (vfatVolumeIsFatX(DeviceExt))
299  {
300  FsdDosDateTimeToSystemTime(DeviceExt,
301  FCB->entry.FatX.CreationDate,
302  FCB->entry.FatX.CreationTime,
303  &BasicInfo->CreationTime);
304  FsdDosDateTimeToSystemTime(DeviceExt,
305  FCB->entry.FatX.AccessDate,
306  FCB->entry.FatX.AccessTime,
307  &BasicInfo->LastAccessTime);
308  FsdDosDateTimeToSystemTime(DeviceExt,
309  FCB->entry.FatX.UpdateDate,
310  FCB->entry.FatX.UpdateTime,
311  &BasicInfo->LastWriteTime);
312  BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
313  }
314  else
315  {
316  FsdDosDateTimeToSystemTime(DeviceExt,
317  FCB->entry.Fat.CreationDate,
318  FCB->entry.Fat.CreationTime,
319  &BasicInfo->CreationTime);
320  FsdDosDateTimeToSystemTime(DeviceExt,
321  FCB->entry.Fat.AccessDate,
322  0,
323  &BasicInfo->LastAccessTime);
324  FsdDosDateTimeToSystemTime(DeviceExt,
325  FCB->entry.Fat.UpdateDate,
326  FCB->entry.Fat.UpdateTime,
327  &BasicInfo->LastWriteTime);
328  BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
329  }
330 
331  BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
332  /* Synthesize FILE_ATTRIBUTE_NORMAL */
333  if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
338  {
339  DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
341  }
342  DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
343 
345  return STATUS_SUCCESS;
346 }
347 
348 
349 static
350 NTSTATUS
353  PVFATFCB FCB,
354  PDEVICE_EXTENSION DeviceExt,
355  PFILE_DISPOSITION_INFORMATION DispositionInfo)
356 {
357  DPRINT("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
358 
359  ASSERT(DeviceExt != NULL);
360  ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
361  ASSERT(FCB != NULL);
362 
363  if (!DispositionInfo->DeleteFile)
364  {
365  /* undelete the file */
367  FileObject->DeletePending = FALSE;
368  return STATUS_SUCCESS;
369  }
370 
372  {
373  /* stream already marked for deletion. just update the file object */
374  FileObject->DeletePending = TRUE;
375  return STATUS_SUCCESS;
376  }
377 
378  if (vfatFCBIsReadOnly(FCB))
379  {
380  return STATUS_CANNOT_DELETE;
381  }
382 
383  if (vfatFCBIsRoot(FCB) || IsDotOrDotDot(&FCB->LongNameU))
384  {
385  /* we cannot delete a '.', '..' or the root directory */
386  return STATUS_ACCESS_DENIED;
387  }
388 
389  if (!MmFlushImageSection (FileObject->SectionObjectPointer, MmFlushForDelete))
390  {
391  /* can't delete a file if its mapped into a process */
392 
393  DPRINT("MmFlushImageSection returned FALSE\n");
394  return STATUS_CANNOT_DELETE;
395  }
396 
397  if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(DeviceExt, FCB))
398  {
399  /* can't delete a non-empty directory */
400 
402  }
403 
404  /* all good */
406  FileObject->DeletePending = TRUE;
407 
408  return STATUS_SUCCESS;
409 }
410 
411 static NTSTATUS
413  IN PDEVICE_EXTENSION DeviceExt,
414  IN PVFATFCB * ParentFCB,
416  IN BOOLEAN ReplaceIfExists,
417  IN PUNICODE_STRING ParentName,
419 {
421  PVFATFCB TargetFcb;
422 
423  DPRINT("vfatPrepareTargetForRename(%p, %p, %wZ, %d, %wZ, %p)\n", DeviceExt, ParentFCB, NewName, ReplaceIfExists, ParentName);
424 
425  *Deleted = FALSE;
426  /* Try to open target */
427  Status = vfatGetFCBForFile(DeviceExt, ParentFCB, &TargetFcb, NewName);
428  /* If it exists */
429  if (NT_SUCCESS(Status))
430  {
431  DPRINT("Target file %wZ exists. FCB Flags %08x\n", NewName, TargetFcb->Flags);
432  /* Check whether we are allowed to replace */
433  if (ReplaceIfExists)
434  {
435  /* If that's a directory or a read-only file, we're not allowed */
436  if (vfatFCBIsDirectory(TargetFcb) || vfatFCBIsReadOnly(TargetFcb))
437  {
438  DPRINT("And this is a readonly file!\n");
439  vfatReleaseFCB(DeviceExt, *ParentFCB);
440  *ParentFCB = NULL;
441  vfatReleaseFCB(DeviceExt, TargetFcb);
443  }
444 
445 
446  /* If we still have a file object, close it. */
447  if (TargetFcb->FileObject)
448  {
449  if (!MmFlushImageSection(TargetFcb->FileObject->SectionObjectPointer, MmFlushForDelete))
450  {
451  DPRINT("MmFlushImageSection failed.\n");
452  vfatReleaseFCB(DeviceExt, *ParentFCB);
453  *ParentFCB = NULL;
454  vfatReleaseFCB(DeviceExt, TargetFcb);
455  return STATUS_ACCESS_DENIED;
456  }
457 
458  TargetFcb->FileObject->DeletePending = TRUE;
459  VfatCloseFile(DeviceExt, TargetFcb->FileObject);
460  }
461 
462  /* If we are here, ensure the file isn't open by anyone! */
463  if (TargetFcb->OpenHandleCount != 0)
464  {
465  DPRINT("There are still open handles for this file.\n");
466  vfatReleaseFCB(DeviceExt, *ParentFCB);
467  *ParentFCB = NULL;
468  vfatReleaseFCB(DeviceExt, TargetFcb);
469  return STATUS_ACCESS_DENIED;
470  }
471 
472  /* Effectively delete old file to allow renaming */
473  DPRINT("Effectively deleting the file.\n");
474  VfatDelEntry(DeviceExt, TargetFcb, NULL);
475  vfatReleaseFCB(DeviceExt, TargetFcb);
476  *Deleted = TRUE;
477  return STATUS_SUCCESS;
478  }
479  else
480  {
481  vfatReleaseFCB(DeviceExt, *ParentFCB);
482  *ParentFCB = NULL;
483  vfatReleaseFCB(DeviceExt, TargetFcb);
485  }
486  }
487  else if (*ParentFCB != NULL)
488  {
489  return STATUS_SUCCESS;
490  }
491 
492  /* Failure */
493  return Status;
494 }
495 
496 static
497 BOOLEAN
499 {
501  PVFATFCB VolFCB;
502 
503  for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
504  {
505  VolFCB = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
506  if (VolFCB->OpenHandleCount != 0)
507  {
508  ASSERT(VolFCB->parentFcb == FCB);
509  DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
510  return TRUE;
511  }
512 
513  if (vfatFCBIsDirectory(VolFCB) && !IsListEmpty(&VolFCB->ParentListHead))
514  {
515  if (IsThereAChildOpened(VolFCB))
516  {
517  return TRUE;
518  }
519  }
520  }
521 
522  return FALSE;
523 }
524 
525 static
526 VOID
528  PDEVICE_EXTENSION DeviceExt,
529  PVFATFCB FCB)
530 {
532  PVFATFCB Child;
533 
534  if (IsListEmpty(&FCB->ParentListHead))
535  return;
536 
537  for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
538  {
540 
541  Child = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
542  DPRINT("Found %wZ with still %lu references (parent: %lu)!\n", &Child->PathNameU, Child->RefCount, FCB->RefCount);
543 
544  Status = vfatSetFCBNewDirName(DeviceExt, Child, FCB);
545  if (!NT_SUCCESS(Status))
546  continue;
547 
549  {
550  VfatRenameChildFCB(DeviceExt, Child);
551  }
552  }
553 }
554 
555 /*
556  * FUNCTION: Set the file name information
557  */
558 static
559 NTSTATUS
562  PVFATFCB FCB,
563  PDEVICE_EXTENSION DeviceExt,
564  PFILE_RENAME_INFORMATION RenameInfo,
565  PFILE_OBJECT TargetFileObject)
566 {
567 #ifdef NASSERTS_RENAME
568 #pragma push_macro("ASSERT")
569 #undef ASSERT
570 #define ASSERT(x) ((VOID) 0)
571 #endif
574  UNICODE_STRING SourcePath;
575  UNICODE_STRING SourceFile;
576  UNICODE_STRING NewPath;
577  UNICODE_STRING NewFile;
578  PFILE_OBJECT RootFileObject;
579  PVFATFCB RootFCB;
580  UNICODE_STRING RenameInfoString;
581  PVFATFCB ParentFCB;
585  BOOLEAN DeletedTarget;
586  ULONG OldReferences, NewReferences;
587  PVFATFCB OldParent;
588 
589  DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceExt, RenameInfo, TargetFileObject);
590 
591  /* Disallow renaming root */
592  if (vfatFCBIsRoot(FCB))
593  {
595  }
596 
597  OldReferences = FCB->parentFcb->RefCount;
598 #ifdef NASSERTS_RENAME
599  UNREFERENCED_PARAMETER(OldReferences);
600 #endif
601 
602  /* If we are performing relative opening for rename, get FO for getting FCB and path name */
603  if (RenameInfo->RootDirectory != NULL)
604  {
605  /* We cannot tolerate relative opening with a full path */
606  if (RenameInfo->FileName[0] == L'\\')
607  {
609  }
610 
615  (PVOID *)&RootFileObject,
616  NULL);
617  if (!NT_SUCCESS(Status))
618  {
619  return Status;
620  }
621 
622  RootFCB = RootFileObject->FsContext;
623  }
624 
625  RtlInitEmptyUnicodeString(&NewName, NULL, 0);
626  ParentFCB = NULL;
627 
628  if (TargetFileObject == NULL)
629  {
630  /* If we don't have target file object, construct paths thanks to relative FCB, if any, and with
631  * information supplied by the user
632  */
633 
634  /* First, setup a string we'll work on */
635  RenameInfoString.Length = RenameInfo->FileNameLength;
636  RenameInfoString.MaximumLength = RenameInfo->FileNameLength;
637  RenameInfoString.Buffer = RenameInfo->FileName;
638 
639  /* Check whether we have FQN */
640  if (RenameInfoString.Length > 6 * sizeof(WCHAR))
641  {
642  if (RenameInfoString.Buffer[0] == L'\\' && RenameInfoString.Buffer[1] == L'?' &&
643  RenameInfoString.Buffer[2] == L'?' && RenameInfoString.Buffer[3] == L'\\' &&
644  RenameInfoString.Buffer[5] == L':' && (RenameInfoString.Buffer[4] >= L'A' &&
645  RenameInfoString.Buffer[4] <= L'Z'))
646  {
647  /* If so, open its target directory */
649  &RenameInfoString,
651  NULL, NULL);
652 
656  &IoStatusBlock,
657  NULL, 0,
659  FILE_OPEN,
661  NULL, 0,
663  NULL,
665  if (!NT_SUCCESS(Status))
666  {
667  goto Cleanup;
668  }
669 
670  /* Get its FO to get the FCB */
674  KernelMode,
675  (PVOID *)&TargetFileObject,
676  NULL);
677  if (!NT_SUCCESS(Status))
678  {
680  goto Cleanup;
681  }
682 
683  /* Are we working on the same volume? */
685  {
686  ObDereferenceObject(TargetFileObject);
688  TargetFileObject = NULL;
690  goto Cleanup;
691  }
692  }
693  }
694 
695  NewName.Length = 0;
696  NewName.MaximumLength = RenameInfo->FileNameLength;
697  if (RenameInfo->RootDirectory != NULL)
698  {
699  NewName.MaximumLength += sizeof(WCHAR) + RootFCB->PathNameU.Length;
700  }
701  else if (RenameInfo->FileName[0] != L'\\')
702  {
703  /* We don't have full path, and we don't have root directory:
704  * => we move inside the same directory
705  */
706  NewName.MaximumLength += sizeof(WCHAR) + FCB->DirNameU.Length;
707  }
708  else if (TargetFileObject != NULL)
709  {
710  /* We had a FQN:
711  * => we need to use its correct path
712  */
713  NewName.MaximumLength += sizeof(WCHAR) + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length;
714  }
715 
717  if (NewName.Buffer == NULL)
718  {
719  if (TargetFileObject != NULL)
720  {
721  ObDereferenceObject(TargetFileObject);
723  TargetFileObject = NULL;
724  }
726  goto Cleanup;
727  }
728 
729  if (RenameInfo->RootDirectory != NULL)
730  {
731  /* Here, copy first absolute and then append relative */
733  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
734  NewName.Length += sizeof(WCHAR);
735  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
736  }
737  else if (RenameInfo->FileName[0] != L'\\')
738  {
739  /* Here, copy first work directory and then append filename */
740  RtlCopyUnicodeString(&NewName, &FCB->DirNameU);
741  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
742  NewName.Length += sizeof(WCHAR);
743  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
744  }
745  else if (TargetFileObject != NULL)
746  {
747  /* Here, copy first path name and then append filename */
748  RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
749  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
750  NewName.Length += sizeof(WCHAR);
751  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
752  }
753  else
754  {
755  /* Here we should have full path, so simply copy it */
756  RtlCopyUnicodeString(&NewName, &RenameInfoString);
757  }
758 
759  /* Do we have to cleanup some stuff? */
760  if (TargetFileObject != NULL)
761  {
762  ObDereferenceObject(TargetFileObject);
764  TargetFileObject = NULL;
765  }
766  }
767  else
768  {
769  /* At that point, we shouldn't care about whether we are relative opening
770  * Target FO FCB should already have full path
771  */
772 
773  /* Before constructing string, just make a sanity check (just to be sure!) */
775  {
777  goto Cleanup;
778  }
779 
780  NewName.Length = 0;
781  NewName.MaximumLength = TargetFileObject->FileName.Length + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length + sizeof(WCHAR);
783  if (NewName.Buffer == NULL)
784  {
786  goto Cleanup;
787  }
788 
789  RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
790  /* If \, it's already backslash terminated, don't add it */
791  if (!vfatFCBIsRoot(TargetFileObject->FsContext))
792  {
793  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
794  NewName.Length += sizeof(WCHAR);
795  }
796  RtlAppendUnicodeStringToString(&NewName, &TargetFileObject->FileName);
797  }
798 
799  /* Explode our paths to get path & filename */
800  vfatSplitPathName(&FCB->PathNameU, &SourcePath, &SourceFile);
801  DPRINT("Old dir: %wZ, Old file: %wZ\n", &SourcePath, &SourceFile);
802  vfatSplitPathName(&NewName, &NewPath, &NewFile);
803  DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
804 
805  if (IsDotOrDotDot(&NewFile))
806  {
808  goto Cleanup;
809  }
810 
811  if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
812  {
814  {
816  ASSERT(OldReferences == FCB->parentFcb->RefCount);
817  goto Cleanup;
818  }
819  }
820 
821  /* Are we working in place? */
822  if (FsRtlAreNamesEqual(&SourcePath, &NewPath, TRUE, NULL))
823  {
824  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
825  {
827  ASSERT(OldReferences == FCB->parentFcb->RefCount);
828  goto Cleanup;
829  }
830 
831  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, TRUE, NULL))
832  {
833  vfatReportChange(DeviceExt,
834  FCB,
838  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, TRUE);
839  if (NT_SUCCESS(Status))
840  {
841  vfatReportChange(DeviceExt,
842  FCB,
846  }
847  }
848  else
849  {
850  /* Try to find target */
851  ParentFCB = FCB->parentFcb;
852  vfatGrabFCB(DeviceExt, ParentFCB);
854  &ParentFCB,
855  &NewFile,
856  RenameInfo->ReplaceIfExists,
857  &NewPath,
858  &DeletedTarget);
859  if (!NT_SUCCESS(Status))
860  {
861  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1);
862  ASSERT(OldReferences == ParentFCB->RefCount - 1);
863  goto Cleanup;
864  }
865 
866  vfatReportChange(DeviceExt,
867  FCB,
871  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, FALSE);
872  if (NT_SUCCESS(Status))
873  {
874  if (DeletedTarget)
875  {
876  vfatReportChange(DeviceExt,
877  FCB,
881  }
882  else
883  {
884  vfatReportChange(DeviceExt,
885  FCB,
889  }
890  }
891  }
892 
893  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1); // extra grab
894  ASSERT(OldReferences == ParentFCB->RefCount - 1); // extra grab
895  }
896  else
897  {
898 
899  /* Try to find target */
900  ParentFCB = NULL;
901  OldParent = FCB->parentFcb;
902 #ifdef NASSERTS_RENAME
903  UNREFERENCED_PARAMETER(OldParent);
904 #endif
906  &ParentFCB,
907  &NewName,
908  RenameInfo->ReplaceIfExists,
909  &NewPath,
910  &DeletedTarget);
911  if (!NT_SUCCESS(Status))
912  {
913  ASSERT(OldReferences == FCB->parentFcb->RefCount);
914  goto Cleanup;
915  }
916 
917  NewReferences = ParentFCB->RefCount;
918 #ifdef NASSERTS_RENAME
919  UNREFERENCED_PARAMETER(NewReferences);
920 #endif
921 
922  vfatReportChange(DeviceExt,
923  FCB,
927  Status = VfatMoveEntry(DeviceExt, FCB, &NewFile, ParentFCB);
928  if (NT_SUCCESS(Status))
929  {
930  if (DeletedTarget)
931  {
932  vfatReportChange(DeviceExt,
933  FCB,
937  }
938  else
939  {
940  vfatReportChange(DeviceExt,
941  FCB,
945  }
946  }
947  }
948 
950  {
951  VfatRenameChildFCB(DeviceExt, FCB);
952  }
953 
954  ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
955  ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
956 Cleanup:
957  if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB);
959  if (RenameInfo->RootDirectory != NULL) ObDereferenceObject(RootFileObject);
960 
961  return Status;
962 #ifdef NASSERTS_RENAME
963 #pragma pop_macro("ASSERT")
964 #endif
965 }
966 
967 /*
968  * FUNCTION: Retrieve the file name information
969  */
970 static
971 NTSTATUS
974  PVFATFCB FCB,
975  PDEVICE_EXTENSION DeviceExt,
976  PFILE_NAME_INFORMATION NameInfo,
978 {
980 
982  UNREFERENCED_PARAMETER(DeviceExt);
983 
984  ASSERT(NameInfo != NULL);
985  ASSERT(FCB != NULL);
986 
987  /* If buffer can't hold at least the file name length, bail out */
989  return STATUS_BUFFER_OVERFLOW;
990 
991  /* Save file name length, and as much file len, as buffer length allows */
992  NameInfo->FileNameLength = FCB->PathNameU.Length;
993 
994  /* Calculate amount of bytes to copy not to overflow the buffer */
995  BytesToCopy = min(FCB->PathNameU.Length,
997 
998  /* Fill in the bytes */
999  RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
1000 
1001  /* Check if we could write more but are not able to */
1003  {
1004  /* Return number of bytes written */
1006  return STATUS_BUFFER_OVERFLOW;
1007  }
1008 
1009  /* We filled up as many bytes, as needed */
1010  *BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
1011 
1012  return STATUS_SUCCESS;
1013 }
1014 
1015 static
1016 NTSTATUS
1018  PVFATFCB Fcb,
1019  PDEVICE_EXTENSION DeviceExt,
1020  PFILE_INTERNAL_INFORMATION InternalInfo,
1022 {
1023  ASSERT(InternalInfo);
1024  ASSERT(Fcb);
1025 
1026  if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
1027  return STATUS_BUFFER_OVERFLOW;
1028 
1029  InternalInfo->IndexNumber.QuadPart = (LONGLONG)vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry) * DeviceExt->FatInfo.BytesPerCluster;
1030 
1032  return STATUS_SUCCESS;
1033 }
1034 
1035 
1036 /*
1037  * FUNCTION: Retrieve the file network open information
1038  */
1039 static
1040 NTSTATUS
1042  PVFATFCB Fcb,
1043  PDEVICE_EXTENSION DeviceExt,
1044  PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
1046 {
1047  ASSERT(NetworkInfo);
1048  ASSERT(Fcb);
1049 
1051  return(STATUS_BUFFER_OVERFLOW);
1052 
1053  if (vfatVolumeIsFatX(DeviceExt))
1054  {
1055  FsdDosDateTimeToSystemTime(DeviceExt,
1056  Fcb->entry.FatX.CreationDate,
1057  Fcb->entry.FatX.CreationTime,
1058  &NetworkInfo->CreationTime);
1059  FsdDosDateTimeToSystemTime(DeviceExt,
1060  Fcb->entry.FatX.AccessDate,
1061  Fcb->entry.FatX.AccessTime,
1062  &NetworkInfo->LastAccessTime);
1063  FsdDosDateTimeToSystemTime(DeviceExt,
1064  Fcb->entry.FatX.UpdateDate,
1065  Fcb->entry.FatX.UpdateTime,
1066  &NetworkInfo->LastWriteTime);
1067  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1068  }
1069  else
1070  {
1071  FsdDosDateTimeToSystemTime(DeviceExt,
1072  Fcb->entry.Fat.CreationDate,
1073  Fcb->entry.Fat.CreationTime,
1074  &NetworkInfo->CreationTime);
1075  FsdDosDateTimeToSystemTime(DeviceExt,
1076  Fcb->entry.Fat.AccessDate,
1077  0,
1078  &NetworkInfo->LastAccessTime);
1079  FsdDosDateTimeToSystemTime(DeviceExt,
1080  Fcb->entry.Fat.UpdateDate,
1081  Fcb->entry.Fat.UpdateTime,
1082  &NetworkInfo->LastWriteTime);
1083  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1084  }
1085 
1086  if (vfatFCBIsDirectory(Fcb))
1087  {
1088  NetworkInfo->EndOfFile.QuadPart = 0L;
1089  NetworkInfo->AllocationSize.QuadPart = 0L;
1090  }
1091  else
1092  {
1093  NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
1094  NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
1095  }
1096 
1097  NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
1098  /* Synthesize FILE_ATTRIBUTE_NORMAL */
1099  if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
1104  {
1105  DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
1106  NetworkInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
1107  }
1108 
1110  return STATUS_SUCCESS;
1111 }
1112 
1113 
1114 static
1115 NTSTATUS
1118  PVFATFCB Fcb,
1119  PDEVICE_EXTENSION DeviceExt,
1122 {
1125 
1126  /* FIXME - use SEH to access the buffer! */
1127  Info->EaSize = 0;
1128  *BufferLength -= sizeof(*Info);
1129  if (DeviceExt->FatInfo.FatType == FAT12 ||
1130  DeviceExt->FatInfo.FatType == FAT16)
1131  {
1132  /* FIXME */
1133  DPRINT1("VFAT: FileEaInformation not implemented!\n");
1134  }
1135  return STATUS_SUCCESS;
1136 }
1137 
1138 
1139 /*
1140  * FUNCTION: Retrieve the all file information
1141  */
1142 static
1143 NTSTATUS
1146  PVFATFCB Fcb,
1147  PDEVICE_EXTENSION DeviceExt,
1150 {
1151  NTSTATUS Status;
1152 
1153  ASSERT(Info);
1154  ASSERT(Fcb);
1155 
1156  if (*BufferLength < FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName))
1157  return STATUS_BUFFER_OVERFLOW;
1158 
1160 
1161  /* Basic Information */
1162  Status = VfatGetBasicInformation(FileObject, Fcb, DeviceExt, &Info->BasicInformation, BufferLength);
1163  if (!NT_SUCCESS(Status)) return Status;
1164  /* Standard Information */
1165  Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
1166  if (!NT_SUCCESS(Status)) return Status;
1167  /* Internal Information */
1168  Status = VfatGetInternalInformation(Fcb, DeviceExt, &Info->InternalInformation, BufferLength);
1169  if (!NT_SUCCESS(Status)) return Status;
1170  /* EA Information */
1171  Status = VfatGetEaInformation(FileObject, Fcb, DeviceExt, &Info->EaInformation, BufferLength);
1172  if (!NT_SUCCESS(Status)) return Status;
1173  /* Position Information */
1174  Status = VfatGetPositionInformation(FileObject, Fcb, DeviceExt, &Info->PositionInformation, BufferLength);
1175  if (!NT_SUCCESS(Status)) return Status;
1176  /* Name Information */
1177  Status = VfatGetNameInformation(FileObject, Fcb, DeviceExt, &Info->NameInformation, BufferLength);
1178 
1179  return Status;
1180 }
1181 
1182 static
1183 VOID
1186  PVFATFCB Fcb,
1187  ULONG Size,
1189  BOOLEAN IsFatX)
1190 {
1191  if (Size > 0)
1192  {
1194  }
1195  else
1196  {
1198  }
1199  if (!vfatFCBIsDirectory(Fcb))
1200  {
1201  if (IsFatX)
1202  Fcb->entry.FatX.FileSize = Size;
1203  else
1204  Fcb->entry.Fat.FileSize = Size;
1205  }
1208 
1210 }
1211 
1212 NTSTATUS
1215  PVFATFCB Fcb,
1216  PDEVICE_EXTENSION DeviceExt,
1218 {
1219  ULONG OldSize;
1220  ULONG Cluster, FirstCluster;
1221  NTSTATUS Status;
1222 
1223  ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
1224  ULONG NewSize = AllocationSize->u.LowPart;
1225  ULONG NCluster;
1226  BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
1227 
1228  DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
1229  &Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
1230 
1231  if (IsFatX)
1232  OldSize = Fcb->entry.FatX.FileSize;
1233  else
1234  OldSize = Fcb->entry.Fat.FileSize;
1235 
1236  if (AllocationSize->u.HighPart > 0)
1237  {
1238  return STATUS_INVALID_PARAMETER;
1239  }
1240 
1241  if (OldSize == NewSize)
1242  {
1243  return STATUS_SUCCESS;
1244  }
1245 
1246  FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
1247 
1248  if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
1249  {
1250  AllocSizeChanged = TRUE;
1251  if (FirstCluster == 0)
1252  {
1253  Fcb->LastCluster = Fcb->LastOffset = 0;
1254  Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
1255  if (!NT_SUCCESS(Status))
1256  {
1257  DPRINT1("NextCluster failed. Status = %x\n", Status);
1258  return Status;
1259  }
1260 
1261  if (FirstCluster == 0xffffffff)
1262  {
1263  return STATUS_DISK_FULL;
1264  }
1265 
1266  Status = OffsetToCluster(DeviceExt, FirstCluster,
1268  &NCluster, TRUE);
1269  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1270  {
1271  /* disk is full */
1272  NCluster = Cluster = FirstCluster;
1274  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1275  {
1276  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1277  WriteCluster(DeviceExt, Cluster, 0);
1278  Cluster = NCluster;
1279  }
1280  return STATUS_DISK_FULL;
1281  }
1282 
1283  if (IsFatX)
1284  {
1285  Fcb->entry.FatX.FirstCluster = FirstCluster;
1286  }
1287  else
1288  {
1289  if (DeviceExt->FatInfo.FatType == FAT32)
1290  {
1291  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1292  Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;
1293  }
1294  else
1295  {
1296  ASSERT((FirstCluster >> 16) == 0);
1297  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1298  }
1299  }
1300  }
1301  else
1302  {
1303  if (Fcb->LastCluster > 0)
1304  {
1305  if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
1306  {
1307  Cluster = Fcb->LastCluster;
1309  }
1310  else
1311  {
1312  Status = OffsetToCluster(DeviceExt, Fcb->LastCluster,
1313  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,
1314  &Cluster, FALSE);
1315  }
1316  }
1317  else
1318  {
1319  Status = OffsetToCluster(DeviceExt, FirstCluster,
1320  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
1321  &Cluster, FALSE);
1322  }
1323 
1324  if (!NT_SUCCESS(Status))
1325  {
1326  return Status;
1327  }
1328 
1329  Fcb->LastCluster = Cluster;
1330  Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
1331 
1332  /* FIXME: Check status */
1333  /* Cluster points now to the last cluster within the chain */
1334  Status = OffsetToCluster(DeviceExt, Cluster,
1335  ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
1336  &NCluster, TRUE);
1337  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1338  {
1339  /* disk is full */
1340  NCluster = Cluster;
1341  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1342  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1343  Cluster = NCluster;
1344  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1345  {
1346  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1347  WriteCluster(DeviceExt, Cluster, 0);
1348  Cluster = NCluster;
1349  }
1350  return STATUS_DISK_FULL;
1351  }
1352  }
1354  }
1355  else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
1356  {
1357  DPRINT("Check for the ability to set file size\n");
1358  if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
1360  {
1361  DPRINT("Couldn't set file size!\n");
1362  return STATUS_USER_MAPPED_FILE;
1363  }
1364  DPRINT("Can set file size\n");
1365 
1366  AllocSizeChanged = TRUE;
1367  /* FIXME: Use the cached cluster/offset better way. */
1368  Fcb->LastCluster = Fcb->LastOffset = 0;
1370  if (NewSize > 0)
1371  {
1372  Status = OffsetToCluster(DeviceExt, FirstCluster,
1374  &Cluster, FALSE);
1375 
1376  NCluster = Cluster;
1377  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1378  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1379  Cluster = NCluster;
1380  }
1381  else
1382  {
1383  if (IsFatX)
1384  {
1385  Fcb->entry.FatX.FirstCluster = 0;
1386  }
1387  else
1388  {
1389  if (DeviceExt->FatInfo.FatType == FAT32)
1390  {
1391  Fcb->entry.Fat.FirstCluster = 0;
1392  Fcb->entry.Fat.FirstClusterHigh = 0;
1393  }
1394  else
1395  {
1396  Fcb->entry.Fat.FirstCluster = 0;
1397  }
1398  }
1399 
1400  NCluster = Cluster = FirstCluster;
1402  }
1403 
1404  while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
1405  {
1406  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1407  WriteCluster(DeviceExt, Cluster, 0);
1408  Cluster = NCluster;
1409  }
1410 
1411  if (DeviceExt->FatInfo.FatType == FAT32)
1412  {
1413  FAT32UpdateFreeClustersCount(DeviceExt);
1414  }
1415  }
1416  else
1417  {
1419  }
1420 
1421  /* Update the on-disk directory entry */
1422  Fcb->Flags |= FCB_IS_DIRTY;
1423  if (AllocSizeChanged)
1424  {
1425  VfatUpdateEntry(DeviceExt, Fcb);
1426 
1428  }
1429  return STATUS_SUCCESS;
1430 }
1431 
1432 /*
1433  * FUNCTION: Retrieve the specified file information
1434  */
1435 NTSTATUS
1437  PVFAT_IRP_CONTEXT IrpContext)
1438 {
1440  PVFATFCB FCB;
1441 
1443  PVOID SystemBuffer;
1445 
1446  /* PRECONDITION */
1447  ASSERT(IrpContext);
1448 
1449  /* INITIALIZATION */
1450  FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
1451  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1452 
1453  DPRINT("VfatQueryInformation is called for '%s'\n",
1455 
1456  if (FCB == NULL)
1457  {
1458  DPRINT1("IRP_MJ_QUERY_INFORMATION without FCB!\n");
1459  IrpContext->Irp->IoStatus.Information = 0;
1460  return STATUS_INVALID_PARAMETER;
1461  }
1462 
1463  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1464  BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
1465 
1467  {
1469  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1470  {
1471  return VfatMarkIrpContextForQueue(IrpContext);
1472  }
1473  }
1474 
1475  switch (FileInformationClass)
1476  {
1479  SystemBuffer,
1480  &BufferLength);
1481  break;
1482 
1485  FCB,
1486  IrpContext->DeviceExt,
1487  SystemBuffer,
1488  &BufferLength);
1489  break;
1490 
1491  case FileBasicInformation:
1493  FCB,
1494  IrpContext->DeviceExt,
1495  SystemBuffer,
1496  &BufferLength);
1497  break;
1498 
1499  case FileNameInformation:
1501  FCB,
1502  IrpContext->DeviceExt,
1503  SystemBuffer,
1504  &BufferLength);
1505  break;
1506 
1509  IrpContext->DeviceExt,
1510  SystemBuffer,
1511  &BufferLength);
1512  break;
1513 
1516  IrpContext->DeviceExt,
1517  SystemBuffer,
1518  &BufferLength);
1519  break;
1520 
1521  case FileAllInformation:
1522  Status = VfatGetAllInformation(IrpContext->FileObject,
1523  FCB,
1524  IrpContext->DeviceExt,
1525  SystemBuffer,
1526  &BufferLength);
1527  break;
1528 
1529  case FileEaInformation:
1530  Status = VfatGetEaInformation(IrpContext->FileObject,
1531  FCB,
1532  IrpContext->DeviceExt,
1533  SystemBuffer,
1534  &BufferLength);
1535  break;
1536 
1539  break;
1540 
1541  default:
1543  }
1544 
1546  {
1548  }
1549 
1551  IrpContext->Irp->IoStatus.Information =
1552  IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
1553  else
1554  IrpContext->Irp->IoStatus.Information = 0;
1555 
1556  return Status;
1557 }
1558 
1559 /*
1560  * FUNCTION: Retrieve the specified file information
1561  */
1562 NTSTATUS
1564  PVFAT_IRP_CONTEXT IrpContext)
1565 {
1567  PVFATFCB FCB;
1569  PVOID SystemBuffer;
1570  BOOLEAN LockDir;
1571 
1572  /* PRECONDITION */
1573  ASSERT(IrpContext);
1574 
1575  DPRINT("VfatSetInformation(IrpContext %p)\n", IrpContext);
1576 
1577  /* INITIALIZATION */
1579  IrpContext->Stack->Parameters.SetFile.FileInformationClass;
1580  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1581  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1582 
1583  DPRINT("VfatSetInformation is called for '%s'\n",
1585 
1586  DPRINT("FileInformationClass %d\n", FileInformationClass);
1587  DPRINT("SystemBuffer %p\n", SystemBuffer);
1588 
1589  if (FCB == NULL)
1590  {
1591  DPRINT1("IRP_MJ_SET_INFORMATION without FCB!\n");
1592  IrpContext->Irp->IoStatus.Information = 0;
1593  return STATUS_INVALID_PARAMETER;
1594  }
1595 
1596  /* Special: We should call MmCanFileBeTruncated here to determine if changing
1597  the file size would be allowed. If not, we bail with the right error.
1598  We must do this before acquiring the lock. */
1600  {
1601  DPRINT("Check for the ability to set file size\n");
1602  if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
1603  (PLARGE_INTEGER)SystemBuffer))
1604  {
1605  DPRINT("Couldn't set file size!\n");
1606  IrpContext->Irp->IoStatus.Information = 0;
1607  return STATUS_USER_MAPPED_FILE;
1608  }
1609  DPRINT("Can set file size\n");
1610  }
1611 
1612  LockDir = FALSE;
1615  {
1616  LockDir = TRUE;
1617  }
1618 
1619  if (LockDir)
1620  {
1622  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1623  {
1624  return VfatMarkIrpContextForQueue(IrpContext);
1625  }
1626  }
1627 
1629  {
1631  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1632  {
1633  if (LockDir)
1634  {
1636  }
1637 
1638  return VfatMarkIrpContextForQueue(IrpContext);
1639  }
1640  }
1641 
1642  switch (FileInformationClass)
1643  {
1646  SystemBuffer);
1647  break;
1648 
1651  FCB,
1652  IrpContext->DeviceExt,
1653  SystemBuffer);
1654  break;
1655 
1659  FCB,
1660  IrpContext->DeviceExt,
1661  (PLARGE_INTEGER)SystemBuffer);
1662  break;
1663 
1664  case FileBasicInformation:
1666  FCB,
1667  IrpContext->DeviceExt,
1668  SystemBuffer);
1669  break;
1670 
1671  case FileRenameInformation:
1673  FCB,
1674  IrpContext->DeviceExt,
1675  SystemBuffer,
1676  IrpContext->Stack->Parameters.SetFile.FileObject);
1677  break;
1678 
1679  default:
1681  }
1682 
1684  {
1686  }
1687 
1688  if (LockDir)
1689  {
1691  }
1692 
1693  IrpContext->Irp->IoStatus.Information = 0;
1694  return Status;
1695 }
1696 
1697 /* EOF */
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define FAT12
Definition: fat.h:167
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1213
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LONGLONG CreationTime
Definition: cdstruc.h:1030
BOOLEAN NTAPI MmCanFileBeTruncated(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize)
Definition: section.c:4722
static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo)
Definition: finfo.c:108
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
return STATUS_NOT_SUPPORTED
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:40
#define TAG_NAME
Definition: vfat.h:553
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:160
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static BOOLEAN IsThereAChildOpened(PVFATFCB FCB)
Definition: finfo.c:498
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
#define FCB_IS_DIRTY
Definition: vfat.h:438
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:523
#define FILE_ACTION_RENAMED_OLD_NAME
const char * FileInformationClassNames[]
Definition: finfo.c:23
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
struct _Entry Entry
Definition: kefuncs.h:627
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: vfat.h:447
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:19
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
Definition: cdstruc.h:902
#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
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:1213
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
NTSTATUS VfatGetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:282
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:294
#define FILE_NOTIFY_CHANGE_SIZE
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
#define FILE_NOTIFY_CHANGE_LAST_WRITE
static NTSTATUS VfatGetEaInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_EA_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1116
#define FILE_NOTIFY_CHANGE_FILE_NAME
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
struct _FILE_ACCESS_INFORMATION FILE_ACCESS_INFORMATION
IO_STATUS_BLOCK IoStatus
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
PFILE_OBJECT FileObject
Definition: vfat.h:591
#define FILE_NOTIFY_CHANGE_DIR_NAME
NTSTATUS vfatSetFCBNewDirName(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
Definition: fcb.c:491
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
#define FILE_SHARE_READ
Definition: compat.h:136
NTSTATUS VfatGetStandardInformation(PVFATFCB FCB, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
Definition: finfo.c:75
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
LONG RefCount
Definition: vfat.h:481
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ROUND_UP_64(n, align)
Definition: vfat.h:34
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
return STATUS_NOT_IMPLEMENTED
static NTSTATUS VfatSetDispositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:351
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1563
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
FORCEINLINE BOOLEAN vfatFCBIsReadOnly(PVFATFCB FCB)
Definition: vfat.h:644
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:53
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:533
#define FILE_READ_DATA
Definition: nt_native.h:628
static NTSTATUS VfatSetRenameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_RENAME_INFORMATION RenameInfo, PFILE_OBJECT TargetFileObject)
Definition: finfo.c:560
#define FILE_ACTION_MODIFIED
PFILE_OBJECT FileObject
Definition: vfat.h:499
ULONG Flags
Definition: vfat.h:496
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
LONG RefCount
Definition: ntfs.h:531
struct _FCB FCB
static VOID VfatRenameChildFCB(PDEVICE_EXTENSION DeviceExt, PVFATFCB FCB)
Definition: finfo.c:527
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1436
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:575
#define FILE_ACTION_REMOVED
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
Definition: fat.c:703
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
#define FILE_WRITE_DATA
Definition: nt_native.h:631
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define FILE_NOTIFY_CHANGE_CREATION
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:513
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
int64_t LONGLONG
Definition: typedefs.h:68
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
struct _VFATFCB * parentFcb
Definition: vfat.h:490
__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
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
DWORD ClusterSize
Definition: format.c:67
#define ObDereferenceObject
Definition: obfuncs.h:203
static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize, BOOLEAN IsFatX)
Definition: finfo.c:1184
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:625
BOOLEAN FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
Definition: dir.c:22
static NTSTATUS VfatGetNetworkOpenInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
Definition: finfo.c:1041
#define _A_VOLID
Definition: dos.h:33
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1978
ULONG Flags
Definition: ntfs.h:532
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
FORCEINLINE BOOLEAN VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb)
Definition: vfat.h:367
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ASSERT(x)
static const WCHAR L[]
Definition: oid.c:1250
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_ACTION_RENAMED_NEW_NAME
static NTSTATUS VfatSetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo)
Definition: finfo.c:153
struct _LARGE_INTEGER::@2277 u
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
Definition: typedefs.h:119
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:30
ERESOURCE MainResource
Definition: ntfs.h:524
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
#define FAT16
Definition: fat.h:168
struct _VFATFCB * PVFATFCB
#define FILE_OPEN
Definition: from_kernel.h:54
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:319
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:658
NTSTATUS vfatRenameEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN BOOLEAN CaseChangeOnly)
Definition: dirwr.c:180
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FILE_NOTIFY_CHANGE_EA
FORCEINLINE NTSTATUS VfatDelEntry(PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:388
NTSTATUS VfatMoveEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN PVFATFCB ParentFcb)
Definition: dirwr.c:1124
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define NULL
Definition: types.h:112
#define FAT32
Definition: fat.h:169
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
static NTSTATUS vfatPrepareTargetForRename(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB *ParentFCB, IN PUNICODE_STRING NewName, IN BOOLEAN ReplaceIfExists, IN PUNICODE_STRING ParentName, OUT PBOOLEAN Deleted)
Definition: finfo.c:412
#define FILE_ACTION_ADDED
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3009
static NTSTATUS VfatGetAllInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_ALL_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1144
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
#define OUT
Definition: typedefs.h:40
UNICODE_STRING PathNameU
Definition: vfat.h:472
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
static NTSTATUS VfatGetNameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
Definition: finfo.c:972
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:117
unsigned int ULONG
Definition: retypes.h:1
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:302
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
ULONG Flags
Definition: vfat.h:586
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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PFCB Fcb
Definition: cdprocs.h:159
ULONG OpenHandleCount
Definition: vfat.h:511
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
LIST_ENTRY ParentListHead
Definition: vfat.h:493
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:7331
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:429
static NTSTATUS VfatGetPositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
Definition: finfo.c:125
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:55
static NTSTATUS VfatGetInternalInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
Definition: finfo.c:1017
base of all file and directory entries
Definition: entries.h:82
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID _Out_ PIO_STATUS_BLOCK _In_ ULONG NotifyFilter
Definition: zwfuncs.h:500
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend)
Definition: rw.c:61