/[winpt]/trunk/Src/wptFileDisk.c
ViewVC logotype

Contents of /trunk/Src/wptFileDisk.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 9969 byte(s)
WinPT initial checkin.


1 /*
2 Control program for a virtual disk driver for Windows NT/2000/XP.
3 Copyright (C) 1999, 2000, 2001, 2002 Bo Brantén.
4
5 Heavily modified for the use with Cryptdisk by Timo Schulz
6 (C) 2004 Timo Schulz
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <windows.h>
22 #include <winioctl.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25
26 #include "openpgp.h"
27
28 /* remember to change the values in wptErrors.h also */
29 #define CDISK_ERR_LOCK 201
30 #define CDISK_ERR_MOUNT 202
31 #define CDISK_ERR_UMOUNT 203
32 #define CDISK_ERR_OPEN 204
33 #define CDISK_ERR_BUSY 205
34 #define CDISK_ERR_QUERY 206
35
36 #define MAX_KEYS 64
37 #define MAX_KEYHASH 32
38 #define MAX_KEY_LENGTH 50
39 #define CCVERSION 0x04
40
41 #define DEVICE_BASE_NAME "\\FileDisk"
42 #define DEVICE_DIR_NAME "\\Device" DEVICE_BASE_NAME
43 #define DEVICE_NAME_PREFIX DEVICE_DIR_NAME DEVICE_BASE_NAME
44
45 #define FILE_DEVICE_FILE_DISK 0x8000
46
47 #define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
48 #define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
49 #define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS)
50
51 typedef struct _OPEN_FILE_INFORMATION {
52 USHORT version;
53 LARGE_INTEGER FileSize;
54 BOOLEAN ReadOnly;
55 USHORT KeyType; //0 None 1 2Fish 2 AES256
56 USHORT KeyNum;
57 USHORT KeyLength;
58 USHORT FileNameLength;
59 UCHAR Key[MAX_KEYS][MAX_KEYHASH];
60 UCHAR DriveLetter;
61 UCHAR FileName[1];
62 } OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION;
63
64 static void
65 print_lasterr (char * prefix)
66 {
67 LPVOID msg;
68
69 FormatMessage(
70 FORMAT_MESSAGE_ALLOCATE_BUFFER |
71 FORMAT_MESSAGE_FROM_SYSTEM |
72 FORMAT_MESSAGE_IGNORE_INSERTS,
73 NULL,
74 GetLastError(),
75 0,
76 (LPTSTR) &msg,
77 0,
78 NULL
79 );
80 MessageBox (NULL, (LPTSTR)msg, prefix, MB_ICONERROR|MB_OK);
81 LocalFree (msg);
82 }
83
84
85 static void
86 add_key (POPEN_FILE_INFORMATION ka, const char * key, size_t len)
87 {
88 gpg_md_t md;
89
90 if (ka->KeyNum >= MAX_KEYS)
91 return;
92
93 switch (ka->KeyType) {
94 case 1: /* 2fish */
95 md = gpg_md_open (MD_RMD160);
96 ka->KeyLength=20;
97 break;
98 case 2: /* AES256 */
99 md = gpg_md_open (MD_SHA512);
100 ka->KeyLength=32;
101 break;
102 case 3: /* AES128 */
103 md = gpg_md_open (MD_SHA256);
104 ka->KeyLength=16;
105 break;
106 case 4: /* AES192 */
107 ka->KeyLength=24;
108 md = gpg_md_open (MD_SHA384);
109 break;
110 }
111 gpg_md_write (md, (char *)key, len);
112 gpg_md_final (md);
113 memcpy (ka->Key[ka->KeyNum++], gpg_md_read (md), ka->KeyLength);
114 gpg_md_close (md);
115 }
116
117
118 int
119 filedisk_mount (int DeviceNumber,
120 POPEN_FILE_INFORMATION ofi,
121 char drivelet,
122 BOOLEAN CdImage)
123 {
124 char VolumeName[] = "\\\\.\\ :";
125 char DeviceName[255];
126 HANDLE Device;
127 DWORD BytesReturned;
128
129 VolumeName[4] = drivelet;
130
131 Device = CreateFile (VolumeName,
132 GENERIC_READ | GENERIC_WRITE,
133 FILE_SHARE_READ | FILE_SHARE_WRITE,
134 NULL,
135 OPEN_EXISTING,
136 FILE_FLAG_NO_BUFFERING,
137 NULL);
138 if (Device != INVALID_HANDLE_VALUE) {
139 SetLastError (ERROR_BUSY);
140 print_lasterr (&VolumeName[4]);
141 return CDISK_ERR_BUSY;
142 }
143
144 if (CdImage)
145 sprintf (DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
146 else
147 sprintf (DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
148
149 if (!DefineDosDevice (DDD_RAW_TARGET_PATH,
150 &VolumeName[4],
151 DeviceName)) {
152 print_lasterr (&VolumeName[4]);
153 return CDISK_ERR_OPEN;
154 }
155
156 Device = CreateFile (VolumeName,
157 GENERIC_READ | GENERIC_WRITE,
158 FILE_SHARE_READ | FILE_SHARE_WRITE,
159 NULL,
160 OPEN_EXISTING,
161 FILE_FLAG_NO_BUFFERING,
162 NULL);
163
164 if (Device == INVALID_HANDLE_VALUE) {
165 print_lasterr (&VolumeName[4]);
166 DefineDosDevice (DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
167 return CDISK_ERR_OPEN;
168 }
169
170 if (!DeviceIoControl (Device,
171 IOCTL_FILE_DISK_OPEN_FILE,
172 ofi,
173 sizeof(OPEN_FILE_INFORMATION) + ofi->FileNameLength - 1,
174 NULL, 0, &BytesReturned, NULL)) {
175 print_lasterr ("Cryptdisk Error");
176 DefineDosDevice (DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
177 return CDISK_ERR_MOUNT;
178 }
179
180 return 0;
181 }
182
183
184 static int
185 filedisk_unmount2 (char drivelet, int flags, int forced)
186 {
187 char VolumeName[60] = "\\\\.\\ :";
188 HANDLE Device;
189 DWORD BytesReturned;
190
191 if (!flags)
192 VolumeName[4] = drivelet;
193 else if (flags & 1)
194 sprintf(VolumeName,"\\\\.\\FileDisk%d", drivelet);
195 else if (flags & 2)
196 sprintf(VolumeName,"\\\\.\\FileDiskCd%d",drivelet);
197
198 Device = CreateFile (VolumeName,
199 GENERIC_READ | GENERIC_WRITE,
200 FILE_SHARE_READ | FILE_SHARE_WRITE,
201 NULL,
202 OPEN_EXISTING,
203 FILE_FLAG_NO_BUFFERING,
204 NULL);
205 if (Device == INVALID_HANDLE_VALUE) {
206 if (forced)
207 print_lasterr(&VolumeName[4]);
208 return CDISK_ERR_OPEN;
209 }
210
211 if (!DeviceIoControl (Device,
212 FSCTL_LOCK_VOLUME,
213 NULL, 0, NULL, 0,
214 &BytesReturned, NULL)) {
215 if (forced) {
216 print_lasterr(&VolumeName[4]);
217 return CDISK_ERR_LOCK;
218 }
219 }
220
221 if (!DeviceIoControl (Device,
222 IOCTL_FILE_DISK_CLOSE_FILE,
223 NULL, 0, NULL, 0,
224 &BytesReturned, NULL )) {
225 if (forced)
226 print_lasterr ("Cryptdisk Error");
227 return CDISK_ERR_UMOUNT;
228 }
229
230 if (!DeviceIoControl (
231 Device, FSCTL_DISMOUNT_VOLUME,
232 NULL, 0, NULL, 0,
233 &BytesReturned, NULL)) {
234 if (forced)
235 print_lasterr (&VolumeName[4]);
236 return CDISK_ERR_UMOUNT;
237 }
238
239 if (!DeviceIoControl (Device,
240 FSCTL_UNLOCK_VOLUME,
241 NULL, 0, NULL, 0,
242 &BytesReturned, NULL)) {
243 if (forced) {
244 print_lasterr (&VolumeName[4]);
245 return CDISK_ERR_LOCK;
246 }
247 }
248
249 CloseHandle (Device);
250
251 if (!DefineDosDevice (
252 DDD_REMOVE_DEFINITION,
253 &VolumeName[4], NULL)) {
254 if (forced)
255 print_lasterr (&VolumeName[4]);
256 return CDISK_ERR_UMOUNT;
257 }
258
259 return 0;
260 }
261
262 int
263 filedisk_unmount (char drivelet, int forced)
264 {
265 char i;
266
267 if (drivelet) {
268 int rc = filedisk_unmount2 (drivelet, 0, forced);
269 if (rc)
270 print_lasterr ("Unmount´");
271 return rc;
272 }
273 for (i=0; i<20;i++) {
274 if (filedisk_unmount2 (i, 1, 0) == CDISK_ERR_OPEN)
275 break;
276 }
277 for (i=0; i<20;i++) {
278 if (filedisk_unmount2 (i, 2, 0) == CDISK_ERR_OPEN)
279 break;
280 }
281 return 0;
282 }
283
284
285 int
286 filedisk_status (char drivelet, LARGE_INTEGER * size, int * rdonly)
287 {
288 char VolumeName[] = "\\\\.\\ :";
289 HANDLE Device;
290 POPEN_FILE_INFORMATION ofi;
291 DWORD BytesReturned;
292
293 VolumeName[4] = drivelet;
294
295 Device = CreateFile (VolumeName,
296 GENERIC_READ,
297 FILE_SHARE_READ | FILE_SHARE_WRITE,
298 NULL,
299 OPEN_EXISTING,
300 FILE_FLAG_NO_BUFFERING,
301 NULL);
302
303 if (Device == INVALID_HANDLE_VALUE) {
304 print_lasterr(&VolumeName[4]);
305 return CDISK_ERR_OPEN;
306 }
307
308 ofi = malloc (sizeof(OPEN_FILE_INFORMATION) + MAX_PATH);
309
310 if (!DeviceIoControl (Device,
311 IOCTL_FILE_DISK_QUERY_FILE,
312 NULL,
313 0,
314 ofi,
315 sizeof(OPEN_FILE_INFORMATION) + MAX_PATH,
316 &BytesReturned, NULL)) {
317 print_lasterr (&VolumeName[4]);
318 return CDISK_ERR_QUERY;
319 }
320
321 if (BytesReturned < sizeof(OPEN_FILE_INFORMATION)) {
322 SetLastError (ERROR_INSUFFICIENT_BUFFER);
323 print_lasterr (&VolumeName[4]);
324 return CDISK_ERR_QUERY;
325 }
326
327 if (size)
328 *size = ofi->FileSize;
329 if (rdonly)
330 *rdonly = ofi->ReadOnly;
331
332 return 0;
333 }
334
335
336 POPEN_FILE_INFORMATION
337 filedisk_init_info (int devnum, char drivelet, const char * file,
338 int ro, int cd_img, unsigned long size, const char * key,
339 int keyalgo)
340 {
341 POPEN_FILE_INFORMATION pfi;
342
343 pfi = calloc (1, sizeof(OPEN_FILE_INFORMATION) + strlen (file) + 7);
344
345 pfi->version = CCVERSION;
346 if (file[0] == '\\') {
347 if (file[1] == '\\' && file[2] != '.') {
348 /* \\server\share\path\filedisk.img */
349 strcpy(pfi->FileName, "\\??\\UNC");
350 strcat(pfi->FileName, file + 1);
351 }
352 else /* \Device\Harddisk0\Partition1\path\filedisk.img */
353 strcpy(pfi->FileName, file);
354 }
355 else { // c:\path\filedisk.img
356 strcpy (pfi->FileName, "\\??\\");
357 strcat (pfi->FileName, file);
358 }
359
360 pfi->FileNameLength = (USHORT) strlen (pfi->FileName);
361 pfi->ReadOnly = ro? TRUE : FALSE;
362 if (cd_img)
363 pfi->ReadOnly = TRUE;
364 if (size)
365 pfi->FileSize.QuadPart = size * 1024;
366 if (key) {
367 if (keyalgo < 1 || keyalgo > 4)
368 pfi->KeyType = 1;
369 else
370 pfi->KeyType = keyalgo;
371 add_key (pfi, key, strlen (key));
372 }
373
374 return pfi;
375 }
376
377
378 void
379 filedisk_free_info (POPEN_FILE_INFORMATION pfi)
380 {
381 if (!pfi)
382 return;
383 free (pfi);
384 }
385

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26