ReactOS  0.4.15-dev-5499-g1341c38
fcb.c
Go to the documentation of this file.
1 /*
2  * PROJECT: VFAT Filesystem
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Routines to manipulate FCBs
5  * COPYRIGHT: Copyright 1998 Jason Filby <jasonfilby@yahoo.com>
6  * Copyright 2001 Rex Jolliff <rex@lvcablemodem.com>
7  * Copyright 2005-2022 HervĂ© Poussineau <hpoussin@reactos.org>
8  * Copyright 2008-2018 Pierre Schweitzer <pierre@reactos.org>
9  */
10 
11 /* ------------------------------------------------------- INCLUDES */
12 
13 #include "vfat.h"
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 #ifdef __GNUC__
19 #include <wctype.h> /* towlower prototype */
20 #endif
21 
22 /* -------------------------------------------------------- DEFINES */
23 
24 #ifdef KDBG
25 extern UNICODE_STRING DebugFile;
26 #endif
27 
28 /* -------------------------------------------------------- PUBLICS */
29 
30 static
31 ULONG
33  ULONG hash,
34  PUNICODE_STRING NameU)
35 {
36  PWCHAR last;
37  PWCHAR curr;
38  register WCHAR c;
39 
40  // LFN could start from "."
41  //ASSERT(NameU->Buffer[0] != L'.');
42  curr = NameU->Buffer;
43  last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
44 
45  while(curr < last)
46  {
47  c = towlower(*curr++);
48  hash = (hash + (c << 4) + (c >> 4)) * 11;
49  }
50  return hash;
51 }
52 
53 VOID
55  PUNICODE_STRING PathNameU,
56  PUNICODE_STRING DirNameU,
57  PUNICODE_STRING FileNameU)
58 {
59  PWCHAR pName;
60  USHORT Length = 0;
61  pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
62  while (*pName != L'\\' && pName >= PathNameU->Buffer)
63  {
64  pName--;
65  Length++;
66  }
67  ASSERT(*pName == L'\\' || pName < PathNameU->Buffer);
68  if (FileNameU)
69  {
70  FileNameU->Buffer = pName + 1;
71  FileNameU->Length = FileNameU->MaximumLength = Length * sizeof(WCHAR);
72  }
73  if (DirNameU)
74  {
75  DirNameU->Buffer = PathNameU->Buffer;
76  DirNameU->Length = (pName + 1 - PathNameU->Buffer) * sizeof(WCHAR);
77  DirNameU->MaximumLength = DirNameU->Length;
78  }
79 }
80 
81 static
82 VOID
84  PVFATFCB Fcb,
85  PUNICODE_STRING NameU)
86 {
87  USHORT PathNameBufferLength;
88 
89  if (NameU)
90  PathNameBufferLength = NameU->Length + sizeof(WCHAR);
91  else
92  PathNameBufferLength = 0;
93 
94  Fcb->PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength, TAG_FCB);
95  if (!Fcb->PathNameBuffer)
96  {
97  /* FIXME: what to do if no more memory? */
98  DPRINT1("Unable to initialize FCB for filename '%wZ'\n", NameU);
99  KeBugCheckEx(FAT_FILE_SYSTEM, (ULONG_PTR)Fcb, (ULONG_PTR)NameU, 0, 0);
100  }
101 
103  Fcb->RFCB.NodeByteSize = sizeof(VFATFCB);
104 
105  Fcb->PathNameU.Length = 0;
106  Fcb->PathNameU.Buffer = Fcb->PathNameBuffer;
107  Fcb->PathNameU.MaximumLength = PathNameBufferLength;
108  Fcb->ShortNameU.Length = 0;
109  Fcb->ShortNameU.Buffer = Fcb->ShortNameBuffer;
110  Fcb->ShortNameU.MaximumLength = sizeof(Fcb->ShortNameBuffer);
111  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
112  if (NameU && NameU->Length)
113  {
114  RtlCopyUnicodeString(&Fcb->PathNameU, NameU);
115  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
116  }
117  else
118  {
119  Fcb->DirNameU.Buffer = Fcb->LongNameU.Buffer = NULL;
120  Fcb->DirNameU.MaximumLength = Fcb->DirNameU.Length = 0;
121  Fcb->LongNameU.MaximumLength = Fcb->LongNameU.Length = 0;
122  }
123  RtlZeroMemory(&Fcb->FCBShareAccess, sizeof(SHARE_ACCESS));
124  Fcb->OpenHandleCount = 0;
125 }
126 
127 PVFATFCB
129  PDEVICE_EXTENSION pVCB,
130  PUNICODE_STRING pFileNameU)
131 {
132  PVFATFCB rcFCB;
133 
134  DPRINT("'%wZ'\n", pFileNameU);
135 
136  rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
137  if (rcFCB == NULL)
138  {
139  return NULL;
140  }
141  RtlZeroMemory(rcFCB, sizeof(VFATFCB));
142  vfatInitFcb(rcFCB, pFileNameU);
143  if (vfatVolumeIsFatX(pVCB))
144  rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
145  else
146  rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
147  rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
148  rcFCB->Hash.self = rcFCB;
149  rcFCB->ShortHash.self = rcFCB;
154  rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
155  rcFCB->RFCB.Resource = &rcFCB->MainResource;
158 
159  return rcFCB;
160 }
161 
162 static
163 VOID
165  PDEVICE_EXTENSION pVCB,
166  PVFATFCB pFCB)
167 {
168  ULONG Index;
169  ULONG ShortIndex;
170  HASHENTRY* entry;
171 
172  Index = pFCB->Hash.Hash % pVCB->HashTableSize;
173  ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
174 
175  if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
176  {
177  entry = pVCB->FcbHashTable[ShortIndex];
178  if (entry->self == pFCB)
179  {
180  pVCB->FcbHashTable[ShortIndex] = entry->next;
181  }
182  else
183  {
184  while (entry->next->self != pFCB)
185  {
186  entry = entry->next;
187  }
188  entry->next = pFCB->ShortHash.next;
189  }
190  }
191  entry = pVCB->FcbHashTable[Index];
192  if (entry->self == pFCB)
193  {
194  pVCB->FcbHashTable[Index] = entry->next;
195  }
196  else
197  {
198  while (entry->next->self != pFCB)
199  {
200  entry = entry->next;
201  }
202  entry->next = pFCB->Hash.next;
203  }
204 
206 }
207 
208 static
209 NTSTATUS
211  PVFATFCB directoryFCB,
212  PUNICODE_STRING LongNameU,
213  PUNICODE_STRING ShortNameU,
214  PUNICODE_STRING NameU)
215 {
216  PWCHAR PathNameBuffer;
217  USHORT PathNameLength;
218 
219  PathNameLength = directoryFCB->PathNameU.Length + max(LongNameU->Length, ShortNameU->Length);
220  if (!vfatFCBIsRoot(directoryFCB))
221  {
222  PathNameLength += sizeof(WCHAR);
223  }
224 
225  if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
226  {
228  }
229  PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
230  if (!PathNameBuffer)
231  {
233  }
234  NameU->Buffer = PathNameBuffer;
235  NameU->Length = 0;
236  NameU->MaximumLength = PathNameLength;
237 
238  RtlCopyUnicodeString(NameU, &directoryFCB->PathNameU);
239  if (!vfatFCBIsRoot(directoryFCB))
240  {
241  RtlAppendUnicodeToString(NameU, L"\\");
242  }
243  if (LongNameU->Length > 0)
244  {
245  RtlAppendUnicodeStringToString(NameU, LongNameU);
246  }
247  else
248  {
249  RtlAppendUnicodeStringToString(NameU, ShortNameU);
250  }
251  NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
252 
253  return STATUS_SUCCESS;
254 }
255 
256 VOID
258  PVFATCCB pCcb)
259 {
260  if (pCcb->SearchPattern.Buffer)
261  {
263  }
264  ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
265 }
266 
267 VOID
269  PVFATFCB pFCB)
270 {
271 #ifdef KDBG
272  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
273  {
274  DPRINT1("Destroying: %p (%wZ) %d\n", pFCB, &pFCB->PathNameU, pFCB->RefCount);
275  }
276 #endif
277 
279 
280  if (!vfatFCBIsRoot(pFCB) &&
282  {
284  }
285  ExFreePool(pFCB->PathNameBuffer);
289  ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
290 }
291 
292 BOOLEAN
294  PVFATFCB FCB)
295 {
296  return FCB->PathNameU.Length == sizeof(WCHAR) && FCB->PathNameU.Buffer[0] == L'\\' ? TRUE : FALSE;
297 }
298 
299 VOID
300 #ifndef KDBG
302 #else
303 _vfatGrabFCB(
304 #endif
305  PDEVICE_EXTENSION pVCB,
306  PVFATFCB pFCB
307 #ifdef KDBG
308  ,
309  PCSTR File,
310  ULONG Line,
311  PCSTR Func
312 #endif
313 )
314 {
315 #ifdef KDBG
316  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
317  {
318  DPRINT1("Inc ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
319  }
320 #else
321  DPRINT("Grabbing FCB at %p: %wZ, refCount:%d\n",
322  pFCB, &pFCB->PathNameU, pFCB->RefCount);
323 #endif
324 
325  ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
326 
327  ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
328  ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
329  ASSERT(pFCB->RefCount > 0);
330  ++pFCB->RefCount;
331 }
332 
333 VOID
334 #ifndef KDBG
336 #else
337 _vfatReleaseFCB(
338 #endif
339  PDEVICE_EXTENSION pVCB,
340  PVFATFCB pFCB
341 #ifdef KDBG
342  ,
343  PCSTR File,
344  ULONG Line,
345  PCSTR Func
346 #endif
347 )
348 {
349  PVFATFCB tmpFcb;
350 
351 #ifdef KDBG
352  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
353  {
354  DPRINT1("Dec ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
355  }
356 #else
357  DPRINT("Releasing FCB at %p: %wZ, refCount:%d\n",
358  pFCB, &pFCB->PathNameU, pFCB->RefCount);
359 #endif
360 
361  ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
362 
363  while (pFCB)
364  {
365  ULONG RefCount;
366 
367  ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
368  ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
369  ASSERT(pFCB->RefCount > 0);
370  RefCount = --pFCB->RefCount;
371 
372  if (RefCount == 1 && BooleanFlagOn(pFCB->Flags, FCB_CACHE_INITIALIZED))
373  {
374  PFILE_OBJECT tmpFileObject;
375  tmpFileObject = pFCB->FileObject;
376 
377  pFCB->FileObject = NULL;
378  CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
379  ClearFlag(pFCB->Flags, FCB_CACHE_INITIALIZED);
380  ObDereferenceObject(tmpFileObject);
381  }
382 
383  if (RefCount == 0)
384  {
385  ASSERT(pFCB->OpenHandleCount == 0);
386  tmpFcb = pFCB->parentFcb;
387  vfatDelFCBFromTable(pVCB, pFCB);
388  vfatDestroyFCB(pFCB);
389  }
390  else
391  {
392  tmpFcb = NULL;
393  }
394  pFCB = tmpFcb;
395  }
396 }
397 
398 static
399 VOID
401  PDEVICE_EXTENSION pVCB,
402  PVFATFCB pFCB)
403 {
404  ULONG Index;
405  ULONG ShortIndex;
406 
407  ASSERT(pFCB->Hash.Hash == vfatNameHash(0, &pFCB->PathNameU));
408  Index = pFCB->Hash.Hash % pVCB->HashTableSize;
409  ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
410 
411  InsertTailList(&pVCB->FcbListHead, &pFCB->FcbListEntry);
412 
413  pFCB->Hash.next = pVCB->FcbHashTable[Index];
414  pVCB->FcbHashTable[Index] = &pFCB->Hash;
415  if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
416  {
417  pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
418  pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
419  }
420  if (pFCB->parentFcb)
421  {
422  vfatGrabFCB(pVCB, pFCB->parentFcb);
423  }
424 }
425 
426 static
427 VOID
431  PVFATFCB Fcb,
433 {
434  ULONG Size;
435 
436  RtlCopyMemory(&Fcb->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
437  RtlCopyUnicodeString(&Fcb->ShortNameU, &DirContext->ShortNameU);
438  Fcb->Hash.Hash = vfatNameHash(0, &Fcb->PathNameU);
439  if (vfatVolumeIsFatX(Vcb))
440  {
441  Fcb->ShortHash.Hash = Fcb->Hash.Hash;
442  }
443  else
444  {
445  Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
446  Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
447  }
448 
449  if (vfatFCBIsDirectory(Fcb))
450  {
451  ULONG FirstCluster, CurrentCluster;
453  Size = 0;
454  FirstCluster = vfatDirEntryGetFirstCluster(Vcb, &Fcb->entry);
455  if (FirstCluster == 1)
456  {
457  Size = Vcb->FatInfo.rootDirectorySectors * Vcb->FatInfo.BytesPerSector;
458  }
459  else if (FirstCluster != 0)
460  {
461  CurrentCluster = FirstCluster;
462  while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
463  {
464  Size += Vcb->FatInfo.BytesPerCluster;
465  Status = NextCluster(Vcb, FirstCluster, &CurrentCluster, FALSE);
466  }
467  }
468  }
469  else if (vfatVolumeIsFatX(Vcb))
470  {
471  Size = Fcb->entry.FatX.FileSize;
472  }
473  else
474  {
475  Size = Fcb->entry.Fat.FileSize;
476  }
477  Fcb->dirIndex = DirContext->DirIndex;
478  Fcb->startIndex = DirContext->StartIndex;
479  Fcb->parentFcb = ParentFcb;
481  {
482  ASSERT(DirContext->DirIndex >= 2 && DirContext->StartIndex >= 2);
483  Fcb->dirIndex = DirContext->DirIndex-2;
484  Fcb->startIndex = DirContext->StartIndex-2;
485  }
488  Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP_64(Size, Vcb->FatInfo.BytesPerCluster);
489 }
490 
491 NTSTATUS
493  PDEVICE_EXTENSION pVCB,
494  PVFATFCB Fcb,
496 {
498  UNICODE_STRING NewNameU;
499 
500  /* Get full path name */
501  Status = vfatMakeFullName(ParentFcb, &Fcb->LongNameU, &Fcb->ShortNameU, &NewNameU);
502  if (!NT_SUCCESS(Status))
503  {
504  return Status;
505  }
506 
507  /* Delete old name */
508  if (Fcb->PathNameBuffer)
509  {
510  ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
511  }
512  Fcb->PathNameU = NewNameU;
513 
514  /* Delete from table */
515  vfatDelFCBFromTable(pVCB, Fcb);
516 
517  /* Split it properly */
518  Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
519  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
520  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
521  Fcb->Hash.Hash = vfatNameHash(0, &Fcb->PathNameU);
522  if (vfatVolumeIsFatX(pVCB))
523  {
524  Fcb->ShortHash.Hash = Fcb->Hash.Hash;
525  }
526  else
527  {
528  Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
529  Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
530  }
531 
532  vfatAddFCBToTable(pVCB, Fcb);
533  vfatReleaseFCB(pVCB, ParentFcb);
534 
535  return STATUS_SUCCESS;
536 }
537 
538 NTSTATUS
540  PDEVICE_EXTENSION pVCB,
541  PVFATFCB Fcb,
544 {
546  PVFATFCB OldParent;
547 
548  DPRINT("vfatUpdateFCB(%p, %p, %p, %p)\n", pVCB, Fcb, DirContext, ParentFcb);
549 
550  /* Get full path name */
551  Status = vfatMakeFullName(ParentFcb, &DirContext->LongNameU, &DirContext->ShortNameU, &Fcb->PathNameU);
552  if (!NT_SUCCESS(Status))
553  {
554  return Status;
555  }
556 
557  /* Delete old name */
558  if (Fcb->PathNameBuffer)
559  {
560  ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
561  }
562 
563  /* Delete from table */
564  vfatDelFCBFromTable(pVCB, Fcb);
565 
566  /* Split it properly */
567  Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
568  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
569  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
570 
571  /* Save old parent */
572  OldParent = Fcb->parentFcb;
573  RemoveEntryList(&Fcb->ParentListEntry);
574 
575  /* Reinit FCB */
577 
578  if (vfatFCBIsDirectory(Fcb))
579  {
581  }
582  InsertTailList(&ParentFcb->ParentListHead, &Fcb->ParentListEntry);
583  vfatAddFCBToTable(pVCB, Fcb);
584 
585  /* If we moved across directories, dereference our old parent
586  * We also dereference in case we're just renaming since AddFCBToTable references it
587  */
588  vfatReleaseFCB(pVCB, OldParent);
589 
590  return STATUS_SUCCESS;
591 }
592 
593 PVFATFCB
595  PDEVICE_EXTENSION pVCB,
596  PUNICODE_STRING PathNameU)
597 {
598  PVFATFCB rcFCB;
599  ULONG Hash;
600  UNICODE_STRING DirNameU;
601  UNICODE_STRING FileNameU;
602  PUNICODE_STRING FcbNameU;
603 
604  HASHENTRY* entry;
605 
606  DPRINT("'%wZ'\n", PathNameU);
607 
608  ASSERT(PathNameU->Length >= sizeof(WCHAR) && PathNameU->Buffer[0] == L'\\');
609  Hash = vfatNameHash(0, PathNameU);
610 
611  entry = pVCB->FcbHashTable[Hash % pVCB->HashTableSize];
612  if (entry)
613  {
614  vfatSplitPathName(PathNameU, &DirNameU, &FileNameU);
615  }
616 
617  while (entry)
618  {
619  if (entry->Hash == Hash)
620  {
621  rcFCB = entry->self;
622  DPRINT("'%wZ' '%wZ'\n", &DirNameU, &rcFCB->DirNameU);
623  if (RtlEqualUnicodeString(&DirNameU, &rcFCB->DirNameU, TRUE))
624  {
625  if (rcFCB->Hash.Hash == Hash)
626  {
627  FcbNameU = &rcFCB->LongNameU;
628  }
629  else
630  {
631  FcbNameU = &rcFCB->ShortNameU;
632  }
633  /* compare the file name */
634  DPRINT("'%wZ' '%wZ'\n", &FileNameU, FcbNameU);
635  if (RtlEqualUnicodeString(&FileNameU, FcbNameU, TRUE))
636  {
637  vfatGrabFCB(pVCB, rcFCB);
638  return rcFCB;
639  }
640  }
641  }
642  entry = entry->next;
643  }
644  return NULL;
645 }
646 
647 PVFATFCB
649  PDEVICE_EXTENSION pVCB)
650 {
651  PVFATFCB FCB;
652  ULONG FirstCluster, CurrentCluster, Size = 0;
654  UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
655 
656  ASSERT(pVCB->RootFcb == NULL);
657 
658  FCB = vfatNewFCB(pVCB, &NameU);
659  if (vfatVolumeIsFatX(pVCB))
660  {
661  memset(FCB->entry.FatX.Filename, ' ', 42);
662  FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
663  FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
664  FCB->entry.FatX.FirstCluster = 1;
665  Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
666  }
667  else
668  {
669  memset(FCB->entry.Fat.ShortName, ' ', 11);
670  FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
671  FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
672  if (pVCB->FatInfo.FatType == FAT32)
673  {
674  CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
675  FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
676  FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
677 
678  while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
679  {
680  Size += pVCB->FatInfo.BytesPerCluster;
681  Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
682  }
683  }
684  else
685  {
686  FCB->entry.Fat.FirstCluster = 1;
687  Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
688  }
689  }
690  FCB->ShortHash.Hash = FCB->Hash.Hash;
691  FCB->RefCount = 2;
692  FCB->dirIndex = 0;
697 
699  vfatAddFCBToTable(pVCB, FCB);
700 
701  /* Cache it */
702  pVCB->RootFcb = FCB;
703 
704  return FCB;
705 }
706 
707 PVFATFCB
709  PDEVICE_EXTENSION pVCB)
710 {
711  PVFATFCB FCB;
712  UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
713 
714  FCB = vfatGrabFCBFromTable(pVCB, &NameU);
715  if (FCB == NULL)
716  {
717  FCB = vfatMakeRootFCB(pVCB);
718  }
719  ASSERT(FCB == pVCB->RootFcb);
720 
721  return FCB;
722 }
723 
724 NTSTATUS
726  PVCB vcb,
727  PVFATFCB directoryFCB,
729  PVFATFCB *fileFCB)
730 {
731  PVFATFCB rcFCB;
732  UNICODE_STRING NameU;
734 
735  Status = vfatMakeFullName(directoryFCB, &DirContext->LongNameU, &DirContext->ShortNameU, &NameU);
736  if (!NT_SUCCESS(Status))
737  {
738  return Status;
739  }
740 
741  rcFCB = vfatNewFCB(vcb, &NameU);
742  vfatInitFCBFromDirEntry(vcb, directoryFCB, rcFCB, DirContext);
743 
744  rcFCB->RefCount = 1;
745  InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
746  vfatAddFCBToTable(vcb, rcFCB);
747  *fileFCB = rcFCB;
748 
750  return STATUS_SUCCESS;
751 }
752 
753 NTSTATUS
755  PDEVICE_EXTENSION vcb,
756  PVFATFCB fcb,
757  PFILE_OBJECT fileObject)
758 {
759  PVFATCCB newCCB;
760 
761 #ifdef KDBG
762  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
763  {
764  DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
765  }
766 #endif
767 
768  newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
769  if (newCCB == NULL)
770  {
772  }
773  RtlZeroMemory(newCCB, sizeof (VFATCCB));
774 
775  fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
776  fileObject->FsContext = fcb;
777  fileObject->FsContext2 = newCCB;
778  fileObject->Vpb = vcb->IoVPB;
779  DPRINT("file open: fcb:%p PathName:%wZ\n", fcb, &fcb->PathNameU);
780 
781 #ifdef KDBG
782  fcb->Flags &= ~FCB_CLEANED_UP;
783  fcb->Flags &= ~FCB_CLOSED;
784 #endif
785 
786  return STATUS_SUCCESS;
787 }
788 
789 NTSTATUS
791  PDEVICE_EXTENSION pDeviceExt,
792  PVFATFCB pDirectoryFCB,
793  PUNICODE_STRING FileToFindU,
794  PVFATFCB *pFoundFCB)
795 {
797  PVOID Context = NULL;
798  PVOID Page = NULL;
799  BOOLEAN First = TRUE;
801  /* This buffer must have a size of 260 characters, because
802  vfatMakeFCBFromDirEntry can copy 20 name entries with 13 characters. */
803  WCHAR LongNameBuffer[260];
804  WCHAR ShortNameBuffer[13];
805  BOOLEAN FoundLong = FALSE;
806  BOOLEAN FoundShort = FALSE;
807  BOOLEAN IsFatX = vfatVolumeIsFatX(pDeviceExt);
808 
809  ASSERT(pDeviceExt);
810  ASSERT(pDirectoryFCB);
811  ASSERT(FileToFindU);
812 
813  DPRINT("vfatDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
814  pDeviceExt, pDirectoryFCB, FileToFindU);
815  DPRINT("Dir Path:%wZ\n", &pDirectoryFCB->PathNameU);
816 
817  DirContext.DirIndex = 0;
818  DirContext.LongNameU.Buffer = LongNameBuffer;
819  DirContext.LongNameU.Length = 0;
820  DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
821  DirContext.ShortNameU.Buffer = ShortNameBuffer;
822  DirContext.ShortNameU.Length = 0;
823  DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
824  DirContext.DeviceExt = pDeviceExt;
825 
826  while (TRUE)
827  {
828  status = VfatGetNextDirEntry(pDeviceExt,
829  &Context,
830  &Page,
831  pDirectoryFCB,
832  &DirContext,
833  First);
834  First = FALSE;
836  {
838  }
839  if (!NT_SUCCESS(status))
840  {
841  return status;
842  }
843 
844  DPRINT(" Index:%u longName:%wZ\n",
845  DirContext.DirIndex, &DirContext.LongNameU);
846 
847  if (!ENTRY_VOLUME(IsFatX, &DirContext.DirEntry))
848  {
849  if (DirContext.LongNameU.Length == 0 ||
850  DirContext.ShortNameU.Length == 0)
851  {
852  DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
854  {
855  ASSERT(DirContext.LongNameU.Length != 0 &&
856  DirContext.ShortNameU.Length != 0);
857  }
859  continue;
860  }
861  FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
862  if (FoundLong == FALSE)
863  {
864  FoundShort = RtlEqualUnicodeString(FileToFindU, &DirContext.ShortNameU, TRUE);
865  }
866  if (FoundLong || FoundShort)
867  {
868  status = vfatMakeFCBFromDirEntry(pDeviceExt,
869  pDirectoryFCB,
870  &DirContext,
871  pFoundFCB);
873  return status;
874  }
875  }
877  }
878 
880 }
881 
882 NTSTATUS
884  PDEVICE_EXTENSION pVCB,
885  PVFATFCB *pParentFCB,
886  PVFATFCB *pFCB,
887  PUNICODE_STRING pFileNameU)
888 {
890  PVFATFCB FCB = NULL;
891  PVFATFCB parentFCB;
892  UNICODE_STRING NameU;
893  UNICODE_STRING RootNameU = RTL_CONSTANT_STRING(L"\\");
894  UNICODE_STRING FileNameU;
895  WCHAR NameBuffer[260];
896  PWCHAR curr, prev, last;
897  ULONG Length;
898 
899  DPRINT("vfatGetFCBForFile (%p,%p,%p,%wZ)\n",
900  pVCB, pParentFCB, pFCB, pFileNameU);
901 
902  RtlInitEmptyUnicodeString(&FileNameU, NameBuffer, sizeof(NameBuffer));
903 
904  parentFCB = *pParentFCB;
905 
906  if (parentFCB == NULL)
907  {
908  /* Passed-in name is the full name */
909  RtlCopyUnicodeString(&FileNameU, pFileNameU);
910 
911  // Trivial case, open of the root directory on volume
912  if (RtlEqualUnicodeString(&FileNameU, &RootNameU, FALSE))
913  {
914  DPRINT("returning root FCB\n");
915 
916  FCB = vfatOpenRootFCB(pVCB);
917  *pFCB = FCB;
918  *pParentFCB = NULL;
919 
921  }
922 
923  /* Check for an existing FCB */
924  FCB = vfatGrabFCBFromTable(pVCB, &FileNameU);
925  if (FCB)
926  {
927  *pFCB = FCB;
928  *pParentFCB = FCB->parentFcb;
929  vfatGrabFCB(pVCB, *pParentFCB);
930  return STATUS_SUCCESS;
931  }
932 
933  last = curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
934  while (*curr != L'\\' && curr > FileNameU.Buffer)
935  {
936  curr--;
937  }
938 
939  if (curr > FileNameU.Buffer)
940  {
941  NameU.Buffer = FileNameU.Buffer;
942  NameU.MaximumLength = NameU.Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
943  FCB = vfatGrabFCBFromTable(pVCB, &NameU);
944  if (FCB)
945  {
946  Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
947  if (Length != FCB->PathNameU.Length)
948  {
949  if (FileNameU.Length + FCB->PathNameU.Length - Length > FileNameU.MaximumLength)
950  {
951  vfatReleaseFCB(pVCB, FCB);
953  }
954  RtlMoveMemory(FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
955  curr, FileNameU.Length - Length);
956  FileNameU.Length += (USHORT)(FCB->PathNameU.Length - Length);
957  curr = FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
958  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
959  }
960  RtlCopyMemory(FileNameU.Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
961  }
962  }
963  else
964  {
965  FCB = NULL;
966  }
967 
968  if (FCB == NULL)
969  {
970  FCB = vfatOpenRootFCB(pVCB);
971  curr = FileNameU.Buffer;
972  }
973 
974  parentFCB = NULL;
975  prev = curr;
976  }
977  else
978  {
979  /* Make absolute path */
980  RtlCopyUnicodeString(&FileNameU, &parentFCB->PathNameU);
981  curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
982  if (*curr != L'\\')
983  {
984  RtlAppendUnicodeToString(&FileNameU, L"\\");
985  curr++;
986  }
987  ASSERT(*curr == L'\\');
988  RtlAppendUnicodeStringToString(&FileNameU, pFileNameU);
989 
990  FCB = parentFCB;
991  parentFCB = NULL;
992  prev = curr;
993  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
994  }
995 
996  while (curr <= last)
997  {
998  if (parentFCB)
999  {
1000  vfatReleaseFCB(pVCB, parentFCB);
1001  parentFCB = NULL;
1002  }
1003  // fail if element in FCB is not a directory
1004  if (!vfatFCBIsDirectory(FCB))
1005  {
1006  DPRINT ("Element in requested path is not a directory\n");
1007 
1008  vfatReleaseFCB(pVCB, FCB);
1009  FCB = NULL;
1010  *pParentFCB = NULL;
1011  *pFCB = NULL;
1012 
1014  }
1015  parentFCB = FCB;
1016  if (prev < curr)
1017  {
1018  Length = (curr - prev) * sizeof(WCHAR);
1019  if (Length != parentFCB->LongNameU.Length)
1020  {
1021  if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
1022  {
1023  vfatReleaseFCB(pVCB, parentFCB);
1024  *pParentFCB = NULL;
1025  *pFCB = NULL;
1027  }
1028  RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
1029  FileNameU.Length - (curr - FileNameU.Buffer) * sizeof(WCHAR));
1030  FileNameU.Length += (USHORT)(parentFCB->LongNameU.Length - Length);
1031  curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
1032  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
1033  }
1034  RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
1035  }
1036  curr++;
1037  prev = curr;
1038  while (*curr != L'\\' && curr <= last)
1039  {
1040  curr++;
1041  }
1042  NameU.Buffer = FileNameU.Buffer;
1043  NameU.Length = (curr - NameU.Buffer) * sizeof(WCHAR);
1044  NameU.MaximumLength = FileNameU.MaximumLength;
1045  DPRINT("%wZ\n", &NameU);
1046  FCB = vfatGrabFCBFromTable(pVCB, &NameU);
1047  if (FCB == NULL)
1048  {
1049  NameU.Buffer = prev;
1050  NameU.MaximumLength = NameU.Length = (curr - prev) * sizeof(WCHAR);
1051  status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
1053  {
1054  *pFCB = NULL;
1055  if (curr > last)
1056  {
1057  *pParentFCB = parentFCB;
1059  }
1060  else
1061  {
1062  vfatReleaseFCB(pVCB, parentFCB);
1063  *pParentFCB = NULL;
1065  }
1066  }
1067  else if (!NT_SUCCESS(status))
1068  {
1069  vfatReleaseFCB(pVCB, parentFCB);
1070  *pParentFCB = NULL;
1071  *pFCB = NULL;
1072 
1073  return status;
1074  }
1075  }
1076  }
1077 
1078  *pParentFCB = parentFCB;
1079  *pFCB = FCB;
1080 
1081  return STATUS_SUCCESS;
1082 }
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
static int Hash(const char *)
Definition: reader.c:2257
#define max(a, b)
Definition: svc.c:63
LIST_ENTRY FcbListEntry
Definition: vfat.h:484
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static NTSTATUS vfatMakeFullName(PVFATFCB directoryFCB, PUNICODE_STRING LongNameU, PUNICODE_STRING ShortNameU, PUNICODE_STRING NameU)
Definition: fcb.c:210
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
UNICODE_STRING ShortNameU
Definition: vfat.h:466
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
Definition: vfat.h:447
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
Definition: vfat.h:536
NPAGED_LOOKASIDE_LIST FcbLookasideList
Definition: vfat.h:417
PVFATFCB vfatOpenRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:708
POINT last
Definition: font.c:46
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:18
#define TRUE
Definition: types.h:120
Definition: cdstruc.h:902
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
ULONG DirIndex
Definition: ntfs.h:533
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
UNICODE_STRING LongNameU
Definition: vfat.h:463
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
Definition: cdstruc.h:498
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:268
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:883
NTSTATUS vfatDirFindFile(PDEVICE_EXTENSION pDeviceExt, PVFATFCB pDirectoryFCB, PUNICODE_STRING FileToFindU, PVFATFCB *pFoundFCB)
Definition: fcb.c:790
UNICODE_STRING SearchPattern
Definition: vfat.h:543
struct _VFATFCB VFATFCB
uint16_t * PWCHAR
Definition: typedefs.h:56
#define InsertTailList(ListHead, Entry)
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:335
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
#define ENTRY_VOLUME(IsFatX, DirEntry)
Definition: vfat.h:206
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
static VOID vfatInitFCBFromDirEntry(PDEVICE_EXTENSION Vcb, PVFATFCB ParentFcb, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext)
Definition: fcb.c:428
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONG RefCount
Definition: vfat.h:481
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
WCHAR First[]
Definition: FormatMessage.c:11
#define ROUND_UP_64(n, align)
Definition: vfat.h:34
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define L(x)
Definition: ntvdm.h:50
unsigned char Attrib
Definition: vfat.h:117
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1295
#define FALSE
Definition: types.h:117
int hash
Definition: main.c:58
static VOID vfatDelFCBFromTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:164
NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB *fileFCB)
Definition: fcb.c:725
ULONG Flags
Definition: vfat.h:496
unsigned char BOOLEAN
LONG RefCount
Definition: ntfs.h:535
struct _FCB FCB
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
NTSTATUS vfatSetFCBNewDirName(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
Definition: fcb.c:492
Definition: bufpool.h:45
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:517
NPAGED_LOOKASIDE_LIST CcbLookasideList
Definition: vfat.h:418
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
ULONG OpenHandleCount
Definition: ntfs.h:537
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static LPSTR pName
Definition: security.c:75
NTSTATUS vfatFCBInitializeCacheFromVolume(PVCB vcb, PVFATFCB fcb)
Definition: dirwr.c:22
struct _fcb fcb
Definition: btrfs_drv.h:1364
struct _VFATFCB * self
Definition: vfat.h:278
#define ASSERT(a)
Definition: mode.c:44
struct _VFATFCB * parentFcb
Definition: vfat.h:490
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TAG_SEARCH
Definition: vfat.h:554
_In_ WDFCOLLECTION _In_ ULONG Index
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define Vcb
Definition: cdprocs.h:1415
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:424
#define ObDereferenceObject
Definition: obfuncs.h:203
const GLubyte * c
Definition: glext.h:8905
#define NODE_TYPE_FCB
Definition: mup.h:20
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
* PFILE_OBJECT
Definition: iotypes.h:1998
struct _HASHENTRY * next
Definition: vfat.h:279
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
FSRTL_COMMON_FCB_HEADER RFCB
Definition: vfat.h:450
#define FCB_CACHE_INITIALIZED
Definition: ntfs.h:508
FILE_LOCK FileLock
Definition: vfat.h:520
Definition: ncftp.h:79
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID vfatDestroyCCB(PVFATCCB pCcb)
Definition: fcb.c:257
#define FCB_IS_FAT
Definition: vfat.h:435
PWCHAR PathNameBuffer
Definition: vfat.h:475
ULONG Hash
Definition: vfat.h:277
FORCEINLINE NTSTATUS VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt, PVOID *pContext, PVOID *pPage, struct _VFATFCB *pDirFcb, struct _VFAT_DIRENTRY_CONTEXT *DirContext, BOOLEAN First)
Definition: vfat.h:397
uint32_t entry
Definition: isohybrid.c:63
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
UNICODE_STRING DirNameU
Definition: vfat.h:469
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:407
#define TAG_FCB
Definition: nodetype.h:152
DIR_ENTRY entry
Definition: vfat.h:457
PUCHAR Attributes
Definition: vfat.h:460
HASHENTRY ShortHash
Definition: vfat.h:517
ERESOURCE PagingIoResource
Definition: vfat.h:453
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:754
unsigned short USHORT
Definition: pedump.c:61
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
void(* Func)(int)
static ULONG vfatNameHash(ULONG hash, PUNICODE_STRING NameU)
Definition: fcb.c:32
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
Definition: vfat.h:224
#define NULL
Definition: types.h:112
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:54
ULONG Flags
Definition: vfat.h:413
#define FCB_IS_VOLUME
Definition: ntfs.h:510
ERESOURCE MainResource
Definition: vfat.h:452
PVFATFCB vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:648
#define FAT32
Definition: fat.h:169
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:38
UNICODE_STRING PathNameU
Definition: vfat.h:472
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
static VOID vfatInitFcb(PVFATFCB Fcb, PUNICODE_STRING NameU)
Definition: fcb.c:83
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define towlower(c)
Definition: wctype.h:97
FAST_MUTEX LastMutex
Definition: vfat.h:527
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PVFATFCB vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:128
const char * PCSTR
Definition: typedefs.h:52
Definition: File.h:15
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
HASHENTRY Hash
Definition: vfat.h:514
NTSTATUS vfatUpdateFCB(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB ParentFcb)
Definition: fcb.c:539
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
LIST_ENTRY ParentListHead
Definition: vfat.h:493
static SERVICE_STATUS status
Definition: service.c:31
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1115
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:518
unsigned char Attrib
Definition: vfat.h:172
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static VOID vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:400
LONGLONG QuadPart
Definition: typedefs.h:114
LIST_ENTRY ParentListEntry
Definition: vfat.h:487
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
Definition: ps.c:97