OSDN Git Service

(none)
[hos/hos-v4a.git] / aplfw / volume / fat / fatvol_create.c
1
2 #include <string.h>
3 #include "fatvol_local.h"
4
5
6 int FatVol_Create(C_FATVOL *self, HANDLE hBlockFile)
7 {
8         unsigned char ubBuf[512];
9         int           i;
10         
11         /* ドライブの設定 */
12         self->hBlockFile = hBlockFile;
13         self->uiOffset   = 0x33*512;
14         
15         /* サイズ取得 */
16         self->uiDriveSize = File_Seek(self->hBlockFile, FILE_SEEK_END, 0);
17         self->iFatType    = FATVOL_TYPE_UNKNOWN;
18         
19         /* BIOS Parameter Block */
20         File_Seek(self->hBlockFile, self->uiOffset, FILE_SEEK_SET);
21         File_Read(self->hBlockFile, ubBuf, 512);
22         
23         /* FAT12/16/32判定 */
24         if ( ubBuf[0x36] == 'F' && ubBuf[0x37] == 'A' && ubBuf[0x38] == 'T' && ubBuf[0x39] == '1' )
25         {
26                 if ( ubBuf[0x3a] == '2' )
27                 {
28                         self->iFatType = FATVOL_TYPE_FAT12;
29                 }
30                 else if ( ubBuf[0x3a] == '6' )
31                 {
32                         self->iFatType = FATVOL_TYPE_FAT16;
33                 }
34         }
35         else if ( ubBuf[0x52] == 'F' && ubBuf[0x53] == 'A' && ubBuf[0x54] == 'T' && ubBuf[0x55] == '3' && ubBuf[0x56] == '2')
36         {
37                 self->iFatType = FATVOL_TYPE_FAT32;
38         }
39         
40         /* フォーマット別情報解析 */
41         switch ( self->iFatType )
42         {
43         case FATVOL_TYPE_FAT12:
44         case FATVOL_TYPE_FAT16:
45                 self->uiBytesPerSector    = ubBuf[0x0b] + ubBuf[0x0c] * 256;            /**< セクタサイズ */
46                 self->uiSectorsPerCluster = ubBuf[0x0d];                                                        /**< 1クラスタのセクタ数 */
47                 self->uiRootDirEntryNum   = ubBuf[0x11] + ubBuf[0x12] * 256;            /**< ルートディレクトリ最大エントリ数 */
48                 self->uiFatStartSector    = ubBuf[0x0e] + ubBuf[0x0f] * 256;            /**< FATの開始セクタ番号 */
49                 self->uiSectorPerFat      = ubBuf[0x16] + ubBuf[0x17] * 256;            /**< FATあたりのセクタ数 */
50                 self->uiFatNum            = ubBuf[0x10];                                                        /**< FAT個数 */
51                 self->uiRootDirSector     = self->uiFatStartSector + (self->uiSectorPerFat * self->uiFatNum);
52                                                                                                                                                         /**< ルートディレクトリ開始位置 */
53                 self->uiCluster0Sector    = self->uiRootDirSector
54                                                                                 + (((self->uiRootDirEntryNum * 32) + self->uiBytesPerSector - 1) / self->uiBytesPerSector)
55                                                                                 - (2 * self->uiSectorsPerCluster);      /**< クラスタ0の開始セクタ */
56                                 
57                 /* FATバッファ準備 */
58                 self->pubFatBuf   = (unsigned char *)SysMem_Alloc(self->uiSectorPerFat * self->uiBytesPerSector);
59                 self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->uiSectorPerFat);
60
61                 /* FATバッファ準備 */
62                 File_Seek(self->hBlockFile, self->uiFatStartSector * self->uiBytesPerSector, FILE_SEEK_SET);
63                 File_Read(self->hBlockFile, self->pubFatBuf, self->uiSectorPerFat * self->uiBytesPerSector);
64                 memset(self->pubFatDirty, 0, self->uiSectorPerFat);
65
66                 break;
67
68         case FATVOL_TYPE_FAT32:
69                 break;
70         
71         default:
72                 return FATVOL_ERR_NG;
73         }
74         
75         /* 最大クラスタ番号算出 */
76         switch ( self->iFatType )
77         {
78         case FATVOL_TYPE_FAT12:
79                 self->uiMaxClusterNum = (self->uiSectorPerFat * self->uiBytesPerSector) / 3 * 2;
80                 if ( self->uiMaxClusterNum >= 0x0ff7 )
81                 {
82                         self->uiMaxClusterNum = 0x0ff6;
83                 }
84                 break;
85
86         case FATVOL_TYPE_FAT16:
87                 self->uiMaxClusterNum = (self->uiSectorPerFat * self->uiBytesPerSector) / 2;
88                 if ( self->uiMaxClusterNum >= 0xfff7 )
89                 {
90                         self->uiMaxClusterNum = 0xfff6;
91                 }
92                 break;
93
94         case FATVOL_TYPE_FAT32:
95                 self->uiMaxClusterNum = (self->uiSectorPerFat * self->uiBytesPerSector) / 4;
96                 break;
97         }
98         
99         /* クラスタバッファ取得 */
100         self->iClusterBufIndex = 0;
101         self->iClusterBufNum   = 32;
102         self->pClusterBuf = (T_FATVOL_CLUSTERBUF *)SysMem_Alloc(sizeof(T_FATVOL_CLUSTERBUF) * self->iClusterBufNum);
103         for ( i = 0; i < self->iClusterBufNum; i++ )
104         {
105                 self->pClusterBuf[i].uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
106                 self->pClusterBuf[i].iDirty       = 0;
107                 self->pClusterBuf[i].pubBuf       = SysMem_Alloc(self->uiSectorsPerCluster * self->uiBytesPerSector);
108         }
109         
110         return FATVOL_ERR_OK;
111 }
112
113
114