5 * PURPOSE: Routines to manipulate directory entries.
6 * COPYRIGHT: See COPYING in the top level directory
7 * PROJECT: ReactOS kernel
8 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
9 * Rex Jolliff (rex@lvcablemodem.com)
12 /* ------------------------------------------------------- INCLUDES */
14 #include <ddk/ntddk.h>
23 #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
26 vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
27 PFAT_DIR_ENTRY pFatDirEntry)
31 if (pDeviceExt->FatInfo.FatType == FAT32)
33 cluster = pFatDirEntry->FirstCluster +
34 pFatDirEntry->FirstClusterHigh * 65536;
38 cluster = pFatDirEntry->FirstCluster;
45 vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry)
47 return pFatDirEntry->Filename [0] == 0xe5;
51 vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry)
53 return pFatDirEntry->Filename [0] == 0;
57 vfatIsDirEntryLongName (FATDirEntry * pFatDirEntry)
59 return pFatDirEntry->Attrib == 0x0f;
63 vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry)
65 return 0x08 == (pFatDirEntry->Attrib & 0x1f);
69 vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName)
71 vfat8Dot3ToString (dirEntry, entryName);
75 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
78 IN OUT PULONG pDirIndex,
80 OUT PFAT_DIR_ENTRY pDirEntry,
81 OUT PULONG pStartIndex)
85 LARGE_INTEGER FileOffset;
86 FATDirEntry * fatDirEntry;
92 FileOffset.u.HighPart = 0;
93 FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE);
95 if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0)
97 if (*pContext != NULL)
99 CcUnpinData(*pContext);
101 if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
104 return STATUS_NO_MORE_ENTRIES;
109 fatDirEntry = (FATDirEntry*)(*pPage) + *pDirIndex % ENTRIES_PER_PAGE;
110 longNameEntry = (slot*) fatDirEntry;
115 *pStartIndex = *pDirIndex;
120 if (vfatIsDirEntryEndMarker(fatDirEntry))
122 CcUnpinData(*pContext);
124 return STATUS_NO_MORE_ENTRIES;
127 if (vfatIsDirEntryDeleted (fatDirEntry))
133 *pStartIndex = *pDirIndex + 1;
138 if (vfatIsDirEntryLongName (fatDirEntry))
142 DPRINT (" long name entry found at %d\n", *pDirIndex);
143 memset(pFileName, 0, 256 * sizeof(WCHAR));
146 DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
147 5, longNameEntry->name0_4,
148 6, longNameEntry->name5_10,
149 2, longNameEntry->name11_12);
151 index = (longNameEntry->id & 0x1f) - 1;
152 dirMap |= 1 << index;
153 pName = pFileName + 13 * index;
155 memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
156 memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
157 memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
159 DPRINT (" longName: [%S]\n", pFileName);
163 memcpy (pDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY));
168 if ((*pDirIndex % ENTRIES_PER_PAGE) == 0)
170 CcUnpinData(*pContext);
171 FileOffset.u.LowPart += PAGE_SIZE;
172 if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
176 return STATUS_NO_MORE_ENTRIES;
178 fatDirEntry = (FATDirEntry*)*pPage;
179 longNameEntry = (slot*) *pPage;
187 return STATUS_SUCCESS;