source: uKadecot/trunk/tools/makefsdata/diskio.c@ 108

Last change on this file since 108 was 108, checked in by coas-nagasima, 9 years ago

MIMEプロパティの変更

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr; charset=SHIFT_JIS
File size: 9.6 KB
Line 
1/*-----------------------------------------------------------------------*/
2/* Low level disk control module for Win32 (C)ChaN, 2013 */
3/*-----------------------------------------------------------------------*/
4
5#include <windows.h>
6#include <tchar.h>
7#include <winioctl.h>
8#include <stdio.h>
9#include "diskio.h"
10#include "ff.h"
11
12
13#define MAX_DRIVES 1 /* Max number of physical drives to be used */
14
15#define SZ_RAMDISK 768 /* Size of RAM disk [kB] */
16#define SS_RAMDISK 512 /* Sector size of RAM disk [byte] */
17
18
19/*--------------------------------------------------------------------------
20
21 Module Private Functions
22
23---------------------------------------------------------------------------*/
24
25#define BUFSIZE 262144UL /* Size of data transfer buffer */
26
27typedef struct {
28 DSTATUS status;
29 WORD sz_sector;
30 DWORD n_sectors;
31 HANDLE h_drive;
32} STAT;
33
34static HANDLE hMutex, hTmrThread;
35static int Drives;
36
37static volatile STAT Stat[MAX_DRIVES];
38
39
40static DWORD TmrThreadID;
41
42static BYTE *Buffer, *RamDisk; /* Poiter to the data transfer buffer and ramdisk */
43
44
45/*-----------------------------------------------------------------------*/
46/* Timer Functions */
47/*-----------------------------------------------------------------------*/
48
49
50DWORD WINAPI tmr_thread (LPVOID parms)
51{
52 DWORD dw;
53 int drv;
54
55
56 for (;;) {
57 Sleep(100);
58 for (drv = 1; drv < Drives; drv++) {
59 Sleep(1);
60 if (Stat[drv].h_drive == INVALID_HANDLE_VALUE || Stat[drv].status & STA_NOINIT || WaitForSingleObject(hMutex, 100) != WAIT_OBJECT_0) continue;
61
62 if (!DeviceIoControl(Stat[drv].h_drive, IOCTL_STORAGE_CHECK_VERIFY, 0, 0, 0, 0, &dw, 0))
63 Stat[drv].status |= STA_NOINIT;
64 ReleaseMutex(hMutex);
65 Sleep(100);
66 }
67 }
68}
69
70
71
72int get_status (
73 BYTE pdrv
74)
75{
76 volatile STAT *stat = &Stat[pdrv];
77 HANDLE h = stat->h_drive;
78 DISK_GEOMETRY parms;
79 DWORD dw;
80
81
82 if (pdrv == 0) { /* RAMDISK */
83 stat->sz_sector = SS_RAMDISK;
84 if (stat->sz_sector < _MIN_SS || stat->sz_sector > _MAX_SS) return 0;
85 stat->n_sectors = SZ_RAMDISK * 1024 / SS_RAMDISK;
86 stat->status = 0;
87 return 1;
88 }
89
90 /* Get physical drive parameters */
91 if ( !DeviceIoControl(h, IOCTL_STORAGE_CHECK_VERIFY, 0, 0, 0, 0, &dw, 0)
92 || !DeviceIoControl(h, IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, &parms, sizeof parms, &dw, 0)) {
93 stat->status = STA_NOINIT;
94 return 0;
95 }
96
97 stat->sz_sector = (WORD)parms.BytesPerSector;
98 if (stat->sz_sector < _MIN_SS || stat->sz_sector > _MAX_SS) return 0;
99 stat->n_sectors = parms.SectorsPerTrack * parms.TracksPerCylinder * (DWORD)parms.Cylinders.QuadPart; //(DWORD)(part.PartitionLength.QuadPart / parms.BytesPerSector);
100 stat->status = DeviceIoControl(h, IOCTL_DISK_IS_WRITABLE, 0, 0, 0, 0, &dw, 0) ? 0 : STA_PROTECT;
101
102 return 1;
103}
104
105
106
107
108/*--------------------------------------------------------------------------
109
110 Public Functions
111
112---------------------------------------------------------------------------*/
113
114
115/*-----------------------------------------------------------------------*/
116/* Initialize Windows disk accesss layer */
117/*-----------------------------------------------------------------------*/
118
119int assign_drives (void)
120{
121 BYTE pdrv, ndrv;
122 TCHAR str[30];
123 HANDLE h;
124 OSVERSIONINFO vinfo = { sizeof (OSVERSIONINFO) };
125
126
127 hMutex = CreateMutex(0, 0, 0);
128 if (hMutex == INVALID_HANDLE_VALUE) return 0;
129
130 Buffer = VirtualAlloc(0, BUFSIZE, MEM_COMMIT, PAGE_READWRITE);
131 if (!Buffer) return 0;
132
133 RamDisk = VirtualAlloc(0, SZ_RAMDISK * 1024, MEM_COMMIT, PAGE_READWRITE);
134 if (!RamDisk) return 0;
135
136 //if (GetVersionEx(&vinfo) == FALSE) return 0;
137 //ndrv = vinfo.dwMajorVersion > 5 ? 1 : MAX_DRIVES;
138 ndrv = 1;
139
140 for (pdrv = 0; pdrv < ndrv; pdrv++) {
141 if (pdrv) { /* \\.\PhysicalDrive1 and later are mapped to disk funtion. */
142 _stprintf_s(str, sizeof(str), _T("\\\\.\\PhysicalDrive%u"), pdrv);
143 h = CreateFile(str, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
144 if (h == INVALID_HANDLE_VALUE) break;
145 Stat[pdrv].h_drive = h;
146 } else { /* \\.\PhysicalDrive0 is not mapped to disk function and map a RAM disk instead. */
147 _stprintf_s(str, sizeof(str), _T("RAM Disk"));
148 }
149 _tprintf(_T("PD#%u <== %s"), pdrv, str);
150 if (get_status(pdrv))
151 _tprintf(_T(" (%uMB, %u bytes * %u sectors)\n"), (UINT)((LONGLONG)Stat[pdrv].sz_sector * Stat[pdrv].n_sectors / 1024 / 1024), Stat[pdrv].sz_sector, Stat[pdrv].n_sectors);
152 else
153 _tprintf(_T(" (Not Ready)\n"));
154 }
155
156 hTmrThread = CreateThread(0, 0, tmr_thread, 0, 0, &TmrThreadID);
157 if (hTmrThread == INVALID_HANDLE_VALUE) pdrv = 0;
158
159 if (ndrv > 1) {
160 if (pdrv == 1)
161 _tprintf(_T("\nYou must run the program as Administrator to access the physical drives.\n"));
162 } else {
163 _tprintf(_T("\nOn the Windows Vista and later, you cannot access the physical drives.\n")
164 _T("Use Windows NT/2k/XP instead.\n"));
165 }
166
167 Drives = pdrv;
168 return pdrv;
169}
170
171
172
173
174
175/*-----------------------------------------------------------------------*/
176/* Initialize Disk Drive */
177/*-----------------------------------------------------------------------*/
178
179DSTATUS disk_initialize (
180 BYTE pdrv /* Physical drive nmuber */
181)
182{
183 DSTATUS sta;
184
185
186 if (WaitForSingleObject(hMutex, 5000) != WAIT_OBJECT_0)
187 return STA_NOINIT;
188
189 if (pdrv >= Drives) {
190 sta = STA_NOINIT;
191 } else {
192 get_status(pdrv);
193 sta = Stat[pdrv].status;
194 }
195
196 ReleaseMutex(hMutex);
197 return sta;
198}
199
200
201
202/*-----------------------------------------------------------------------*/
203/* Get Disk Status */
204/*-----------------------------------------------------------------------*/
205
206DSTATUS disk_status (
207 BYTE pdrv /* Physical drive nmuber (0) */
208)
209{
210 DSTATUS sta;
211
212
213 if (pdrv >= Drives) {
214 sta = STA_NOINIT;
215 } else {
216 sta = Stat[pdrv].status;
217 }
218
219 return sta;
220}
221
222
223
224/*-----------------------------------------------------------------------*/
225/* Read Sector(s) */
226/*-----------------------------------------------------------------------*/
227
228DRESULT disk_read (
229 BYTE pdrv, /* Physical drive nmuber (0) */
230 BYTE *buff, /* Pointer to the data buffer to store read data */
231 DWORD sector, /* Start sector number (LBA) */
232 UINT count /* Number of sectors to read */
233)
234{
235 DWORD nc, rnc;
236 LARGE_INTEGER ofs;
237 DSTATUS res;
238
239
240 if (pdrv >= Drives || Stat[pdrv].status & STA_NOINIT || WaitForSingleObject(hMutex, 3000) != WAIT_OBJECT_0)
241 return RES_NOTRDY;
242
243 nc = (DWORD)count * Stat[pdrv].sz_sector;
244 ofs.QuadPart = (LONGLONG)sector * Stat[pdrv].sz_sector;
245 if (pdrv) {
246 if (nc > BUFSIZE) {
247 res = RES_PARERR;
248 } else {
249 if (SetFilePointer(Stat[pdrv].h_drive, ofs.LowPart, &ofs.HighPart, FILE_BEGIN) != ofs.LowPart) {
250 res = RES_ERROR;
251 } else {
252 if (!ReadFile(Stat[pdrv].h_drive, Buffer, nc, &rnc, 0) || nc != rnc) {
253 res = RES_ERROR;
254 } else {
255 memcpy(buff, Buffer, nc);
256 res = RES_OK;
257 }
258 }
259 }
260 } else {
261 memcpy(buff, RamDisk + ofs.LowPart, nc);
262 res = RES_OK;
263 }
264
265 ReleaseMutex(hMutex);
266 return res;
267}
268
269
270
271/*-----------------------------------------------------------------------*/
272/* Write Sector(s) */
273/*-----------------------------------------------------------------------*/
274
275DRESULT disk_write (
276 BYTE pdrv, /* Physical drive nmuber (0) */
277 const BYTE *buff, /* Pointer to the data to be written */
278 DWORD sector, /* Start sector number (LBA) */
279 UINT count /* Number of sectors to write */
280)
281{
282 DWORD nc, rnc;
283 LARGE_INTEGER ofs;
284 DRESULT res;
285
286
287 if (pdrv >= Drives || Stat[pdrv].status & STA_NOINIT || WaitForSingleObject(hMutex, 3000) != WAIT_OBJECT_0)
288 return RES_NOTRDY;
289
290 res = RES_OK;
291 if (Stat[pdrv].status & STA_PROTECT) {
292 res = RES_WRPRT;
293 } else {
294 nc = (DWORD)count * Stat[pdrv].sz_sector;
295 if (nc > BUFSIZE)
296 res = RES_PARERR;
297 }
298
299 ofs.QuadPart = (LONGLONG)sector * Stat[pdrv].sz_sector;
300 if (pdrv) {
301 if (res == RES_OK) {
302 if (SetFilePointer(Stat[pdrv].h_drive, ofs.LowPart, &ofs.HighPart, FILE_BEGIN) != ofs.LowPart) {
303 res = RES_ERROR;
304 } else {
305 memcpy(Buffer, buff, nc);
306 if (!WriteFile(Stat[pdrv].h_drive, Buffer, nc, &rnc, 0) || nc != rnc)
307 res = RES_ERROR;
308 }
309 }
310 } else {
311 memcpy(RamDisk + ofs.LowPart, buff, nc);
312 res = RES_OK;
313 }
314
315 ReleaseMutex(hMutex);
316 return res;
317}
318
319
320
321/*-----------------------------------------------------------------------*/
322/* Miscellaneous Functions */
323/*-----------------------------------------------------------------------*/
324
325DRESULT disk_ioctl (
326 BYTE pdrv, /* Physical drive nmuber (0) */
327 BYTE ctrl, /* Control code */
328 void *buff /* Buffer to send/receive data block */
329)
330{
331 DRESULT res = RES_PARERR;
332
333
334 if (pdrv >= Drives || (Stat[pdrv].status & STA_NOINIT))
335 return RES_NOTRDY;
336
337 switch (ctrl) {
338 case CTRL_SYNC:
339 res = RES_OK;
340 break;
341
342 case GET_SECTOR_COUNT:
343 *(DWORD*)buff = Stat[pdrv].n_sectors;
344 res = RES_OK;
345 break;
346
347 case GET_SECTOR_SIZE:
348 *(WORD*)buff = Stat[pdrv].sz_sector;
349 res = RES_OK;
350 break;
351
352 case GET_BLOCK_SIZE:
353 *(DWORD*)buff = 128;
354 res = RES_OK;
355 break;
356
357 case 200:
358 {
359 HANDLE h;
360 DWORD br;
361
362 h = CreateFile((TCHAR*)buff, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
363 if (!pdrv && h != INVALID_HANDLE_VALUE) {
364 if (ReadFile(h, RamDisk, SZ_RAMDISK * 1024, &br, 0))
365 res = RES_OK;
366 CloseHandle(h);
367 }
368 }
369 break;
370
371 case 201:
372 {
373 HANDLE h;
374 DWORD br;
375
376 h = CreateFile((TCHAR*)buff, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
377 if(!pdrv && h != INVALID_HANDLE_VALUE) {
378 if (WriteFile(h, RamDisk, SZ_RAMDISK * 1024, &br, 0))
379 res = RES_OK;
380 CloseHandle(h);
381 }
382 }
383 break;
384
385 }
386
387 return res;
388}
389
390
391
Note: See TracBrowser for help on using the repository browser.