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