/[winpt]/trunk/Src/wptCryptdiskSrv.cpp
ViewVC logotype

Annotation of /trunk/Src/wptCryptdiskSrv.cpp

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 size: 11586 byte(s)
WinPT initial checkin.


1 twoaday 2 /* wptCryptdiskSrv.cpp - Server application for Cryptdisk
2     *
3     * Control program for a virtual disk driver for Windows NT/2000/XP.
4     * Copyright (C) 1999, 2000, 2001, 2002 Bo Brantén.
5     *
6     * Heavily modified for the use with Cryptdisk by Timo Schulz
7     * (C) 2004 Timo Schulz
8    
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21    
22     #include <windows.h>
23     #include <winioctl.h>
24     #include <stdio.h>
25     #include <sys/types.h>
26    
27     #define PGM_NAME "CryptdiskSrv"
28    
29     /* remember to change the values in wptErrors.h also */
30     #define CDISK_ERR_LOCK 201
31     #define CDISK_ERR_MOUNT 202
32     #define CDISK_ERR_UMOUNT 203
33     #define CDISK_ERR_OPEN 204
34     #define CDISK_ERR_BUSY 205
35     #define CDISK_ERR_QUERY 206
36    
37     #define DEVICE_BASE_NAME "\\FileDisk"
38     #define DEVICE_DIR_NAME "\\Device" DEVICE_BASE_NAME
39     #define DEVICE_NAME_PREFIX DEVICE_DIR_NAME DEVICE_BASE_NAME
40    
41     #define FILE_DEVICE_FILE_DISK 0x8000
42    
43     #define IOCTL_FILE_DISK_OPEN_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
44     #define IOCTL_FILE_DISK_CLOSE_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
45     #define IOCTL_FILE_DISK_QUERY_FILE CTL_CODE(FILE_DEVICE_FILE_DISK, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS)
46    
47     enum cmd_t {
48     CMD_MOUNT =0,
49     CMD_NEW =1,
50     CMD_UMOUNT =2,
51     CMD_UMOUNT2 =3,
52     };
53    
54     struct private_ofi_s {
55     INT forced;
56     INT cmd;
57     INT devnum;
58     CHAR drvlet;
59     LARGE_INTEGER filesize;
60     BOOLEAN readonly;
61     USHORT flen;
62     UCHAR fname[MAX_PATH+1];
63     };
64    
65    
66     typedef struct _OPEN_FILE_INFORMATION {
67     LARGE_INTEGER FileSize;
68     BOOLEAN ReadOnly;
69     USHORT FileNameLength;
70     UCHAR FileName[1];
71     } OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION;
72    
73    
74     static struct private_ofi_s ofi;
75     static HANDLE wait_ev = NULL;
76    
77     static void
78     print_lasterr (char * prefix)
79     {
80     LPVOID msg;
81    
82     FormatMessage(
83     FORMAT_MESSAGE_ALLOCATE_BUFFER |
84     FORMAT_MESSAGE_FROM_SYSTEM |
85     FORMAT_MESSAGE_IGNORE_INSERTS,
86     NULL,
87     GetLastError(),
88     0,
89     (LPTSTR) &msg,
90     0,
91     NULL
92     );
93     MessageBox (NULL, (LPTSTR)msg, prefix, MB_ICONERROR|MB_OK);
94     LocalFree (msg);
95     }
96    
97    
98     int
99     filedisk_mount (int DeviceNumber,
100     POPEN_FILE_INFORMATION ofi,
101     char drivelet,
102     BOOLEAN CdImage)
103     {
104     char VolumeName[] = "\\\\.\\ :";
105     char DeviceName[255];
106     HANDLE Device;
107     DWORD BytesReturned;
108    
109     VolumeName[4] = drivelet;
110    
111     Device = CreateFile (VolumeName,
112     GENERIC_READ | GENERIC_WRITE,
113     FILE_SHARE_READ | FILE_SHARE_WRITE,
114     NULL,
115     OPEN_EXISTING,
116     FILE_FLAG_NO_BUFFERING,
117     NULL);
118     if (Device != INVALID_HANDLE_VALUE) {
119     SetLastError (ERROR_BUSY);
120     print_lasterr (&VolumeName[4]);
121     return CDISK_ERR_BUSY;
122     }
123    
124     if (CdImage)
125     sprintf (DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
126     else
127     sprintf (DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
128    
129     if (!DefineDosDevice (DDD_RAW_TARGET_PATH,
130     &VolumeName[4],
131     DeviceName)) {
132     print_lasterr (&VolumeName[4]);
133     return CDISK_ERR_OPEN;
134     }
135    
136     Device = CreateFile (VolumeName,
137     GENERIC_READ | GENERIC_WRITE,
138     FILE_SHARE_READ | FILE_SHARE_WRITE,
139     NULL,
140     OPEN_EXISTING,
141     FILE_FLAG_NO_BUFFERING,
142     NULL);
143    
144     if (Device == INVALID_HANDLE_VALUE) {
145     print_lasterr (&VolumeName[4]);
146     DefineDosDevice (DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
147     return CDISK_ERR_OPEN;
148     }
149    
150     if (!DeviceIoControl (Device,
151     IOCTL_FILE_DISK_OPEN_FILE,
152     ofi,
153     sizeof(OPEN_FILE_INFORMATION) + ofi->FileNameLength - 1,
154     NULL, 0, &BytesReturned, NULL)) {
155     print_lasterr ("Cryptdisk Error");
156     DefineDosDevice (DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
157     return CDISK_ERR_MOUNT;
158     }
159    
160     return 0;
161     }
162    
163    
164     static int
165     filedisk_unmount2 (char drivelet, int flags, int forced)
166     {
167     char VolumeName[60] = "\\\\.\\ :";
168     HANDLE Device;
169     DWORD BytesReturned;
170    
171     if (!flags)
172     VolumeName[4] = drivelet;
173     else if (flags & 1)
174     sprintf(VolumeName,"\\\\.\\FileDisk%d", drivelet);
175     else if (flags & 2)
176     sprintf(VolumeName,"\\\\.\\FileDiskCd%d",drivelet);
177    
178     Device = CreateFile (VolumeName,
179     GENERIC_READ | GENERIC_WRITE,
180     FILE_SHARE_READ | FILE_SHARE_WRITE,
181     NULL,
182     OPEN_EXISTING,
183     FILE_FLAG_NO_BUFFERING,
184     NULL);
185     if (Device == INVALID_HANDLE_VALUE) {
186     if (forced)
187     print_lasterr(&VolumeName[4]);
188     return CDISK_ERR_OPEN;
189     }
190    
191     if (!DeviceIoControl (Device,
192     FSCTL_LOCK_VOLUME,
193     NULL, 0, NULL, 0,
194     &BytesReturned, NULL)) {
195     if (forced) {
196     print_lasterr(&VolumeName[4]);
197     return CDISK_ERR_LOCK;
198     }
199     }
200    
201     if (!DeviceIoControl (Device,
202     IOCTL_FILE_DISK_CLOSE_FILE,
203     NULL, 0, NULL, 0,
204     &BytesReturned, NULL )) {
205     if (forced)
206     print_lasterr ("Cryptdisk Error");
207     return CDISK_ERR_UMOUNT;
208     }
209    
210     if (!DeviceIoControl (
211     Device, FSCTL_DISMOUNT_VOLUME,
212     NULL, 0, NULL, 0,
213     &BytesReturned, NULL)) {
214     if (forced)
215     print_lasterr (&VolumeName[4]);
216     return CDISK_ERR_UMOUNT;
217     }
218    
219     if (!DeviceIoControl (Device,
220     FSCTL_UNLOCK_VOLUME,
221     NULL, 0, NULL, 0,
222     &BytesReturned, NULL)) {
223     if (forced) {
224     print_lasterr (&VolumeName[4]);
225     return CDISK_ERR_LOCK;
226     }
227     }
228    
229     CloseHandle (Device);
230    
231     if (!DefineDosDevice (
232     DDD_REMOVE_DEFINITION,
233     &VolumeName[4], NULL)) {
234     if (forced)
235     print_lasterr (&VolumeName[4]);
236     return CDISK_ERR_UMOUNT;
237     }
238    
239     return 0;
240     }
241    
242     int
243     filedisk_unmount (char drivelet, int forced)
244     {
245     char i;
246    
247     if (drivelet) {
248     int rc = filedisk_unmount2 (drivelet, 0, forced);
249     if (rc)
250     print_lasterr ("Unmount");
251     return rc;
252     }
253     for (i=0; i<20;i++) {
254     if (filedisk_unmount2 (i, 1, 0) == CDISK_ERR_OPEN)
255     break;
256     }
257     for (i=0; i<20;i++) {
258     if (filedisk_unmount2 (i, 2, 0) == CDISK_ERR_OPEN)
259     break;
260     }
261     return 0;
262     }
263    
264    
265     int
266     filedisk_status (char drivelet, LARGE_INTEGER * size, int * rdonly)
267     {
268     char VolumeName[] = "\\\\.\\ :";
269     HANDLE Device;
270     POPEN_FILE_INFORMATION ofi;
271     DWORD BytesReturned;
272    
273     VolumeName[4] = drivelet;
274    
275     Device = CreateFile (VolumeName,
276     GENERIC_READ,
277     FILE_SHARE_READ | FILE_SHARE_WRITE,
278     NULL,
279     OPEN_EXISTING,
280     FILE_FLAG_NO_BUFFERING,
281     NULL);
282    
283     if (Device == INVALID_HANDLE_VALUE) {
284     print_lasterr(&VolumeName[4]);
285     return CDISK_ERR_OPEN;
286     }
287    
288     ofi = (POPEN_FILE_INFORMATION)malloc (sizeof(OPEN_FILE_INFORMATION) + MAX_PATH);
289    
290     if (!DeviceIoControl (Device,
291     IOCTL_FILE_DISK_QUERY_FILE,
292     NULL,
293     0,
294     ofi,
295     sizeof(OPEN_FILE_INFORMATION) + MAX_PATH,
296     &BytesReturned, NULL)) {
297     print_lasterr (&VolumeName[4]);
298     return CDISK_ERR_QUERY;
299     }
300    
301     if (BytesReturned < sizeof(OPEN_FILE_INFORMATION)) {
302     SetLastError (ERROR_INSUFFICIENT_BUFFER);
303     print_lasterr (&VolumeName[4]);
304     return CDISK_ERR_QUERY;
305     }
306    
307     if (size)
308     *size = ofi->FileSize;
309     if (rdonly)
310     *rdonly = ofi->ReadOnly;
311    
312     return 0;
313     }
314    
315    
316     POPEN_FILE_INFORMATION
317     filedisk_init_info (int devnum, char drivelet, const char * file,
318     int ro, int cd_img, unsigned long size)
319     {
320     POPEN_FILE_INFORMATION pfi;
321     char * p;
322    
323     pfi = (POPEN_FILE_INFORMATION)
324     calloc (1, sizeof(OPEN_FILE_INFORMATION) + strlen (file) + 7);
325     p = (char *)pfi->FileName;
326    
327     if (file[0] == '\\') {
328     if (file[1] == '\\' && file[2] != '.') {
329     /* \\server\share\path\filedisk.img */
330     strcpy(p, "\\??\\UNC");
331     strcat(p, file + 1);
332     }
333     else /* \Device\Harddisk0\Partition1\path\filedisk.img */
334     strcpy(p, file);
335     }
336     else { // c:\path\filedisk.img
337     strcpy (p, "\\??\\");
338     strcat (p, file);
339     }
340    
341     pfi->FileNameLength = (USHORT) strlen (p);
342     pfi->ReadOnly = ro? TRUE : FALSE;
343     if (cd_img)
344     pfi->ReadOnly = TRUE;
345     if (size)
346     pfi->FileSize.QuadPart = size * 1024;
347     return pfi;
348     }
349    
350    
351     void
352     filedisk_free_info (POPEN_FILE_INFORMATION pfi)
353     {
354     if (!pfi)
355     return;
356     free (pfi);
357     }
358    
359    
360     LRESULT CALLBACK
361     def_window_proc (HWND hwnd, UINT msg, WPARAM w, LPARAM l)
362     {
363     COPYDATASTRUCT * cds;
364    
365     switch (msg) {
366     case WM_DESTROY:
367     PostQuitMessage (0);
368     break;
369    
370     case WM_COPYDATA:
371     cds = (COPYDATASTRUCT *)l;
372     if (!cds || cds->cbData == 0)
373     break;
374     memcpy ((private_ofi_s *)&ofi, cds->lpData, cds->cbData);
375     DestroyWindow (hwnd);
376     break;
377     }
378     return DefWindowProc (hwnd, msg, w, l);
379     }
380    
381    
382     int WINAPI
383     WinMain (HINSTANCE h, HINSTANCE hp, LPSTR cl, int show)
384     {
385     POPEN_FILE_INFORMATION pfi;
386     WNDCLASS wc = {0, def_window_proc, 0, 0, h, 0, 0, 0, 0, PGM_NAME};
387     HWND hwnd;
388     MSG msg;
389     int rc;
390    
391     wait_ev = CreateEvent (NULL, FALSE, FALSE, "cryptdisksrv.wait");
392     if (!wait_ev) {
393     MessageBox (NULL, "Could not create wait event.", "CryptdiskSrv",
394     MB_ICONERROR|MB_OK);
395     return 0;
396     }
397    
398     rc = RegisterClass (&wc);
399     if (rc == FALSE) {
400     MessageBox (NULL, "Could not register window class", "CryptdiskSrv",
401     MB_ICONERROR|MB_OK);
402     CloseHandle (wait_ev);
403     return 0;
404     }
405    
406     hwnd = CreateWindow (PGM_NAME,
407     PGM_NAME,
408     0, 0, 0, 0, 0,
409     NULL,
410     NULL,
411     h,
412     NULL);
413     if (hwnd == NULL) {
414     MessageBox (NULL, "Could not create window", "CryptdiskSrv",
415     MB_ICONERROR|MB_OK);
416     CloseHandle (wait_ev);
417     return 0;
418     }
419    
420     UpdateWindow (hwnd);
421     while (GetMessage (&msg, hwnd, 0, 0)) {
422     TranslateMessage (&msg);
423     DispatchMessage (&msg);
424     }
425    
426     {
427     FILE * logf;
428    
429     logf = fopen ("cryptdisk.log", "a+b");
430     if (logf) {
431     fprintf (logf, "cmd=%d devnum=%d drive=%c name=%s len=%d size=%d forced=%d\r\n",
432     ofi.cmd, ofi.devnum, ofi.drvlet, ofi.fname, ofi.flen,
433     ofi.filesize, ofi.forced);
434     fclose (logf);
435     }
436     }
437    
438     SetEvent (wait_ev);
439     switch (ofi.cmd) {
440     case CMD_NEW:
441     case CMD_MOUNT:
442     pfi = filedisk_init_info (ofi.devnum, ofi.drvlet,
443     (const char *)ofi.fname,
444     0, 0, ofi.filesize.LowPart);
445     rc = filedisk_mount (ofi.devnum, pfi, ofi.drvlet, FALSE);
446     filedisk_free_info (pfi);
447     break;
448    
449     case CMD_UMOUNT:
450     rc = filedisk_unmount (ofi.drvlet, ofi.forced);
451     break;
452    
453     case CMD_UMOUNT2:
454     rc = filedisk_unmount (0, 0);
455     break;
456     }
457     ResetEvent (wait_ev);
458     CloseHandle (wait_ev);
459     return rc;
460     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26