1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006-2007 Dave Chapman
12 * error(), lock_volume() and unlock_volume() functions and inspiration taken
14 * RawDisk - Direct Disk Read/Write Access for NT/2000/XP
15 * Copyright (c) 2003 Jan Kiszka
16 * http://www.stud.uni-hannover.de/user/73174/RawDisk/
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
35 #include <sys/types.h>
43 static int lock_volume(HANDLE hDisk
)
47 return DeviceIoControl(hDisk
, FSCTL_LOCK_VOLUME
, NULL
, 0, NULL
, 0,
51 static int unlock_volume(HANDLE hDisk
)
55 return DeviceIoControl(hDisk
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0,
59 void ipod_print_error(char* msg
)
64 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
|
65 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, GetLastError(),
66 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), pMsgBuf
,
72 int ipod_open(struct ipod_t
* ipod
, int silent
)
74 DISK_GEOMETRY_EX diskgeometry_ex
;
75 DISK_GEOMETRY diskgeometry
;
78 ipod
->dh
= CreateFileA(ipod
->diskname
, GENERIC_READ
,
79 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
80 FILE_FLAG_WRITE_THROUGH
| FILE_FLAG_NO_BUFFERING
, NULL
);
82 if (ipod
->dh
== INVALID_HANDLE_VALUE
) {
83 if (!silent
) ipod_print_error(" Error opening disk: ");
84 if(GetLastError() == ERROR_ACCESS_DENIED
)
90 if (!lock_volume(ipod
->dh
)) {
91 if (!silent
) ipod_print_error(" Error locking disk: ");
97 ipod
->sectors_per_track
= 0;
99 if (!DeviceIoControl(ipod
->dh
,
100 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
,
104 sizeof(diskgeometry_ex
),
107 if (!DeviceIoControl(ipod
->dh
,
108 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
112 sizeof(diskgeometry
),
115 if (!silent
) ipod_print_error(" Error reading disk geometry: ");
118 ipod
->sector_size
= diskgeometry
.BytesPerSector
;
119 ipod
->num_heads
= diskgeometry
.TracksPerCylinder
;
120 ipod
->sectors_per_track
= diskgeometry
.SectorsPerTrack
;
123 ipod
->sector_size
= diskgeometry_ex
.Geometry
.BytesPerSector
;
124 ipod
->num_heads
= diskgeometry_ex
.Geometry
.TracksPerCylinder
;
125 ipod
->sectors_per_track
= diskgeometry_ex
.Geometry
.SectorsPerTrack
;
131 int ipod_reopen_rw(struct ipod_t
* ipod
)
133 /* Close existing file and re-open for writing */
134 unlock_volume(ipod
->dh
);
135 CloseHandle(ipod
->dh
);
137 ipod
->dh
= CreateFileA(ipod
->diskname
, GENERIC_READ
| GENERIC_WRITE
,
138 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
139 FILE_FLAG_WRITE_THROUGH
| FILE_FLAG_NO_BUFFERING
, NULL
);
141 if (ipod
->dh
== INVALID_HANDLE_VALUE
) {
142 ipod_print_error(" Error opening disk: ");
146 if (!lock_volume(ipod
->dh
)) {
147 ipod_print_error(" Error locking disk: ");
154 int ipod_close(struct ipod_t
* ipod
)
156 unlock_volume(ipod
->dh
);
157 CloseHandle(ipod
->dh
);
161 int ipod_alloc_buffer(struct ipod_t
* ipod
, int bufsize
)
163 /* The ReadFile function requires a memory buffer aligned to a multiple of
164 the disk sector size. */
165 ipod
->sectorbuf
= (unsigned char*)VirtualAlloc(NULL
, bufsize
, MEM_COMMIT
, PAGE_READWRITE
);
166 if (ipod
->sectorbuf
== NULL
) {
167 ipod_print_error(" Error allocating a buffer: ");
173 int ipod_dealloc_buffer(struct ipod_t
* ipod
)
175 if (ipod
->sectorbuf
== NULL
) {
178 if(!VirtualFree(ipod
->sectorbuf
, 0, MEM_RELEASE
)) {
179 ipod_print_error(" Error releasing buffer ");
182 ipod
->sectorbuf
= NULL
;
186 int ipod_seek(struct ipod_t
* ipod
, unsigned long pos
)
188 if (SetFilePointer(ipod
->dh
, pos
, NULL
, FILE_BEGIN
)==0xffffffff) {
189 ipod_print_error(" Seek error ");
195 ssize_t
ipod_read(struct ipod_t
* ipod
, int nbytes
)
199 if(ipod
->sectorbuf
== NULL
) {
202 if (!ReadFile(ipod
->dh
, ipod
->sectorbuf
, nbytes
, &count
, NULL
)) {
203 ipod_print_error(" Error reading from disk: ");
210 ssize_t
ipod_write(struct ipod_t
* ipod
, int nbytes
)
214 if(ipod
->sectorbuf
== NULL
) {
217 if (!WriteFile(ipod
->dh
, ipod
->sectorbuf
, nbytes
, &count
, NULL
)) {
218 ipod_print_error(" Error writing to disk: ");