Reactos
1////////////////////////////////////////////////////////////////////
2// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3// All rights reserved
4// This file was released under the GPLv2 on June 2015.
5////////////////////////////////////////////////////////////////////
6
7/*************************************************************************
8*
9* File: user_lib.cpp
10*
11* Module: User-mode library
12*
13* Description: common useful user-mode functions
14*
15* Author: Ivan
16*
17*************************************************************************/
18
19
20#ifndef __USER_LIB_CPP__
21#define __USER_LIB_CPP__
22
23#include "user_lib.h"
24
25TCHAR* MediaTypeStrings[] =
26{
27 "CD-ROM" ,
28 "CD-R" ,
29 "CD-RW" ,
30 "DVD-ROM" ,
31 "DVD-RAM" ,
32 "DVD-R" ,
33 "DVD-RW" ,
34 "DVD+R" ,
35 "DVD+RW" ,
36 "DD CD-ROM" ,
37 "DD CD-R" ,
38 "DD CD-RW" ,
39 "BD-ROM" ,
40 "BD-RE" ,
41 "[BUSY]" ,
42 "Unknown"
43};
44
45void * __cdecl mymemchr (
46 const void * buf,
47 int chr,
48 size_t cnt
49 )
50{
51 while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
52 buf = (unsigned char *)buf + 1;
53 cnt--;
54 }
55
56 return(cnt ? (void *)buf : NULL);
57} // end mymemchr()
58
59char * __cdecl mystrrchr(
60 const char * string,
61 int ch
62 )
63{
64 char *start = (char *)string;
65
66 while (*string++) {;}
67
68 while (--string != start && *string != (char)ch) {;}
69
70 if (*string == (char)ch) {
71 return( (char *)string );
72 }
73
74 return(NULL);
75} // end mystrrchr()
76
77char * __cdecl mystrchr(
78 const char * string,
79 int ch
80 )
81{
82 while (*string != (char)ch && *string != '\0' ) {
83 string++;
84 }
85
86 if (*string == (char)ch) {
87 return( (char *)string );
88 }
89
90 return(NULL);
91} // end mystrchr()
92
93
94int __cdecl Exist (
95 PCHAR path
96 )
97{
98 DWORD attr;
99
100 attr = GetFileAttributes((LPTSTR)path);
101 if (attr == 0xffffffff) {
102 return 0;
103 }
104
105 return 1;
106
107} // end Exist()
108
109ULONG
110MyMessageBox(
111 HINSTANCE hInst,
112 HWND hWnd,
113 LPCSTR pszFormat,
114 LPCSTR pszTitle,
115 UINT fuStyle,
116 ...
117 )
118{
119 CHAR szTitle[80];
120 CHAR szFormat[1024];
121 LPSTR pszMessage;
122 BOOL fOk;
123 int result;
124 va_list ArgList;
125
126 if (!HIWORD(pszTitle)) {
127 LoadString(hInst, LOWORD(pszTitle), szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
128 pszTitle = szTitle;
129 }
130
131 if (!HIWORD(pszFormat)) {
132 // Allow this to be a resource ID
133 LoadString(hInst, LOWORD(pszFormat), szFormat, sizeof(szFormat)/sizeof(szFormat[0]));
134 pszFormat = szFormat;
135 }
136
137 va_start(ArgList, fuStyle);
138 fOk = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
139 | FORMAT_MESSAGE_FROM_STRING,
140 pszFormat, 0, 0, (LPTSTR)&pszMessage, 0, &ArgList);
141
142 va_end(ArgList);
143
144 if (fOk && pszMessage) {
145 result = MessageBox(hWnd, pszMessage, pszTitle, fuStyle | MB_SETFOREGROUND);
146 LocalFree(pszMessage);
147 } else {
148 return -1;
149 }
150
151 return result;
152} // end MyMessageBox()
153
154
155/// Return service status by service name.
156JS_SERVICE_STATE
157ServiceInfo(
158 LPCTSTR ServiceName
159 )
160{
161 SC_HANDLE schService;
162 DWORD RC;
163 SERVICE_STATUS ssStatus;
164 JS_SERVICE_STATE return_value;
165 SC_HANDLE schSCManager;
166
167 schSCManager = OpenSCManager(
168 NULL, // machine (NULL == local)
169 NULL, // database (NULL == default)
170 SC_MANAGER_ALL_ACCESS // access required
171 );
172 if (!schSCManager) {
173 schSCManager = OpenSCManager(
174 NULL, // machine (NULL == local)
175 NULL, // database (NULL == default)
176 SC_MANAGER_CONNECT // access required
177 );
178 }
179 if (!schSCManager)
180 return JS_ERROR_STATUS;
181 schService = OpenService(schSCManager, ServiceName, SERVICE_QUERY_STATUS);
182 if (!schService) {
183 RC = GetLastError();
184 CloseServiceHandle(schSCManager);
185 if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return JS_SERVICE_NOT_PRESENT;
186 else return JS_ERROR_STATUS;
187 }
188 QueryServiceStatus(schService, &ssStatus);
189 if(ssStatus.dwCurrentState == SERVICE_RUNNING) {
190 return_value = JS_SERVICE_RUNNING;
191 } else {
192 return_value = JS_SERVICE_NOT_RUNNING;
193 }
194 CloseServiceHandle(schService);
195 CloseServiceHandle(schSCManager);
196 return return_value;
197} // end ServiceInfo()
198
199BOOL
200CheckCdrwFilter(
201 BOOL ReInstall
202 )
203{
204 char CdromUpperFilters[1024];
205 bool found = false;
206
207 if (LOBYTE(LOWORD(GetVersion())) < 5) {
208 return true;
209 }
210
211 if (GetRegString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],arraylen(CdromUpperFilters))) {
212 char *token = &CdromUpperFilters[0];
213
214 while (*token) {
215 if (!strcmp(token,CDRW_SERVICE)) {
216 found = true;
217 break;
218 }
219 token += strlen(token)+1;
220 }
221 if (!found) {
222 memcpy(token,CDRW_SERVICE,sizeof(CDRW_SERVICE));
223 *(token+sizeof(CDRW_SERVICE)) = '\0';
224 *(token+sizeof(CDRW_SERVICE)+1) = '\0';
225 if(ReInstall) {
226 RegisterString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],TRUE,token-&CdromUpperFilters[0]+sizeof(CDRW_SERVICE)+1);
227 found = true;
228 }
229 }
230 } else {
231 memcpy(CdromUpperFilters,CDRW_SERVICE,sizeof(CDRW_SERVICE));
232 CdromUpperFilters[sizeof(CDRW_SERVICE)] = '\0';
233 CdromUpperFilters[sizeof(CDRW_SERVICE)+1] = '\0';
234 if(ReInstall) {
235 RegisterString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],TRUE,sizeof(CDRW_SERVICE)+1);
236 found = true;
237 }
238 }
239 return found;
240
241} // end CheckCdrwFilter()
242
243BOOL
244RegisterString(
245 LPSTR pszKey,
246 LPSTR pszValue,
247 LPSTR pszData,
248 BOOLEAN MultiSz,
249 DWORD size
250 )
251{
252
253 HKEY hKey;
254 DWORD dwDisposition;
255
256 // Create the key, if it exists it will be opened
257 if (ERROR_SUCCESS !=
258 RegCreateKeyEx(
259 HKEY_LOCAL_MACHINE, // handle of an open key
260 pszKey, // address of subkey name
261 0, // reserved
262 NULL, // address of class string
263 REG_OPTION_NON_VOLATILE, // special options flag
264 KEY_ALL_ACCESS, // desired security access
265 NULL, // address of key security structure
266 &hKey, // address of buffer for opened handle
267 &dwDisposition)) // address of disposition value buffer
268 {
269 return FALSE;
270 }
271
272 // Write the value and it's data to the key
273 if (ERROR_SUCCESS !=
274 RegSetValueEx(
275 hKey, // handle of key to set value for
276 pszValue, // address of value to set
277 0, // reserved
278 MultiSz ? REG_MULTI_SZ : REG_SZ, // flag for value type
279 (CONST BYTE *)pszData, // address of value data
280 MultiSz ? size : strlen(pszData) )) // size of value data
281 {
282
283 RegCloseKey(hKey);
284 return FALSE;
285 }
286
287 // Close the key
288 RegCloseKey(hKey);
289
290 return TRUE;
291} // end RegisterString()
292
293BOOL
294RegDelString(
295 LPSTR pszKey,
296 LPSTR pszValue
297 )
298{
299
300 HKEY hKey;
301 DWORD dwDisposition;
302
303 // Create the key, if it exists it will be opened
304 if (ERROR_SUCCESS !=
305 RegCreateKeyEx(
306 HKEY_LOCAL_MACHINE, // handle of an open key
307 pszKey, // address of subkey name
308 0, // reserved
309 NULL, // address of class string
310 REG_OPTION_NON_VOLATILE, // special options flag
311 KEY_ALL_ACCESS, // desired security access
312 NULL, // address of key security structure
313 &hKey, // address of buffer for opened handle
314 &dwDisposition)) // address of disposition value buffer
315 {
316 return FALSE;
317 }
318
319 // Write the value and it's data to the key
320 if (ERROR_SUCCESS !=
321 RegDeleteValue(
322 hKey, // handle of key to set value for
323 pszValue))
324 {
325
326 RegCloseKey(hKey);
327 return FALSE;
328 }
329
330 // Close the key
331 RegCloseKey(hKey);
332
333 return TRUE;
334} // end RegDelString()
335
336/// Get string from registry by Key path and Value name
337BOOL
338GetRegString(
339 LPSTR pszKey,
340 LPSTR pszValue,
341 LPSTR pszData,
342 DWORD dwBufSize
343 )
344{
345
346 HKEY hKey;
347 DWORD dwDataSize = dwBufSize;
348 DWORD dwValueType = REG_SZ;
349
350 if(!dwBufSize)
351 return FALSE;
352
353 RegOpenKeyEx(
354 HKEY_LOCAL_MACHINE, // handle of open key
355 pszKey, // address of name of subkey to open
356 0, // reserved
357 KEY_QUERY_VALUE, // security access mask
358 &hKey // address of handle of open key
359 );
360
361 if (ERROR_SUCCESS != RegQueryValueEx(
362 hKey, // handle of key to query
363 pszValue, // address of name of value to query
364 0, // reserved
365 &dwValueType, // address of buffer for value type
366 (BYTE *)pszData, // address of data buffer
367 &dwDataSize // address of data buffer size
368 )) return FALSE;
369
370 if (pszData[dwDataSize-1] != '\0')
371 pszData[dwDataSize-1] = '\0';
372
373 return TRUE;
374} // end GetRegString()
375
376BOOL
377RegisterDword(
378 LPSTR pszKey,
379 LPSTR pszValue,
380 DWORD dwData
381 )
382{
383
384 HKEY hKey;
385 DWORD dwDisposition;
386
387 // Create the key, if it exists it will be opened
388 if (ERROR_SUCCESS !=
389 RegCreateKeyEx(
390 HKEY_LOCAL_MACHINE, // handle of an open key
391 pszKey, // address of subkey name
392 0, // reserved
393 NULL, // address of class string
394 REG_OPTION_NON_VOLATILE, // special options flag
395 KEY_ALL_ACCESS, // desired security access
396 NULL, // address of key security structure
397 &hKey, // address of buffer for opened handle
398 &dwDisposition)) // address of disposition value buffer
399 {
400 return FALSE;
401 }
402
403 // Write the value and it's data to the key
404 if (ERROR_SUCCESS !=
405 RegSetValueEx(
406 hKey, // handle of key to set value for
407 pszValue, // address of value to set
408 0, // reserved
409 REG_DWORD, // flag for value type
410 (CONST BYTE *)&dwData, // address of value data
411 4 )) // size of value data
412 {
413
414 RegCloseKey(hKey);
415 return FALSE;
416 }
417
418 // Close the key
419 RegCloseKey(hKey);
420
421 return TRUE;
422} // end RegisterDword()
423
424BOOL
425GetRegUlong(
426 LPSTR pszKey,
427 LPSTR pszValue,
428 PULONG pszData
429 )
430{
431
432 HKEY hKey;
433 DWORD dwDataSize = 4;
434 DWORD dwValueType = REG_DWORD;
435 ULONG origValue = *pszData;
436
437 if(RegOpenKeyEx(
438 HKEY_LOCAL_MACHINE, // handle of open key
439 pszKey, // address of name of subkey to open
440 0, // reserved
441 KEY_QUERY_VALUE, // security access mask
442 &hKey // address of handle of open key
443 ) != ERROR_SUCCESS) {
444 (*pszData) = origValue;
445 return FALSE;
446 }
447
448 if(RegQueryValueEx(
449 hKey, // handle of key to query
450 pszValue, // address of name of value to query
451 0, // reserved
452 &dwValueType,// address of buffer for value type
453 (BYTE *)pszData, // address of data buffer
454 &dwDataSize // address of data buffer size
455 ) != ERROR_SUCCESS) {
456 (*pszData) = origValue;
457 }
458
459 RegCloseKey(hKey);
460
461 return TRUE;
462} // end GetRegUlong()
463
464BOOL
465SetRegUlong(
466 LPSTR pszKey,
467 LPSTR pszValue,
468 PULONG pszData
469 )
470{
471
472 HKEY hKey;
473 DWORD dwDataSize = 4;
474 DWORD dwValueType = REG_DWORD;
475 LPVOID lpMsgBuf;
476 LONG RC;
477
478 if (!(ERROR_SUCCESS == (RC = RegOpenKeyEx(
479 HKEY_LOCAL_MACHINE, // handle of open key
480 pszKey, // address of name of subkey to open
481 0, // reserved
482 KEY_ALL_ACCESS , // security access mask
483 &hKey // address of handle of open key
484 )))) {
485 FormatMessage(
486 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
487 NULL,
488 RC,
489 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
490 (LPTSTR) &lpMsgBuf,
491 0,
492 NULL);
493
494 // Display the string.
495 MessageBox( NULL, (CCHAR*)lpMsgBuf, "Error", MB_OK|MB_ICONHAND );
496
497 // Free the buffer.
498 LocalFree( lpMsgBuf );
499 return FALSE;
500 }
501
502 if (!(ERROR_SUCCESS == (RC = RegSetValueEx(
503 hKey, // handle of key to query
504 pszValue, // address of name of value to query
505 0, // reserved
506 REG_DWORD,// address of buffer for value type
507 (BYTE *)pszData, // address of data buffer
508 sizeof(ULONG) // data buffer size
509 )))) {
510 FormatMessage(
511 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
512 NULL,
513 RC,
514 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
515 (LPTSTR) &lpMsgBuf,
516 0,
517 NULL);
518
519 // Display the string.
520 MessageBox( NULL, (CCHAR*)lpMsgBuf, "Error", MB_OK|MB_ICONHAND );
521
522 // Free the buffer.
523 LocalFree( lpMsgBuf );
524
525 }
526 RegCloseKey(hKey);
527 return TRUE;
528} // end SetRegUlong()
529
530BOOL
531Privilege(
532 LPTSTR pszPrivilege,
533 BOOL bEnable
534 )
535{
536
537 HANDLE hToken;
538 TOKEN_PRIVILEGES tp;
539
540 //
541 // obtain the token, first check the thread and then the process
542 //
543 if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hToken)){
544 if (GetLastError() == ERROR_NO_TOKEN) {
545 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
546 return FALSE;
547 }
548 else return FALSE;
549 }
550
551 //
552 // get the luid for the privilege
553 //
554 if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))
555 return FALSE;
556
557 tp.PrivilegeCount = 1;
558
559 if (bEnable)
560 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
561 else
562 tp.Privileges[0].Attributes = 0;
563
564 //
565 // enable or disable the privilege
566 //
567 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
568 return FALSE;
569
570 if (!CloseHandle(hToken))
571 return FALSE;
572
573 return TRUE;
574} // end Privilege()
575
576typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
577
578
579BOOL IsWow64(VOID)
580{
581 BOOL bIsWow64 = FALSE;
582 LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");
583
584 if (NULL != fnIsWow64Process)
585 {
586 if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
587 {
588 return FALSE;
589 }
590 }
591 return bIsWow64;
592} // end IsWow64()
593
594
595HANDLE
596CreatePublicEvent(
597 PWCHAR EventName
598 )
599{
600 SECURITY_DESCRIPTOR sdPublic;
601 SECURITY_ATTRIBUTES saPublic;
602
603 InitializeSecurityDescriptor(
604 &sdPublic,
605 SECURITY_DESCRIPTOR_REVISION
606 );
607
608 SetSecurityDescriptorDacl(
609 &sdPublic,
610 TRUE,
611 NULL,
612 FALSE
613 );
614
615 saPublic.nLength = sizeof(saPublic);
616 saPublic.lpSecurityDescriptor = &sdPublic;
617
618 return CreateEventW(
619 &saPublic,
620 TRUE,
621 FALSE,
622 EventName);
623
624} // end CreatePublicEvent()
625
626/// Send Device IO Controls to undelaying level via handle
627ULONG
628UDFPhSendIOCTL(
629 IN ULONG IoControlCode,
630 IN HANDLE DeviceObject,
631 IN PVOID InputBuffer ,
632 IN ULONG InputBufferLength,
633 OUT PVOID OutputBuffer ,
634 IN ULONG OutputBufferLength,
635 IN BOOLEAN OverrideVerify,
636 IN PVOID Dummy
637 )
638{
639 ULONG real_read;
640 ULONG ret;
641 LONG offh=0;
642 ULONG RC = DeviceIoControl(DeviceObject,IoControlCode,
643 InputBuffer,InputBufferLength,
644 OutputBuffer,OutputBufferLength,
645 &real_read,NULL);
646
647 if (!RC) {
648 ret = GetLastError();
649 }
650 return RC ? 1 : -1;
651} // end UDFPhSendIOCTL()
652
653CHAR RealDeviceName[MAX_PATH+1];
654
655PCHAR
656UDFGetDeviceName(
657 PCHAR szDeviceName
658 )
659{
660 HANDLE hDevice;
661 WCHAR DeviceName[MAX_PATH+1];
662 ULONG RC;
663
664 ODS(" UDFGetDeviceName\r\n");
665 hDevice = CreateFile(szDeviceName, GENERIC_READ ,
666 FILE_SHARE_READ,
667 NULL,
668 OPEN_EXISTING,
669 FILE_ATTRIBUTE_NORMAL, NULL);
670
671 if (hDevice == ((HANDLE)-1)) {
672 strcpy(RealDeviceName,"");
673 return (PCHAR)&RealDeviceName;
674 }
675
676 RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_NAME,hDevice,
677 &DeviceName,(MAX_PATH+1)*sizeof(WCHAR),
678 &DeviceName,(MAX_PATH+1)*sizeof(WCHAR), FALSE,NULL);
679
680 if(RC == 1) {
681 wcstombs((PCHAR)&RealDeviceName,&DeviceName[1],(USHORT)DeviceName[0]);
682 RealDeviceName[(USHORT)DeviceName[0]/sizeof(USHORT)] = '\0';
683 } else {
684 strcpy(RealDeviceName, szDeviceName+4);
685 }
686
687 CloseHandle(hDevice);
688
689 return (PCHAR)(strrchr(RealDeviceName, '\\')+1);
690} // end UDFGetDeviceName()
691
692BOOL
693GetOptUlong(
694 PCHAR Path,
695 PCHAR OptName,
696 PULONG OptVal
697 )
698{
699 if(!Path) {
700 return FALSE;
701 }
702 if(Path[0] && Path[1] == ':') {
703 CHAR SettingFile[MAX_PATH];
704 CHAR Setting[16];
705
706 sprintf(SettingFile, "%s\\%s", Path, UDF_CONFIG_STREAM_NAME);
707 GetPrivateProfileString("DiskSettings", OptName, "d", &Setting[0], 10, SettingFile);
708 Setting[15]=0;
709 if (Setting[0] != 'd') {
710 if(Setting[0] == '0' && Setting[1] == 'x') {
711 sscanf(Setting+2, "%x", OptVal);
712 } else {
713 sscanf(Setting, "%d", OptVal);
714 }
715 return TRUE;
716 }
717 return FALSE;
718 }
719 return GetRegUlong(Path, OptName, OptVal);
720} // end GetOptUlong()
721
722BOOL
723SetOptUlong(
724 PCHAR Path,
725 PCHAR OptName,
726 PULONG OptVal
727 )
728{
729 if(!Path) {
730 return FALSE;
731 }
732 if(Path[0] && Path[1] == ':') {
733 CHAR SettingFile[MAX_PATH];
734 CHAR Setting[16];
735 if(Path[2] != '\\') {
736 sprintf(SettingFile, "%s\\%s", Path, UDF_CONFIG_STREAM_NAME);
737 } else {
738 sprintf(SettingFile, "%s%s", Path, UDF_CONFIG_STREAM_NAME);
739 }
740 sprintf(Setting, "%d\n", (*OptVal));
741 return WritePrivateProfileString("DiskSettings", OptName, Setting, SettingFile);
742 }
743 return SetRegUlong(Path, OptName, OptVal);
744} // end SetOptUlong()
745
746ULONG
747UDFGetOptUlongInherited(
748 PCHAR Drive,
749 PCHAR OptName,
750 PULONG OptVal,
751 ULONG CheckDepth
752 )
753{
754 CHAR LocalPath[1024];
755 ULONG retval = 0;
756
757 ODS(" UDFGetOptUlongInherited\r\n");
758
759 if(GetOptUlong(UDF_SERVICE_PARAM_PATH, OptName, OptVal)) {
760 retval = UDF_OPTION_GLOBAL;
761 }
762 if(CheckDepth <= UDF_OPTION_GLOBAL) {
763 return retval;
764 }
765 strcpy(LocalPath,UDF_SERVICE_PARAM_PATH);
766 strcat(LocalPath,"\\");
767 strcat(LocalPath,UDFGetDeviceName(Drive));
768 if(GetOptUlong(LocalPath, OptName, OptVal)) {
769 retval = UDF_OPTION_DEVSPEC;
770 }
771 if(CheckDepth <= UDF_OPTION_DEVSPEC) {
772 return retval;
773 }
774 if(GetOptUlong(Drive, OptName, OptVal))
775 retval = UDF_OPTION_DISKSPEC;
776 return retval;
777} // end UDFGetOptUlongInherited()
778
779HANDLE
780OpenOurVolume(
781 PCHAR szDeviceName
782 )
783{
784 HANDLE hDevice;
785
786 // Open device volume
787 hDevice = CreateFile(szDeviceName, GENERIC_READ ,
788 FILE_SHARE_READ,
789 NULL,
790 OPEN_EXISTING,
791 FILE_ATTRIBUTE_NORMAL, NULL);
792
793 if (hDevice == ((HANDLE)-1)) {
794 hDevice = CreateFile(szDeviceName, GENERIC_READ ,
795 FILE_SHARE_READ | FILE_SHARE_WRITE,
796 NULL,
797 OPEN_EXISTING,
798 FILE_ATTRIBUTE_NORMAL, NULL);
799
800 }
801 return hDevice;
802} // end OpenOurVolume()
803
804ULONG
805drv_letter_to_index(
806 WCHAR a
807 )
808{
809 if(a >= 'a' && a <= 'z') {
810 return a - 'a';
811 }
812 if(a >= 'A' && a <= 'Z') {
813 return a - 'A';
814 }
815 return -1;
816} // end drv_letter_to_index()
817
818/// Start app with desired parameters
819DWORD
820WINAPI
821LauncherRoutine2(
822 LPVOID lpParameter
823 )
824{
825 PCHAR ParamStr = (PCHAR)lpParameter;
826 STARTUPINFO proc_startup_info;
827 PROCESS_INFORMATION proc_info;
828 CHAR szLaunchPath[MAX_PATH],ErrMes[50];
829 INT index;
830 ULONG MkUdfRetCode;
831 CHAR szTemp[256];
832
833 GetRegString(UDF_KEY,"ToolsPath",szLaunchPath, sizeof(szLaunchPath));
834 SetCurrentDirectory(szLaunchPath);
835
836 strcat(szLaunchPath,"\\");
837 //strcat(szLaunchPath,UDFFMT);
838 strcat(szLaunchPath,ParamStr);
839
840 //strcpy(MkUdfStatus,"");
841
842#ifndef TESTMODE
843 proc_startup_info.cb = sizeof(proc_startup_info);
844 proc_startup_info.lpReserved = 0;
845 proc_startup_info.lpReserved2 = 0;
846 proc_startup_info.cbReserved2 = 0;
847 proc_startup_info.lpDesktop = 0;
848 proc_startup_info.lpTitle = 0;
849 proc_startup_info.dwFlags = 0;
850
851 proc_startup_info.hStdInput = NULL;
852 proc_startup_info.hStdOutput = NULL;
853 proc_startup_info.hStdError = NULL;
854
855 if(CreateProcess(NULL, szLaunchPath, 0,0, TRUE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
856 0,0, &proc_startup_info, &proc_info)) {
857
858 //hFmtProc[i] = proc_info.hProcess;
859 WaitForSingleObject(proc_info.hProcess, -1);
860 GetExitCodeProcess(proc_info.hProcess, &MkUdfRetCode);
861 index=0;
862/*
863 while (mkudf_err_msg[index].err_code != 0xffffffff){
864 if (mkudf_err_msg[index].err_code == MkUdfRetCode) break;
865 index++;
866 }
867*/
868 //strcpy(MkUdfStatus,mkudf_err_msg[index].err_msg);
869
870 CloseHandle(proc_info.hThread);
871 CloseHandle(proc_info.hProcess);
872 } else {
873 strcpy(ErrMes,"Stop: Cannot launch ");
874 strcat(ErrMes,szLaunchPath);
875 sprintf(szTemp," error %d",GetLastError());
876 strcat(ErrMes,szTemp);
877 MessageBox(NULL,ErrMes,"UDFFormat",MB_OK | MB_ICONHAND);
878
879 }
880#else
881 MessageBox(NULL,szLaunchPath,"Message",MB_OK);
882 Sleep(500);
883 MkUdfRetCode = MKUDF_OK;
884// MkUdfRetCode = MKUDF_FORMAT_REQUIRED;
885// MkUdfRetCode = MKUDF_CANT_BLANK;
886
887 index = 0;
888 while (mkudf_err_msg[index].err_code != 0xffffffff){
889 if (mkudf_err_msg[index].err_code == MkUdfRetCode) break;
890 index++;
891 }
892 //strcpy(MkUdfStatus,mkudf_err_msg[index].err_msg);
893
894#endif
895 return MkUdfRetCode;
896} // end LauncherRoutine2()
897
898
899#endif // __USER_LIB_CPP__