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

Annotation of /trunk/Src/wptCryptdiskSrv.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26