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"
18 FATVOL_ERR FatVol_Constructor(C_FATVOL *self, const T_VOLUMEOBJ_METHODS *pMethods, const char *pszPath)
20 unsigned char ubBuf[512];
24 self->hBlockFile = File_Open(pszPath, FILE_OPEN_READ | FILE_OPEN_WRITE);
25 if ( self->hBlockFile == HANDLE_NULL )
32 /* パーティーションテーブルチェック */
33 File_Seek(self->hBlockFile, 0, FILE_SEEK_SET);
34 File_Read(self->hBlockFile, ubBuf, 512);
35 if ( ubBuf[0x1fe] == 0x55 && ubBuf[0x1ff] == 0xaa ) /* シグネチャコードチェック */
37 /* パーティーションテーブル0のみ確認 */
38 if ( ubBuf[0x1be + 0x04] == 0x01 /* FAT12 */
39 || ubBuf[0x1be + 0x04] == 0x04 /* FAT16(32MB未満) */
40 || ubBuf[0x1be + 0x04] == 0x06 /* FAT16(32MB以上) */
41 || ubBuf[0x1be + 0x04] == 0x0b /* FAT32 */
42 || ubBuf[0x1be + 0x04] == 0x0c /* FAT32X (LBA) */
43 || ubBuf[0x1be + 0x04] == 0x0e ) /* FAT16X (LBA) */
45 self->Offset = ubBuf[0x1be + 0x08]
46 + (ubBuf[0x1be + 0x09] << 8)
47 + (ubBuf[0x1be + 0x0a] << 16)
48 + (ubBuf[0x1be + 0x0b] << 24);
55 self->DriveSize = File_Seek(self->hBlockFile, 0, FILE_SEEK_END);
56 self->iFatType = FATVOL_TYPE_UNKNOWN;
59 /* BIOS Parameter Block */
60 File_Seek(self->hBlockFile, self->Offset, FILE_SEEK_SET);
61 File_Read(self->hBlockFile, ubBuf, 512);
64 if ( ubBuf[0x36] == 'F' && ubBuf[0x37] == 'A' && ubBuf[0x38] == 'T' && ubBuf[0x39] == '1' )
66 if ( ubBuf[0x3a] == '2' )
68 self->iFatType = FATVOL_TYPE_FAT12;
70 else if ( ubBuf[0x3a] == '6' )
72 self->iFatType = FATVOL_TYPE_FAT16;
75 else if ( ubBuf[0x52] == 'F' && ubBuf[0x53] == 'A' && ubBuf[0x54] == 'T' && ubBuf[0x55] == '3' && ubBuf[0x56] == '2')
77 self->iFatType = FATVOL_TYPE_FAT32;
82 switch ( self->iFatType )
84 case FATVOL_TYPE_FAT12:
85 case FATVOL_TYPE_FAT16:
86 self->BytesPerSector = ubBuf[0x0b] + (ubBuf[0x0c] << 8); /**< セクタサイズ */
87 self->SectorsPerCluster = ubBuf[0x0d]; /**< 1クラスタのセクタ数 */
88 self->FatStartSector = ubBuf[0x0e] + (ubBuf[0x0f] << 8); /**< FATの開始セクタ番号 */
89 self->RootDirEntryNum = ubBuf[0x11] + (ubBuf[0x12] << 8); /**< ルートディレクトリ最大エントリ数 */
90 self->SectorNum = ubBuf[0x13] + (ubBuf[0x14] << 8); /**< 総セクタ数 */
91 self->SectorPerFat = ubBuf[0x16] + (ubBuf[0x17] << 8); /**< FATあたりのセクタ数 */
92 self->FatNum = ubBuf[0x10]; /**< FAT個数 */
93 self->RootDirSector = self->FatStartSector + (self->SectorPerFat * self->FatNum);
96 self->BytesPerCluster = self->BytesPerSector * self->SectorsPerCluster; /**< 1クラスタサイズ */
97 self->Cluster0Sector = self->RootDirSector
98 + (((self->RootDirEntryNum * 32) + self->BytesPerSector - 1) / self->BytesPerSector)
99 - (2 * self->SectorsPerCluster); /**< クラスタ0の開始セクタ */
100 self->ClusterNum = (self->SectorNum - self->Cluster0Sector) / self->SectorsPerCluster;
102 self->RootDirCluster = 0xf0000000;
105 self->pubFatBuf = (unsigned char *)SysMem_Alloc(self->SectorPerFat * self->BytesPerSector);
106 self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->SectorPerFat);
109 File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector + self->Offset, FILE_SEEK_SET);
110 File_Read(self->hBlockFile, self->pubFatBuf, self->SectorPerFat * self->BytesPerSector);
111 memset(self->pubFatDirty, 0, self->SectorPerFat);
115 case FATVOL_TYPE_FAT32:
116 self->BytesPerSector = ubBuf[0x0b] + (ubBuf[0x0c] << 8); /**< セクタサイズ */
117 self->SectorsPerCluster = ubBuf[0x0d]; /**< 1クラスタのセクタ数 */
118 self->FatStartSector = ubBuf[0x0e] + (ubBuf[0x0f] << 8); /**< FATの開始セクタ番号 */
119 self->RootDirEntryNum = ubBuf[0x11] + (ubBuf[0x12] << 8); /**< ルートディレクトリ最大エントリ数 */
120 /* self->SectorNum = ubBuf[0x13] + (ubBuf[0x14] << 8); */ /**< 総セクタ数 */
121 self->SectorNum = ubBuf[0x20] + (ubBuf[0x21] << 8) + (ubBuf[0x22] << 16) + (ubBuf[0x23] << 24);
122 self->SectorPerFat = ubBuf[0x24] + (ubBuf[0x25] << 8) + (ubBuf[0x26] << 16) + (ubBuf[0x27] << 24); /**< FATあたりのセクタ数 */
123 self->FatNum = ubBuf[0x10]; /**< FAT個数 */
124 self->RootDirSector = self->FatStartSector + (self->SectorPerFat * self->FatNum);
125 /**< ルートディレクトリ開始位置 */
127 self->BytesPerCluster = self->BytesPerSector * self->SectorsPerCluster; /**< 1クラスタサイズ */
128 self->Cluster0Sector = self->RootDirSector
129 + (((self->RootDirEntryNum * 32) + self->BytesPerSector - 1) / self->BytesPerSector)
130 - (2 * self->SectorsPerCluster); /**< クラスタ0の開始セクタ */
131 self->ClusterNum = (self->SectorNum - self->Cluster0Sector) / self->SectorsPerCluster;
133 self->RootDirCluster = ubBuf[0x2c] + (ubBuf[0x2d] << 8) + (ubBuf[0x2e] << 16) + (ubBuf[0x2f] << 24);
136 self->pubFatBuf = (unsigned char *)SysMem_Alloc(self->SectorPerFat * self->BytesPerSector);
137 self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->SectorPerFat);
140 File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector + self->Offset, FILE_SEEK_SET);
141 File_Read(self->hBlockFile, self->pubFatBuf, self->SectorPerFat * self->BytesPerSector);
142 memset(self->pubFatDirty, 0, self->SectorPerFat);
147 return FATVOL_ERR_NG;
151 self->iClusterBufNum = 8;
152 self->pClusterBuf = (T_FATVOL_CLUSTERBUF *)SysMem_Alloc(sizeof(T_FATVOL_CLUSTERBUF) * self->iClusterBufNum);
153 for ( i = 0; i < self->iClusterBufNum; i++ )
155 self->pClusterBuf[i].uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
156 self->pClusterBuf[i].iDirty = 0;
157 self->pClusterBuf[i].pubBuf = SysMem_Alloc(self->BytesPerCluster);
161 /* 親クラスコンストラクタ呼び出し */
162 VolumeObj_Constructor(&self->VolumeObj, pMethods);
165 self->hMtx = SysMtx_Create(SYSMTX_ATTR_NORMAL);
167 return FATVOL_ERR_OK;