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)
24 FATVOL_UINT uiDirStartCluster;
25 FATVOL_UINT uiDirCluster;
26 FATVOL_UINT uiDirEntryPos;
31 FATVOL_UINT uiFileCluster;
32 unsigned char ubFileAttr;
34 T_FATVOL_CLUSTERBUF *pClusterBuf;
35 unsigned char *pubBuf;
41 self = (C_FATVOL *)pDrvObj;
45 SysMtx_Lock(self->hMtx);
49 uiDirStartCluster = FATVOL_CLUSTER_ENDMARKER;
50 uiDirCluster = FATVOL_CLUSTER_ENDMARKER;
52 uiFileCluster = self->RootDirCluster;
60 while ( pszPath[0] == '/' )
66 for ( i = 0; pszPath[i] != '\0'; i++ )
69 if ( pszPath[i] == '/' )
84 for ( i = 0, j = 0; i < iNameLen && j < 8; i++, j++ )
86 if ( pszPath[i] == '.' )
90 szName[j] = pszPath[i];
96 if ( pszPath[i] != '.' && i < iNameLen ) /* ファイル名長すぎ */
98 SysMtx_Unlock(self->hMtx);
103 if ( pszPath[i] == '.' )
107 for ( j = 0; i < iNameLen && j < 3; i++, j++ )
109 szName[8+j] = pszPath[i];
115 if ( i < iNameLen ) /* 拡張子長すぎ */
117 SysMtx_Unlock(self->hMtx);
127 for ( i = 0; i < 8+3; i++ )
130 if ( szName[i] >= 'a' && szName[i] <= 'z')
132 szName[i] -= ('a' - 'A');
135 if ( szName[0] == 0xe5 )
143 uiDirStartCluster = uiFileCluster;
144 uiDirCluster = uiDirStartCluster;
146 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
148 SysMtx_Unlock(self->hMtx);
157 pubBuf = &pClusterBuf->pubBuf[uiDirEntryPos];
160 if ( pubBuf[0] == 0x00 )
166 if ( memcmp(pubBuf, szName, 8+3) == 0 )
169 uiFileCluster = pubBuf[26] + (pubBuf[27] << 8);
170 if ( self->iFatType == FATVOL_TYPE_FAT32 )
172 uiFileCluster += (pubBuf[20] << 16) + (pubBuf[21] << 24);
176 ubFileAttr = pubBuf[11];
179 FileSize = pubBuf[28] + (pubBuf[29] << 8) + (pubBuf[30] << 16) + (pubBuf[31] << 24);
187 if ( uiDirEntryPos >= self->BytesPerCluster )
189 FatVol_RelClusterBuf(self, pClusterBuf, 0);
190 uiDirCluster = FatVol_GetNextCluster(self, uiDirCluster);
191 if ( uiDirCluster == FATVOL_CLUSTER_ENDMARKER
192 || (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
194 SysMtx_Unlock(self->hMtx);
202 FatVol_RelClusterBuf(self, pClusterBuf, 0);
205 /* これ以上開くサブディレクトリがなければ抜ける */
206 if ( !(iEntryHit && (ubFileAttr & 0x10)) )
213 /* パスをすべて探索できていなければNG */
214 if ( *pszPath != '\0' )
216 SysMtx_Unlock(self->hMtx);
225 if ( !(iMode & FILE_OPEN_CREATE) )
227 SysMtx_Unlock(self->hMtx);
233 uiDirCluster = uiDirStartCluster;
235 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
237 SysMtx_Unlock(self->hMtx);
245 pubBuf = &pClusterBuf->pubBuf[uiDirEntryPos];
248 if ( pubBuf[0] == 0xe5 || pubBuf[0] == 0x00 )
255 if ( uiDirEntryPos >= self->BytesPerCluster ) /* クラスタ越えなら */
257 FatVol_RelClusterBuf(self, pClusterBuf, 0);
258 uiDirCluster = FatVol_GetNextCluster(self, uiDirCluster);
259 if ( uiDirCluster == FATVOL_CLUSTER_ENDMARKER )
261 /* FAT32以外のルートディレクトリなら拡張不能 */
262 if ( self->iFatType != FATVOL_TYPE_FAT32 && uiDirCluster >= 0xf0000000 )
264 SysMtx_Unlock(self->hMtx);
267 if ( (uiFileCluster = FatVol_GetNewCluster(self)) == FATVOL_CLUSTER_ENDMARKER )
269 SysMtx_Unlock(self->hMtx);
272 FatVol_SetNextCluster(self, uiDirCluster, uiFileCluster);
273 uiDirCluster = uiFileCluster;
275 if ( (pClusterBuf = FatVol_GetClusterBuf(self, uiDirCluster, 1)) == NULL )
277 SysMtx_Unlock(self->hMtx);
285 if ( (uiFileCluster = FatVol_GetNewCluster(self)) == FATVOL_CLUSTER_ENDMARKER )
287 FatVol_RelClusterBuf(self, pClusterBuf, 0);
288 SysMtx_Unlock(self->hMtx);
291 FatVol_SetNextCluster(self, uiFileCluster, FATVOL_CLUSTER_ENDMARKER);
293 memset(&pubBuf[0], 0, 32); /* 初期化 */
294 memcpy(&pubBuf[0], szName, 8+3); /* ファイル名 */
295 pubBuf[11] = (iMode & FILE_OPEN_DIR) ? 0x10 : 0x20; /* 属性 */
296 pubBuf[26] = ((uiFileCluster >> 0) & 0xff); /* 開始クラスタ */
297 pubBuf[27] = ((uiFileCluster >> 8) & 0xff);
298 pubBuf[20] = ((uiFileCluster >> 16) & 0xff);
299 pubBuf[21] = ((uiFileCluster >> 24) & 0xff);
301 ubFileAttr = pubBuf[11];
304 FatVol_RelClusterBuf(self, pClusterBuf, 1);
308 if ( ((ubFileAttr & 0x10) && !(iMode & FILE_OPEN_DIR))
309 || (!(ubFileAttr & 0x10) && (iMode & FILE_OPEN_DIR)) )
311 SysMtx_Unlock(self->hMtx);
316 hFile = FatVol_FileCreate(self, uiFileCluster, uiDirCluster, uiDirEntryPos, FileSize, iMode);
317 if ( hFile != HANDLE_NULL )
323 SysMtx_Unlock(self->hMtx);