[FATTEN]
[reactos.git] / reactos / tools / fatten / fatfs / diskio.c
1 /*-----------------------------------------------------------------------*/
2 /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */
3 /*-----------------------------------------------------------------------*/
4 /* If a working storage control module is available, it should be */
5 /* attached to the FatFs via a glue function rather than modifying it. */
6 /* This is an example of glue functions to attach various exsisting */
7 /* storage control module to the FatFs module with a defined API. */
8 /*-----------------------------------------------------------------------*/
9 #include "diskio.h"
10 #include <stdio.h>
11
12 /*-----------------------------------------------------------------------*/
13 /* Correspondence between physical drive number and image file handles. */
14
15 UINT sectorCount[1] = { 0 };
16 FILE* driveHandle[1] = { NULL };
17 const int driveHandleCount = sizeof(driveHandle) / sizeof(FILE*);
18
19 /*-----------------------------------------------------------------------*/
20 /* Open an image file a Drive */
21 /*-----------------------------------------------------------------------*/
22
23 DSTATUS disk_openimage(BYTE pdrv, const char* imageFileName)
24 {
25 if (pdrv < driveHandleCount)
26 {
27 if (driveHandle[0] != NULL)
28 return 0;
29
30 driveHandle[0] = fopen(imageFileName, "r+b");
31 if (!driveHandle[0])
32 {
33 driveHandle[0] = fopen(imageFileName, "w+");
34 }
35
36 if (driveHandle[0] != NULL)
37 return 0;
38 }
39 return STA_NOINIT;
40 }
41
42
43 /*-----------------------------------------------------------------------*/
44 /* Cleanup a Drive */
45 /*-----------------------------------------------------------------------*/
46
47 VOID disk_cleanup(
48 BYTE pdrv /* Physical drive nmuber (0..) */
49 )
50 {
51 if (pdrv < driveHandleCount)
52 {
53 if (driveHandle[pdrv] != NULL)
54 {
55 fclose(driveHandle[pdrv]);
56 driveHandle[pdrv] = NULL;
57 }
58 }
59 }
60
61 /*-----------------------------------------------------------------------*/
62 /* Inidialize a Drive */
63 /*-----------------------------------------------------------------------*/
64
65 DSTATUS disk_initialize(
66 BYTE pdrv /* Physical drive nmuber (0..) */
67 )
68 {
69 if (pdrv == 0) /* only one drive (image file) supported atm. */
70 {
71 return 0;
72 }
73 return STA_NOINIT;
74 }
75
76
77
78 /*-----------------------------------------------------------------------*/
79 /* Get Disk Status */
80 /*-----------------------------------------------------------------------*/
81
82 DSTATUS disk_status(
83 BYTE pdrv /* Physical drive nmuber (0..) */
84 )
85 {
86 if (pdrv < driveHandleCount)
87 {
88 if (driveHandle[pdrv] != NULL)
89 return 0;
90 }
91 return STA_NOINIT;
92 }
93
94 /*-----------------------------------------------------------------------*/
95 /* Read Sector(s) */
96 /*-----------------------------------------------------------------------*/
97
98 DRESULT disk_read(
99 BYTE pdrv, /* Physical drive nmuber (0..) */
100 BYTE *buff, /* Data buffer to store read data */
101 DWORD sector, /* Sector address (LBA) */
102 UINT count /* Number of sectors to read (1..128) */
103 )
104 {
105 DWORD result;
106
107 if (pdrv < driveHandleCount)
108 {
109 if (driveHandle[pdrv] != NULL)
110 {
111 if (fseek(driveHandle[pdrv], sector * 512, SEEK_SET))
112 return RES_ERROR;
113
114 result = fread(buff, 512, count, driveHandle[pdrv]);
115
116 if (result != count)
117 return RES_ERROR;
118
119 return RES_OK;
120 }
121 }
122
123 return RES_PARERR;
124 }
125
126
127
128 /*-----------------------------------------------------------------------*/
129 /* Write Sector(s) */
130 /*-----------------------------------------------------------------------*/
131
132 #if _USE_WRITE
133 DRESULT disk_write(
134 BYTE pdrv, /* Physical drive nmuber (0..) */
135 const BYTE *buff, /* Data to be written */
136 DWORD sector, /* Sector address (LBA) */
137 UINT count /* Number of sectors to write (1..128) */
138 )
139 {
140 DWORD result;
141
142 if (pdrv < driveHandleCount)
143 {
144 if (driveHandle[pdrv] != NULL)
145 {
146 if (fseek(driveHandle[pdrv], sector * 512, SEEK_SET))
147 return RES_ERROR;
148
149 result = fwrite(buff, 512, count, driveHandle[pdrv]);
150
151 if (result != count)
152 return RES_ERROR;
153
154 return RES_OK;
155 }
156 }
157
158 return RES_PARERR;
159 }
160 #endif
161
162
163 /*-----------------------------------------------------------------------*/
164 /* Miscellaneous Functions */
165 /*-----------------------------------------------------------------------*/
166
167 #if _USE_IOCTL
168 DRESULT disk_ioctl(
169 BYTE pdrv, /* Physical drive nmuber (0..) */
170 BYTE cmd, /* Control code */
171 void *buff /* Buffer to send/receive control data */
172 )
173 {
174 if (pdrv < driveHandleCount)
175 {
176 if (driveHandle[pdrv] != NULL)
177 {
178 switch (cmd)
179 {
180 case CTRL_SYNC:
181 fflush(driveHandle[pdrv]);
182 return RES_OK;
183 case GET_SECTOR_SIZE:
184 *(DWORD*)buff = 512;
185 return RES_OK;
186 case GET_BLOCK_SIZE:
187 *(DWORD*)buff = 512;
188 return RES_OK;
189 case GET_SECTOR_COUNT:
190 {
191 if (sectorCount[pdrv] <= 0)
192 {
193 if (fseek(driveHandle[pdrv], 0, SEEK_END))
194 printf("fseek failed!\n");
195 else
196 sectorCount[pdrv] = ftell(driveHandle[pdrv]) / 512;
197 }
198
199 *(DWORD*)buff = sectorCount[pdrv];
200 return RES_OK;
201 }
202 case SET_SECTOR_COUNT:
203 {
204 int count = *(DWORD*)buff;
205 long size;
206
207 sectorCount[pdrv] = count;
208
209 fseek(driveHandle[pdrv], 0, SEEK_END);
210 size = ftell(driveHandle[pdrv]) / 512;
211
212 if (size < count)
213 {
214 if (fseek(driveHandle[pdrv], count * 512 - 1, SEEK_SET))
215 return RES_ERROR;
216
217 fwrite(buff, 1, 1, driveHandle[pdrv]);
218
219 return RES_OK;
220 }
221 else
222 {
223 // SHRINKING NOT IMPLEMENTED
224 return RES_OK;
225 }
226 }
227 }
228 }
229 }
230
231 return RES_PARERR;
232 }
233 #endif