ReactOS 0.4.15-dev-7961-gdcf9eb0
dirwr.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: Write in directory
5 * COPYRIGHT: Copyright 1999-2001 Rex Jolliff <rex@lvcablemodem.com>
6 * Copyright 2004-2008 Hervé Poussineau <hpoussin@reactos.org>
7 * Copyright 2010-2018 Pierre Schweitzer <pierre@reactos.org>
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "vfat.h"
13
14#define NDEBUG
15#include <debug.h>
16
17#ifdef KDBG
18extern UNICODE_STRING DebugFile;
19#endif
20
23 PVCB vcb,
25{
26 PFILE_OBJECT fileObject;
27 PVFATCCB newCCB;
29 BOOLEAN Acquired;
30
31 /* Don't re-initialize if already done */
33 {
34 return STATUS_SUCCESS;
35 }
36
38 ASSERT(fcb->FileObject == NULL);
39
40 Acquired = FALSE;
41 if (!ExIsResourceAcquiredExclusive(&vcb->DirResource))
42 {
43 ExAcquireResourceExclusiveLite(&vcb->DirResource, TRUE);
44 Acquired = TRUE;
45 }
46
47 fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
48 if (fileObject == NULL)
49 {
51 goto Quit;
52 }
53
54#ifdef KDBG
55 if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
56 {
57 DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
58 }
59#endif
60
61 newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
62 if (newCCB == NULL)
63 {
65 ObDereferenceObject(fileObject);
66 goto Quit;
67 }
68 RtlZeroMemory(newCCB, sizeof (VFATCCB));
69
70 fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
71 fileObject->FsContext = fcb;
72 fileObject->FsContext2 = newCCB;
73 fileObject->Vpb = vcb->IoVPB;
74 fcb->FileObject = fileObject;
75
77 {
78 CcInitializeCacheMap(fileObject,
79 (PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
80 TRUE,
82 fcb);
83 }
85 {
87 fcb->FileObject = NULL;
88 ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
89 ObDereferenceObject(fileObject);
90 if (Acquired)
91 {
92 ExReleaseResourceLite(&vcb->DirResource);
93 }
94 return status;
95 }
97
98 vfatGrabFCB(vcb, fcb);
101
102Quit:
103 if (Acquired)
104 {
105 ExReleaseResourceLite(&vcb->DirResource);
106 }
107
108 return status;
109}
110
111/*
112 * update an existing FAT entry
113 */
116 IN PDEVICE_EXTENSION DeviceExt,
117 IN PVFATFCB pFcb)
118{
120 PDIR_ENTRY PinEntry;
122 ULONG SizeDirEntry;
123 ULONG dirIndex;
125
126 ASSERT(pFcb);
127
128 if (vfatVolumeIsFatX(DeviceExt))
129 {
130 SizeDirEntry = sizeof(FATX_DIR_ENTRY);
131 dirIndex = pFcb->startIndex;
132 }
133 else
134 {
135 SizeDirEntry = sizeof(FAT_DIR_ENTRY);
136 dirIndex = pFcb->dirIndex;
137 }
138
139 DPRINT("updEntry dirIndex %u, PathName \'%wZ\'\n", dirIndex, &pFcb->PathNameU);
140
141 if (vfatFCBIsRoot(pFcb) || BooleanFlagOn(pFcb->Flags, FCB_IS_FAT | FCB_IS_VOLUME))
142 {
143 return STATUS_SUCCESS;
144 }
145
146 ASSERT(pFcb->parentFcb);
147
148 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
149 if (!NT_SUCCESS(Status))
150 {
151 return Status;
152 }
153
154 Offset.u.HighPart = 0;
155 Offset.u.LowPart = dirIndex * SizeDirEntry;
157 {
158 CcPinRead(pFcb->parentFcb->FileObject, &Offset, SizeDirEntry, PIN_WAIT, &Context, (PVOID*)&PinEntry);
159 }
161 {
162 DPRINT1("Failed write to \'%wZ\'.\n", &pFcb->parentFcb->PathNameU);
164 }
165 _SEH2_END;
166
167 pFcb->Flags &= ~FCB_IS_DIRTY;
168 RtlCopyMemory(PinEntry, &pFcb->entry, SizeDirEntry);
171 return STATUS_SUCCESS;
172}
173
174/*
175 * rename an existing FAT entry
176 */
179 IN PDEVICE_EXTENSION DeviceExt,
180 IN PVFATFCB pFcb,
182 IN BOOLEAN CaseChangeOnly)
183{
184 OEM_STRING NameA;
185 ULONG StartIndex;
188 PFATX_DIR_ENTRY pDirEntry;
190
191 DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
192
193 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
194 if (!NT_SUCCESS(Status))
195 {
196 return Status;
197 }
198
199 if (vfatVolumeIsFatX(DeviceExt))
200 {
202
203 /* Open associated dir entry */
204 StartIndex = pFcb->startIndex;
205 Offset.u.HighPart = 0;
206 Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
208 {
209 CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, PIN_WAIT, &Context, (PVOID*)&pDirEntry);
210 }
212 {
213 DPRINT1("CcPinRead(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
215 }
216 _SEH2_END;
217
218 pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
219
220 /* Set file name */
221 NameA.Buffer = (PCHAR)pDirEntry->Filename;
222 NameA.Length = 0;
223 NameA.MaximumLength = 42;
225 pDirEntry->FilenameLength = (unsigned char)NameA.Length;
226
227 /* Update FCB */
228 DirContext.DeviceExt = DeviceExt;
229 DirContext.ShortNameU.Length = 0;
230 DirContext.ShortNameU.MaximumLength = 0;
231 DirContext.ShortNameU.Buffer = NULL;
232 DirContext.LongNameU = *FileName;
233 DirContext.DirEntry.FatX = *pDirEntry;
234
237
238 Status = vfatUpdateFCB(DeviceExt, pFcb, &DirContext, pFcb->parentFcb);
239 if (NT_SUCCESS(Status))
240 {
241 CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL);
242 }
243
244 return Status;
245 }
246 else
247 {
248 /* This we cannot handle properly, move file - would likely need love */
249 return VfatMoveEntry(DeviceExt, pFcb, FileName, pFcb->parentFcb);
250 }
251}
252
253/*
254 * try to find contiguous entries frees in directory,
255 * extend a directory if is necessary
256 */
259 IN PDEVICE_EXTENSION DeviceExt,
260 IN PVFATFCB pDirFcb,
261 IN ULONG nbSlots,
263{
265 ULONG i, count, size, nbFree = 0;
266 PDIR_ENTRY pFatEntry = NULL;
269 ULONG SizeDirEntry;
270 BOOLEAN IsFatX = vfatVolumeIsFatX(DeviceExt);
271 FileOffset.QuadPart = 0;
272
273 if (IsFatX)
274 SizeDirEntry = sizeof(FATX_DIR_ENTRY);
275 else
276 SizeDirEntry = sizeof(FAT_DIR_ENTRY);
277
278 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pDirFcb);
279 if (!NT_SUCCESS(Status))
280 {
281 return FALSE;
282 }
283
284 count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
285 size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
286 for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
287 {
288 if (Context == NULL || (i % size) == 0)
289 {
290 if (Context)
291 {
293 }
295 {
296 CcPinRead(pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, PIN_WAIT, &Context, (PVOID*)&pFatEntry);
297 }
299 {
300 _SEH2_YIELD(return FALSE);
301 }
302 _SEH2_END;
303
304 FileOffset.u.LowPart += DeviceExt->FatInfo.BytesPerCluster;
305 }
306 if (ENTRY_END(IsFatX, pFatEntry))
307 {
308 break;
309 }
310 if (ENTRY_DELETED(IsFatX, pFatEntry))
311 {
312 nbFree++;
313 }
314 else
315 {
316 nbFree = 0;
317 }
318 if (nbFree == nbSlots)
319 {
320 break;
321 }
322 }
323 if (Context)
324 {
326 Context = NULL;
327 }
328 if (nbFree == nbSlots)
329 {
330 /* found enough contiguous free slots */
331 *start = i - nbSlots + 1;
332 }
333 else
334 {
335 *start = i - nbFree;
336 if (*start + nbSlots > count)
337 {
339 /* extend the directory */
340 if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
341 {
342 /* We can't extend a root directory on a FAT12/FAT16/FATX partition */
343 return FALSE;
344 }
345 AllocationSize.QuadPart = pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster;
346 Status = VfatSetAllocationSizeInformation(pDirFcb->FileObject, pDirFcb,
347 DeviceExt, &AllocationSize);
348 if (!NT_SUCCESS(Status))
349 {
350 return FALSE;
351 }
352 /* clear the new dir cluster */
353 FileOffset.u.LowPart = (ULONG)(pDirFcb->RFCB.FileSize.QuadPart -
354 DeviceExt->FatInfo.BytesPerCluster);
356 {
357 CcPinRead(pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, PIN_WAIT, &Context, (PVOID*)&pFatEntry);
358 }
360 {
361 _SEH2_YIELD(return FALSE);
362 }
363 _SEH2_END;
364
365 if (IsFatX)
366 memset(pFatEntry, 0xff, DeviceExt->FatInfo.BytesPerCluster);
367 else
368 RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
369 }
370 else if (*start + nbSlots < count)
371 {
372 /* clear the entry after the last new entry */
373 FileOffset.u.LowPart = (*start + nbSlots) * SizeDirEntry;
375 {
376 CcPinRead(pDirFcb->FileObject, &FileOffset, SizeDirEntry, PIN_WAIT, &Context, (PVOID*)&pFatEntry);
377 }
379 {
380 _SEH2_YIELD(return FALSE);
381 }
382 _SEH2_END;
383
384 if (IsFatX)
385 memset(pFatEntry, 0xff, SizeDirEntry);
386 else
387 RtlZeroMemory(pFatEntry, SizeDirEntry);
388 }
389 if (Context)
390 {
393 }
394 }
395 DPRINT("nbSlots %u nbFree %u, entry number %u\n", nbSlots, nbFree, *start);
396 return TRUE;
397}
398
399/*
400 create a new FAT entry
401*/
402static NTSTATUS
404 IN PDEVICE_EXTENSION DeviceExt,
405 IN PUNICODE_STRING NameU,
406 IN PVFATFCB* Fcb,
408 IN ULONG RequestedOptions,
409 IN UCHAR ReqAttr,
410 IN PVFAT_MOVE_CONTEXT MoveContext)
411{
413 PFAT_DIR_ENTRY pFatEntry;
414 slot *pSlots;
415 USHORT nbSlots = 0, j;
417 BOOLEAN needTilde = FALSE, needLong = FALSE;
418 BOOLEAN BaseAllLower, BaseAllUpper;
419 BOOLEAN ExtensionAllLower, ExtensionAllUpper;
420 BOOLEAN InExtension;
422 WCHAR c;
423 ULONG CurrentCluster;
424 LARGE_INTEGER SystemTime, FileOffset;
426 ULONG size;
427 long i;
428
429 OEM_STRING NameA;
430 CHAR aName[13];
431 BOOLEAN IsNameLegal;
432 BOOLEAN SpacesFound;
433
435 WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
436 WCHAR ShortNameBuffer[13];
437
438 DPRINT("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
439
440 DirContext.LongNameU = *NameU;
441 IsDirectory = BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE);
442
443 /* nb of entry needed for long name+normal entry */
444 nbSlots = (DirContext.LongNameU.Length / sizeof(WCHAR) + 12) / 13 + 1;
445 DPRINT("NameLen= %u, nbSlots =%u\n", DirContext.LongNameU.Length / sizeof(WCHAR), nbSlots);
447 if (Buffer == NULL)
448 {
450 }
451 RtlZeroMemory(Buffer, (nbSlots - 1) * sizeof(FAT_DIR_ENTRY));
452 pSlots = (slot *) Buffer;
453
454 NameA.Buffer = aName;
455 NameA.Length = 0;
456 NameA.MaximumLength = sizeof(aName);
457
458 DirContext.DeviceExt = DeviceExt;
459 DirContext.ShortNameU.Buffer = ShortNameBuffer;
460 DirContext.ShortNameU.Length = 0;
461 DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
462
463 RtlZeroMemory(&DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
464
465 IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.LongNameU, &NameA, &SpacesFound);
466
467 if (!IsNameLegal || SpacesFound)
468 {
469 GENERATE_NAME_CONTEXT NameContext;
470 VFAT_DIRENTRY_CONTEXT SearchContext;
471 WCHAR ShortSearchName[13];
472 needTilde = TRUE;
473 needLong = TRUE;
474 RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
475 SearchContext.DeviceExt = DeviceExt;
476 SearchContext.LongNameU.Buffer = LongNameBuffer;
477 SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
478 SearchContext.ShortNameU.Buffer = ShortSearchName;
479 SearchContext.ShortNameU.MaximumLength = sizeof(ShortSearchName);
480
481 for (i = 0; i < 100; i++)
482 {
483 RtlGenerate8dot3Name(&DirContext.LongNameU, FALSE, &NameContext, &DirContext.ShortNameU);
484 DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
485 SearchContext.DirIndex = 0;
486 Status = FindFile(DeviceExt, ParentFcb, &DirContext.ShortNameU, &SearchContext, TRUE);
487 if (!NT_SUCCESS(Status))
488 {
489 break;
490 }
491 else if (MoveContext)
492 {
493 ASSERT(*Fcb);
494 if (strncmp((char *)SearchContext.DirEntry.Fat.ShortName, (char *)(*Fcb)->entry.Fat.ShortName, 11) == 0)
495 {
496 if (MoveContext->InPlace)
497 {
498 ASSERT(SearchContext.DirEntry.Fat.FileSize == MoveContext->FileSize);
499 break;
500 }
501 }
502 }
503 }
504 if (i == 100) /* FIXME : what to do after this ? */
505 {
507 return STATUS_UNSUCCESSFUL;
508 }
509 IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.ShortNameU, &NameA, &SpacesFound);
510 }
511 else
512 {
513 BaseAllLower = BaseAllUpper = TRUE;
514 ExtensionAllLower = ExtensionAllUpper = TRUE;
515 InExtension = FALSE;
516 for (i = 0; i < DirContext.LongNameU.Length / sizeof(WCHAR); i++)
517 {
518 c = DirContext.LongNameU.Buffer[i];
519 if (c >= L'A' && c <= L'Z')
520 {
521 if (InExtension)
522 ExtensionAllLower = FALSE;
523 else
524 BaseAllLower = FALSE;
525 }
526 else if (c >= L'a' && c <= L'z')
527 {
528 if (InExtension)
529 ExtensionAllUpper = FALSE;
530 else
531 BaseAllUpper = FALSE;
532 }
533 else if (c > 0x7f)
534 {
535 needLong = TRUE;
536 break;
537 }
538
539 if (c == L'.')
540 {
541 InExtension = TRUE;
542 }
543 }
544
545 if ((!BaseAllLower && !BaseAllUpper) ||
546 (!ExtensionAllLower && !ExtensionAllUpper))
547 {
548 needLong = TRUE;
549 }
550
551 RtlUpcaseUnicodeString(&DirContext.ShortNameU, &DirContext.LongNameU, FALSE);
552 DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
553 }
554 aName[NameA.Length] = 0;
555 DPRINT("'%s', '%wZ', needTilde=%u, needLong=%u\n",
556 aName, &DirContext.LongNameU, needTilde, needLong);
557 memset(DirContext.DirEntry.Fat.ShortName, ' ', 11);
558 for (i = 0; i < 8 && aName[i] && aName[i] != '.'; i++)
559 {
560 DirContext.DirEntry.Fat.Filename[i] = aName[i];
561 }
562 if (aName[i] == '.')
563 {
564 i++;
565 for (j = 0; j < 3 && aName[i]; j++, i++)
566 {
567 DirContext.DirEntry.Fat.Ext[j] = aName[i];
568 }
569 }
570 if (DirContext.DirEntry.Fat.Filename[0] == 0xe5)
571 {
572 DirContext.DirEntry.Fat.Filename[0] = 0x05;
573 }
574
575 if (needLong)
576 {
577 RtlCopyMemory(LongNameBuffer, DirContext.LongNameU.Buffer, DirContext.LongNameU.Length);
578 DirContext.LongNameU.Buffer = LongNameBuffer;
579 DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
580 DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0;
581 memset(DirContext.LongNameU.Buffer + DirContext.LongNameU.Length / sizeof(WCHAR) + 1, 0xff,
582 DirContext.LongNameU.MaximumLength - DirContext.LongNameU.Length - sizeof(WCHAR));
583 }
584 else
585 {
586 nbSlots = 1;
587 if (BaseAllLower && !BaseAllUpper)
588 {
589 DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_BASE;
590 }
591 if (ExtensionAllLower && !ExtensionAllUpper)
592 {
593 DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_EXT;
594 }
595 }
596
597 DPRINT ("dos name=%11.11s\n", DirContext.DirEntry.Fat.Filename);
598
599 /* set attributes */
600 DirContext.DirEntry.Fat.Attrib = ReqAttr;
601 if (IsDirectory)
602 {
603 DirContext.DirEntry.Fat.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
604 }
605 /* set dates and times */
606 KeQuerySystemTime(&SystemTime);
607 FsdSystemTimeToDosDateTime(DeviceExt, &SystemTime, &DirContext.DirEntry.Fat.CreationDate,
608 &DirContext.DirEntry.Fat.CreationTime);
609 DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
610 DirContext.DirEntry.Fat.UpdateTime = DirContext.DirEntry.Fat.CreationTime;
611 DirContext.DirEntry.Fat.AccessDate = DirContext.DirEntry.Fat.CreationDate;
612 /* If it's moving, preserve creation time and file size */
613 if (MoveContext != NULL)
614 {
615 DirContext.DirEntry.Fat.CreationDate = MoveContext->CreationDate;
616 DirContext.DirEntry.Fat.CreationTime = MoveContext->CreationTime;
617 DirContext.DirEntry.Fat.FileSize = MoveContext->FileSize;
618 }
619
620 if (needLong)
621 {
622 /* calculate checksum for 8.3 name */
623 for (pSlots[0].alias_checksum = 0, i = 0; i < 11; i++)
624 {
625 pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
626 | ((pSlots[0].alias_checksum & 0xfe) >> 1))
627 + DirContext.DirEntry.Fat.ShortName[i]);
628 }
629 /* construct slots and entry */
630 for (i = nbSlots - 2; i >= 0; i--)
631 {
632 DPRINT("construct slot %d\n", i);
633 pSlots[i].attr = 0xf;
634 if (i)
635 {
636 pSlots[i].id = (unsigned char)(nbSlots - i - 1);
637 }
638 else
639 {
640 pSlots[i].id = (unsigned char)(nbSlots - i - 1 + 0x40);
641 }
642 pSlots[i].alias_checksum = pSlots[0].alias_checksum;
643 RtlCopyMemory(pSlots[i].name0_4, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13, 10);
644 RtlCopyMemory(pSlots[i].name5_10, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 5, 12);
645 RtlCopyMemory(pSlots[i].name11_12, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 11, 4);
646 }
647 }
648 /* try to find nbSlots contiguous entries frees in directory */
649 if (!vfatFindDirSpace(DeviceExt, ParentFcb, nbSlots, &DirContext.StartIndex))
650 {
652 return STATUS_DISK_FULL;
653 }
654 DirContext.DirIndex = DirContext.StartIndex + nbSlots - 1;
655 if (IsDirectory)
656 {
657 /* If we aren't moving, use next */
658 if (MoveContext == NULL)
659 {
660 CurrentCluster = 0;
661 Status = NextCluster(DeviceExt, 0, &CurrentCluster, TRUE);
662 if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
663 {
665 if (!NT_SUCCESS(Status))
666 {
667 return Status;
668 }
669 return STATUS_DISK_FULL;
670 }
671
672 if (DeviceExt->FatInfo.FatType == FAT32)
673 {
675 }
676 }
677 else
678 {
679 CurrentCluster = MoveContext->FirstCluster;
680 }
681
682 if (DeviceExt->FatInfo.FatType == FAT32)
683 {
684 DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
685 }
686 DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
687 }
688 else if (MoveContext != NULL)
689 {
690 CurrentCluster = MoveContext->FirstCluster;
691
692 if (DeviceExt->FatInfo.FatType == FAT32)
693 {
694 DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
695 }
696 DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
697 }
698
699 /* No need to init cache here, vfatFindDirSpace() will have done it for us */
701
702 i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
703 FileOffset.u.HighPart = 0;
704 FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
705 if (DirContext.StartIndex / i == DirContext.DirIndex / i)
706 {
707 /* one cluster */
709 {
710 CcPinRead(ParentFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY), PIN_WAIT, &Context, (PVOID*)&pFatEntry);
711 }
713 {
716 }
717 _SEH2_END;
718
719 if (nbSlots > 1)
720 {
721 RtlCopyMemory(pFatEntry, Buffer, (nbSlots - 1) * sizeof(FAT_DIR_ENTRY));
722 }
723 RtlCopyMemory(pFatEntry + (nbSlots - 1), &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
724 }
725 else
726 {
727 /* two clusters */
728 size = DeviceExt->FatInfo.BytesPerCluster -
729 (DirContext.StartIndex * sizeof(FAT_DIR_ENTRY)) % DeviceExt->FatInfo.BytesPerCluster;
730 i = size / sizeof(FAT_DIR_ENTRY);
732 {
734 }
736 {
739 }
740 _SEH2_END;
741 RtlCopyMemory(pFatEntry, Buffer, size);
744 FileOffset.u.LowPart += size;
746 {
747 CcPinRead(ParentFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY) - size, PIN_WAIT, &Context, (PVOID*)&pFatEntry);
748 }
750 {
753 }
754 _SEH2_END;
755 if (nbSlots - 1 > i)
756 {
757 RtlCopyMemory(pFatEntry, (PVOID)(Buffer + size), (nbSlots - 1 - i) * sizeof(FAT_DIR_ENTRY));
758 }
759 RtlCopyMemory(pFatEntry + nbSlots - 1 - i, &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
760 }
763
764 if (MoveContext != NULL)
765 {
766 /* We're modifying an existing FCB - likely rename/move */
767 Status = vfatUpdateFCB(DeviceExt, *Fcb, &DirContext, ParentFcb);
768 }
769 else
770 {
772 }
773 if (!NT_SUCCESS(Status))
774 {
776 return Status;
777 }
778
779 DPRINT("new : entry=%11.11s\n", (*Fcb)->entry.Fat.Filename);
780 DPRINT("new : entry=%11.11s\n", DirContext.DirEntry.Fat.Filename);
781
782 if (IsDirectory)
783 {
785 if (!NT_SUCCESS(Status))
786 {
788 return Status;
789 }
790
791 FileOffset.QuadPart = 0;
793 {
794 CcPinRead((*Fcb)->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, PIN_WAIT, &Context, (PVOID*)&pFatEntry);
795 }
797 {
800 }
801 _SEH2_END;
802 /* clear the new directory cluster if not moving */
803 if (MoveContext == NULL)
804 {
805 RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
806 /* create '.' and '..' */
807 pFatEntry[0] = DirContext.DirEntry.Fat;
808 RtlCopyMemory(pFatEntry[0].ShortName, ". ", 11);
809 pFatEntry[1] = DirContext.DirEntry.Fat;
810 RtlCopyMemory(pFatEntry[1].ShortName, ".. ", 11);
811 }
812
813 pFatEntry[1].FirstCluster = ParentFcb->entry.Fat.FirstCluster;
814 pFatEntry[1].FirstClusterHigh = ParentFcb->entry.Fat.FirstClusterHigh;
816 {
817 pFatEntry[1].FirstCluster = 0;
818 pFatEntry[1].FirstClusterHigh = 0;
819 }
822 }
824 DPRINT("addentry ok\n");
825 return STATUS_SUCCESS;
826}
827
828/*
829 create a new FAT entry
830*/
831static NTSTATUS
833 IN PDEVICE_EXTENSION DeviceExt,
834 IN PUNICODE_STRING NameU,
835 IN PVFATFCB* Fcb,
837 IN ULONG RequestedOptions,
838 IN UCHAR ReqAttr,
839 IN PVFAT_MOVE_CONTEXT MoveContext)
840{
842 LARGE_INTEGER SystemTime, FileOffset;
843 OEM_STRING NameA;
845 PFATX_DIR_ENTRY pFatXDirEntry;
846 ULONG Index;
847
848 DPRINT("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
849
850 DirContext.LongNameU = *NameU;
851
852 if (DirContext.LongNameU.Length / sizeof(WCHAR) > 42)
853 {
854 /* name too long */
856 }
857
858 /* try to find 1 entry free in directory */
859 if (!vfatFindDirSpace(DeviceExt, ParentFcb, 1, &DirContext.StartIndex))
860 {
861 return STATUS_DISK_FULL;
862 }
863 Index = DirContext.DirIndex = DirContext.StartIndex;
865 {
866 DirContext.DirIndex += 2;
867 DirContext.StartIndex += 2;
868 }
869
870 DirContext.ShortNameU.Buffer = 0;
871 DirContext.ShortNameU.Length = 0;
872 DirContext.ShortNameU.MaximumLength = 0;
873 DirContext.DeviceExt = DeviceExt;
874 RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
875 memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
876 /* Use cluster, if moving */
877 if (MoveContext != NULL)
878 {
879 DirContext.DirEntry.FatX.FirstCluster = MoveContext->FirstCluster;
880 }
881 else
882 {
883 DirContext.DirEntry.FatX.FirstCluster = 0;
884 }
885 DirContext.DirEntry.FatX.FileSize = 0;
886
887 /* set file name */
888 NameA.Buffer = (PCHAR)DirContext.DirEntry.FatX.Filename;
889 NameA.Length = 0;
890 NameA.MaximumLength = 42;
891 RtlUnicodeStringToOemString(&NameA, &DirContext.LongNameU, FALSE);
892 DirContext.DirEntry.FatX.FilenameLength = (unsigned char)NameA.Length;
893
894 /* set attributes */
895 DirContext.DirEntry.FatX.Attrib = ReqAttr;
896 if (BooleanFlagOn(RequestedOptions, FILE_DIRECTORY_FILE))
897 {
898 DirContext.DirEntry.FatX.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
899 }
900
901 /* set dates and times */
902 KeQuerySystemTime(&SystemTime);
903 FsdSystemTimeToDosDateTime(DeviceExt, &SystemTime, &DirContext.DirEntry.FatX.CreationDate,
904 &DirContext.DirEntry.FatX.CreationTime);
905 DirContext.DirEntry.FatX.UpdateDate = DirContext.DirEntry.FatX.CreationDate;
906 DirContext.DirEntry.FatX.UpdateTime = DirContext.DirEntry.FatX.CreationTime;
907 DirContext.DirEntry.FatX.AccessDate = DirContext.DirEntry.FatX.CreationDate;
908 DirContext.DirEntry.FatX.AccessTime = DirContext.DirEntry.FatX.CreationTime;
909 /* If it's moving, preserve creation time and file size */
910 if (MoveContext != NULL)
911 {
912 DirContext.DirEntry.FatX.CreationDate = MoveContext->CreationDate;
913 DirContext.DirEntry.FatX.CreationTime = MoveContext->CreationTime;
914 DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize;
915 }
916
917 /* No need to init cache here, vfatFindDirSpace() will have done it for us */
919
920 /* add entry into parent directory */
921 FileOffset.u.HighPart = 0;
922 FileOffset.u.LowPart = Index * sizeof(FATX_DIR_ENTRY);
924 {
926 }
928 {
930 }
931 _SEH2_END;
932 RtlCopyMemory(pFatXDirEntry, &DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
935
936 if (MoveContext != NULL)
937 {
938 /* We're modifying an existing FCB - likely rename/move */
939 /* FIXME: check status */
940 vfatUpdateFCB(DeviceExt, *Fcb, &DirContext, ParentFcb);
941 }
942 else
943 {
944 /* FIXME: check status */
946 }
947
948 DPRINT("addentry ok\n");
949 return STATUS_SUCCESS;
950}
951
952/*
953 * deleting an existing FAT entry
954 */
955static NTSTATUS
957 IN PDEVICE_EXTENSION DeviceExt,
958 IN PVFATFCB pFcb,
959 OUT PVFAT_MOVE_CONTEXT MoveContext)
960{
961 ULONG CurrentCluster = 0, NextCluster, i;
964 PFAT_DIR_ENTRY pDirEntry = NULL;
966
967 ASSERT(pFcb);
968 ASSERT(pFcb->parentFcb);
969
970 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
971 if (!NT_SUCCESS(Status))
972 {
973 return Status;
974 }
975
976 DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
977 DPRINT("delete entry: %u to %u\n", pFcb->startIndex, pFcb->dirIndex);
978 Offset.u.HighPart = 0;
979 for (i = pFcb->startIndex; i <= pFcb->dirIndex; i++)
980 {
981 if (Context == NULL || ((i * sizeof(FAT_DIR_ENTRY)) % PAGE_SIZE) == 0)
982 {
983 if (Context)
984 {
987 }
988 Offset.u.LowPart = (i * sizeof(FAT_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
990 {
991 CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, PIN_WAIT, &Context, (PVOID*)&pDirEntry);
992 }
994 {
996 }
997 _SEH2_END;
998 }
999 pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))].Filename[0] = 0xe5;
1000 if (i == pFcb->dirIndex)
1001 {
1002 CurrentCluster =
1004 (PDIR_ENTRY)&pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))]);
1005 }
1006 }
1007
1008 /* In case of moving, save properties */
1009 if (MoveContext != NULL)
1010 {
1011 pDirEntry = &pDirEntry[pFcb->dirIndex % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))];
1012 MoveContext->FirstCluster = CurrentCluster;
1013 MoveContext->FileSize = pDirEntry->FileSize;
1014 MoveContext->CreationTime = pDirEntry->CreationTime;
1015 MoveContext->CreationDate = pDirEntry->CreationDate;
1016 }
1017
1018 if (Context)
1019 {
1022 }
1023
1024 /* In case of moving, don't delete data */
1025 if (MoveContext == NULL)
1026 {
1027 while (CurrentCluster && CurrentCluster != 0xffffffff)
1028 {
1029 GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
1030 /* FIXME: check status */
1031 WriteCluster(DeviceExt, CurrentCluster, 0);
1032 CurrentCluster = NextCluster;
1033 }
1034
1035 if (DeviceExt->FatInfo.FatType == FAT32)
1036 {
1038 }
1039 }
1040
1041 return STATUS_SUCCESS;
1042}
1043
1044/*
1045 * deleting an existing FAT entry
1046 */
1047static NTSTATUS
1049 IN PDEVICE_EXTENSION DeviceExt,
1050 IN PVFATFCB pFcb,
1051 OUT PVFAT_MOVE_CONTEXT MoveContext)
1052{
1053 ULONG CurrentCluster = 0, NextCluster;
1054 PVOID Context = NULL;
1056 PFATX_DIR_ENTRY pDirEntry;
1057 ULONG StartIndex;
1059
1060 ASSERT(pFcb);
1061 ASSERT(pFcb->parentFcb);
1062 ASSERT(vfatVolumeIsFatX(DeviceExt));
1063
1064 StartIndex = pFcb->startIndex;
1065
1066 Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
1067 if (!NT_SUCCESS(Status))
1068 {
1069 return Status;
1070 }
1071
1072 DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
1073 DPRINT("delete entry: %u\n", StartIndex);
1074 Offset.u.HighPart = 0;
1075 Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
1076 _SEH2_TRY
1077 {
1078 CcPinRead(pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, PIN_WAIT, &Context, (PVOID*)&pDirEntry);
1079 }
1081 {
1082 DPRINT1("CcPinRead(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
1084 }
1085 _SEH2_END;
1086 pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
1087 pDirEntry->FilenameLength = 0xe5;
1088 CurrentCluster = vfatDirEntryGetFirstCluster(DeviceExt,
1089 (PDIR_ENTRY)pDirEntry);
1090
1091 /* In case of moving, save properties */
1092 if (MoveContext != NULL)
1093 {
1094 MoveContext->FirstCluster = CurrentCluster;
1095 MoveContext->FileSize = pDirEntry->FileSize;
1096 MoveContext->CreationTime = pDirEntry->CreationTime;
1097 MoveContext->CreationDate = pDirEntry->CreationDate;
1098 }
1099
1102
1103 /* In case of moving, don't delete data */
1104 if (MoveContext == NULL)
1105 {
1106 while (CurrentCluster && CurrentCluster != 0xffffffff)
1107 {
1108 GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
1109 /* FIXME: check status */
1110 WriteCluster(DeviceExt, CurrentCluster, 0);
1111 CurrentCluster = NextCluster;
1112 }
1113 }
1114
1115 return STATUS_SUCCESS;
1116}
1117
1118/*
1119 * move an existing FAT entry
1120 */
1123 IN PDEVICE_EXTENSION DeviceExt,
1124 IN PVFATFCB pFcb,
1127{
1129 PVFATFCB OldParent;
1130 VFAT_MOVE_CONTEXT MoveContext;
1131
1132 DPRINT("VfatMoveEntry(%p, %p, %wZ, %p)\n", DeviceExt, pFcb, FileName, ParentFcb);
1133
1134 /* Delete old entry while keeping data */
1135 Status = VfatDelEntry(DeviceExt, pFcb, &MoveContext);
1136 if (!NT_SUCCESS(Status))
1137 {
1138 return Status;
1139 }
1140
1141 OldParent = pFcb->parentFcb;
1142 CcFlushCache(&OldParent->SectionObjectPointers, NULL, 0, NULL);
1143 MoveContext.InPlace = (OldParent == ParentFcb);
1144
1145 /* Add our new entry with our cluster */
1146 Status = VfatAddEntry(DeviceExt,
1147 FileName,
1148 &pFcb,
1149 ParentFcb,
1151 *pFcb->Attributes,
1152 &MoveContext);
1153
1154 CcFlushCache(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, NULL);
1155
1156 return Status;
1157}
1158
1163
1165 FATXIsDirectoryEmpty, // .IsDirectoryEmpty
1166 FATXAddEntry, // .AddEntry
1167 FATXDelEntry, // .DelEntry
1168 FATXGetNextDirEntry, // .GetNextDirEntry
1169};
1170
1172 FATIsDirectoryEmpty, // .IsDirectoryEmpty
1173 FATAddEntry, // .AddEntry
1174 FATDelEntry, // .DelEntry
1175 FATGetNextDirEntry, // .GetNextDirEntry
1176};
1177
1178/* EOF */
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
NTSYSAPI VOID NTAPI RtlGenerate8dot3Name(_In_ PCUNICODE_STRING Name, _In_ BOOLEAN AllowExtendedCharacters, _Inout_ PGENERATE_NAME_CONTEXT Context, _Inout_ PUNICODE_STRING Name8dot3)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define DPRINT1
Definition: precomp.h:8
#define FAT32
Definition: fat.h:169
struct _fcb fcb
Definition: btrfs_drv.h:1364
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
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
_In_ PFCB Fcb
Definition: cdprocs.h:159
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:425
Definition: bufpool.h:45
ULONG vfatDirEntryGetFirstCluster(PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
Definition: direntry.c:18
BOOLEAN FATIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
Definition: direntry.c:42
VFAT_DISPATCH FatXDispatch
Definition: dirwr.c:1164
BOOLEAN FATXIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
Definition: direntry.c:118
NTSTATUS vfatRenameEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN BOOLEAN CaseChangeOnly)
Definition: dirwr.c:178
VFAT_DISPATCH FatDispatch
Definition: dirwr.c:1171
NTSTATUS FATXGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
static NTSTATUS FATAddEntry(IN PDEVICE_EXTENSION DeviceExt, IN PUNICODE_STRING NameU, IN PVFATFCB *Fcb, IN PVFATFCB ParentFcb, IN ULONG RequestedOptions, IN UCHAR ReqAttr, IN PVFAT_MOVE_CONTEXT MoveContext)
Definition: dirwr.c:403
NTSTATUS VfatMoveEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, IN PUNICODE_STRING FileName, IN PVFATFCB ParentFcb)
Definition: dirwr.c:1122
static NTSTATUS FATXDelEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, OUT PVFAT_MOVE_CONTEXT MoveContext)
Definition: dirwr.c:1048
BOOLEAN vfatFindDirSpace(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pDirFcb, IN ULONG nbSlots, OUT PULONG start)
Definition: dirwr.c:258
NTSTATUS vfatFCBInitializeCacheFromVolume(PVCB vcb, PVFATFCB fcb)
Definition: dirwr.c:22
NTSTATUS FATGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
static NTSTATUS FATDelEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb, OUT PVFAT_MOVE_CONTEXT MoveContext)
Definition: dirwr.c:956
static NTSTATUS FATXAddEntry(IN PDEVICE_EXTENSION DeviceExt, IN PUNICODE_STRING NameU, IN PVFATFCB *Fcb, IN PVFATFCB ParentFcb, IN ULONG RequestedOptions, IN UCHAR ReqAttr, IN PVFAT_MOVE_CONTEXT MoveContext)
Definition: dirwr.c:832
NTSTATUS VfatUpdateEntry(IN PDEVICE_EXTENSION DeviceExt, IN PVFATFCB pFcb)
Definition: dirwr.c:115
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
@ FindFile
Definition: find.c:28
unsigned char
Definition: typeof.h:29
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define TAG_DIRENT
Definition: nodetype.h:158
#define FCB_IS_VOLUME
Definition: ntfs.h:510
#define FCB_CACHE_INITIALIZED
Definition: ntfs.h:508
BOOLEAN FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, PUSHORT pDosDate, PUSHORT pDosTime)
Definition: dir.c:52
NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster)
Definition: fat.c:744
NTSTATUS FAT32UpdateFreeClustersCount(PDEVICE_EXTENSION DeviceExt)
Definition: fat.c:1215
NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue)
Definition: fat.c:705
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend)
Definition: rw.c:38
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define NonPagedPool
Definition: env_spec_w32.h:307
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1306
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:322
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
#define c
Definition: ke_i.h:80
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PIN_WAIT
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NPAGED_LOOKASIDE_LIST CcbLookasideList
Definition: vfat.h:418
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
Definition: vfat.h:422
unsigned char Filename[8]
Definition: vfat.h:114
unsigned char ShortName[11]
Definition: vfat.h:115
unsigned short CreationDate
Definition: vfat.h:120
unsigned long FileSize
Definition: vfat.h:129
unsigned short FirstCluster
Definition: vfat.h:128
unsigned short CreationTime
Definition: vfat.h:120
unsigned short FirstClusterHigh
Definition: vfat.h:123
unsigned long FileSize
Definition: vfat.h:175
unsigned short CreationDate
Definition: vfat.h:179
unsigned char Filename[42]
Definition: vfat.h:173
unsigned char FilenameLength
Definition: vfat.h:171
unsigned short CreationTime
Definition: vfat.h:178
LONGLONG CreationTime
Definition: cdstruc.h:1030
ULONG Flags
Definition: ntfs.h:536
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:517
ULONG DirIndex
Definition: ntfs.h:533
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1115
PFILE_OBJECT FileObject
Definition: ntfs.h:520
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
Definition: vfat.h:537
Definition: vfat.h:448
struct _VFATFCB * parentFcb
Definition: vfat.h:490
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: vfat.h:451
UNICODE_STRING ShortNameU
Definition: vfat.h:603
UNICODE_STRING LongNameU
Definition: vfat.h:602
DIR_ENTRY DirEntry
Definition: vfat.h:601
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:604
BOOLEAN InPlace
Definition: vfat.h:613
Definition: vfat.h:185
unsigned char id
Definition: vfat.h:186
unsigned char alias_checksum
Definition: vfat.h:190
unsigned char attr
Definition: vfat.h:188
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
STRING OEM_STRING
Definition: umtypes.h:203
Definition: vfat.h:225
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
struct _LARGE_INTEGER::@2295 u
#define ENTRY_DELETED(IsFatX, DirEntry)
Definition: vfat.h:205
struct _FATDirEntry FAT_DIR_ENTRY
Definition: vfat.h:167
struct _FATXDirEntry FATX_DIR_ENTRY
Definition: vfat.h:222
FORCEINLINE NTSTATUS VfatAddEntry(PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING NameU, struct _VFATFCB **Fcb, struct _VFATFCB *ParentFcb, ULONG RequestedOptions, UCHAR ReqAttr, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:375
union _DIR_ENTRY * PDIR_ENTRY
Definition: vfat.h:230
#define VFAT_CASE_LOWER_EXT
Definition: vfat.h:201
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
#define LONGNAME_MAX_LENGTH
Definition: vfat.h:203
#define VFAT_CASE_LOWER_BASE
Definition: vfat.h:200
FORCEINLINE NTSTATUS VfatDelEntry(PDEVICE_EXTENSION DeviceExt, struct _VFATFCB *Fcb, struct _VFAT_MOVE_CONTEXT *MoveContext)
Definition: vfat.h:388
#define ENTRY_END(IsFatX, DirEntry)
Definition: vfat.h:207
#define FCB_IS_FAT
Definition: vfat.h:435
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651
NTSTATUS vfatUpdateFCB(PDEVICE_EXTENSION pVCB, PVFATFCB Fcb, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB ParentFcb)
Definition: fcb.c:539
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB *fileFCB)
Definition: fcb.c:725
VOID vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
Definition: fcb.c:301
NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize)
Definition: finfo.c:1211
_In_ WDFCOLLECTION _In_ ULONG Index
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175