ReactOS  0.4.14-dev-55-g2da92ac
fcb.c
Go to the documentation of this file.
1 /*
2 * FILE: drivers/filesystems/fastfat/fcb.c
3 * PURPOSE: Routines to manipulate FCBs.
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS kernel
6 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
7 * Rex Jolliff (rex@lvcablemodem.com)
8 * Herve Poussineau (reactos@poussine.freesurf.fr)
9 * Pierre Schweitzer (pierre@reactos.org)
10 */
11 
12 /* ------------------------------------------------------- INCLUDES */
13 
14 #include "vfat.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #ifdef __GNUC__
20 #include <wctype.h> /* towlower prototype */
21 #endif
22 
23 /* -------------------------------------------------------- DEFINES */
24 
25 #ifdef KDBG
26 extern UNICODE_STRING DebugFile;
27 #endif
28 
29 /* -------------------------------------------------------- PUBLICS */
30 
31 static
32 ULONG
34  ULONG hash,
35  PUNICODE_STRING NameU)
36 {
37  PWCHAR last;
38  PWCHAR curr;
39  register WCHAR c;
40 
41  // LFN could start from "."
42  //ASSERT(NameU->Buffer[0] != L'.');
43  curr = NameU->Buffer;
44  last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
45 
46  while(curr < last)
47  {
48  c = towlower(*curr++);
49  hash = (hash + (c << 4) + (c >> 4)) * 11;
50  }
51  return hash;
52 }
53 
54 VOID
56  PUNICODE_STRING PathNameU,
57  PUNICODE_STRING DirNameU,
58  PUNICODE_STRING FileNameU)
59 {
60  PWCHAR pName;
61  USHORT Length = 0;
62  pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
63  while (*pName != L'\\' && pName >= PathNameU->Buffer)
64  {
65  pName--;
66  Length++;
67  }
68  ASSERT(*pName == L'\\' || pName < PathNameU->Buffer);
69  if (FileNameU)
70  {
71  FileNameU->Buffer = pName + 1;
72  FileNameU->Length = FileNameU->MaximumLength = Length * sizeof(WCHAR);
73  }
74  if (DirNameU)
75  {
76  DirNameU->Buffer = PathNameU->Buffer;
77  DirNameU->Length = (pName + 1 - PathNameU->Buffer) * sizeof(WCHAR);
78  DirNameU->MaximumLength = DirNameU->Length;
79  }
80 }
81 
82 static
83 VOID
85  PVFATFCB Fcb,
86  PUNICODE_STRING NameU)
87 {
88  USHORT PathNameBufferLength;
89 
90  if (NameU)
91  PathNameBufferLength = NameU->Length + sizeof(WCHAR);
92  else
93  PathNameBufferLength = 0;
94 
95  Fcb->PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameBufferLength, TAG_FCB);
96  if (!Fcb->PathNameBuffer)
97  {
98  /* FIXME: what to do if no more memory? */
99  DPRINT1("Unable to initialize FCB for filename '%wZ'\n", NameU);
100  KeBugCheckEx(FAT_FILE_SYSTEM, (ULONG_PTR)Fcb, (ULONG_PTR)NameU, 0, 0);
101  }
102 
104  Fcb->RFCB.NodeByteSize = sizeof(VFATFCB);
105 
106  Fcb->PathNameU.Length = 0;
107  Fcb->PathNameU.Buffer = Fcb->PathNameBuffer;
108  Fcb->PathNameU.MaximumLength = PathNameBufferLength;
109  Fcb->ShortNameU.Length = 0;
110  Fcb->ShortNameU.Buffer = Fcb->ShortNameBuffer;
111  Fcb->ShortNameU.MaximumLength = sizeof(Fcb->ShortNameBuffer);
112  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
113  if (NameU && NameU->Length)
114  {
115  RtlCopyUnicodeString(&Fcb->PathNameU, NameU);
116  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
117  }
118  else
119  {
120  Fcb->DirNameU.Buffer = Fcb->LongNameU.Buffer = NULL;
121  Fcb->DirNameU.MaximumLength = Fcb->DirNameU.Length = 0;
122  Fcb->LongNameU.MaximumLength = Fcb->LongNameU.Length = 0;
123  }
124  RtlZeroMemory(&Fcb->FCBShareAccess, sizeof(SHARE_ACCESS));
125  Fcb->OpenHandleCount = 0;
126 }
127 
128 PVFATFCB
130  PDEVICE_EXTENSION pVCB,
131  PUNICODE_STRING pFileNameU)
132 {
133  PVFATFCB rcFCB;
134 
135  DPRINT("'%wZ'\n", pFileNameU);
136 
137  rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList);
138  if (rcFCB == NULL)
139  {
140  return NULL;
141  }
142  RtlZeroMemory(rcFCB, sizeof(VFATFCB));
143  vfatInitFcb(rcFCB, pFileNameU);
144  if (vfatVolumeIsFatX(pVCB))
145  rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
146  else
147  rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
148  rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
149  rcFCB->Hash.self = rcFCB;
150  rcFCB->ShortHash.self = rcFCB;
155  rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
156  rcFCB->RFCB.Resource = &rcFCB->MainResource;
159 
160  return rcFCB;
161 }
162 
163 static
164 VOID
166  PDEVICE_EXTENSION pVCB,
167  PVFATFCB pFCB)
168 {
169  ULONG Index;
170  ULONG ShortIndex;
171  HASHENTRY* entry;
172 
173  Index = pFCB->Hash.Hash % pVCB->HashTableSize;
174  ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
175 
176  if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
177  {
178  entry = pVCB->FcbHashTable[ShortIndex];
179  if (entry->self == pFCB)
180  {
181  pVCB->FcbHashTable[ShortIndex] = entry->next;
182  }
183  else
184  {
185  while (entry->next->self != pFCB)
186  {
187  entry = entry->next;
188  }
189  entry->next = pFCB->ShortHash.next;
190  }
191  }
192  entry = pVCB->FcbHashTable[Index];
193  if (entry->self == pFCB)
194  {
195  pVCB->FcbHashTable[Index] = entry->next;
196  }
197  else
198  {
199  while (entry->next->self != pFCB)
200  {
201  entry = entry->next;
202  }
203  entry->next = pFCB->Hash.next;
204  }
205 
207 }
208 
209 static
210 NTSTATUS
212  PVFATFCB directoryFCB,
213  PUNICODE_STRING LongNameU,
214  PUNICODE_STRING ShortNameU,
215  PUNICODE_STRING NameU)
216 {
217  PWCHAR PathNameBuffer;
218  USHORT PathNameLength;
219 
220  PathNameLength = directoryFCB->PathNameU.Length + max(LongNameU->Length, ShortNameU->Length);
221  if (!vfatFCBIsRoot(directoryFCB))
222  {
223  PathNameLength += sizeof(WCHAR);
224  }
225 
226  if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
227  {
229  }
230  PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
231  if (!PathNameBuffer)
232  {
234  }
235  NameU->Buffer = PathNameBuffer;
236  NameU->Length = 0;
237  NameU->MaximumLength = PathNameLength;
238 
239  RtlCopyUnicodeString(NameU, &directoryFCB->PathNameU);
240  if (!vfatFCBIsRoot(directoryFCB))
241  {
242  RtlAppendUnicodeToString(NameU, L"\\");
243  }
244  if (LongNameU->Length > 0)
245  {
246  RtlAppendUnicodeStringToString(NameU, LongNameU);
247  }
248  else
249  {
250  RtlAppendUnicodeStringToString(NameU, ShortNameU);
251  }
252  NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
253 
254  return STATUS_SUCCESS;
255 }
256 
257 VOID
259  PVFATCCB pCcb)
260 {
261  if (pCcb->SearchPattern.Buffer)
262  {
264  }
265  ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb);
266 }
267 
268 VOID
270  PVFATFCB pFCB)
271 {
272 #ifdef KDBG
273  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
274  {
275  DPRINT1("Destroying: %p (%wZ) %d\n", pFCB, &pFCB->PathNameU, pFCB->RefCount);
276  }
277 #endif
278 
280 
281  if (!vfatFCBIsRoot(pFCB) &&
283  {
285  }
286  ExFreePool(pFCB->PathNameBuffer);
290  ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
291 }
292 
293 BOOLEAN
295  PVFATFCB FCB)
296 {
297  return FCB->PathNameU.Length == sizeof(WCHAR) && FCB->PathNameU.Buffer[0] == L'\\' ? TRUE : FALSE;
298 }
299 
300 VOID
301 #ifndef KDBG
303 #else
304 _vfatGrabFCB(
305 #endif
306  PDEVICE_EXTENSION pVCB,
307  PVFATFCB pFCB
308 #ifdef KDBG
309  ,
310  PCSTR File,
311  ULONG Line,
312  PCSTR Func
313 #endif
314 )
315 {
316 #ifdef KDBG
317  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
318  {
319  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);
320  }
321 #else
322  DPRINT("Grabbing FCB at %p: %wZ, refCount:%d\n",
323  pFCB, &pFCB->PathNameU, pFCB->RefCount);
324 #endif
325 
326  ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
327 
328  ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
329  ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
330  ASSERT(pFCB->RefCount > 0);
331  ++pFCB->RefCount;
332 }
333 
334 VOID
335 #ifndef KDBG
337 #else
338 _vfatReleaseFCB(
339 #endif
340  PDEVICE_EXTENSION pVCB,
341  PVFATFCB pFCB
342 #ifdef KDBG
343  ,
344  PCSTR File,
345  ULONG Line,
346  PCSTR Func
347 #endif
348 )
349 {
350  PVFATFCB tmpFcb;
351 
352 #ifdef KDBG
353  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &pFCB->LongNameU, FALSE, NULL))
354  {
355  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);
356  }
357 #else
358  DPRINT("Releasing FCB at %p: %wZ, refCount:%d\n",
359  pFCB, &pFCB->PathNameU, pFCB->RefCount);
360 #endif
361 
362  ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
363 
364  while (pFCB)
365  {
366  ULONG RefCount;
367 
368  ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
369  ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
370  ASSERT(pFCB->RefCount > 0);
371  RefCount = --pFCB->RefCount;
372 
373  if (RefCount == 1 && BooleanFlagOn(pFCB->Flags, FCB_CACHE_INITIALIZED))
374  {
375  PFILE_OBJECT tmpFileObject;
376  tmpFileObject = pFCB->FileObject;
377 
378  pFCB->FileObject = NULL;
379  CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
380  ClearFlag(pFCB->Flags, FCB_CACHE_INITIALIZED);
381  ObDereferenceObject(tmpFileObject);
382  }
383 
384  if (RefCount == 0)
385  {
386  ASSERT(pFCB->OpenHandleCount == 0);
387  tmpFcb = pFCB->parentFcb;
388  vfatDelFCBFromTable(pVCB, pFCB);
389  vfatDestroyFCB(pFCB);
390  }
391  else
392  {
393  tmpFcb = NULL;
394  }
395  pFCB = tmpFcb;
396  }
397 }
398 
399 static
400 VOID
402  PDEVICE_EXTENSION pVCB,
403  PVFATFCB pFCB)
404 {
405  ULONG Index;
406  ULONG ShortIndex;
407 
408  ASSERT(pFCB->Hash.Hash == vfatNameHash(0, &pFCB->PathNameU));
409  Index = pFCB->Hash.Hash % pVCB->HashTableSize;
410  ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
411 
412  InsertTailList(&pVCB->FcbListHead, &pFCB->FcbListEntry);
413 
414  pFCB->Hash.next = pVCB->FcbHashTable[Index];
415  pVCB->FcbHashTable[Index] = &pFCB->Hash;
416  if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
417  {
418  pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
419  pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
420  }
421  if (pFCB->parentFcb)
422  {
423  vfatGrabFCB(pVCB, pFCB->parentFcb);
424  }
425 }
426 
427 static
428 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;
480  {
481  ASSERT(DirContext->DirIndex >= 2 && DirContext->StartIndex >= 2);
482  Fcb->dirIndex = DirContext->DirIndex-2;
483  Fcb->startIndex = DirContext->StartIndex-2;
484  }
487  Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP_64(Size, Vcb->FatInfo.BytesPerCluster);
488 }
489 
490 NTSTATUS
492  PDEVICE_EXTENSION pVCB,
493  PVFATFCB Fcb,
495 {
497  UNICODE_STRING NewNameU;
498 
499  /* Get full path name */
500  Status = vfatMakeFullName(ParentFcb, &Fcb->LongNameU, &Fcb->ShortNameU, &NewNameU);
501  if (!NT_SUCCESS(Status))
502  {
503  return Status;
504  }
505 
506  /* Delete old name */
507  if (Fcb->PathNameBuffer)
508  {
509  ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
510  }
511  Fcb->PathNameU = NewNameU;
512 
513  /* Delete from table */
514  vfatDelFCBFromTable(pVCB, Fcb);
515 
516  /* Split it properly */
517  Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
518  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
519  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
520  Fcb->Hash.Hash = vfatNameHash(0, &Fcb->PathNameU);
521  if (vfatVolumeIsFatX(pVCB))
522  {
523  Fcb->ShortHash.Hash = Fcb->Hash.Hash;
524  }
525  else
526  {
527  Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
528  Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
529  }
530 
531  vfatAddFCBToTable(pVCB, Fcb);
532  vfatReleaseFCB(pVCB, ParentFcb);
533 
534  return STATUS_SUCCESS;
535 }
536 
537 NTSTATUS
539  PDEVICE_EXTENSION pVCB,
540  PVFATFCB Fcb,
543 {
545  PVFATFCB OldParent;
546 
547  DPRINT("vfatUpdateFCB(%p, %p, %p, %p)\n", pVCB, Fcb, DirContext, ParentFcb);
548 
549  /* Get full path name */
550  Status = vfatMakeFullName(ParentFcb, &DirContext->LongNameU, &DirContext->ShortNameU, &Fcb->PathNameU);
551  if (!NT_SUCCESS(Status))
552  {
553  return Status;
554  }
555 
556  /* Delete old name */
557  if (Fcb->PathNameBuffer)
558  {
559  ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
560  }
561 
562  /* Delete from table */
563  vfatDelFCBFromTable(pVCB, Fcb);
564 
565  /* Split it properly */
566  Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
567  Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
568  vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
569 
570  /* Save old parent */
571  OldParent = Fcb->parentFcb;
572  RemoveEntryList(&Fcb->ParentListEntry);
573 
574  /* Reinit FCB */
576 
577  if (vfatFCBIsDirectory(Fcb))
578  {
580  }
581  Fcb->parentFcb = ParentFcb;
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, rcFCB, DirContext);
743 
744  rcFCB->RefCount = 1;
745  rcFCB->parentFcb = directoryFCB;
746  InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
747  vfatAddFCBToTable(vcb, rcFCB);
748  *fileFCB = rcFCB;
749 
751  return STATUS_SUCCESS;
752 }
753 
754 NTSTATUS
756  PDEVICE_EXTENSION vcb,
757  PVFATFCB fcb,
758  PFILE_OBJECT fileObject)
759 {
760  PVFATCCB newCCB;
761 
762 #ifdef KDBG
763  if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
764  {
765  DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
766  }
767 #endif
768 
769  newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
770  if (newCCB == NULL)
771  {
773  }
774  RtlZeroMemory(newCCB, sizeof (VFATCCB));
775 
776  fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
777  fileObject->FsContext = fcb;
778  fileObject->FsContext2 = newCCB;
779  fileObject->Vpb = vcb->IoVPB;
780  DPRINT("file open: fcb:%p PathName:%wZ\n", fcb, &fcb->PathNameU);
781 
782 #ifdef KDBG
783  fcb->Flags &= ~FCB_CLEANED_UP;
784  fcb->Flags &= ~FCB_CLOSED;
785 #endif
786 
787  return STATUS_SUCCESS;
788 }
789 
790 NTSTATUS
792  PDEVICE_EXTENSION pDeviceExt,
793  PVFATFCB pDirectoryFCB,
794  PUNICODE_STRING FileToFindU,
795  PVFATFCB *pFoundFCB)
796 {
798  PVOID Context = NULL;
799  PVOID Page = NULL;
800  BOOLEAN First = TRUE;
802  /* This buffer must have a size of 260 characters, because
803  vfatMakeFCBFromDirEntry can copy 20 name entries with 13 characters. */
804  WCHAR LongNameBuffer[260];
805  WCHAR ShortNameBuffer[13];
806  BOOLEAN FoundLong = FALSE;
807  BOOLEAN FoundShort = FALSE;
808  BOOLEAN IsFatX = vfatVolumeIsFatX(pDeviceExt);
809 
810  ASSERT(pDeviceExt);
811  ASSERT(pDirectoryFCB);
812  ASSERT(FileToFindU);
813 
814  DPRINT("vfatDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
815  pDeviceExt, pDirectoryFCB, FileToFindU);
816  DPRINT("Dir Path:%wZ\n", &pDirectoryFCB->PathNameU);
817 
818  DirContext.DirIndex = 0;
819  DirContext.LongNameU.Buffer = LongNameBuffer;
820  DirContext.LongNameU.Length = 0;
821  DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
822  DirContext.ShortNameU.Buffer = ShortNameBuffer;
823  DirContext.ShortNameU.Length = 0;
824  DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
825  DirContext.DeviceExt = pDeviceExt;
826 
827  while (TRUE)
828  {
829  status = VfatGetNextDirEntry(pDeviceExt,
830  &Context,
831  &Page,
832  pDirectoryFCB,
833  &DirContext,
834  First);
835  First = FALSE;
837  {
839  }
840  if (!NT_SUCCESS(status))
841  {
842  return status;
843  }
844 
845  DPRINT(" Index:%u longName:%wZ\n",
846  DirContext.DirIndex, &DirContext.LongNameU);
847 
848  if (!ENTRY_VOLUME(IsFatX, &DirContext.DirEntry))
849  {
850  if (DirContext.LongNameU.Length == 0 ||
851  DirContext.ShortNameU.Length == 0)
852  {
853  DPRINT1("WARNING: File system corruption detected. You may need to run a disk repair utility.\n");
855  {
856  ASSERT(DirContext.LongNameU.Length != 0 &&
857  DirContext.ShortNameU.Length != 0);
858  }
860  continue;
861  }
862  FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
863  if (FoundLong == FALSE)
864  {
865  FoundShort = RtlEqualUnicodeString(FileToFindU, &DirContext.ShortNameU, TRUE);
866  }
867  if (FoundLong || FoundShort)
868  {
869  status = vfatMakeFCBFromDirEntry(pDeviceExt,
870  pDirectoryFCB,
871  &DirContext,
872  pFoundFCB);
874  return status;
875  }
876  }
878  }
879 
881 }
882 
883 NTSTATUS
885  PDEVICE_EXTENSION pVCB,
886  PVFATFCB *pParentFCB,
887  PVFATFCB *pFCB,
888  PUNICODE_STRING pFileNameU)
889 {
891  PVFATFCB FCB = NULL;
892  PVFATFCB parentFCB;
893  UNICODE_STRING NameU;
894  UNICODE_STRING RootNameU = RTL_CONSTANT_STRING(L"\\");
895  UNICODE_STRING FileNameU;
896  WCHAR NameBuffer[260];
897  PWCHAR curr, prev, last;
898  ULONG Length;
899 
900  DPRINT("vfatGetFCBForFile (%p,%p,%p,%wZ)\n",
901  pVCB, pParentFCB, pFCB, pFileNameU);
902 
903  RtlInitEmptyUnicodeString(&FileNameU, NameBuffer, sizeof(NameBuffer));
904 
905  parentFCB = *pParentFCB;
906 
907  if (parentFCB == NULL)
908  {
909  /* Passed-in name is the full name */
910  RtlCopyUnicodeString(&FileNameU, pFileNameU);
911 
912  // Trivial case, open of the root directory on volume
913  if (RtlEqualUnicodeString(&FileNameU, &RootNameU, FALSE))
914  {
915  DPRINT("returning root FCB\n");
916 
917  FCB = vfatOpenRootFCB(pVCB);
918  *pFCB = FCB;
919  *pParentFCB = NULL;
920 
922  }
923 
924  /* Check for an existing FCB */
925  FCB = vfatGrabFCBFromTable(pVCB, &FileNameU);
926  if (FCB)
927  {
928  *pFCB = FCB;
929  *pParentFCB = FCB->parentFcb;
930  vfatGrabFCB(pVCB, *pParentFCB);
931  return STATUS_SUCCESS;
932  }
933 
934  last = curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
935  while (*curr != L'\\' && curr > FileNameU.Buffer)
936  {
937  curr--;
938  }
939 
940  if (curr > FileNameU.Buffer)
941  {
942  NameU.Buffer = FileNameU.Buffer;
943  NameU.MaximumLength = NameU.Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
944  FCB = vfatGrabFCBFromTable(pVCB, &NameU);
945  if (FCB)
946  {
947  Length = (curr - FileNameU.Buffer) * sizeof(WCHAR);
948  if (Length != FCB->PathNameU.Length)
949  {
950  if (FileNameU.Length + FCB->PathNameU.Length - Length > FileNameU.MaximumLength)
951  {
952  vfatReleaseFCB(pVCB, FCB);
954  }
955  RtlMoveMemory(FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR),
956  curr, FileNameU.Length - Length);
957  FileNameU.Length += (USHORT)(FCB->PathNameU.Length - Length);
958  curr = FileNameU.Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
959  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
960  }
961  RtlCopyMemory(FileNameU.Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
962  }
963  }
964  else
965  {
966  FCB = NULL;
967  }
968 
969  if (FCB == NULL)
970  {
971  FCB = vfatOpenRootFCB(pVCB);
972  curr = FileNameU.Buffer;
973  }
974 
975  parentFCB = NULL;
976  prev = curr;
977  }
978  else
979  {
980  /* Make absolute path */
981  RtlCopyUnicodeString(&FileNameU, &parentFCB->PathNameU);
982  curr = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
983  if (*curr != L'\\')
984  {
985  RtlAppendUnicodeToString(&FileNameU, L"\\");
986  curr++;
987  }
988  ASSERT(*curr == L'\\');
989  RtlAppendUnicodeStringToString(&FileNameU, pFileNameU);
990 
991  FCB = parentFCB;
992  parentFCB = NULL;
993  prev = curr;
994  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
995  }
996 
997  while (curr <= last)
998  {
999  if (parentFCB)
1000  {
1001  vfatReleaseFCB(pVCB, parentFCB);
1002  parentFCB = NULL;
1003  }
1004  // fail if element in FCB is not a directory
1005  if (!vfatFCBIsDirectory(FCB))
1006  {
1007  DPRINT ("Element in requested path is not a directory\n");
1008 
1009  vfatReleaseFCB(pVCB, FCB);
1010  FCB = NULL;
1011  *pParentFCB = NULL;
1012  *pFCB = NULL;
1013 
1015  }
1016  parentFCB = FCB;
1017  if (prev < curr)
1018  {
1019  Length = (curr - prev) * sizeof(WCHAR);
1020  if (Length != parentFCB->LongNameU.Length)
1021  {
1022  if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
1023  {
1024  vfatReleaseFCB(pVCB, parentFCB);
1025  *pParentFCB = NULL;
1026  *pFCB = NULL;
1028  }
1029  RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
1030  FileNameU.Length - (curr - FileNameU.Buffer) * sizeof(WCHAR));
1031  FileNameU.Length += (USHORT)(parentFCB->LongNameU.Length - Length);
1032  curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
1033  last = FileNameU.Buffer + FileNameU.Length / sizeof(WCHAR) - 1;
1034  }
1035  RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
1036  }
1037  curr++;
1038  prev = curr;
1039  while (*curr != L'\\' && curr <= last)
1040  {
1041  curr++;
1042  }
1043  NameU.Buffer = FileNameU.Buffer;
1044  NameU.Length = (curr - NameU.Buffer) * sizeof(WCHAR);
1045  NameU.MaximumLength = FileNameU.MaximumLength;
1046  DPRINT("%wZ\n", &NameU);
1047  FCB = vfatGrabFCBFromTable(pVCB, &NameU);
1048  if (FCB == NULL)
1049  {
1050  NameU.Buffer = prev;
1051  NameU.MaximumLength = NameU.Length = (curr - prev) * sizeof(WCHAR);
1052  status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
1054  {
1055  *pFCB = NULL;
1056  if (curr > last)
1057  {
1058  *pParentFCB = parentFCB;
1060  }
1061  else
1062  {
1063  vfatReleaseFCB(pVCB, parentFCB);
1064  *pParentFCB = NULL;
1066  }
1067  }
1068  else if (!NT_SUCCESS(status))
1069  {
1070  vfatReleaseFCB(pVCB, parentFCB);
1071  *pParentFCB = NULL;
1072  *pFCB = NULL;
1073 
1074  return status;
1075  }
1076  }
1077  }
1078 
1079  *pParentFCB = parentFCB;
1080  *pFCB = FCB;
1081 
1082  return STATUS_SUCCESS;
1083 }
static int Hash(const char *)
Definition: reader.c:2257
#define TAG_FCB
Definition: vfat.h:541
#define max(a, b)
Definition: svc.c:63
NTSTATUS vfatUpdateFCB(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB ParentFcb)
Definition: fcb.c:538
static VOID vfatInitFcb(PVFATFCB Fcb, PUNICODE_STRING NameU)
Definition: fcb.c:84
LIST_ENTRY FcbListEntry
Definition: vfat.h:478
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:40
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
UNICODE_STRING ShortNameU
Definition: vfat.h:460
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:441
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:1261
Definition: vfat.h:530
NPAGED_LOOKASIDE_LIST FcbLookasideList
Definition: vfat.h:411
POINT last
Definition: font.c:46
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:19
Definition: cdstruc.h:908
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
static VOID vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:401
PVFATFCB vfatOpenRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:708
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1278
NTSTATUS vfatAttachFCBToFileObject(PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject)
Definition: fcb.c:755
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
ULONG DirIndex
Definition: ntfs.h:529
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:631
UNICODE_STRING LongNameU
Definition: vfat.h:457
Definition: cdstruc.h:504
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:294
UNICODE_STRING SearchPattern
Definition: vfat.h:537
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
struct _VFATFCB VFATFCB
uint16_t * PWCHAR
Definition: typedefs.h:54
#define InsertTailList(ListHead, Entry)
NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB *fileFCB)
Definition: fcb.c:725
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
NTSTATUS vfatSetFCBNewDirName(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFATFCB ParentFcb)
Definition: fcb.c:491
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
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:263
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
LONG RefCount
Definition: vfat.h:475
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:93
while(1)
Definition: macro.lex.yy.c:740
unsigned char Attrib
Definition: vfat.h:117
int hash
Definition: main.c:58
ULONG Flags
Definition: vfat.h:490
unsigned char BOOLEAN
LONG RefCount
Definition: ntfs.h:531
struct _FCB FCB
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PVFATFCB vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
Definition: fcb.c:648
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:513
NPAGED_LOOKASIDE_LIST CcbLookasideList
Definition: vfat.h:412
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:645
ULONG OpenHandleCount
Definition: ntfs.h:533
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:24
struct _fcb fcb
Definition: btrfs_drv.h:1301
struct _VFATFCB * self
Definition: vfat.h:278
struct _VFATFCB * parentFcb
Definition: vfat.h:484
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TAG_SEARCH
Definition: vfat.h:548
#define NODE_TYPE_FCB
Definition: vfat.h:439
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define Vcb
Definition: cdprocs.h:1425
static ULONG vfatNameHash(ULONG hash, PUNICODE_STRING NameU)
Definition: fcb.c:33
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:429
const GLubyte * c
Definition: glext.h:8905
static const UCHAR Index[8]
Definition: usbohci.c:18
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:269
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1955
struct _HASHENTRY * next
Definition: vfat.h:279
_In_ PFCB ParentFcb
Definition: cdprocs.h:741
FSRTL_COMMON_FCB_HEADER RFCB
Definition: vfat.h:444
PVFATFCB vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PUNICODE_STRING PathNameU)
Definition: fcb.c:594
FILE_LOCK FileLock
Definition: vfat.h:514
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: ncftp.h:79
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FCB_IS_FAT
Definition: vfat.h:429
VOID vfatDestroyCCB(PVFATCCB pCcb)
Definition: fcb.c:258
static VOID vfatInitFCBFromDirEntry(PDEVICE_EXTENSION Vcb, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext)
Definition: fcb.c:429
static const WCHAR L[]
Definition: oid.c:1250
PWCHAR PathNameBuffer
Definition: vfat.h:469
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:391
uint32_t entry
Definition: isohybrid.c:63
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
UNICODE_STRING DirNameU
Definition: vfat.h:463
#define FCB_CACHE_INITIALIZED
Definition: vfat.h:427
#define VFAT_BREAK_ON_CORRUPTION
Definition: vfat.h:401
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:40
#define FCB_IS_VOLUME
Definition: vfat.h:431
DIR_ENTRY entry
Definition: vfat.h:451
PUCHAR Attributes
Definition: vfat.h:454
HASHENTRY ShortHash
Definition: vfat.h:511
ERESOURCE PagingIoResource
Definition: vfat.h:447
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
void(* Func)(int)
#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
PVFATFCB vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:129
Definition: vfat.h:224
ULONG Flags
Definition: vfat.h:407
ERESOURCE MainResource
Definition: vfat.h:446
#define FAT32
Definition: fat.h:169
#define DPRINT1
Definition: precomp.h:8
static NTSTATUS vfatMakeFullName(PVFATFCB directoryFCB, PUNICODE_STRING LongNameU, PUNICODE_STRING ShortNameU, PUNICODE_STRING NameU)
Definition: fcb.c:211
UNICODE_STRING PathNameU
Definition: vfat.h:466
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:302
#define towlower(c)
Definition: wctype.h:97
FAST_MUTEX LastMutex
Definition: vfat.h:521
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:336
NTSTATUS vfatDirFindFile(PDEVICE_EXTENSION pDeviceExt, PVFATFCB pDirectoryFCB, PUNICODE_STRING FileToFindU, PVFATFCB *pFoundFCB)
Definition: fcb.c:791
const char * PCSTR
Definition: typedefs.h:51
Definition: File.h:15
NTSTATUS vfatGetFCBForFile(PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU)
Definition: fcb.c:884
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
HASHENTRY Hash
Definition: vfat.h:508
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
static VOID vfatDelFCBFromTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:165
return STATUS_SUCCESS
Definition: btrfs.c:2966
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
LIST_ENTRY ParentListHead
Definition: vfat.h:487
static SERVICE_STATUS status
Definition: service.c:31
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
Definition: fcb.c:55
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:514
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:107
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112
LIST_ENTRY ParentListEntry
Definition: vfat.h:481
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
Definition: ps.c:97