ReactOS  0.4.13-dev-257-gfabbd7c
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  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) ||
382  (FCB->LongNameU.Length == sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.') ||
383  (FCB->LongNameU.Length == 2 * sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.' && FCB->LongNameU.Buffer[1] == L'.'))
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 (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
806  {
808  {
810  ASSERT(OldReferences == FCB->parentFcb->RefCount);
811  goto Cleanup;
812  }
813  }
814 
815  /* Are we working in place? */
816  if (FsRtlAreNamesEqual(&SourcePath, &NewPath, TRUE, NULL))
817  {
818  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
819  {
821  ASSERT(OldReferences == FCB->parentFcb->RefCount);
822  goto Cleanup;
823  }
824 
825  if (FsRtlAreNamesEqual(&SourceFile, &NewFile, TRUE, NULL))
826  {
827  vfatReportChange(DeviceExt,
828  FCB,
832  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, TRUE);
833  if (NT_SUCCESS(Status))
834  {
835  vfatReportChange(DeviceExt,
836  FCB,
840  }
841  }
842  else
843  {
844  /* Try to find target */
845  ParentFCB = FCB->parentFcb;
846  vfatGrabFCB(DeviceExt, ParentFCB);
848  &ParentFCB,
849  &NewFile,
850  RenameInfo->ReplaceIfExists,
851  &NewPath,
852  &DeletedTarget);
853  if (!NT_SUCCESS(Status))
854  {
855  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1);
856  ASSERT(OldReferences == ParentFCB->RefCount - 1);
857  goto Cleanup;
858  }
859 
860  vfatReportChange(DeviceExt,
861  FCB,
865  Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, FALSE);
866  if (NT_SUCCESS(Status))
867  {
868  if (DeletedTarget)
869  {
870  vfatReportChange(DeviceExt,
871  FCB,
875  }
876  else
877  {
878  vfatReportChange(DeviceExt,
879  FCB,
883  }
884  }
885  }
886 
887  ASSERT(OldReferences == FCB->parentFcb->RefCount - 1); // extra grab
888  ASSERT(OldReferences == ParentFCB->RefCount - 1); // extra grab
889  }
890  else
891  {
892 
893  /* Try to find target */
894  ParentFCB = NULL;
895  OldParent = FCB->parentFcb;
896 #ifdef NASSERTS_RENAME
897  UNREFERENCED_PARAMETER(OldParent);
898 #endif
900  &ParentFCB,
901  &NewName,
902  RenameInfo->ReplaceIfExists,
903  &NewPath,
904  &DeletedTarget);
905  if (!NT_SUCCESS(Status))
906  {
907  ASSERT(OldReferences == FCB->parentFcb->RefCount);
908  goto Cleanup;
909  }
910 
911  NewReferences = ParentFCB->RefCount;
912 #ifdef NASSERTS_RENAME
913  UNREFERENCED_PARAMETER(NewReferences);
914 #endif
915 
916  vfatReportChange(DeviceExt,
917  FCB,
921  Status = VfatMoveEntry(DeviceExt, FCB, &NewFile, ParentFCB);
922  if (NT_SUCCESS(Status))
923  {
924  if (DeletedTarget)
925  {
926  vfatReportChange(DeviceExt,
927  FCB,
931  }
932  else
933  {
934  vfatReportChange(DeviceExt,
935  FCB,
939  }
940  }
941  }
942 
944  {
945  VfatRenameChildFCB(DeviceExt, FCB);
946  }
947 
948  ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
949  ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
950 Cleanup:
951  if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB);
953  if (RenameInfo->RootDirectory != NULL) ObDereferenceObject(RootFileObject);
954 
955  return Status;
956 #ifdef NASSERTS_RENAME
957 #pragma pop_macro("ASSERT")
958 #endif
959 }
960 
961 /*
962  * FUNCTION: Retrieve the file name information
963  */
964 static
965 NTSTATUS
968  PVFATFCB FCB,
969  PDEVICE_EXTENSION DeviceExt,
970  PFILE_NAME_INFORMATION NameInfo,
972 {
974 
976  UNREFERENCED_PARAMETER(DeviceExt);
977 
978  ASSERT(NameInfo != NULL);
979  ASSERT(FCB != NULL);
980 
981  /* If buffer can't hold at least the file name length, bail out */
983  return STATUS_BUFFER_OVERFLOW;
984 
985  /* Save file name length, and as much file len, as buffer length allows */
986  NameInfo->FileNameLength = FCB->PathNameU.Length;
987 
988  /* Calculate amount of bytes to copy not to overflow the buffer */
989  BytesToCopy = min(FCB->PathNameU.Length,
991 
992  /* Fill in the bytes */
993  RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
994 
995  /* Check if we could write more but are not able to */
996  if (*BufferLength < FCB->PathNameU.Length + (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
997  {
998  /* Return number of bytes written */
1000  return STATUS_BUFFER_OVERFLOW;
1001  }
1002 
1003  /* We filled up as many bytes, as needed */
1004  *BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
1005 
1006  return STATUS_SUCCESS;
1007 }
1008 
1009 static
1010 NTSTATUS
1012  PVFATFCB Fcb,
1013  PDEVICE_EXTENSION DeviceExt,
1014  PFILE_INTERNAL_INFORMATION InternalInfo,
1016 {
1017  ASSERT(InternalInfo);
1018  ASSERT(Fcb);
1019 
1020  if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
1021  return STATUS_BUFFER_OVERFLOW;
1022 
1023  InternalInfo->IndexNumber.QuadPart = (LONGLONG)vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry) * DeviceExt->FatInfo.BytesPerCluster;
1024 
1026  return STATUS_SUCCESS;
1027 }
1028 
1029 
1030 /*
1031  * FUNCTION: Retrieve the file network open information
1032  */
1033 static
1034 NTSTATUS
1036  PVFATFCB Fcb,
1037  PDEVICE_EXTENSION DeviceExt,
1038  PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
1040 {
1041  ASSERT(NetworkInfo);
1042  ASSERT(Fcb);
1043 
1045  return(STATUS_BUFFER_OVERFLOW);
1046 
1047  if (vfatVolumeIsFatX(DeviceExt))
1048  {
1049  FsdDosDateTimeToSystemTime(DeviceExt,
1050  Fcb->entry.FatX.CreationDate,
1051  Fcb->entry.FatX.CreationTime,
1052  &NetworkInfo->CreationTime);
1053  FsdDosDateTimeToSystemTime(DeviceExt,
1054  Fcb->entry.FatX.AccessDate,
1055  Fcb->entry.FatX.AccessTime,
1056  &NetworkInfo->LastAccessTime);
1057  FsdDosDateTimeToSystemTime(DeviceExt,
1058  Fcb->entry.FatX.UpdateDate,
1059  Fcb->entry.FatX.UpdateTime,
1060  &NetworkInfo->LastWriteTime);
1061  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1062  }
1063  else
1064  {
1065  FsdDosDateTimeToSystemTime(DeviceExt,
1066  Fcb->entry.Fat.CreationDate,
1067  Fcb->entry.Fat.CreationTime,
1068  &NetworkInfo->CreationTime);
1069  FsdDosDateTimeToSystemTime(DeviceExt,
1070  Fcb->entry.Fat.AccessDate,
1071  0,
1072  &NetworkInfo->LastAccessTime);
1073  FsdDosDateTimeToSystemTime(DeviceExt,
1074  Fcb->entry.Fat.UpdateDate,
1075  Fcb->entry.Fat.UpdateTime,
1076  &NetworkInfo->LastWriteTime);
1077  NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
1078  }
1079 
1080  if (vfatFCBIsDirectory(Fcb))
1081  {
1082  NetworkInfo->EndOfFile.QuadPart = 0L;
1083  NetworkInfo->AllocationSize.QuadPart = 0L;
1084  }
1085  else
1086  {
1087  NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
1088  NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
1089  }
1090 
1091  NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
1092  /* Synthesize FILE_ATTRIBUTE_NORMAL */
1093  if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
1098  {
1099  DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
1100  NetworkInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
1101  }
1102 
1104  return STATUS_SUCCESS;
1105 }
1106 
1107 
1108 static
1109 NTSTATUS
1112  PVFATFCB Fcb,
1113  PDEVICE_EXTENSION DeviceExt,
1116 {
1119 
1120  /* FIXME - use SEH to access the buffer! */
1121  Info->EaSize = 0;
1122  *BufferLength -= sizeof(*Info);
1123  if (DeviceExt->FatInfo.FatType == FAT12 ||
1124  DeviceExt->FatInfo.FatType == FAT16)
1125  {
1126  /* FIXME */
1127  DPRINT1("VFAT: FileEaInformation not implemented!\n");
1128  }
1129  return STATUS_SUCCESS;
1130 }
1131 
1132 
1133 /*
1134  * FUNCTION: Retrieve the all file information
1135  */
1136 static
1137 NTSTATUS
1140  PVFATFCB Fcb,
1141  PDEVICE_EXTENSION DeviceExt,
1144 {
1145  NTSTATUS Status;
1146 
1147  ASSERT(Info);
1148  ASSERT(Fcb);
1149 
1150  if (*BufferLength < FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName))
1151  return STATUS_BUFFER_OVERFLOW;
1152 
1154 
1155  /* Basic Information */
1156  Status = VfatGetBasicInformation(FileObject, Fcb, DeviceExt, &Info->BasicInformation, BufferLength);
1157  if (!NT_SUCCESS(Status)) return Status;
1158  /* Standard Information */
1159  Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
1160  if (!NT_SUCCESS(Status)) return Status;
1161  /* Internal Information */
1162  Status = VfatGetInternalInformation(Fcb, DeviceExt, &Info->InternalInformation, BufferLength);
1163  if (!NT_SUCCESS(Status)) return Status;
1164  /* EA Information */
1165  Status = VfatGetEaInformation(FileObject, Fcb, DeviceExt, &Info->EaInformation, BufferLength);
1166  if (!NT_SUCCESS(Status)) return Status;
1167  /* Position Information */
1168  Status = VfatGetPositionInformation(FileObject, Fcb, DeviceExt, &Info->PositionInformation, BufferLength);
1169  if (!NT_SUCCESS(Status)) return Status;
1170  /* Name Information */
1171  Status = VfatGetNameInformation(FileObject, Fcb, DeviceExt, &Info->NameInformation, BufferLength);
1172 
1173  return Status;
1174 }
1175 
1176 static
1177 VOID
1180  PVFATFCB Fcb,
1181  ULONG Size,
1183  BOOLEAN IsFatX)
1184 {
1185  if (Size > 0)
1186  {
1188  }
1189  else
1190  {
1192  }
1193  if (!vfatFCBIsDirectory(Fcb))
1194  {
1195  if (IsFatX)
1196  Fcb->entry.FatX.FileSize = Size;
1197  else
1198  Fcb->entry.Fat.FileSize = Size;
1199  }
1202 
1204 }
1205 
1206 NTSTATUS
1209  PVFATFCB Fcb,
1210  PDEVICE_EXTENSION DeviceExt,
1212 {
1213  ULONG OldSize;
1214  ULONG Cluster, FirstCluster;
1215  NTSTATUS Status;
1216 
1217  ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
1218  ULONG NewSize = AllocationSize->u.LowPart;
1219  ULONG NCluster;
1220  BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
1221 
1222  DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
1223  &Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
1224 
1225  if (IsFatX)
1226  OldSize = Fcb->entry.FatX.FileSize;
1227  else
1228  OldSize = Fcb->entry.Fat.FileSize;
1229 
1230  if (AllocationSize->u.HighPart > 0)
1231  {
1232  return STATUS_INVALID_PARAMETER;
1233  }
1234 
1235  if (OldSize == NewSize)
1236  {
1237  return STATUS_SUCCESS;
1238  }
1239 
1240  FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
1241 
1242  if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
1243  {
1244  AllocSizeChanged = TRUE;
1245  if (FirstCluster == 0)
1246  {
1247  Fcb->LastCluster = Fcb->LastOffset = 0;
1248  Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
1249  if (!NT_SUCCESS(Status))
1250  {
1251  DPRINT1("NextCluster failed. Status = %x\n", Status);
1252  return Status;
1253  }
1254 
1255  if (FirstCluster == 0xffffffff)
1256  {
1257  return STATUS_DISK_FULL;
1258  }
1259 
1260  Status = OffsetToCluster(DeviceExt, FirstCluster,
1262  &NCluster, TRUE);
1263  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1264  {
1265  /* disk is full */
1266  NCluster = Cluster = FirstCluster;
1268  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1269  {
1270  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1271  WriteCluster(DeviceExt, Cluster, 0);
1272  Cluster = NCluster;
1273  }
1274  return STATUS_DISK_FULL;
1275  }
1276 
1277  if (IsFatX)
1278  {
1279  Fcb->entry.FatX.FirstCluster = FirstCluster;
1280  }
1281  else
1282  {
1283  if (DeviceExt->FatInfo.FatType == FAT32)
1284  {
1285  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1286  Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;
1287  }
1288  else
1289  {
1290  ASSERT((FirstCluster >> 16) == 0);
1291  Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
1292  }
1293  }
1294  }
1295  else
1296  {
1297  if (Fcb->LastCluster > 0)
1298  {
1299  if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
1300  {
1301  Cluster = Fcb->LastCluster;
1303  }
1304  else
1305  {
1306  Status = OffsetToCluster(DeviceExt, Fcb->LastCluster,
1307  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,
1308  &Cluster, FALSE);
1309  }
1310  }
1311  else
1312  {
1313  Status = OffsetToCluster(DeviceExt, FirstCluster,
1314  Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
1315  &Cluster, FALSE);
1316  }
1317 
1318  if (!NT_SUCCESS(Status))
1319  {
1320  return Status;
1321  }
1322 
1323  Fcb->LastCluster = Cluster;
1324  Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
1325 
1326  /* FIXME: Check status */
1327  /* Cluster points now to the last cluster within the chain */
1328  Status = OffsetToCluster(DeviceExt, Cluster,
1329  ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
1330  &NCluster, TRUE);
1331  if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
1332  {
1333  /* disk is full */
1334  NCluster = Cluster;
1335  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1336  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1337  Cluster = NCluster;
1338  while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
1339  {
1340  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1341  WriteCluster(DeviceExt, Cluster, 0);
1342  Cluster = NCluster;
1343  }
1344  return STATUS_DISK_FULL;
1345  }
1346  }
1348  }
1349  else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
1350  {
1351  DPRINT("Check for the ability to set file size\n");
1352  if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
1354  {
1355  DPRINT("Couldn't set file size!\n");
1356  return STATUS_USER_MAPPED_FILE;
1357  }
1358  DPRINT("Can set file size\n");
1359 
1360  AllocSizeChanged = TRUE;
1361  /* FIXME: Use the cached cluster/offset better way. */
1362  Fcb->LastCluster = Fcb->LastOffset = 0;
1364  if (NewSize > 0)
1365  {
1366  Status = OffsetToCluster(DeviceExt, FirstCluster,
1368  &Cluster, FALSE);
1369 
1370  NCluster = Cluster;
1371  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1372  WriteCluster(DeviceExt, Cluster, 0xffffffff);
1373  Cluster = NCluster;
1374  }
1375  else
1376  {
1377  if (IsFatX)
1378  {
1379  Fcb->entry.FatX.FirstCluster = 0;
1380  }
1381  else
1382  {
1383  if (DeviceExt->FatInfo.FatType == FAT32)
1384  {
1385  Fcb->entry.Fat.FirstCluster = 0;
1386  Fcb->entry.Fat.FirstClusterHigh = 0;
1387  }
1388  else
1389  {
1390  Fcb->entry.Fat.FirstCluster = 0;
1391  }
1392  }
1393 
1394  NCluster = Cluster = FirstCluster;
1396  }
1397 
1398  while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
1399  {
1400  Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
1401  WriteCluster(DeviceExt, Cluster, 0);
1402  Cluster = NCluster;
1403  }
1404 
1405  if (DeviceExt->FatInfo.FatType == FAT32)
1406  {
1407  FAT32UpdateFreeClustersCount(DeviceExt);
1408  }
1409  }
1410  else
1411  {
1413  }
1414 
1415  /* Update the on-disk directory entry */
1416  Fcb->Flags |= FCB_IS_DIRTY;
1417  if (AllocSizeChanged)
1418  {
1419  VfatUpdateEntry(DeviceExt, Fcb);
1420 
1422  }
1423  return STATUS_SUCCESS;
1424 }
1425 
1426 /*
1427  * FUNCTION: Retrieve the specified file information
1428  */
1429 NTSTATUS
1431  PVFAT_IRP_CONTEXT IrpContext)
1432 {
1434  PVFATFCB FCB;
1435 
1437  PVOID SystemBuffer;
1439 
1440  /* PRECONDITION */
1441  ASSERT(IrpContext);
1442 
1443  /* INITIALIZATION */
1444  FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
1445  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1446 
1447  DPRINT("VfatQueryInformation is called for '%s'\n",
1449 
1450  if (FCB == NULL)
1451  {
1452  DPRINT1("IRP_MJ_QUERY_INFORMATION without FCB!\n");
1453  IrpContext->Irp->IoStatus.Information = 0;
1454  return STATUS_INVALID_PARAMETER;
1455  }
1456 
1457  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1458  BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
1459 
1461  {
1463  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1464  {
1465  return VfatMarkIrpContextForQueue(IrpContext);
1466  }
1467  }
1468 
1469  switch (FileInformationClass)
1470  {
1473  SystemBuffer,
1474  &BufferLength);
1475  break;
1476 
1479  FCB,
1480  IrpContext->DeviceExt,
1481  SystemBuffer,
1482  &BufferLength);
1483  break;
1484 
1485  case FileBasicInformation:
1487  FCB,
1488  IrpContext->DeviceExt,
1489  SystemBuffer,
1490  &BufferLength);
1491  break;
1492 
1493  case FileNameInformation:
1495  FCB,
1496  IrpContext->DeviceExt,
1497  SystemBuffer,
1498  &BufferLength);
1499  break;
1500 
1503  IrpContext->DeviceExt,
1504  SystemBuffer,
1505  &BufferLength);
1506  break;
1507 
1510  IrpContext->DeviceExt,
1511  SystemBuffer,
1512  &BufferLength);
1513  break;
1514 
1515  case FileAllInformation:
1516  Status = VfatGetAllInformation(IrpContext->FileObject,
1517  FCB,
1518  IrpContext->DeviceExt,
1519  SystemBuffer,
1520  &BufferLength);
1521  break;
1522 
1523  case FileEaInformation:
1524  Status = VfatGetEaInformation(IrpContext->FileObject,
1525  FCB,
1526  IrpContext->DeviceExt,
1527  SystemBuffer,
1528  &BufferLength);
1529  break;
1530 
1533  break;
1534 
1535  default:
1537  }
1538 
1540  {
1542  }
1543 
1545  IrpContext->Irp->IoStatus.Information =
1546  IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
1547  else
1548  IrpContext->Irp->IoStatus.Information = 0;
1549 
1550  return Status;
1551 }
1552 
1553 /*
1554  * FUNCTION: Retrieve the specified file information
1555  */
1556 NTSTATUS
1558  PVFAT_IRP_CONTEXT IrpContext)
1559 {
1561  PVFATFCB FCB;
1563  PVOID SystemBuffer;
1564  BOOLEAN LockDir;
1565 
1566  /* PRECONDITION */
1567  ASSERT(IrpContext);
1568 
1569  DPRINT("VfatSetInformation(IrpContext %p)\n", IrpContext);
1570 
1571  /* INITIALIZATION */
1573  IrpContext->Stack->Parameters.SetFile.FileInformationClass;
1574  FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
1575  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
1576 
1577  DPRINT("VfatSetInformation is called for '%s'\n",
1579 
1580  DPRINT("FileInformationClass %d\n", FileInformationClass);
1581  DPRINT("SystemBuffer %p\n", SystemBuffer);
1582 
1583  if (FCB == NULL)
1584  {
1585  DPRINT1("IRP_MJ_SET_INFORMATION without FCB!\n");
1586  IrpContext->Irp->IoStatus.Information = 0;
1587  return STATUS_INVALID_PARAMETER;
1588  }
1589 
1590  /* Special: We should call MmCanFileBeTruncated here to determine if changing
1591  the file size would be allowed. If not, we bail with the right error.
1592  We must do this before acquiring the lock. */
1594  {
1595  DPRINT("Check for the ability to set file size\n");
1596  if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
1597  (PLARGE_INTEGER)SystemBuffer))
1598  {
1599  DPRINT("Couldn't set file size!\n");
1600  IrpContext->Irp->IoStatus.Information = 0;
1601  return STATUS_USER_MAPPED_FILE;
1602  }
1603  DPRINT("Can set file size\n");
1604  }
1605 
1606  LockDir = FALSE;
1609  {
1610  LockDir = TRUE;
1611  }
1612 
1613  if (LockDir)
1614  {
1616  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1617  {
1618  return VfatMarkIrpContextForQueue(IrpContext);
1619  }
1620  }
1621 
1623  {
1625  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1626  {
1627  if (LockDir)
1628  {
1630  }
1631 
1632  return VfatMarkIrpContextForQueue(IrpContext);
1633  }
1634  }
1635 
1636  switch (FileInformationClass)
1637  {
1640  SystemBuffer);
1641  break;
1642 
1645  FCB,
1646  IrpContext->DeviceExt,
1647  SystemBuffer);
1648  break;
1649 
1653  FCB,
1654  IrpContext->DeviceExt,
1655  (PLARGE_INTEGER)SystemBuffer);
1656  break;
1657 
1658  case FileBasicInformation:
1660  FCB,
1661  IrpContext->DeviceExt,
1662  SystemBuffer);
1663  break;
1664 
1665  case FileRenameInformation:
1667  FCB,
1668  IrpContext->DeviceExt,
1669  SystemBuffer,
1670  IrpContext->Stack->Parameters.SetFile.FileObject);
1671  break;
1672 
1673  default:
1675  }
1676 
1678  {
1680  }
1681 
1682  if (LockDir)
1683  {
1685  }
1686 
1687  IrpContext->Irp->IoStatus.Information = 0;
1688  return Status;
1689 }
1690 
1691 /* 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:1207
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LONGLONG CreationTime
Definition: cdstruc.h:1036
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:38
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:40
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define TAG_NAME
Definition: vfat.h:547
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:432
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:507
#define FILE_ACTION_RENAMED_OLD_NAME
const char * FileInformationClassNames[]
Definition: finfo.c:23
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:434
struct _Entry Entry
Definition: kefuncs.h:640
Definition: vfat.h:441
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:579
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:19
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
#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:631
NTSTATUS VfatGetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:282
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:294
#define FILE_NOTIFY_CHANGE_SIZE
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2982
#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:1110
#define FILE_NOTIFY_CHANGE_FILE_NAME
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1538
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
PFILE_OBJECT FileObject
Definition: vfat.h:585
#define FILE_NOTIFY_CHANGE_DIR_NAME
NTSTATUS vfatSetFCBNewDirName(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
Definition: fcb.c:491
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
struct TraceInfo Info
#define FILE_SHARE_READ
Definition: compat.h:125
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:475
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:93
static NTSTATUS VfatSetDispositionInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_EXTENSION DeviceExt, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:349
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1557
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:638
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:53
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#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:493
ULONG Flags
Definition: vfat.h:490
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
LONG RefCount
Definition: ntfs.h:519
struct _FCB FCB
static VOID VfatRenameChildFCB(PDEVICE_EXTENSION DeviceExt, PVFATFCB FCB)
Definition: finfo.c:527
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1430
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:569
#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:697
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#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
#define FILE_NOTIFY_CHANGE_CREATION
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:501
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:645
int64_t LONGLONG
Definition: typedefs.h:66
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:484
__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:430
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
DWORD ClusterSize
Definition: format.c:67
static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize, BOOLEAN IsFatX)
Definition: finfo.c:1178
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
FORCEINLINE NTSTATUS VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
Definition: vfat.h:619
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:1035
#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:1954
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ULONG Flags
Definition: ntfs.h:520
#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:66
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:361
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#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
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
Definition: typedefs.h:117
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
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:512
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
#define FAT16
Definition: fat.h:168
struct _VFATFCB * PVFATFCB
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
FORCEINLINE VOID vfatReportChange(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB Fcb, IN ULONG FilterMatch, IN ULONG Action)
Definition: vfat.h:652
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:61
#define FILE_NOTIFY_CHANGE_EA
FORCEINLINE NTSTATUS VfatDelEntry(PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:382
NTSTATUS VfatMoveEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN PVFATFCB ParentFcb)
Definition: dirwr.c:1126
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
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:254
#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:578
#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:1138
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
struct _LARGE_INTEGER::@2192 u
#define OUT
Definition: typedefs.h:39
UNICODE_STRING PathNameU
Definition: vfat.h:466
#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:966
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:117
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:302
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE Child
Definition: acpixf.h:716
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG Flags
Definition: vfat.h:580
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:884
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
_In_ PFCB Fcb
Definition: cdprocs.h:151
ULONG OpenHandleCount
Definition: vfat.h:505
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
PIO_STACK_LOCATION Stack
Definition: vfat.h:582
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
LIST_ENTRY ParentListHead
Definition: vfat.h:487
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:6995
_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:1011
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:112
#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