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