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

Annotation of /trunk/Src/wptFileDisk.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide 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 twoaday 2 /*
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