1 /* $Id: direntry.c,v 1.2 2001/07/13 10:31:14 ekohl Exp $
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 CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
24 (pDeviceExt)->BytesPerCluster : PAGESIZE)
26 #define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
27 (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->BytesPerSector)))
31 vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt
,
32 PFAT_DIR_ENTRY pFatDirEntry
)
36 if (pDeviceExt
->FatType
== FAT32
)
38 cluster
= pFatDirEntry
->FirstCluster
+
39 pFatDirEntry
->FirstClusterHigh
* 65536;
43 cluster
= pFatDirEntry
->FirstCluster
;
50 vfatIsDirEntryDeleted (FATDirEntry
* pFatDirEntry
)
52 return pFatDirEntry
->Filename
[0] == 0xe5;
56 vfatIsDirEntryEndMarker (FATDirEntry
* pFatDirEntry
)
58 return pFatDirEntry
->Filename
[0] == 0;
62 vfatIsDirEntryLongName (FATDirEntry
* pFatDirEntry
)
64 return pFatDirEntry
->Attrib
== 0x0f;
68 vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry
, PWSTR entryName
)
70 vfat8Dot3ToString (dirEntry
->Filename
, dirEntry
->Ext
, entryName
);
74 vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt
,
75 PVFATFCB pDirectoryFCB
,
76 ULONG
* pDirectoryIndex
,
78 PFAT_DIR_ENTRY pDirEntry
)
81 ULONG indexInPage
= *pDirectoryIndex
% ENTRIES_PER_CACHEPAGE(pDeviceExt
);
82 ULONG pageNumber
= *pDirectoryIndex
/ ENTRIES_PER_CACHEPAGE(pDeviceExt
);
83 PVOID currentPage
= NULL
;
84 PCACHE_SEGMENT cacheSegment
= NULL
;
85 FATDirEntry
* fatDirEntry
;
89 DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
98 DPRINT ("Validating current directory page\n");
99 status
= vfatRequestAndValidateRegion (pDeviceExt
,
101 pageNumber
* CACHEPAGESIZE(pDeviceExt
),
102 (PVOID
*) ¤tPage
,
105 if (!NT_SUCCESS (status
))
112 fatDirEntry
= (FATDirEntry
*) currentPage
;
114 if (vfatIsDirEntryEndMarker (&fatDirEntry
[indexInPage
]))
116 DPRINT ("end of directory, returning no more entries\n");
117 status
= vfatReleaseRegion (pDeviceExt
,
120 return STATUS_NO_MORE_ENTRIES
;
122 else if (vfatIsDirEntryLongName (&fatDirEntry
[indexInPage
]))
124 DPRINT (" long name entry found at %d\n", *pDirectoryIndex
);
125 longNameEntry
= (slot
*) currentPage
;
127 DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
128 5, longNameEntry
[indexInPage
].name0_4
,
129 6, longNameEntry
[indexInPage
].name5_10
,
130 2, longNameEntry
[indexInPage
].name11_12
);
132 vfat_initstr (pLongFileName
, 256);
133 vfat_wcsncpy (pLongFileName
, longNameEntry
[indexInPage
].name0_4
, 5);
134 vfat_wcsncat (pLongFileName
, longNameEntry
[indexInPage
].name5_10
, 5, 6);
135 vfat_wcsncat (pLongFileName
, longNameEntry
[indexInPage
].name11_12
, 11, 2);
137 DPRINT (" longName: [%S]\n", pLongFileName
);
140 while ((longNameEntry
[indexInPage
].id
!= 0x41) &&
141 (longNameEntry
[indexInPage
].id
!= 0x01) &&
142 (longNameEntry
[indexInPage
].attr
> 0))
144 (*pDirectoryIndex
)++;
146 if (indexInPage
== ENTRIES_PER_CACHEPAGE(pDeviceExt
))
151 status
= vfatReleaseRegion (pDeviceExt
,
154 if (!NT_SUCCESS (status
))
158 status
= vfatRequestAndValidateRegion (pDeviceExt
,
160 pageNumber
* CACHEPAGESIZE(pDeviceExt
),
161 (PVOID
*) ¤tPage
,
164 if (!NT_SUCCESS (status
))
168 longNameEntry
= (slot
*) currentPage
;
170 DPRINT (" index %d\n", *pDirectoryIndex
);
172 DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
173 5, longNameEntry
[indexInPage
].name0_4
,
174 6, longNameEntry
[indexInPage
].name5_10
,
175 2, longNameEntry
[indexInPage
].name11_12
);
178 vfat_movstr (pLongFileName
, 13, 0, cpos
* 13);
179 vfat_wcsncpy (pLongFileName
, longNameEntry
[indexInPage
].name0_4
, 5);
180 vfat_wcsncat (pLongFileName
, longNameEntry
[indexInPage
].name5_10
, 5, 6);
181 vfat_wcsncat (pLongFileName
, longNameEntry
[indexInPage
].name11_12
, 11, 2);
183 DPRINT (" longName: [%S]\n", pLongFileName
);
186 (*pDirectoryIndex
)++;
188 if (indexInPage
== ENTRIES_PER_CACHEPAGE(pDeviceExt
))
193 status
= vfatReleaseRegion (pDeviceExt
,
196 if (!NT_SUCCESS (status
))
200 status
= vfatRequestAndValidateRegion (pDeviceExt
,
202 pageNumber
* CACHEPAGESIZE(pDeviceExt
),
203 (PVOID
*) ¤tPage
,
206 if (!NT_SUCCESS (status
))
214 memcpy (pDirEntry
, &fatDirEntry
[indexInPage
], sizeof (FAT_DIR_ENTRY
));
215 (*pDirectoryIndex
)++;
220 DPRINT ("Releasing current directory page\n");
221 status
= vfatReleaseRegion (pDeviceExt
,