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

Contents of /trunk/Src/wptCryptdiskSrv.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (show annotations)
Mon Oct 31 21:14:11 2005 UTC (19 years, 4 months ago) by werner
File size: 11175 byte(s)
More changes.  Compiles again but there are at least gettext issues with
w32-gettext.c.  I can't get a gpg-error build with ENABLE_NLS.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26