ReactOS 0.4.15-dev-8408-g466a198
direntry.c File Reference
#include "vfat.h"
#include <debug.h>
Include dependency graph for direntry.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pFatDirEntry)
 
BOOLEAN FATIsDirectoryEmpty (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
 
BOOLEAN FATXIsDirectoryEmpty (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
 
NTSTATUS FATGetNextDirEntry (PVOID *pContext, PVOID *pPage, IN PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
 
NTSTATUS FATXGetNextDirEntry (PVOID *pContext, PVOID *pPage, IN PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file direntry.c.

Function Documentation

◆ FATGetNextDirEntry()

NTSTATUS FATGetNextDirEntry ( PVOID pContext,
PVOID pPage,
IN PVFATFCB  pDirFcb,
PVFAT_DIRENTRY_CONTEXT  DirContext,
BOOLEAN  First 
)

Definition at line 185 of file direntry.c.

191{
192 ULONG dirMap;
195 PFAT_DIR_ENTRY fatDirEntry;
196 slot * longNameEntry;
197 ULONG index;
198
199 UCHAR CheckSum, shortCheckSum;
200 USHORT i;
201 BOOLEAN Valid = TRUE;
202 BOOLEAN Back = FALSE;
203
205
206 DirContext->LongNameU.Length = 0;
207 DirContext->LongNameU.Buffer[0] = UNICODE_NULL;
208
209 FileOffset.u.HighPart = 0;
211
213 if (!NT_SUCCESS(Status))
214 {
215 return Status;
216 }
217
218 if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
219 {
220 if (*pContext != NULL)
221 {
222 CcUnpinData(*pContext);
223 }
224
225 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
226 {
227 *pContext = NULL;
229 }
230
232 {
233 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
234 }
236 {
237 *pContext = NULL;
239 }
240 _SEH2_END;
241 }
242
243 fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
244 longNameEntry = (slot*) fatDirEntry;
245 dirMap = 0;
246
247 if (First)
248 {
249 /* This is the first call to vfatGetNextDirEntry. Possible the start index points
250 * into a long name or points to a short name with an assigned long name.
251 * We must go back to the real start of the entry */
252 while (DirContext->DirIndex > 0 &&
253 !FAT_ENTRY_END(fatDirEntry) &&
254 !FAT_ENTRY_DELETED(fatDirEntry) &&
255 ((!FAT_ENTRY_LONG(fatDirEntry) && !Back) ||
256 (FAT_ENTRY_LONG(fatDirEntry) && !(longNameEntry->id & 0x40))))
257 {
259 Back = TRUE;
260
262 {
263 CcUnpinData(*pContext);
264 FileOffset.u.LowPart -= PAGE_SIZE;
265
266 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
267 {
268 *pContext = NULL;
270 }
271
273 {
274 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
275 }
277 {
278 *pContext = NULL;
280 }
281 _SEH2_END;
282
283 fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
284 longNameEntry = (slot*) fatDirEntry;
285 }
286 else
287 {
288 fatDirEntry--;
289 longNameEntry--;
290 }
291 }
292
293 if (Back && !FAT_ENTRY_END(fatDirEntry) &&
294 (FAT_ENTRY_DELETED(fatDirEntry) || !FAT_ENTRY_LONG(fatDirEntry)))
295 {
297
299 {
300 CcUnpinData(*pContext);
301 FileOffset.u.LowPart += PAGE_SIZE;
302
303 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
304 {
305 *pContext = NULL;
307 }
308
310 {
311 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
312 }
314 {
315 *pContext = NULL;
317 }
318 _SEH2_END;
319
320 fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
321 longNameEntry = (slot*) *pPage;
322 }
323 else
324 {
325 fatDirEntry++;
326 longNameEntry++;
327 }
328 }
329 }
330
331 DirContext->StartIndex = DirContext->DirIndex;
332 CheckSum = 0;
333
334 while (TRUE)
335 {
336 if (FAT_ENTRY_END(fatDirEntry))
337 {
338 CcUnpinData(*pContext);
339 *pContext = NULL;
341 }
342
343 if (FAT_ENTRY_DELETED(fatDirEntry))
344 {
345 dirMap = 0;
346 DirContext->LongNameU.Buffer[0] = 0;
347 DirContext->StartIndex = DirContext->DirIndex + 1;
348 }
349 else
350 {
351 if (FAT_ENTRY_LONG(fatDirEntry))
352 {
353 if (dirMap == 0)
354 {
355 DPRINT (" long name entry found at %u\n", DirContext->DirIndex);
356 RtlZeroMemory(DirContext->LongNameU.Buffer, DirContext->LongNameU.MaximumLength);
357 CheckSum = longNameEntry->alias_checksum;
358 Valid = TRUE;
359 }
360
361 DPRINT(" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
362 5, longNameEntry->name0_4,
363 6, longNameEntry->name5_10,
364 2, longNameEntry->name11_12);
365
366 index = longNameEntry->id & 0x3f; // Note: it can be 0 for corrupted FS
367
368 /* Make sure index is valid and we have enough space in buffer
369 (we count one char for \0) */
370 if (index > 0 &&
371 index * 13 < DirContext->LongNameU.MaximumLength / sizeof(WCHAR))
372 {
373 index--; // make index 0 based
374 dirMap |= 1 << index;
375
376 pName = DirContext->LongNameU.Buffer + index * 13;
377 RtlCopyMemory(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
378 RtlCopyMemory(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
379 RtlCopyMemory(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
380
381 if (longNameEntry->id & 0x40)
382 {
383 /* It's last LFN entry. Terminate filename with \0 */
384 pName[13] = UNICODE_NULL;
385 }
386 }
387 else
388 DPRINT1("Long name entry has invalid index: %x!\n", longNameEntry->id);
389
390 DPRINT (" longName: [%S]\n", DirContext->LongNameU.Buffer);
391
392 if (CheckSum != longNameEntry->alias_checksum)
393 {
394 DPRINT1("Found wrong alias checksum in long name entry (first %x, current %x, %S)\n",
395 CheckSum, longNameEntry->alias_checksum, DirContext->LongNameU.Buffer);
396 Valid = FALSE;
397 }
398 }
399 else
400 {
401 shortCheckSum = 0;
402 for (i = 0; i < 11; i++)
403 {
404 shortCheckSum = (((shortCheckSum & 1) << 7)
405 | ((shortCheckSum & 0xfe) >> 1))
406 + fatDirEntry->ShortName[i];
407 }
408
409 if (shortCheckSum != CheckSum && DirContext->LongNameU.Buffer[0])
410 {
411 DPRINT1("Checksum from long and short name is not equal (short: %x, long: %x, %S)\n",
412 shortCheckSum, CheckSum, DirContext->LongNameU.Buffer);
413 DirContext->LongNameU.Buffer[0] = 0;
414 }
415
416 if (Valid == FALSE)
417 {
418 DirContext->LongNameU.Buffer[0] = 0;
419 }
420
421 RtlCopyMemory (&DirContext->DirEntry.Fat, fatDirEntry, sizeof (FAT_DIR_ENTRY));
422 break;
423 }
424 }
425
427
429 {
430 CcUnpinData(*pContext);
431 FileOffset.u.LowPart += PAGE_SIZE;
432
433 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
434 {
435 *pContext = NULL;
437 }
438
440 {
441 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
442 }
444 {
445 *pContext = NULL;
447 }
448 _SEH2_END;
449
450 fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
451 longNameEntry = (slot*) *pPage;
452 }
453 else
454 {
455 fatDirEntry++;
456 longNameEntry++;
457 }
458 }
459
460 /* Make sure filename is NULL terminate and calculate length */
461 DirContext->LongNameU.Buffer[DirContext->LongNameU.MaximumLength / sizeof(WCHAR) - 1]
462 = UNICODE_NULL;
463 DirContext->LongNameU.Length = (USHORT)(wcslen(DirContext->LongNameU.Buffer) * sizeof(WCHAR));
464
465 /* Init short name */
466 vfat8Dot3ToString(&DirContext->DirEntry.Fat, &DirContext->ShortNameU);
467
468 /* If we found no LFN, use short name as long */
469 if (DirContext->LongNameU.Length == 0)
470 RtlCopyUnicodeString(&DirContext->LongNameU, &DirContext->ShortNameU);
471
472 return STATUS_SUCCESS;
473}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:425
NTSTATUS vfatFCBInitializeCacheFromVolume(PVCB vcb, PVFATFCB fcb)
Definition: dirwr.c:22
#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:33
VOID vfat8Dot3ToString(PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
Definition: create.c:19
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
GLuint index
Definition: glext.h:6031
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static LPSTR pName
Definition: security.c:75
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
#define MAP_WAIT
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
Definition: pinsup.c:694
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
unsigned char ShortName[11]
Definition: vfat.h:115
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:517
ULONG DirIndex
Definition: ntfs.h:533
Definition: vfat.h:185
WCHAR name11_12[2]
Definition: vfat.h:193
WCHAR name5_10[6]
Definition: vfat.h:191
unsigned char id
Definition: vfat.h:186
unsigned char alias_checksum
Definition: vfat.h:190
WCHAR name0_4[5]
Definition: vfat.h:187
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
struct _LARGE_INTEGER::@2289 u
struct _FATDirEntry * PFAT_DIR_ENTRY
Definition: vfat.h:167
#define FAT_ENTRY_DELETED(DirEntry)
Definition: vfat.h:209
#define FAT_ENTRY_LONG(DirEntry)
Definition: vfat.h:211
#define FAT_ENTRY_END(DirEntry)
Definition: vfat.h:210
#define FAT_ENTRIES_PER_PAGE
Definition: vfat.h:219
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ FATIsDirectoryEmpty()

BOOLEAN FATIsDirectoryEmpty ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  Fcb 
)

Definition at line 42 of file direntry.c.

45{
48 PFAT_DIR_ENTRY FatDirEntry;
49 ULONG Index, MaxIndex;
51
52 if (vfatFCBIsRoot(Fcb))
53 {
54 Index = 0;
55 }
56 else
57 {
58 Index = 2;
59 }
60
61 FileOffset.QuadPart = 0;
62 MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FAT_DIR_ENTRY);
63
65 if (!NT_SUCCESS(Status))
66 {
67 return FALSE;
68 }
69
70 while (Index < MaxIndex)
71 {
72 if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
73 {
74 if (Context != NULL)
75 {
77 }
78
80 {
81 CcMapData(Fcb->FileObject, &FileOffset, sizeof(FAT_DIR_ENTRY), MAP_WAIT, &Context, (PVOID*)&FatDirEntry);
82 }
84 {
85 _SEH2_YIELD(return TRUE);
86 }
88
89 FatDirEntry += Index % FAT_ENTRIES_PER_PAGE;
90 FileOffset.QuadPart += PAGE_SIZE;
91 }
92
93 if (FAT_ENTRY_END(FatDirEntry))
94 {
96 return TRUE;
97 }
98
99 if (!FAT_ENTRY_DELETED(FatDirEntry))
100 {
102 return FALSE;
103 }
104
105 Index++;
106 FatDirEntry++;
107 }
108
109 if (Context)
110 {
112 }
113
114 return TRUE;
115}
_In_ PFCB Fcb
Definition: cdprocs.h:159
PFILE_OBJECT FileObject
Definition: ntfs.h:520
struct _FATDirEntry FAT_DIR_ENTRY
Definition: vfat.h:167
BOOLEAN vfatFCBIsRoot(PVFATFCB FCB)
Definition: fcb.c:293
_In_ WDFCOLLECTION _In_ ULONG Index

◆ FATXGetNextDirEntry()

NTSTATUS FATXGetNextDirEntry ( PVOID pContext,
PVOID pPage,
IN PVFATFCB  pDirFcb,
PVFAT_DIRENTRY_CONTEXT  DirContext,
BOOLEAN  First 
)

Definition at line 476 of file direntry.c.

482{
484 PFATX_DIR_ENTRY fatxDirEntry;
485 OEM_STRING StringO;
486 ULONG DirIndex = DirContext->DirIndex;
488
489 FileOffset.u.HighPart = 0;
490
492
493 if (!vfatFCBIsRoot(pDirFcb))
494 {
495 /* need to add . and .. entries */
496 switch (DirContext->DirIndex)
497 {
498 case 0: /* entry . */
499 wcscpy(DirContext->LongNameU.Buffer, L".");
500 DirContext->LongNameU.Length = sizeof(WCHAR);
501 DirContext->ShortNameU = DirContext->LongNameU;
502 RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
503 DirContext->DirEntry.FatX.Filename[0] = '.';
504 DirContext->DirEntry.FatX.FilenameLength = 1;
505 DirContext->StartIndex = 0;
506 return STATUS_SUCCESS;
507
508 case 1: /* entry .. */
509 wcscpy(DirContext->LongNameU.Buffer, L"..");
510 DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
511 DirContext->ShortNameU = DirContext->LongNameU;
512 RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
513 DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
514 DirContext->DirEntry.FatX.FilenameLength = 2;
515 DirContext->StartIndex = 1;
516 return STATUS_SUCCESS;
517
518 default:
519 DirIndex -= 2;
520 }
521 }
522
524 if (!NT_SUCCESS(Status))
525 {
526 return Status;
527 }
528
529 if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
530 {
531 if (*pContext != NULL)
532 {
533 CcUnpinData(*pContext);
534 }
535 FileOffset.u.LowPart = ROUND_DOWN(DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
536 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
537 {
538 *pContext = NULL;
540 }
541
543 {
544 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
545 }
547 {
548 *pContext = NULL;
550 }
551 _SEH2_END;
552 }
553
554 fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
555
556 DirContext->StartIndex = DirContext->DirIndex;
557
558 while (TRUE)
559 {
560 if (FATX_ENTRY_END(fatxDirEntry))
561 {
562 CcUnpinData(*pContext);
563 *pContext = NULL;
565 }
566
567 if (!FATX_ENTRY_DELETED(fatxDirEntry))
568 {
569 RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
570 break;
571 }
573 DirContext->StartIndex++;
574 DirIndex++;
575 if ((DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
576 {
577 CcUnpinData(*pContext);
578 FileOffset.u.LowPart += PAGE_SIZE;
579 if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart)
580 {
581 *pContext = NULL;
583 }
584
586 {
587 CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, MAP_WAIT, pContext, pPage);
588 }
590 {
591 *pContext = NULL;
593 }
594 _SEH2_END;
595
596 fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
597 }
598 else
599 {
600 fatxDirEntry++;
601 }
602 }
603 StringO.Buffer = (PCHAR)fatxDirEntry->Filename;
604 StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
605 RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
606 DirContext->ShortNameU = DirContext->LongNameU;
607 return STATUS_SUCCESS;
608}
#define PCHAR
Definition: match.c:90
NTSYSAPI NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING DestinationString, PCOEM_STRING SourceString, BOOLEAN AllocateDestinationString)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
unsigned char Filename[42]
Definition: vfat.h:173
unsigned char FilenameLength
Definition: vfat.h:171
STRING OEM_STRING
Definition: umtypes.h:203
#define FATX_ENTRY_END(DirEntry)
Definition: vfat.h:215
struct _FATXDirEntry * PFATX_DIR_ENTRY
Definition: vfat.h:222
#define FATX_ENTRIES_PER_PAGE
Definition: vfat.h:220
#define FATX_ENTRY_DELETED(DirEntry)
Definition: vfat.h:214

◆ FATXIsDirectoryEmpty()

BOOLEAN FATXIsDirectoryEmpty ( PDEVICE_EXTENSION  DeviceExt,
PVFATFCB  Fcb 
)

Definition at line 118 of file direntry.c.

121{
124 PFATX_DIR_ENTRY FatXDirEntry;
125 ULONG Index = 0, MaxIndex;
127
128 FileOffset.QuadPart = 0;
129 MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
130
132 if (!NT_SUCCESS(Status))
133 {
134 return FALSE;
135 }
136
137 while (Index < MaxIndex)
138 {
139 if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
140 {
141 if (Context != NULL)
142 {
144 }
145
147 {
148 CcMapData(Fcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY), MAP_WAIT, &Context, (PVOID*)&FatXDirEntry);
149 }
151 {
152 _SEH2_YIELD(return TRUE);
153 }
154 _SEH2_END;
155
156 FatXDirEntry += Index % FATX_ENTRIES_PER_PAGE;
157 FileOffset.QuadPart += PAGE_SIZE;
158 }
159
160 if (FATX_ENTRY_END(FatXDirEntry))
161 {
163 return TRUE;
164 }
165
166 if (!FATX_ENTRY_DELETED(FatXDirEntry))
167 {
169 return FALSE;
170 }
171
172 Index++;
173 FatXDirEntry++;
174 }
175
176 if (Context)
177 {
179 }
180
181 return TRUE;
182}
struct _FATXDirEntry FATX_DIR_ENTRY
Definition: vfat.h:222

◆ vfatDirEntryGetFirstCluster()

ULONG vfatDirEntryGetFirstCluster ( PDEVICE_EXTENSION  pDeviceExt,
PDIR_ENTRY  pFatDirEntry 
)

Definition at line 18 of file direntry.c.

21{
22 ULONG cluster;
23
24 if (pDeviceExt->FatInfo.FatType == FAT32)
25 {
26 cluster = pFatDirEntry->Fat.FirstCluster |
27 (pFatDirEntry->Fat.FirstClusterHigh << 16);
28 }
29 else if (vfatVolumeIsFatX(pDeviceExt))
30 {
31 cluster = pFatDirEntry->FatX.FirstCluster;
32 }
33 else
34 {
35 cluster = pFatDirEntry->Fat.FirstCluster;
36 }
37
38 return cluster;
39}
#define FAT32
Definition: fat.h:169
unsigned short FirstCluster
Definition: vfat.h:128
unsigned short FirstClusterHigh
Definition: vfat.h:123
unsigned long FirstCluster
Definition: vfat.h:174
FAT_DIR_ENTRY Fat
Definition: vfat.h:226
FATX_DIR_ENTRY FatX
Definition: vfat.h:227
FORCEINLINE BOOLEAN vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
Definition: vfat.h:651

Referenced by FATDelEntry(), FATXDelEntry(), VfatGetInternalInformation(), VfatGetRetrievalPointers(), vfatInitFCBFromDirEntry(), VfatReadFileData(), VfatSetAllocationSizeInformation(), VfatWrite(), and VfatWriteFileData().