OSDN Git Service

(none)
[hos/hos-v4a.git] / aplfw / driver / volume / fat / fatvol_constructor.c
1 /** 
2  *  Hyper Operating System  Application Framework
3  *
4  * @file  fatvol.h
5  * @brief %jp{FATボリューム用デバイスドライバ}
6  *
7  * Copyright (C) 2006-2007 by Project HOS
8  * http://sourceforge.jp/projects/hos/
9  */
10
11
12 #include <string.h>
13 #include "fatvol_local.h"
14
15
16
17 /* コンストラクタ */
18 FATVOL_ERR FatVol_Constructor(C_FATVOL *self, const T_VOLUMEOBJ_METHODS *pMethods, const char *pszPath)
19 {
20         unsigned char ubBuf[512];
21         int           i;
22                 
23         /* ブロックデバイスのオープン */
24         self->hBlockFile = File_Open(pszPath, FILE_OPEN_READ | FILE_OPEN_WRITE);
25         if ( self->hBlockFile == HANDLE_NULL )
26         {
27                 return FATVOL_ERR_NG;
28         }
29
30         self->Offset = 0;
31                 
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 )     /* シグネチャコードチェック */
36         {
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) */
44                 {
45                         self->Offset = ubBuf[0x1be + 0x08]
46                                                         + (ubBuf[0x1be + 0x09] << 8)
47                                                         + (ubBuf[0x1be + 0x0a] << 16)
48                                                         + (ubBuf[0x1be + 0x0b] << 24);
49                         self->Offset *= 512;
50                 }
51         }
52         
53         
54         /* サイズ取得 */
55         self->DriveSize  = File_Seek(self->hBlockFile, 0, FILE_SEEK_END);
56         self->iFatType   = FATVOL_TYPE_UNKNOWN;
57         
58         
59         /* BIOS Parameter Block */
60         File_Seek(self->hBlockFile, self->Offset, FILE_SEEK_SET);
61         File_Read(self->hBlockFile, ubBuf, 512);
62         
63         /* FAT12/16/32判定 */
64         if ( ubBuf[0x36] == 'F' && ubBuf[0x37] == 'A' && ubBuf[0x38] == 'T' && ubBuf[0x39] == '1' )
65         {
66                 if ( ubBuf[0x3a] == '2' )
67                 {
68                         self->iFatType = FATVOL_TYPE_FAT12;
69                 }
70                 else if ( ubBuf[0x3a] == '6' )
71                 {
72                         self->iFatType = FATVOL_TYPE_FAT16;
73                 }
74         }
75         else if ( ubBuf[0x52] == 'F' && ubBuf[0x53] == 'A' && ubBuf[0x54] == 'T' && ubBuf[0x55] == '3' && ubBuf[0x56] == '2')
76         {
77                 self->iFatType = FATVOL_TYPE_FAT32;
78         }
79         
80         
81         /* フォーマット別情報解析 */
82         switch ( self->iFatType )
83         {
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);
94                                                                                                                                                                         /**< ルートディレクトリ開始位置 */
95
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;
101                                                                                                                                                                         /**< 総クラスタ数 */
102                 self->RootDirCluster    = 0xf0000000;
103                 
104                 /* FATバッファ準備 */
105                 self->pubFatBuf   = (unsigned char *)SysMem_Alloc(self->SectorPerFat * self->BytesPerSector);
106                 self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->SectorPerFat);
107
108                 /* FAT読み出し */
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);
112                 
113                 break;
114
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                                                                                                                                                                         /**< ルートディレクトリ開始位置 */
126
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;
132                                                                                                                                                                         /**< 総クラスタ数 */
133                 self->RootDirCluster    = ubBuf[0x2c] + (ubBuf[0x2d] << 8) + (ubBuf[0x2e] << 16) + (ubBuf[0x2f] << 24);
134                 
135                 /* FATバッファ準備 */
136                 self->pubFatBuf   = (unsigned char *)SysMem_Alloc(self->SectorPerFat * self->BytesPerSector);
137                 self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->SectorPerFat);
138
139                 /* FAT読み出し */
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);
143
144                 break;
145         
146         default:
147                 return FATVOL_ERR_NG;
148         }
149         
150         /* クラスタバッファ取得 */
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++ )
154         {
155                 self->pClusterBuf[i].uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
156                 self->pClusterBuf[i].iDirty       = 0;
157                 self->pClusterBuf[i].pubBuf       = SysMem_Alloc(self->BytesPerCluster);
158         }
159         
160         
161         /* 親クラスコンストラクタ呼び出し */
162         VolumeObj_Constructor(&self->VolumeObj, pMethods);      
163         
164         /* ミューテックス生成 */
165         self->hMtx = SysMtx_Create(SYSMTX_ATTR_NORMAL);
166         
167         return FATVOL_ERR_OK;
168 }
169
170
171