2 * Hyper Operating System Application Framework
5 * @brief %jp{FATボリューム用デバイスドライバ}
7 * Copyright (C) 2006-2007 by Project HOS
8 * http://sourceforge.jp/projects/hos/
13 #include "fatvol_local.h"
17 HANDLE FatVol_Open(C_DRVOBJ *pDrvObj, const char *pszPath, int iMode)
21 FATVOL_UINT uiDirStartCluster;
22 FATVOL_UINT uiDirCluster;
23 FATVOL_UINT uiDirEntryPos;
26 FATVOL_UINT uiFileCluster;
27 unsigned char ubFileAttr;
29 T_FATVOL_CLUSTERBUF *pClusterBuf;
30 unsigned char *pubBuf;
36 self = (C_FATVOL *)pDrvObj;
40 SysMtx_Lock(self->hMtx);
44 uiDirStartCluster = FATVOL_CLUSTER_ENDMARKER;
45 uiDirCluster = FATVOL_CLUSTER_ENDMARKER;
47 uiFileCluster = self->RootDirCluster;
55 while ( pszPath[0] == '/' )
61 for ( i = 0; pszPath[i] != '\0'; i++ )
64 if ( pszPath[i] == '/' )
79 for ( i = 0, j = 0; i < iNameLen && j < 8; i++, j++ )
81 if ( pszPath[i] == '.' )
85 szName[j] = pszPath[i];
91 if ( pszPath[i] != '.' && i < iNameLen ) /* ファイル名長すぎ */
93 SysMtx_Unlock(self->hMtx);
98 if ( pszPath[i] == '.' )
102 for ( j = 0; i < iNameLen && j < 3; i++, j++ )
104 szName[8+j] = pszPath[i];
110 if ( i < iNameLen ) /* 拡張子長すぎ */
112 SysMtx_Unlock(self->hMtx);
122 for ( i = 0; i < 8+3; i++ )
125 if ( szName[i] >= 'a' && szName[i] <= 'z')
127 szName[i] -= ('a' - 'A');
130 if ( szName[0] == 0xe5 )
138 uiDirStartCluster = uiFileCluster;
139 uiDirCluster = uiDirStartCluster;
141 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
143 SysMtx_Unlock(self->hMtx);
152 pubBuf = &pClusterBuf->pubBuf[uiDirEntryPos];
155 if ( pubBuf[0] == 0x00 )
161 if ( memcmp(pubBuf, szName, 8+3) == 0 )
164 uiFileCluster = pubBuf[26] + (pubBuf[27] << 8);
165 if ( self->iFatType == FATVOL_TYPE_FAT32 )
167 uiFileCluster += (pubBuf[20] << 16) + (pubBuf[21] << 24);
171 ubFileAttr = pubBuf[11];
174 FileSize = pubBuf[28] + (pubBuf[29] << 8) + (pubBuf[30] << 16) + (pubBuf[31] << 24);
182 if ( uiDirEntryPos >= self->BytesPerCluster )
184 FatVol_RelClusterBuf(self, pClusterBuf, 0);
185 uiDirCluster = FatVol_GetNextCluster(self, uiDirCluster);
186 if ( uiDirCluster == FATVOL_CLUSTER_ENDMARKER
187 || (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
189 SysMtx_Unlock(self->hMtx);
197 FatVol_RelClusterBuf(self, pClusterBuf, 0);
200 /* これ以上開くサブディレクトリがなければ抜ける */
201 if ( !(iEntryHit && (ubFileAttr & 0x10)) )
208 /* パスをすべて探索できていなければNG */
209 if ( *pszPath != '\0' )
211 SysMtx_Unlock(self->hMtx);
220 if ( iMode & FILE_OPEN_EXIST )
222 SysMtx_Unlock(self->hMtx);
227 uiDirCluster = uiDirStartCluster;
229 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
231 SysMtx_Unlock(self->hMtx);
239 pubBuf = &pClusterBuf->pubBuf[uiDirEntryPos];
242 if ( pubBuf[0] == 0xe5 || pubBuf[0] == 0x00 )
249 if ( uiDirEntryPos >= self->BytesPerCluster ) /* クラスタ越えなら */
251 FatVol_RelClusterBuf(self, pClusterBuf, 0);
252 uiDirCluster = FatVol_GetNextCluster(self, uiDirCluster);
253 if ( uiDirCluster == FATVOL_CLUSTER_ENDMARKER )
255 /* FAT32以外のルートディレクトリなら拡張不能 */
256 if ( self->iFatType != FATVOL_TYPE_FAT32 && uiDirCluster >= 0x0f000000 )
258 SysMtx_Unlock(self->hMtx);
261 if ( (uiFileCluster = FatVol_AllocCluster(self)) == FATVOL_CLUSTER_ENDMARKER )
263 SysMtx_Unlock(self->hMtx);
266 FatVol_SetNextCluster(self, uiDirCluster, uiFileCluster);
267 uiDirCluster = uiFileCluster;
269 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
271 SysMtx_Unlock(self->hMtx);
279 if ( (uiFileCluster = FatVol_AllocCluster(self)) == FATVOL_CLUSTER_ENDMARKER )
281 FatVol_RelClusterBuf(self, pClusterBuf, 0);
282 SysMtx_Unlock(self->hMtx);
285 FatVol_SetNextCluster(self, uiFileCluster, FATVOL_CLUSTER_ENDMARKER);
287 MemUtil_MemSetB(&pubBuf[0], 0, 32); /* 初期化 */
288 MemUtil_MemCopyB(&pubBuf[0], szName, 8+3); /* ファイル名 */
289 pubBuf[11] = (iMode & FILE_OPEN_DIR) ? 0x10 : 0x20; /* 属性 */
290 pubBuf[26] = ((uiFileCluster >> 0) & 0xff); /* 開始クラスタ */
291 pubBuf[27] = ((uiFileCluster >> 8) & 0xff);
292 pubBuf[20] = ((uiFileCluster >> 16) & 0xff);
293 pubBuf[21] = ((uiFileCluster >> 24) & 0xff);
295 ubFileAttr = pubBuf[11];
298 FatVol_RelClusterBuf(self, pClusterBuf, 1);
303 if ( iMode & FILE_OPEN_CREATE )
305 FatVol_FreeCluster(self, uiFileCluster);
306 FatVol_SetNextCluster(self, uiFileCluster, FATVOL_CLUSTER_ENDMARKER);
312 if ( ((ubFileAttr & 0x10) && !(iMode & FILE_OPEN_DIR))
313 || (!(ubFileAttr & 0x10) && (iMode & FILE_OPEN_DIR)) )
315 SysMtx_Unlock(self->hMtx);
320 hFile = FatFile_Create(self, uiFileCluster, uiDirCluster, uiDirEntryPos, FileSize, iMode);
321 if ( hFile != HANDLE_NULL )
327 SysMtx_Unlock(self->hMtx);