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

Annotation of /trunk/Src/wptCryptdisk.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (hide annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 15905 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


1 werner 36 /* wptCryptdisk.cpp
2 twoaday 185 * Copyright (C) 2004, 2006 Timo Schulz
3 werner 36 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20     #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23    
24 twoaday 185 #if 0 /* disabled until the code really works on all systems. */
25 werner 36 #include <windows.h>
26     #include <winioctl.h>
27     #include <stdio.h>
28     #include <ctype.h>
29    
30 werner 47 #include "resource.h"
31 werner 36 #include "wptCryptdisk.h"
32     #include "wptTypes.h"
33     #include "wptW32API.h"
34     #include "wptNLS.h"
35     #include "wptErrors.h"
36    
37     /*DWORD SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options);*/
38     typedef DWORD (WINAPI *sh_format_drive_p) (HWND, UINT, UINT, UINT);
39    
40     static mount_list_t mounted=NULL;
41     static HMODULE shell32=NULL;
42     static sh_format_drive_p shfmt=NULL;
43    
44    
45     static int
46     is_nt4 (void)
47     {
48     static int nt_flag = -1;
49     OSVERSIONINFO osinf;
50    
51     if (nt_flag != -1)
52     return nt_flag;
53    
54     memset (&osinf, 0, sizeof osinf);
55     osinf.dwOSVersionInfoSize = sizeof osinf;
56     GetVersionEx (&osinf);
57     if (osinf.dwPlatformId == VER_PLATFORM_WIN32_NT) {
58     nt_flag = 1;
59     shell32 = LoadLibrary ("SHELL32.DLL");
60     shfmt = (sh_format_drive_p)GetProcAddress (shell32, "SHFormatDrive");
61     if (!shfmt)
62     BUG (0);
63     }
64     else
65     nt_flag = 0;
66     return nt_flag;
67     }
68    
69     static int
70     check_filedisk (void)
71     {
72     HKEY hk;
73     int rc = -1;
74    
75     rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
76     "SYSTEM\\CurrentControlSet\\Services\\FileDisk",
77     0, KEY_READ, &hk);
78     if (rc == ERROR_SUCCESS) {
79     RegCloseKey (hk);
80     rc = 0;
81     }
82     return rc;
83     }
84    
85    
86     int
87     cryptdisk_available (void)
88     {
89     return (is_nt4 () == 1 && check_filedisk () == 0)? 1 : 0;
90     }
91    
92    
93     void
94     cryptdisk_cleanup (void)
95     {
96     if (shell32)
97     FreeLibrary (shell32);
98     shell32 = NULL;
99     }
100    
101    
102     static int
103     num_of_devices (void)
104     {
105     HKEY hk;
106     BYTE buf[32];
107     DWORD n=0, type=0;
108     int rc;
109    
110     rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
111     "SYSTEM\\CurrentControlSet\\Services\\FileDisk\\Parameters",
112     0, KEY_READ, &hk);
113     if (rc != ERROR_SUCCESS)
114     return -1;
115    
116     n = sizeof buf-1;
117     memset (buf, 0, sizeof buf);
118     rc = RegQueryValueEx (hk, "NumberOfDevices", 0, &type, buf, &n);
119     if (rc != ERROR_SUCCESS || type != REG_DWORD)
120     n=0;
121     else
122     n = *buf;
123     RegCloseKey (hk);
124     return n;
125     }
126    
127    
128     static HWND
129     start_cryptdisk_server (HANDLE * r_proc)
130     {
131     STARTUPINFO si;
132     PROCESS_INFORMATION pi;
133    
134     memset (&si, 0, sizeof si);
135     memset (&pi, 0, sizeof pi);
136     si.cb = sizeof si;
137    
138     if (CreateProcess (NULL, "CryptdiskSrv", NULL, NULL, FALSE, 0,
139     NULL, NULL, &si, &pi) == FALSE) {
140     msg_box (NULL, _("Could not execute Cryptdisk Server."),
141     _("Cryptdisk Error"), MB_ERR);
142     return NULL;
143     }
144     *r_proc = pi.hProcess;
145     Sleep (300);
146     return FindWindow ("CryptdiskSrv", NULL);
147     }
148    
149    
150     static int
151     cryptdisk_mount (int devnum,
152     const char * imgfile,
153 twoaday 193 DWORD size,
154 werner 36 const char * hdlet)
155     {
156     HWND h;
157     HANDLE proc, wait_ev;
158     COPYDATASTRUCT cds;
159     struct private_ofi_s ofi;
160    
161     h = start_cryptdisk_server (&proc);
162     if (!h)
163     return WPTERR_GENERAL;
164     memset (&ofi, 0, sizeof ofi);
165     ofi.cmd = CMD_MOUNT;
166     ofi.devnum = devnum;
167     ofi.filesize.LowPart = size;
168     ofi.drvlet = *hdlet;
169     ofi.readonly = 0;
170     strcpy ((char *)ofi.fname, imgfile);
171     ofi.flen = strlen (imgfile);
172    
173     wait_ev = OpenEvent (SYNCHRONIZE, FALSE, "cryptdisksrv.wait");
174     if (!wait_ev)
175     BUG (0);
176     memset (&cds, 0, sizeof cds);
177     cds.cbData = sizeof ofi;
178     cds.lpData = &ofi;
179     SendMessage (h, WM_COPYDATA, (WPARAM)GetDesktopWindow (), (LPARAM)&cds);
180     WaitForSingleObject (wait_ev, INFINITE);
181     CloseHandle (wait_ev);
182     CloseHandle (proc);
183     return 0;
184     }
185    
186    
187    
188     int
189     cryptdisk_unmount (char drivelet, int forced)
190     {
191     HWND h;
192     HANDLE proc;
193     COPYDATASTRUCT cds;
194     struct private_ofi_s ofi;
195    
196     h = start_cryptdisk_server (&proc);
197     if (!h)
198     return WPTERR_GENERAL;
199    
200     memset (&ofi, 0, sizeof ofi);
201     ofi.cmd = CMD_UMOUNT;
202     ofi.drvlet = drivelet;
203     ofi.forced = forced;
204    
205     memset (&cds, 0, sizeof cds);
206     cds.lpData = &ofi;
207     cds.cbData = sizeof ofi;
208     SendMessage (h, WM_COPYDATA, (WPARAM)GetDesktopWindow (), (LPARAM)&cds);
209     CloseHandle (proc);
210    
211     return 0;
212     }
213    
214     static void
215     print_lasterr (char * prefix)
216     {
217     LPVOID msg;
218    
219     FormatMessage(
220     FORMAT_MESSAGE_ALLOCATE_BUFFER |
221     FORMAT_MESSAGE_FROM_SYSTEM |
222     FORMAT_MESSAGE_IGNORE_INSERTS,
223     NULL,
224     GetLastError(),
225     0,
226     (LPTSTR) &msg,
227     0,
228     NULL
229     );
230     MessageBox (NULL, (LPTSTR)msg, prefix, MB_ICONERROR|MB_OK);
231     LocalFree (msg);
232     }
233    
234    
235     static int
236     filedisk_status (char drivelet, LARGE_INTEGER * size, int * rdonly)
237     {
238     char VolumeName[] = "\\\\.\\ :";
239     HANDLE Device;
240     POPEN_FILE_INFORMATION ofi;
241     DWORD BytesReturned;
242     int n= sizeof (OPEN_FILE_INFORMATION)+ MAX_PATH;
243    
244     VolumeName[4] = drivelet;
245    
246     Device = CreateFile (VolumeName,
247     GENERIC_READ,
248     FILE_SHARE_READ | FILE_SHARE_WRITE,
249     NULL,
250     OPEN_EXISTING,
251     FILE_FLAG_NO_BUFFERING,
252     NULL);
253    
254     if (Device == INVALID_HANDLE_VALUE) {
255     print_lasterr(&VolumeName[4]);
256     return WPTERR_CDISK_OPEN;
257     }
258    
259     ofi = (POPEN_FILE_INFORMATION)malloc (n);
260    
261     if (!DeviceIoControl (Device,
262     IOCTL_FILE_DISK_QUERY_FILE,
263     NULL,
264     0,
265     ofi,
266     sizeof(OPEN_FILE_INFORMATION) + MAX_PATH,
267     &BytesReturned, NULL)) {
268     print_lasterr (&VolumeName[4]);
269     return WPTERR_CDISK_QUERY;
270     }
271    
272     if (BytesReturned < sizeof(OPEN_FILE_INFORMATION)) {
273     SetLastError (ERROR_INSUFFICIENT_BUFFER);
274     print_lasterr (&VolumeName[4]);
275     return WPTERR_CDISK_QUERY;
276     }
277    
278     if (size)
279     *size = ofi->FileSize;
280     if (rdonly)
281     *rdonly = ofi->ReadOnly;
282    
283     return 0;
284     }
285    
286    
287     static mount_list_t
288     new_mount_list (const char * drive, int devnum)
289     {
290     mount_list_t n;
291    
292     n = (mount_list_t)calloc (1, sizeof *n);
293     if (n) {
294     strcpy (n->drive, drive);
295     n->devnum = devnum;
296     n->ttl = 1;
297     filedisk_status (*drive, &n->size, &n->rdonly);
298     }
299     return n;
300     }
301    
302    
303     static mount_list_t
304     find_mount_list (mount_list_t root, const char * drive)
305     {
306     mount_list_t n;
307    
308     for (n=root; n; n=n->next) {
309     if (n->ttl == 0)
310     continue;
311     if (!strncmp (n->drive, drive, strlen (drive)))
312     return n;
313     }
314     return NULL;
315     }
316    
317    
318     static void
319     add_mount_list (mount_list_t root, mount_list_t node)
320     {
321     mount_list_t n;
322    
323     if (find_mount_list (root, node->drive))
324     return;
325    
326     for (n=root; n->next; n=n->next)
327     ;
328     n->next = node;
329     }
330    
331    
332     static void
333     remove_mount_list (mount_list_t root, mount_list_t node)
334     {
335     mount_list_t n;
336    
337     n = find_mount_list (root, node->drive);
338     if (n)
339     n->ttl = 0;
340     }
341    
342    
343     static void
344     free_mount_list (mount_list_t root)
345     {
346     mount_list_t n;
347    
348     while (root) {
349     n = root->next;
350     free (root);
351     root = n;
352     }
353     }
354    
355    
356     static int
357     last_devnum (mount_list_t root)
358     {
359     mount_list_t n;
360     int devnum=0;
361    
362     if (!root)
363     return 0;
364    
365     for (n=root; n; n=n->next) {
366     if (devnum < n->devnum)
367     devnum=n->devnum;
368     }
369     return devnum+1;
370     }
371    
372    
373     static char
374     init_drives (HWND dlg, int ctlid)
375     {
376     char buf[512], drv[5];
377     DWORD n=0, i=0;
378    
379     n=GetLogicalDriveStrings (sizeof buf-1, buf);
380     for (i=0; i < n; i++) {
381     memcpy (drv, buf+i, 3); drv[3]=0;
382     i += 3;
383     }
384     if (!dlg && ctlid == -1)
385     return ++drv[0];
386    
387     for (++drv[0]; drv[0] < 'Z'; drv[0]++)
388     SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
389     (LPARAM)(const char *)drv);
390     SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, 0, 0);
391     return 0;
392     }
393    
394    
395     static int
396 twoaday 193 check_freespace (const char * imgfile, DWORD size)
397 werner 36 {
398     ULARGE_INTEGER tocaller, total, totfree;
399     char buf[128] = {0};
400    
401     if (!strchr (imgfile, ':'))
402     GetCurrentDirectory (sizeof buf-1, buf);
403     else
404     strncpy (buf, imgfile, sizeof buf-1);
405     buf[3] = '\0';
406     GetDiskFreeSpaceEx (buf, &tocaller, &total, &totfree);
407     if (size > tocaller.LowPart)
408     return -1;
409     return 0;
410     }
411    
412    
413     static void
414     do_check (HWND dlg)
415     {
416     if (!cryptdisk_serv_run ()) { /* xxx */
417     msg_box (dlg, _("The Cryptdisk service seems to be available but "
418     "it is not started yet.\nPlease start the service "
419     "and try again."), _("Cryptdisk Error"), MB_ERR);
420     EndDialog (dlg, TRUE);
421     }
422     }
423    
424    
425     BOOL CALLBACK
426     cryptdisk_new_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
427     {
428     const char * ciphers [] = {
429     "twofish",
430     NULL
431     };
432     const char * s;
433     char imgfile[128], key[128], drv[3];
434     int i;
435 twoaday 193 DWORD size=0;
436 werner 36
437     switch (msg) {
438     case WM_INITDIALOG:
439     do_check (dlg);
440     SetDlgItemInt (dlg, IDC_CDNEW_SIZE, DISK_DEFSIZE, FALSE);
441     for (i=0; (s=ciphers[i]); i++)
442     SendDlgItemMessage (dlg, IDC_CDNEW_CIPHERS, CB_ADDSTRING,
443     0, (LPARAM)(const char *) s);
444     SendDlgItemMessage (dlg, IDC_CDNEW_CIPHERS, CB_SETCURSEL, 0, 0);
445     center_window (dlg, NULL);
446     SetForegroundWindow (dlg);
447     break;
448    
449     case WM_COMMAND:
450     switch (LOWORD (wparam)) {
451     case IDOK:
452     i = GetDlgItemText (dlg, IDC_CDNEW_IMGFILE, imgfile, sizeof imgfile-1);
453     if (!i) {
454     msg_box (dlg, _("Please enter a name for the image file."),
455     _("Cryptdisk"), MB_ERR);
456     return FALSE;
457     }
458     if (file_exist_check (imgfile) == 0) {
459     i = msg_box (dlg, _("This volume file already exists.\n"
460     "Do you want to overwrite it?"),
461     _("Cryptdisk Warning"), MB_YESNO|MB_WARN);
462     if (i == IDNO)
463     return FALSE;
464     }
465     for (i=0; i < (int)strlen (imgfile); i++)
466     imgfile[i] = toupper (imgfile[i]);
467     size = GetDlgItemInt (dlg, IDC_CDNEW_SIZE, NULL, FALSE);
468     if (!size) {
469     msg_box (dlg, _("Please enter the size for the volume"),
470     _("Cryptdisk"), MB_INFO);
471     return FALSE;
472     }
473     size *= 1024; /*KB*/
474     if (check_freespace (imgfile, (size*1024))) {
475     msg_box (dlg, _("There is not enough free disk space to "
476     "store the volume."), _("Cryptdisk"), MB_ERR);
477     return FALSE;
478     }
479     i = GetDlgItemText (dlg, IDC_CDNEW_PASS, key, sizeof key-1);
480     if (!i) {
481     msg_box (dlg, _("Please enter a passphrase for the volume."),
482     _("Cryptdisk"), MB_ERR);
483     return FALSE;
484     }
485     strcpy (drv, "?:\\");
486     drv[0] = init_drives (NULL, -1);
487     i = cryptdisk_mount (last_devnum (mounted), imgfile, size, drv);
488     if (!i)
489     shfmt (dlg, drv[0] - 65, 0, 0);
490     break;
491     case IDCANCEL:
492     EndDialog (dlg, FALSE);
493     break;
494     }
495     break;
496    
497     }
498    
499     return FALSE;
500     }
501    
502    
503     BOOL CALLBACK
504     cryptdisk_mount_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
505     {
506     const char * s_imgfile;
507     char buf[8], drive[8], passwd[64], imgfile[128];
508     int n, i, devnum=0;
509     int rc;
510    
511     switch (msg) {
512     case WM_INITDIALOG:
513     do_check (dlg);
514     s_imgfile = (const char *)lparam;
515     if (s_imgfile)
516     SetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, s_imgfile);
517     init_drives (dlg, IDC_CDMOUNT_DRV);
518     n = num_of_devices ();
519     if (n == -1) {
520     msg_box (dlg, _("Cannot determine the number of drives."),
521     _("Cryptdisk Error"), MB_ERR);
522     EndDialog (dlg, FALSE);
523     }
524     for (i=last_devnum (mounted); i < n; i++) {
525     sprintf (buf, "%d", i);
526     SendDlgItemMessage (dlg, IDC_CDMOUNT_ID, CB_ADDSTRING, 0,
527     (LPARAM)(const char *)buf);
528     }
529     SendDlgItemMessage (dlg, IDC_CDMOUNT_ID, CB_SETCURSEL, 0, 0);
530     center_window (dlg, NULL);
531     SetForegroundWindow (dlg);
532     break;
533    
534     case WM_COMMAND:
535     switch (LOWORD (wparam)) {
536     case IDC_CDMOUNT_SELFILE:
537     s_imgfile = get_fileopen_dlg (dlg, _("Select Crypdisk Volume"),
538     NULL, NULL);
539     if (s_imgfile != NULL)
540     SetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, s_imgfile);
541     break;
542    
543     case IDOK:
544     n = item_get_text_length (dlg, IDC_CDMOUNT_IMGFILE);
545     if (!n) {
546     msg_box (dlg, _("Please enter the name of the image file."),
547     _("Cryptdisk Error"), MB_ERR);
548     return FALSE;
549     }
550     n = item_get_text_length (dlg, IDC_CDMOUNT_PASS);
551     if (!n) {
552     msg_box (dlg, _("Please enter a password."),
553     _("Cryptdisk Error"), MB_ERR);
554     return FALSE;
555     }
556     devnum = GetDlgItemInt (dlg, IDC_CDMOUNT_ID, NULL, FALSE);
557     GetDlgItemText (dlg, IDC_CDMOUNT_DRV, drive, sizeof drive-1);
558     GetDlgItemText (dlg, IDC_CDMOUNT_PASS, passwd, sizeof passwd-1);
559     GetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, imgfile, sizeof imgfile-1);
560     if (file_exist_check (imgfile)) {
561     msg_box (dlg, _("Image file does not exist or could not be accessed."),
562     _("Cryptdisk Error"), MB_ERR);
563     return FALSE;
564     }
565     rc = cryptdisk_mount (devnum, imgfile, 0, drive);
566     if (!rc) {
567 twoaday 77 mount_list_t t = new_mount_list (drive, devnum);
568 werner 36 if (!mounted)
569 twoaday 77 mounted = t;
570 werner 36 else
571 twoaday 77 add_mount_list (mounted, t);
572 werner 36 EndDialog (dlg, TRUE);
573     }
574     else
575     msg_box (dlg, winpt_strerror (rc), _("Cryptdisk Error"), MB_ERR);
576     break;
577    
578     case IDCANCEL:
579     EndDialog (dlg, FALSE);
580     break;
581     }
582     break;
583     }
584     return FALSE;
585     }
586    
587    
588     static void
589     load_devs_from_mountlist (HWND dlg, int ctlid)
590     {
591     mount_list_t n;
592     char buf[128];
593    
594     if (!mounted)
595     return;
596    
597     for (n=mounted; n; n=n->next) {
598     if (n->ttl == 0)
599     continue;
600     _snprintf (buf, sizeof buf-1, _("Drive %s (ID %d); Size %d MB, Readonly=%s"),
601     n->drive, n->devnum, n->size.LowPart/1024/1024,
602     n->rdonly? "true" : "false");
603     SendDlgItemMessage (dlg, ctlid, LB_ADDSTRING, 0, (LPARAM)(const char *)buf);
604     }
605    
606     }
607    
608    
609     static void
610     do_reaping (void)
611     {
612     mount_list_t n;
613     int ndevs=0, numount=0;
614    
615     for (n=mounted; n; n=n->next) {
616     if (n->ttl == 0)
617     numount++;
618     ndevs++;
619     }
620     if (ndevs == numount) {
621     free_mount_list (mounted);
622     mounted = NULL;
623     }
624     }
625    
626    
627     BOOL CALLBACK
628     cryptdisk_umount_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
629     {
630     mount_list_t vol;
631     char buf[128];
632     int n, rc=0;
633    
634     switch (msg) {
635     case WM_INITDIALOG:
636     do_check (dlg);
637     load_devs_from_mountlist (dlg, IDC_CDUMOUNT_LIST);
638     center_window (dlg, NULL);
639     SetForegroundWindow (dlg);
640     break;
641    
642     case WM_DESTROY:
643     do_reaping ();
644     break;
645    
646     case WM_COMMAND:
647     switch (LOWORD (wparam)) {
648     case IDOK:
649     n = SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_GETCURSEL, 0, 0);
650     if (n == LB_ERR) {
651     msg_box (dlg, _("Please select one drive to umount."), _("Cryptdisk"), MB_INFO);
652     return FALSE;
653     }
654     SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_GETTEXT, n,
655     (LPARAM)(char *)buf);
656     strcpy (buf, buf+6);
657     buf[2] = '\0';
658     vol = find_mount_list (mounted, buf);
659     if (!vol)
660     BUG (0);
661     rc = cryptdisk_unmount (buf[0], 0);
662     //if (rc == WPTERR_CDISK_LOCK)
663     // rc = cryptdisk_unmount (buf[0], 0);
664     if (!rc) {
665     SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_DELETESTRING, (WPARAM)n, 0);
666     remove_mount_list (mounted, vol);
667     }
668     else
669     msg_box (dlg, winpt_strerror (rc), _("Cryptdisk Error"), MB_ERR);
670     break;
671     case IDCANCEL:
672     EndDialog (dlg, FALSE);
673     break;
674     }
675     break;
676     }
677    
678     return FALSE;
679     }
680    
681    
682     int
683     cryptdisk_serv_run (void)
684     {
685     SC_HANDLE hd;
686     ENUM_SERVICE_STATUS ess[4096];
687     DWORD nservs=0, dummy=0;
688     DWORD i;
689     int rc=0;
690    
691     hd = OpenSCManager (NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
692     if (!hd)
693     return 0;
694    
695     EnumServicesStatus (hd, SERVICE_DRIVER, SERVICE_ACTIVE,
696     (LPENUM_SERVICE_STATUS)&ess,
697     sizeof ess-1, &dummy, &nservs, &dummy);
698    
699     for (i=0; i < nservs; i++) {
700     if (!strnicmp ("FileDisk", ess[i].lpDisplayName, 8)) {
701     rc = 1;
702     break;
703     }
704     }
705    
706     CloseServiceHandle (hd);
707     return rc;
708     }
709 twoaday 185 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26