diff options
Diffstat (limited to 'rbutil/ipodpatcher/ipodio-win32.c')
-rw-r--r-- | rbutil/ipodpatcher/ipodio-win32.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/rbutil/ipodpatcher/ipodio-win32.c b/rbutil/ipodpatcher/ipodio-win32.c new file mode 100644 index 0000000000..83f00b8cd9 --- /dev/null +++ b/rbutil/ipodpatcher/ipodio-win32.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006-2007 Dave Chapman | ||
11 | * | ||
12 | * error(), lock_volume() and unlock_volume() functions and inspiration taken | ||
13 | * from: | ||
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/ | ||
17 | * | ||
18 | * All files in this archive are subject to the GNU General Public License. | ||
19 | * See the file COPYING in the source tree root for full license agreement. | ||
20 | * | ||
21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
22 | * KIND, either express or implied. | ||
23 | * | ||
24 | ****************************************************************************/ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <unistd.h> | ||
28 | #include <fcntl.h> | ||
29 | #include <string.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <sys/types.h> | ||
32 | #include <sys/stat.h> | ||
33 | #ifdef __WIN32__ | ||
34 | #include <windows.h> | ||
35 | #include <winioctl.h> | ||
36 | #endif | ||
37 | |||
38 | #include "ipodio.h" | ||
39 | |||
40 | static int lock_volume(HANDLE hDisk) | ||
41 | { | ||
42 | DWORD dummy; | ||
43 | |||
44 | return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, | ||
45 | &dummy, NULL); | ||
46 | } | ||
47 | |||
48 | static int unlock_volume(HANDLE hDisk) | ||
49 | { | ||
50 | DWORD dummy; | ||
51 | |||
52 | return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, | ||
53 | &dummy, NULL); | ||
54 | } | ||
55 | |||
56 | void print_error(char* msg) | ||
57 | { | ||
58 | char* pMsgBuf; | ||
59 | |||
60 | printf(msg); | ||
61 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||
62 | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), | ||
63 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pMsgBuf, | ||
64 | 0, NULL); | ||
65 | printf(pMsgBuf); | ||
66 | LocalFree(pMsgBuf); | ||
67 | } | ||
68 | |||
69 | int ipod_open(struct ipod_t* ipod, int silent) | ||
70 | { | ||
71 | DISK_GEOMETRY_EX diskgeometry_ex; | ||
72 | DISK_GEOMETRY diskgeometry; | ||
73 | unsigned long n; | ||
74 | |||
75 | ipod->dh = CreateFile(ipod->diskname, GENERIC_READ, | ||
76 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | ||
77 | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); | ||
78 | |||
79 | if (ipod->dh == INVALID_HANDLE_VALUE) { | ||
80 | if (!silent) print_error(" Error opening disk: "); | ||
81 | return -1; | ||
82 | } | ||
83 | |||
84 | if (!lock_volume(ipod->dh)) { | ||
85 | if (!silent) print_error(" Error locking disk: "); | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | if (!DeviceIoControl(ipod->dh, | ||
90 | IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, | ||
91 | NULL, | ||
92 | 0, | ||
93 | &diskgeometry_ex, | ||
94 | sizeof(diskgeometry_ex), | ||
95 | &n, | ||
96 | NULL)) { | ||
97 | if (!DeviceIoControl(ipod->dh, | ||
98 | IOCTL_DISK_GET_DRIVE_GEOMETRY, | ||
99 | NULL, | ||
100 | 0, | ||
101 | &diskgeometry, | ||
102 | sizeof(diskgeometry), | ||
103 | &n, | ||
104 | NULL)) { | ||
105 | if (!silent) print_error(" Error reading disk geometry: "); | ||
106 | return -1; | ||
107 | } else { | ||
108 | ipod->sector_size=diskgeometry.BytesPerSector; | ||
109 | } | ||
110 | } else { | ||
111 | ipod->sector_size=diskgeometry_ex.Geometry.BytesPerSector; | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | int ipod_reopen_rw(struct ipod_t* ipod) | ||
118 | { | ||
119 | /* Close existing file and re-open for writing */ | ||
120 | unlock_volume(ipod->dh); | ||
121 | CloseHandle(ipod->dh); | ||
122 | |||
123 | ipod->dh = CreateFile(ipod->diskname, GENERIC_READ | GENERIC_WRITE, | ||
124 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | ||
125 | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); | ||
126 | |||
127 | if (ipod->dh == INVALID_HANDLE_VALUE) { | ||
128 | print_error(" Error opening disk: "); | ||
129 | return -1; | ||
130 | } | ||
131 | |||
132 | if (!lock_volume(ipod->dh)) { | ||
133 | print_error(" Error locking disk: "); | ||
134 | return -1; | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | int ipod_close(struct ipod_t* ipod) | ||
141 | { | ||
142 | unlock_volume(ipod->dh); | ||
143 | CloseHandle(ipod->dh); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize) | ||
148 | { | ||
149 | /* The ReadFile function requires a memory buffer aligned to a multiple of | ||
150 | the disk sector size. */ | ||
151 | *sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE); | ||
152 | if (*sectorbuf == NULL) { | ||
153 | print_error(" Error allocating a buffer: "); | ||
154 | return -1; | ||
155 | } | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int ipod_seek(struct ipod_t* ipod, unsigned long pos) | ||
160 | { | ||
161 | if (SetFilePointer(ipod->dh, pos, NULL, FILE_BEGIN)==0xffffffff) { | ||
162 | print_error(" Seek error "); | ||
163 | return -1; | ||
164 | } | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | int ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes) | ||
169 | { | ||
170 | unsigned long count; | ||
171 | |||
172 | if (!ReadFile(ipod->dh, buf, nbytes, &count, NULL)) { | ||
173 | print_error(" Error reading from disk: "); | ||
174 | return -1; | ||
175 | } | ||
176 | |||
177 | return count; | ||
178 | } | ||
179 | |||
180 | int ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes) | ||
181 | { | ||
182 | unsigned long count; | ||
183 | |||
184 | if (!WriteFile(ipod->dh, buf, nbytes, &count, NULL)) { | ||
185 | print_error(" Error writing to disk: "); | ||
186 | return -1; | ||
187 | } | ||
188 | |||
189 | return count; | ||
190 | } | ||