ReactOS  0.4.15-dev-5455-g015cd25
finfo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: VFAT Filesystem
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: File information routines
5  * COPYRIGHT: Copyright 1998 Jason Filby <jasonfilby@yahoo.com>
6  * Copyright 2005 HervĂ© Poussineau <hpoussin@reactos.org>
7  * Copyright 2008-2018 Pierre Schweitzer <pierre@reactos.org>
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "vfat.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 #define NASSERTS_RENAME
18 
19 /* GLOBALS ******************************************************************/
20 
22 {
23  "??????",
24  "FileDirectoryInformation",
25  "FileFullDirectoryInformation",
26  "FileBothDirectoryInformation",
27  "FileBasicInformation",
28  "FileStandardInformation",
29  "FileInternalInformation",
30  "FileEaInformation",
31  "FileAccessInformation",
32  "FileNameInformation",
33  "FileRenameInformation",
34  "FileLinkInformation",
35  "FileNamesInformation",
36  "FileDispositionInformation",
37  "FilePositionInformation",
38  "FileFullEaInformation",
39  "FileModeInformation",
40  "FileAlignmentInformation",
41  "FileAllInformation",
42  "FileAllocationInformation",
43  "FileEndOfFileInformation",
44  "FileAlternateNameInformation",
45  "FileStreamInformation",
46  "FilePipeInformation",
47  "FilePipeLocalInformation",
48  "FilePipeRemoteInformation",
49  "FileMailslotQueryInformation",
50  "FileMailslotSetInformation",
51  "FileCompressionInformation",
52  "FileObjectIdInformation",
53  "FileCompletionInformation",
54  "FileMoveClusterInformation",
55  "FileQuotaInformation",
56  "FileReparsePointInformation",
57  "FileNetworkOpenInformation",
58  "FileAttributeTagInformation",
59  "FileTrackingInformation",
60  "FileIdBothDirectoryInformation",
61  "FileIdFullDirectoryInformation",
62  "FileValidDataLengthInformation",
63  "FileShortNameInformation",
64  "FileMaximumInformation"
65 };
66 
67 /* FUNCTIONS ****************************************************************/
68 
69 /*
70  * FUNCTION: Retrieve the standard file information
71  */
74  PVFATFCB FCB,
75  PFILE_STANDARD_INFORMATION StandardInfo,
77 {
80 
81  /* PRECONDITION */
82  ASSERT(StandardInfo != NULL);
83  ASSERT(FCB != NULL);
84 
86  {
87  StandardInfo->AllocationSize.QuadPart = 0;
88  StandardInfo->EndOfFile.QuadPart = 0;
89  StandardInfo->Directory = TRUE;
90  }
91  else
92  {
93  StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
94  StandardInfo->EndOfFile = FCB->RFCB.FileSize;
95  StandardInfo->Directory = FALSE;
96  }
97  StandardInfo->NumberOfLinks = 1;
99 
101  return STATUS_SUCCESS;
102 }
103 
104 static
105 NTSTATUS
108  PFILE_POSITION_INFORMATION PositionInfo)
109 {
110  DPRINT("FsdSetPositionInformation()\n");
111 
112  DPRINT("PositionInfo %p\n", PositionInfo);
113  DPRINT("Setting position %u\n", PositionInfo->CurrentByteOffset.u.LowPart);
114 
115  FileObject->CurrentByteOffset.QuadPart =
116  PositionInfo->CurrentByteOffset.QuadPart;
117 
118  return STATUS_SUCCESS;
119 }
120 
121 static
122 NTSTATUS
125  PVFATFCB FCB,
126  PDEVICE_EXTENSION DeviceExt,
127  PFILE_POSITION_INFORMATION PositionInfo,
129 {
132  UNREFERENCED_PARAMETER(DeviceExt);
133 
134  DPRINT("VfatGetPositionInformation()\n");
135 
137  return STATUS_BUFFER_OVERFLOW;
138 
139  PositionInfo->CurrentByteOffset.QuadPart =
140  FileObject->CurrentByteOffset.QuadPart;
141 
142  DPRINT("Getting position %I64x\n",
143  PositionInfo->CurrentByteOffset.QuadPart);
144 
146  return STATUS_SUCCESS;
147 }
148 
149 static
150 NTSTATUS
153  PVFATFCB FCB,
154  PDEVICE_EXTENSION DeviceExt,
155  PFILE_BASIC_INFORMATION BasicInfo)
156 {
158 
159  DPRINT("VfatSetBasicInformation()\n");
160 
161  ASSERT(NULL != FileObject);
162  ASSERT(NULL != FCB);
163  ASSERT(NULL != DeviceExt);
164  ASSERT(NULL != BasicInfo);
165  /* Check volume label bit */
166  ASSERT(0 == (*FCB->Attributes & _A_VOLID));
167 
168  NotifyFilter = 0;
169 
170  if (BasicInfo->FileAttributes != 0)
171  {
173 
179 
180  if (vfatFCBIsDirectory(FCB))
181  {
183  {
184  DPRINT("Setting temporary attribute on a directory!\n");
186  }
187 
189  }
190  else
191  {
193  {
194  DPRINT("Setting directory attribute on a file!\n");
196  }
197  }
198 
199  if (Attributes != *FCB->Attributes)
200  {
201  *FCB->Attributes = Attributes;
202  DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
204  }
205  }
206 
207  if (vfatVolumeIsFatX(DeviceExt))
208  {
209  if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
210  {
211  FsdSystemTimeToDosDateTime(DeviceExt,
212  &BasicInfo->CreationTime,
213  &FCB->entry.FatX.CreationDate,
214  &FCB->entry.FatX.CreationTime);
216  }
217 
218  if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
219  {
220  FsdSystemTimeToDosDateTime(DeviceExt,
221  &BasicInfo->LastAccessTime,
222  &FCB->entry.FatX.AccessDate,
223  &FCB->entry.FatX.AccessTime);
225  }
226 
227  if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
228  {
229  FsdSystemTimeToDosDateTime(DeviceExt,
230  &BasicInfo->LastWriteTime,
231  &FCB->entry.FatX.UpdateDate,
232  &FCB->entry.FatX.UpdateTime);
234  }
235  }
236  else
237  {
238  if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
239  {
240  FsdSystemTimeToDosDateTime(DeviceExt,
241  &BasicInfo->CreationTime,
242  &FCB->entry.Fat.CreationDate,
243  &FCB->entry.Fat.CreationTime);
245  }
246 
247  if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
248  {
249  FsdSystemTimeToDosDateTime(DeviceExt,
250  &BasicInfo->LastAccessTime,
251  &FCB->entry.Fat.AccessDate,
252  NULL);
254  }
255 
256  if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
257  {
258  FsdSystemTimeToDosDateTime(DeviceExt,
259  &BasicInfo->LastWriteTime,
260  &FCB->entry.Fat.UpdateDate,
261  &FCB->entry.Fat.UpdateTime);
263  }
264  }
265 
266  VfatUpdateEntry(DeviceExt, FCB);
267 
268  if (NotifyFilter != 0)
269  {
270  vfatReportChange(DeviceExt,
271  FCB,
272  NotifyFilter,
274  }
275 
276  return STATUS_SUCCESS;
277 }
278 
279 NTSTATUS
282  PVFATFCB FCB,
283  PDEVICE_EXTENSION DeviceExt,
284  PFILE_BASIC_INFORMATION BasicInfo,
286 {
288 
289  DPRINT("VfatGetBasicInformation()\n");
290 
291  if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
292  return STATUS_BUFFER_OVERFLOW;
293 
294  RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
295 
296  if (vfatVolumeIsFatX(DeviceExt))
297  {
298  FsdDosDateTimeToSystemTime(DeviceExt,
299  FCB->entry.FatX.CreationDate,
300  FCB->entry.FatX.CreationTime,
301  &BasicInfo->CreationTime);
302  FsdDosDateTimeToSystemTime(DeviceExt,
303  FCB->entry.FatX.AccessDate,
304  FCB->entry.FatX.AccessTime,
305  &BasicInfo->LastAccessTime);
306  FsdDosDateTimeToSystemTime(DeviceExt,
307  FCB->entry.FatX.UpdateDate,
308  FCB->entry.FatX.UpdateTime,
309  &BasicInfo->LastWriteTime);
310  BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
311  }
312  else
313  {
314  FsdDosDateTimeToSystemTime(DeviceExt,
315  FCB->entry.Fat.CreationDate,
316  FCB->entry.Fat.CreationTime,
317  &BasicInfo->CreationTime);
318  FsdDosDateTimeToSystemTime(DeviceExt,
319  FCB->entry.Fat.AccessDate,
320  0,
321  &BasicInfo->LastAccessTime);
322  FsdDosDateTimeToSystemTime(DeviceExt,
323  FCB->entry.Fat.UpdateDate,
324  FCB->entry.Fat.UpdateTime,
325  &BasicInfo->LastWriteTime);
326  BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
327  }
328 
329  BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
330  /* Synthesize FILE_ATTRIBUTE_NORMAL */
331  if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
336  {
337  DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
339  }
340  DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
341 
343  return STATUS_SUCCESS;
344 }
345 
346 
347 static
348 NTSTATUS
351  PVFATFCB FCB,
352  PDEVICE_EXTENSION DeviceExt,
353  PFILE_DISPOSITION_INFORMATION DispositionInfo)
354 {
355  DPRINT("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
356 
357  ASSERT(DeviceExt != NULL);
358  ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
359  ASSERT(FCB != NULL);
360 
361  if (!DispositionInfo->DeleteFile)
362  {
363  /* undelete the file */
365  FileObject->DeletePending = FALSE;
366  return STATUS_SUCCESS;
367  }
368 
370  {
371  /* stream already marked for deletion. just update the file object */
372  FileObject->DeletePending = TRUE;
373  return STATUS_SUCCESS;
374  }
375 
376  if (vfatFCBIsReadOnly(FCB))
377  {
378  return STATUS_CANNOT_DELETE;
379  }
380 
381  if (vfatFCBIsRoot(FCB) || IsDotOrDotDot(&FCB->LongNameU))
382  {
383  /* we cannot delete a '.', '..' or the root directory */
384  return STATUS_ACCESS_DENIED;
385  }
386 
387  if (!MmFlushImageSection (FileObject->SectionObjectPointer, MmFlushForDelete))
388  {
389  /* can't delete a file if its mapped into a process */
390 
391  DPRINT("MmFlushImageSection returned FALSE\n");
392  return STATUS_CANNOT_DELETE;
393  }
394 
395  if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(DeviceExt, FCB))
396  {
397  /* can't delete a non-empty directory */
398 
400  }
401 
402  /* all good */
404  FileObject->DeletePending = TRUE;
405 
406  return STATUS_SUCCESS;
407 }
408 
409 static NTSTATUS
411  IN PDEVICE_EXTENSION DeviceExt,
412  IN PVFATFCB * ParentFCB,
414  IN BOOLEAN ReplaceIfExists,
415  IN PUNICODE_STRING ParentName,
417 {
419  PVFATFCB TargetFcb;
420 
421  DPRINT("vfatPrepareTargetForRename(%p, %p, %wZ, %d, %wZ, %p)\n", DeviceExt, ParentFCB, NewName, ReplaceIfExists, ParentName);
422 
423  *Deleted = FALSE;
424  /* Try to open target */
425  Status = vfatGetFCBForFile(DeviceExt, ParentFCB, &TargetFcb, NewName);
426  /* If it exists */
427  if (NT_SUCCESS(Status))
428  {
429  DPRINT("Target file %wZ exists. FCB Flags %08x\n", NewName, TargetFcb->Flags);
430  /* Check whether we are allowed to replace */
431  if (ReplaceIfExists)
432  {
433  /* If that's a directory or a read-only file, we're not allowed */
434  if (vfatFCBIsDirectory(TargetFcb) || vfatFCBIsReadOnly(TargetFcb))
435  {
436  DPRINT("And this is a readonly file!\n");
437  vfatReleaseFCB(DeviceExt, *ParentFCB);
438  *ParentFCB = NULL;
439  vfatReleaseFCB(DeviceExt, TargetFcb);
441  }
442 
443 
444  /* If we still have a file object, close it. */
445  if (TargetFcb->FileObject)
446  {
447  if (!MmFlushImageSection(TargetFcb->FileObject->SectionObjectPointer, MmFlushForDelete))
448  {
449  DPRINT("MmFlushImageSection failed.\n");
450  vfatReleaseFCB(DeviceExt, *ParentFCB);
451  *ParentFCB = NULL;
452  vfatReleaseFCB(DeviceExt, TargetFcb);
453  return STATUS_ACCESS_DENIED;
454  }
455 
456  TargetFcb->FileObject->DeletePending = TRUE;
457  VfatCloseFile(DeviceExt, TargetFcb->FileObject);
458  }
459 
460  /* If we are here, ensure the file isn't open by anyone! */
461  if (TargetFcb->OpenHandleCount != 0)
462  {
463  DPRINT("There are still open handles for this file.\n");
464  vfatReleaseFCB(DeviceExt, *ParentFCB);
465  *ParentFCB = NULL;
466  vfatReleaseFCB(DeviceExt, TargetFcb);
467  return STATUS_ACCESS_DENIED;
468  }
469 
470  /* Effectively delete old file to allow renaming */
471  DPRINT("Effectively deleting the file.\n");
472  VfatDelEntry(DeviceExt, TargetFcb, NULL);
473  vfatReleaseFCB(DeviceExt, TargetFcb);
474  *Deleted = TRUE;
475  return STATUS_SUCCESS;
476  }
477  else
478  {
479  vfatReleaseFCB(DeviceExt, *ParentFCB);
480  *ParentFCB = NULL;
481  vfatReleaseFCB(DeviceExt, TargetFcb);
483  }
484  }
485  else if (*ParentFCB != NULL)
486  {
487  return STATUS_SUCCESS;
488  }
489 
490  /* Failure */
491  return Status;
492 }
493 
494 static
495 BOOLEAN
497 {
499  PVFATFCB VolFCB;
500 
501  for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
502  {
503  VolFCB = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
504  if (VolFCB->OpenHandleCount != 0)
505  {
506  ASSERT(VolFCB->parentFcb == FCB);
507  DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
508  return TRUE;
509  }
510 
511  if (vfatFCBIsDirectory(VolFCB) && !IsListEmpty(&VolFCB->ParentListHead))
512  {
513  if (IsThereAChildOpened(VolFCB))
514  {
515  return TRUE;
516  }
517  }
518  }
519 
520  return FALSE;
521 }
522 
523 static
524 VOID
526  PDEVICE_EXTENSION DeviceExt,
527  PVFATFCB FCB)
528 {
530  PVFATFCB Child;
531 
532  if (IsListEmpty(&FCB->ParentListHead))
533  return;
534 
535  for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
536  {
538 
539  Child = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
540  DPRINT("Found %wZ with still %lu references (parent: %lu)!\n", &Child->PathNameU, Child->RefCount, FCB->RefCount);
541 
542  Status = vfatSetFCBNewDirName(DeviceExt, Child, FCB);
543  if (!NT_SUCCESS(Status))
544  continue;
545 
547  {
548  VfatRenameChildFCB(DeviceExt, Child);
549  }
550  }
551 }
552 
553 /*
554  * FUNCTION: Set the file name information
555  */
556 static
557 NTSTATUS
560  PVFATFCB FCB,
561  PDEVICE_EXTENSION DeviceExt,
562  PFILE_RENAME_INFORMATION RenameInfo,
563  PFILE_OBJECT TargetFileObject)
564 {
565 #ifdef NASSERTS_RENAME
566 #pragma push_macro("ASSERT")
567 #undef ASSERT
568 #define ASSERT(x) ((VOID) 0)
569 #endif
572  UNICODE_STRING SourcePath;
573  UNICODE_STRING SourceFile;
574  UNICODE_STRING NewPath;
575  UNICODE_STRING NewFile;
576  PFILE_OBJECT RootFileObject;
577  PVFATFCB RootFCB;
578  UNICODE_STRING RenameInfoString;
579  PVFATFCB ParentFCB;
583  BOOLEAN DeletedTarget;
584  ULONG OldReferences, NewReferences;
585  PVFATFCB OldParent;
586 
587  DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceExt, RenameInfo, TargetFileObject);
588 
589  /* Disallow renaming root */
590  if (vfatFCBIsRoot(FCB))
591  {
593  }
594 
595  OldReferences = FCB->parentFcb->RefCount;
596 #ifdef NASSERTS_RENAME
597  UNREFERENCED_PARAMETER(OldReferences);
598 #endif
599 
600  /* If we are performing relative opening for rename, get FO for getting FCB and path name */
601  if (RenameInfo->RootDirectory != NULL)
602  {
603  /* We cannot tolerate relative opening with a full path */
604  if (RenameInfo->FileName[0] == L'\\')
605  {
607  }
608 
613  (PVOID *)&RootFileObject,
614  NULL);
615  if (!NT_SUCCESS(Status))
616  {
617  return Status;
618  }
619 
620  RootFCB = RootFileObject->FsContext;
621  }
622 
623  RtlInitEmptyUnicodeString(&NewName, NULL, 0);
624  ParentFCB = NULL;
625 
626  if (TargetFileObject == NULL)
627  {
628  /* If we don't have target file object, construct paths thanks to relative FCB, if any, and with
629  * information supplied by the user
630  */
631 
632  /* First, setup a string we'll work on */
633  RenameInfoString.Length = RenameInfo->FileNameLength;
634  RenameInfoString.MaximumLength = RenameInfo->FileNameLength;
635  RenameInfoString.Buffer = RenameInfo->FileName;
636 
637  /* Check whether we have FQN */
638  if (RenameInfoString.Length > 6 * sizeof(WCHAR))
639  {
640  if (RenameInfoString.Buffer[0] == L'\\' && RenameInfoString.Buffer[1] == L'?' &&
641  RenameInfoString.Buffer[2] == L'?' && RenameInfoString.Buffer[3] == L'\\' &&
642  RenameInfoString.Buffer[5] == L':' && (RenameInfoString.Buffer[4] >= L'A' &&
643  RenameInfoString.Buffer[4] <= L'Z'))
644  {
645  /* If so, open its target directory */
647  &RenameInfoString,
649  NULL, NULL);
650 
654  &IoStatusBlock,
655  NULL, 0,
657  FILE_OPEN,
659  NULL, 0,
661  NULL,
663  if (!NT_SUCCESS(Status))
664  {
665  goto Cleanup;
666  }
667 
668  /* Get its FO to get the FCB */
672  KernelMode,
673  (PVOID *)&TargetFileObject,
674  NULL);
675  if (!NT_SUCCESS(Status))
676  {
678  goto Cleanup;
679  }
680 
681  /* Are we working on the same volume? */
683  {
684  ObDereferenceObject(TargetFileObject);
686  TargetFileObject = NULL;
688  goto Cleanup;
689  }
690  }
691  }
692 
693  NewName.Length = 0;
694  NewName.MaximumLength = RenameInfo->FileNameLength;
695  if (RenameInfo->RootDirectory != NULL)
696  {
697  NewName.MaximumLength += sizeof(WCHAR) + RootFCB->PathNameU.Length;
698  }
699  else if (RenameInfo->FileName[0] != L'\\')
700  {
701  /* We don't have full path, and we don't have root directory:
702  * => we move inside the same directory
703  */
704  NewName.MaximumLength += sizeof(WCHAR) + FCB->DirNameU.Length;
705  }
706  else if (TargetFileObject != NULL)
707  {
708  /* We had a FQN:
709  * => we need to use its correct path
710  */
711  NewName.MaximumLength += sizeof(WCHAR) + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length;
712  }
713 
715  if (NewName.Buffer == NULL)
716  {
717  if (TargetFileObject != NULL)
718  {
719  ObDereferenceObject(TargetFileObject);
721  TargetFileObject = NULL;
722  }
724  goto Cleanup;
725  }
726 
727  if (RenameInfo->RootDirectory != NULL)
728  {
729  /* Here, copy first absolute and then append relative */
731  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
732  NewName.Length += sizeof(WCHAR);
733  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
734  }
735  else if (RenameInfo->FileName[0] != L'\\')
736  {
737  /* Here, copy first work directory and then append filename */
738  RtlCopyUnicodeString(&NewName, &FCB->DirNameU);
739  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
740  NewName.Length += sizeof(WCHAR);
741  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
742  }
743  else if (TargetFileObject != NULL)
744  {
745  /* Here, copy first path name and then append filename */
746  RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
747  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
748  NewName.Length += sizeof(WCHAR);
749  RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
750  }
751  else
752  {
753  /* Here we should have full path, so simply copy it */
754  RtlCopyUnicodeString(&NewName, &RenameInfoString);
755  }
756 
757  /* Do we have to cleanup some stuff? */
758  if (TargetFileObject != NULL)
759  {
760  ObDereferenceObject(TargetFileObject);
762  TargetFileObject = NULL;
763  }
764  }
765  else
766  {
767  /* At that point, we shouldn't care about whether we are relative opening
768  * Target FO FCB should already have full path
769  */
770 
771  /* Before constructing string, just make a sanity check (just to be sure!) */
773  {
775  goto Cleanup;
776  }
777 
778  NewName.Length = 0;
779  NewName.MaximumLength = TargetFileObject->FileName.Length + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length + sizeof(WCHAR);
781  if (NewName.Buffer == NULL)
782  {
784  goto Cleanup;
785  }
786 
787  RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
788  /* If \, it's already backslash terminated, don't add it */
789  if (!vfatFCBIsRoot(TargetFileObject->FsContext))
790  {
791  NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
792  NewName.Length += sizeof(WCHAR);
793  }
794  RtlAppendUnicodeStringToString(&NewName, &TargetFileObject->FileName);
795  }
796 
797  /* Explode our paths to get path & filename */
798  vfatSplitPathName(&FCB->PathNameU, &SourcePath, &SourceFile);
799  DPRINT("Old dir: %wZ, Old file: %wZ\n", &SourcePath, &SourceFile);
800  vfatSplitPathName(&NewName, &NewPath, &NewFile);
801  DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
802 
803  if (IsDotOrDotDot(&NewFile))
804  {
806  goto Cleanup;
807  }
808 
809  if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
810  {
812  {
814  ASSERT(OldReferences == FCB->parentFcb->RefCount);
815  goto Cleanup;
816  }
817  }
818 
819  /* Are we working in place? */
820  if (FsRtlAreNamesEqual(&SourcePath, &NewPath, TRUE, NULL))
821  {
822  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
823  {
825  ASSERT(OldReferences == FCB->parentFcb->RefCount);
826  goto Cleanup;
827  }
828 
829  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, TRUE, NULL))
830  {
831  vfatReportChange(DeviceExt,
832  FCB,
836  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, TRUE);
837  if (NT_SUCCESS(Status))
838  {
839  vfatReportChange(DeviceExt,
840  FCB,
844  }
845  }
846  else
847  {
848  /* Try to find target */
849  ParentFCB = FCB->parentFcb;
850  vfatGrabFCB(DeviceExt, ParentFCB);
852  &ParentFCB,
853  &NewFile,
854  RenameInfo->ReplaceIfExists,
855  &NewPath,
856  &DeletedTarget);
857  if (!NT_SUCCESS(Status))
858  {
859  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1);
860  ASSERT(OldReferences == ParentFCB->RefCount - 1);
861  goto Cleanup;
862  }
863 
864  vfatReportChange(DeviceExt,
865  FCB,
869  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, FALSE);
870  if (NT_SUCCESS(Status))
871  {
872  if (DeletedTarget)
873  {
874  vfatReportChange(DeviceExt,
875  FCB,
879  }
880  else
881  {
882  vfatReportChange(DeviceExt,
883  FCB,
887  }
888  }
889  }
890 
891  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1); // extra grab
892  ASSERT(OldReferences == ParentFCB->RefCount - 1); // extra grab
893  }
894  else
895  {
896 
897  /* Try to find target */
898  ParentFCB = NULL;
899  OldParent = FCB->parentFcb;
900 #ifdef NASSERTS_RENAME
901  UNREFERENCED_PARAMETER(OldParent);
902 #endif
904  &ParentFCB,
905  &NewName,
906  RenameInfo->ReplaceIfExists,
907  &NewPath,
908  &DeletedTarget);
909  if (!NT_SUCCESS(Status))
910  {
911  ASSERT(OldReferences == FCB->parentFcb->RefCount);
912  goto Cleanup;
913  }
914 
915  NewReferences = ParentFCB->RefCount;
916 #ifdef NASSERTS_RENAME
917  UNREFERENCED_PARAMETER(NewReferences);
918 #endif
919 
920  vfatReportChange(DeviceExt,
921  FCB,
925  Status = VfatMoveEntry(DeviceExt, FCB, &NewFile, ParentFCB);
926  if (NT_SUCCESS(Status))
927  {
928  if (DeletedTarget)
929  {
930  vfatReportChange(DeviceExt,
931  FCB,
935  }
936  else
937  {
938  vfatReportChange(DeviceExt,
939  FCB,
943  }
944  }
945  }
946 
948  {
949  VfatRenameChildFCB(DeviceExt, FCB);
950  }
951 
952  ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
953  ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
954 Cleanup:
955  if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB);
957  if (RenameInfo->RootDirectory != NULL) ObDereferenceObject(RootFileObject);
958 
959  return Status;
960 #ifdef NASSERTS_RENAME
961 #pragma pop_macro("ASSERT")
962 #endif
963 }
964 
965 /*
966  * FUNCTION: Retrieve the file name information
967  */
968 static
969 NTSTATUS
972  PVFATFCB FCB,
973  PDEVICE_EXTENSION DeviceExt,
974  PFILE_NAME_INFORMATION NameInfo,
976 {
978 
980  UNREFERENCED_PARAMETER(DeviceExt);
981 
982  ASSERT(NameInfo != NULL);
983  ASSERT(FCB != NULL);
984 
985  /* If buffer can't hold at least the file name length, bail out */
987  return STATUS_BUFFER_OVERFLOW;
988 
989  /* Save file name length, and as much file len, as buffer length allows */
990  NameInfo->FileNameLength = FCB->PathNameU.Length;
991 
992  /* Calculate amount of bytes to copy not to overflow the buffer */
993  BytesToCopy = min(FCB->PathNameU.Length,
995 
996  /* Fill in the bytes */
997  RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
998 
999  /* Check if we could write more but are not able to */
1001  {
1002  /* Return number of bytes written */
1004  return STATUS_BUFFER_OVERFLOW;
1005  }
1006 
1007  /* We filled up as many bytes, as needed */
1008  *BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
1009 
1010  return STATUS_SUCCESS;
1011 }
1012 
1013 static
1014 NTSTATUS
1016  PVFATFCB Fcb,
1017  PDEVICE_EXTENSION DeviceExt,
1018  PFILE_INTERNAL_INFORMATION InternalInfo,
1020 {
1021  ASSERT(InternalInfo);
1022  ASSERT(Fcb);
1023 
1024  if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
1025  return STATUS_BUFFER_OVERFLOW;
1026 
1027  InternalInfo->IndexNumber.QuadPart = (LONGLONG)vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry) * DeviceExt->FatInfo.BytesPerCluster;
1028 
1030  return STATUS_SUCCESS;
1031 }
1032 
1033 
1034 /*
1035  * FUNCTION: Retrieve the file network open information
1036  */
1037 static
1038 NTSTATUS
1040  PVFATFCB Fcb,
1041  PDEVICE_EXTENSION DeviceExt,
1042  PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
1044 {
1045  ASSERT(NetworkInfo);
1046  ASSERT(Fcb);
1047 
1049  return(STATUS_BUFFER_OVERFLOW);
1050 
1051  if (vfatVolumeIsFatX(DeviceExt))
1052  {
1053  FsdDosDateTimeToSystemTime(DeviceExt,
1054  Fcb->entry.FatX.CreationDate,
1055  Fcb->entry.FatX.CreationTime,
1056  &NetworkInfo->CreationTime);
1057  FsdDosDateTimeToSystemTime(DeviceExt,
1058  Fcb->entry.FatX.AccessDate,
1059  Fcb->entry.FatX.AccessTime,
1060  &NetworkInfo->LastAccessTime);
1061  FsdDosDateTimeToSystemTime(DeviceExt,
1062  Fcb->entry.FatX.UpdateDate,
1063  Fcb->entry.FatX.UpdateTime,
1064  &NetworkInfo->LastWriteTime);
1065  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1066  }
1067  else
1068  {
1069  FsdDosDateTimeToSystemTime(DeviceExt,
1070  Fcb->entry.Fat.CreationDate,
1071  Fcb->entry.Fat.CreationTime,
1072  &NetworkInfo->CreationTime);
1073  FsdDosDateTimeToSystemTime(DeviceExt,
1074  Fcb->entry.Fat.AccessDate,
1075  0,
1076  &NetworkInfo->LastAccessTime);
1077  FsdDosDateTimeToSystemTime(DeviceExt,
1078  Fcb->entry.Fat.UpdateDate,
1079  Fcb->entry.Fat.UpdateTime,
1080  &NetworkInfo->LastWriteTime);
1081  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1082  }
1083 
1084  if (vfatFCBIsDirectory(Fcb))
1085  {
1086  NetworkInfo->EndOfFile.QuadPart = 0L;
1087  NetworkInfo->AllocationSize.QuadPart = 0L;
1088  }
1089  else
1090  {
1091  NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
1092  NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
1093  }
1094 
1095  NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
1096  /* Synthesize FILE_ATTRIBUTE_NORMAL */
1097  if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
1102  {
1103  DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
1104  NetworkInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
1105  }
1106 
1108  return STATUS_SUCCESS;
1109 }
1110 
1111 
1112 static
1113 NTSTATUS
1116  PVFATFCB Fcb,
1117  PDEVICE_EXTENSION DeviceExt,
1120 {
1123 
1124  /* FIXME - use SEH to access the buffer! */
1125  Info->EaSize = 0;
1126  *BufferLength -= sizeof(*Info);
1127  if (DeviceExt->FatInfo.FatType == FAT12 ||
1128  DeviceExt->FatInfo.FatType == FAT16)
1129  {
1130  /* FIXME */
1131  DPRINT1("VFAT: FileEaInformation not implemented!\n");
1132  }
1133  return STATUS_SUCCESS;
1134 }
1135 
1136 
1137 /*
1138  * FUNCTION: Retrieve the all file information
1139  */
1140 static
1141 NTSTATUS
1144  PVFATFCB Fcb,
1145  PDEVICE_EXTENSION DeviceExt,
1148 {
1149  NTSTATUS Status;
1150 
1151  ASSERT(Info);
1152  ASSERT(Fcb);
1153 
1154  if (*BufferLength < FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName))
1155  return STATUS_BUFFER_OVERFLOW;
1156 
1158 
1159  /* Basic Information */
1160  Status = VfatGetBasicInformation(FileObject, Fcb, DeviceExt, &Info->BasicInformation, BufferLength);
1161  if (!NT_SUCCESS(Status)) return Status;
1162  /* Standard Information */
1163  Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
1164  if (!NT_SUCCESS(Status)) return Status;
1165  /* Internal Information */
1166  Status = VfatGetInternalInformation(Fcb, DeviceExt, &Info->InternalInformation, BufferLength);
1167  if (!NT_SUCCESS(Status)) return Status;
1168  /* EA Information */
1169  Status = VfatGetEaInformation(FileObject, Fcb, DeviceExt, &Info->EaInformation, BufferLength);
1170  if (!NT_SUCCESS(Status)) return Status;
1171  /* Position Information */
1172  Status = VfatGetPositionInformation(FileObject, Fcb, DeviceExt, &Info->PositionInformation, BufferLength);
1173  if (!NT_SUCCESS(Status)) return Status;
1174  /* Name Information */
1175  Status = VfatGetNameInformation(FileObject, Fcb, DeviceExt, &Info->NameInformation, BufferLength);
1176 
1177  return Status;
1178 }
1179 
1180 static
1181 VOID
1184  PVFATFCB Fcb,
1185  ULONG Size,
1187  BOOLEAN IsFatX)
1188 {
1189  if (Size > 0)
1190  {
1192  }
1193  else
1194  {
1196  }
1197  if (!vfatFCBIsDirectory(Fcb))
1198  {
1199  if (IsFatX)
1200  Fcb->entry.FatX.FileSize = Size;
1201  else
1202  Fcb->entry.Fat.FileSize = Size;
1203  }
1206 
1208 }
1209 
1210 NTSTATUS
1213  PVFATFCB Fcb,
1214  PDEVICE_EXTENSION DeviceExt,
1216 {
1217  ULONG OldSize;
1218  ULONG Cluster, FirstCluster;
1219  NTSTATUS Status;
1220 
1221  ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
1222  ULONG NewSize = AllocationSize->u.LowPart;
1223  ULONG NCluster;
1224  BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
1225 
1226  DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
1227  &Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
1228 
1229  if (IsFatX)
1230  OldSize = Fcb->entry.FatX.FileSize;
1231  else
1232  OldSize = Fcb->entry.Fat.FileSize;
1233 
1234  if (AllocationSize->u.HighPart > 0)
1235  {
1236  return STATUS_INVALID_PARAMETER;
1237  }
1238 
1239  if (OldSize == NewSize)
1240  {
1241  return STATUS_SUCCESS;
1242  }
1243 
1244  FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
1245 
1246  if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
1247  {
1248  AllocSizeChanged = TRUE;
1249  if (FirstCluster == 0)
1250  {
1251  Fcb->LastCluster = Fcb->LastOffset = 0;
1252  Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
1253  if (!NT_SUCCESS(Status))
1254  {
1255  DPRINT1("NextCluster failed. Status = %x\n", Status);
1256  return Status;
1257  }
1258 
1259  if (FirstCluster == 0xffffffff)
1260  {
1261  return STATUS_DISK_FULL;
1262  }
1263 
1264  Status = OffsetToCluster(DeviceExt, FirstCluster,
1266  &NCluster, TRUE);
1267  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1268  {
1269  /* disk is full */
1270  NCluster = Cluster = FirstCluster;
1272  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1273  {
1274  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1275  WriteCluster(DeviceExt, Cluster, 0);
1276  Cluster = NCluster;
1277  }
1278  return STATUS_DISK_FULL;
1279  }
1280 
1281  if (IsFatX)
1282  {
1283  Fcb->entry.FatX.FirstCluster = FirstCluster;
1284  }
1285  else
1286  {
1287  if (DeviceExt->FatInfo.FatType == FAT32)
1288  {
1289  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1290  Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;
1291  }
1292  else
1293  {
1294  ASSERT((FirstCluster >> 16) == 0);
1295  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1296  }
1297  }
1298  }
1299  else
1300  {
1301  if (Fcb->LastCluster > 0)
1302  {
1303  if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
1304  {
1305  Cluster = Fcb->LastCluster;
1307  }
1308  else
1309  {
1310  Status = OffsetToCluster(DeviceExt, Fcb->LastCluster,
1311  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,
1312  &Cluster, FALSE);
1313  }
1314  }
1315  else
1316  {
1317  Status = OffsetToCluster(DeviceExt, FirstCluster,
1318  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
1319  &Cluster, FALSE);
1320  }
1321 
1322  if (!NT_SUCCESS(Status))
1323  {
1324  return Status;
1325  }
1326 
1327  Fcb->LastCluster = Cluster;
1328  Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
1329 
1330  /* FIXME: Check status */
1331  /* Cluster points now to the last cluster within the chain */
1332  Status = OffsetToCluster(DeviceExt, Cluster,
1333  ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
1334  &NCluster, TRUE);
1335  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1336  {
1337  /* disk is full */
1338  NCluster = Cluster;
1339  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1340  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1341  Cluster = NCluster;
1342  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1343  {
1344  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1345  WriteCluster(DeviceExt, Cluster, 0);
1346  Cluster = NCluster;
1347  }
1348  return STATUS_DISK_FULL;
1349  }
1350  }
1352  }
1353  else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
1354  {
1355  DPRINT("Check for the ability to set file size\n");
1356  if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
1358  {
1359  DPRINT("Couldn't set file size!\n");
1360  return STATUS_USER_MAPPED_FILE;
1361  }
1362  DPRINT("Can set file size\n");
1363 
1364  AllocSizeChanged = TRUE;
1365  /* FIXME: Use the cached cluster/offset better way. */
1366  Fcb->LastCluster = Fcb->LastOffset = 0;
1368  if (NewSize > 0)
1369  {
1370  Status = OffsetToCluster(DeviceExt, FirstCluster,
1372  &Cluster, FALSE);
1373 
1374  NCluster = Cluster;
1375  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1376  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1377  Cluster = NCluster;
1378  }
1379  else
1380  {
1381  if (IsFatX)
1382  {
1383  Fcb->entry.FatX.FirstCluster = 0;
1384  }
1385  else
1386  {
1387  if (DeviceExt->FatInfo.FatType == FAT32)
1388  {
1389  Fcb->entry.Fat.FirstCluster = 0;
1390  Fcb->entry.Fat.FirstClusterHigh = 0;
1391  }
1392  else
1393  {
1394  Fcb->entry.Fat.FirstCluster = 0;
1395  }
1396  }
1397 
1398  NCluster = Cluster = FirstCluster;
1400  }
1401 
1402  while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
1403  {
1404  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1405  WriteCluster(DeviceExt, Cluster, 0);
1406  Cluster = NCluster;
1407  }
1408 
1409  if (DeviceExt->FatInfo.FatType == FAT32)
1410  {
1411  FAT32UpdateFreeClustersCount(DeviceExt);
1412  }
1413  }
1414  else
1415  {
1417  }
1418 
1419  /* Update the on-disk directory entry */
1420  Fcb->Flags |= FCB_IS_DIRTY;
1421  if (AllocSizeChanged)
1422  {
1423  VfatUpdateEntry(DeviceExt, Fcb);
1424 
1426  }
1427  return STATUS_SUCCESS;
1428 }
1429 
1430 /*
1431  * FUNCTION: Retrieve the specified file information
1432  */
1433 NTSTATUS
1435  PVFAT_IRP_CONTEXT IrpContext)
1436 {
1438  PVFATFCB FCB;
1439 
1441  PVOID SystemBuffer;
1443 
1444  /* PRECONDITION */
1445  ASSERT(IrpContext);
1446 
1447  /* INITIALIZATION */
1448  FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
1449  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1450 
1451  DPRINT("VfatQueryInformation is called for '%s'\n",
1453 
1454  if (FCB == NULL)
1455  {
1456  DPRINT1("IRP_MJ_QUERY_INFORMATION without FCB!\n");
1457  IrpContext->Irp->IoStatus.Information = 0;
1458  return STATUS_INVALID_PARAMETER;
1459  }
1460 
1461  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1462  BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
1463 
1465  {
1467  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1468  {
1469  return VfatMarkIrpContextForQueue(IrpContext);
1470  }
1471  }
1472 
1473  switch (FileInformationClass)
1474  {
1477  SystemBuffer,
1478  &BufferLength);
1479  break;
1480 
1483  FCB,
1484  IrpContext->DeviceExt,
1485  SystemBuffer,
1486  &BufferLength);
1487  break;
1488 
1489  case FileBasicInformation:
1491  FCB,
1492  IrpContext->DeviceExt,
1493  SystemBuffer,
1494  &BufferLength);
1495  break;
1496 
1497  case FileNameInformation:
1499  FCB,
1500  IrpContext->DeviceExt,
1501  SystemBuffer,
1502  &BufferLength);
1503  break;
1504 
1507  IrpContext->DeviceExt,
1508  SystemBuffer,
1509  &BufferLength);
1510  break;
1511 
1514  IrpContext->DeviceExt,
1515  SystemBuffer,
1516  &BufferLength);
1517  break;
1518 
1519  case FileAllInformation:
1520  Status = VfatGetAllInformation(IrpContext->FileObject,
1521  FCB,
1522  IrpContext->DeviceExt,
1523  SystemBuffer,
1524  &BufferLength);
1525  break;
1526 
1527  case FileEaInformation:
1528  Status = VfatGetEaInformation(IrpContext->FileObject,
1529  FCB,
1530  IrpContext->DeviceExt,
1531  SystemBuffer,
1532  &BufferLength);
1533  break;
1534 
1537  break;
1538 
1539  default:
1541  }
1542 
1544  {
1546  }
1547 
1549  IrpContext->Irp->IoStatus.Information =
1550  IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
1551  else
1552  IrpContext->Irp->IoStatus.Information = 0;
1553 
1554  return Status;
1555 }
1556 
1557 /*
1558  * FUNCTION: Retrieve the specified file information
1559  */
1560 NTSTATUS
1562  PVFAT_IRP_CONTEXT IrpContext)
1563 {
1565  PVFATFCB FCB;
1567  PVOID SystemBuffer;
1568  BOOLEAN LockDir;
1569 
1570  /* PRECONDITION */
1571  ASSERT(IrpContext);
1572 
1573  DPRINT("VfatSetInformation(IrpContext %p)\n", IrpContext);
1574 
1575  /* INITIALIZATION */
1577  IrpContext->Stack->Parameters.SetFile.FileInformationClass;
1578  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1579  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1580 
1581  DPRINT("VfatSetInformation is called for '%s'\n",
1583 
1584  DPRINT("FileInformationClass %d\n", FileInformationClass);
1585  DPRINT("SystemBuffer %p\n", SystemBuffer);
1586 
1587  if (FCB == NULL)
1588  {
1589  DPRINT1("IRP_MJ_SET_INFORMATION without FCB!\n");
1590  IrpContext->Irp->IoStatus.Information = 0;
1591  return STATUS_INVALID_PARAMETER;
1592  }
1593 
1594  /* Special: We should call MmCanFileBeTruncated here to determine if changing
1595  the file size would be allowed. If not, we bail with the right error.
1596  We must do this before acquiring the lock. */
1598  {
1599  DPRINT("Check for the ability to set file size\n");
1600  if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
1601  (PLARGE_INTEGER)SystemBuffer))
1602  {
1603  DPRINT("Couldn't set file size!\n");
1604  IrpContext->Irp->IoStatus.Information = 0;
1605  return STATUS_USER_MAPPED_FILE;
1606  }
1607  DPRINT("Can set file size\n");
1608  }
1609 
1610  LockDir = FALSE;
1613  {
1614  LockDir = TRUE;
1615  }
1616 
1617  if (LockDir)
1618  {
1620  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1621  {
1622  return VfatMarkIrpContextForQueue(IrpContext);
1623  }
1624  }
1625 
1627  {
1629  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1630  {
1631  if (LockDir)
1632  {
1634  }
1635 
1636  return VfatMarkIrpContextForQueue(IrpContext);
1637  }
1638  }
1639 
1640  switch (FileInformationClass)
1641  {
1644  SystemBuffer);
1645  break;
1646 
1649  FCB,
1650  IrpContext->DeviceExt,
1651  SystemBuffer);
1652  break;
1653 
1657  FCB,
1658  IrpContext->DeviceExt,
1659  (PLARGE_INTEGER)SystemBuffer);
1660  break;
1661 
1662  case FileBasicInformation:
1664  FCB,
1665  IrpContext->DeviceExt,
1666  SystemBuffer);
1667  break;
1668 
1669  case FileRenameInformation:
1671  FCB,
1672  IrpContext->DeviceExt,
1673  SystemBuffer,
1674  IrpContext->Stack->Parameters.SetFile.FileObject);
1675  break;
1676 
1677  default:
1679  }
1680 
1682  {
1684  }
1685 
1686  if (LockDir)
1687  {
1689  }
1690 
1691  IrpContext->Irp->IoStatus.Information = 0;
1692  return Status;
1693 }
1694 
1695 /* EOF */
struct _LARGE_INTEGER::@2253 u
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define FAT12
Definition: fat.h:167
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:4163
#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
#define TAG_NAME
Definition: vfat.h:553
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:52
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
Definition: fat.c:705
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:1215
#define FCB_IS_DIRTY
Definition: vfat.h:438
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:540
#define FILE_ACTION_RENAMED_OLD_NAME
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
static NTSTATUS VfatGetNameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
Definition: finfo.c:970
struct _Entry Entry
Definition: kefuncs.h:629
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1434
Definition: vfat.h:447
USHORT MaximumLength
Definition: env_spec_w32.h:370
static NTSTATUS VfatGetInternalInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
Definition: finfo.c:1015
#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:18
#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)
static VOID VfatRenameChildFCB(PDEVICE_EXTENSION DeviceExt, PVFATFCB FCB)
Definition: finfo.c:525
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:410
BOOLEAN IsDotOrDotDot(PCUNICODE_STRING Name)
Definition: string.c:28
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:883
#define FILE_NOTIFY_CHANGE_SIZE
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#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
NTSTATUS VfatGetStandardInformation(PVFATFCB FCB, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
Definition: finfo.c:73
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
PFILE_OBJECT FileObject
Definition: vfat.h:591
#define FILE_NOTIFY_CHANGE_DIR_NAME
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
#define FILE_SHARE_READ
Definition: compat.h:136
_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)
NTSTATUS VfatGetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:280
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
static NTSTATUS VfatGetAllInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_ALL_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1142
#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
#define L(x)
Definition: ntvdm.h:50
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:494
FORCEINLINE BOOLEAN vfatFCBIsReadOnly(PVFATFCB FCB)
Definition: vfat.h:644
#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
#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:535
struct _FCB FCB
#define FILE_ACTION_REMOVED
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
static NTSTATUS VfatSetDispositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:349
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955
NTSTATUS vfatSetFCBNewDirName(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
Definition: fcb.c:492
#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:517
static NTSTATUS VfatGetPositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
Definition: finfo.c:123
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static NTSTATUS VfatGetNetworkOpenInformation(PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
Definition: finfo.c:1039
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1211
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
static NTSTATUS VfatGetEaInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_EA_INFORMATION Info, PULONG BufferLength)
Definition: finfo.c:1114
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:4257
#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
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:625
#define _A_VOLID
Definition: dos.h:33
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
BOOLEAN FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
Definition: dir.c:21
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
ULONG Flags
Definition: ntfs.h:536
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
static NTSTATUS VfatSetRenameInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_RENAME_INFORMATION RenameInfo, PFILE_OBJECT TargetFileObject)
Definition: finfo.c:558
#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 FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_ACTION_RENAMED_NEW_NAME
_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
ERESOURCE MainResource
Definition: ntfs.h:528
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend)
Definition: rw.c:59
#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:33
static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo)
Definition: finfo.c:106
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:178
static BOOLEAN IsThereAChildOpened(PVFATFCB FCB)
Definition: finfo.c:496
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FILE_NOTIFY_CHANGE_EA
const char * FileInformationClassNames[]
Definition: finfo.c:21
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:1122
#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
static NTSTATUS VfatSetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo)
Definition: finfo.c:151
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define NULL
Definition: types.h:112
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:54
NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:159
#define FAT32
Definition: fat.h:169
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#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
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:38
_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
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:115
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1561
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ASSERT(x)
#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
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:474
#define STATUS_SUCCESS
Definition: shellext.h:65
static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize, BOOLEAN IsFatX)
Definition: finfo.c:1182
#define DPRINT
Definition: sndvol32.h:71
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
_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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
LIST_ENTRY ParentListHead
Definition: vfat.h:493
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:7352
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:429
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