//////////////////////////////////////////////////////////////////// // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine // All rights reserved // This file was released under the GPLv2 on June 2015. //////////////////////////////////////////////////////////////////// /************************************************************************* * * File: user_lib.cpp * * Module: User-mode library * * Description: common useful user-mode functions * * Author: Ivan * *************************************************************************/ #ifndef __USER_LIB_CPP__ #define __USER_LIB_CPP__ #include "user_lib.h" TCHAR* MediaTypeStrings[] = { "CD-ROM" , "CD-R" , "CD-RW" , "DVD-ROM" , "DVD-RAM" , "DVD-R" , "DVD-RW" , "DVD+R" , "DVD+RW" , "DD CD-ROM" , "DD CD-R" , "DD CD-RW" , "BD-ROM" , "BD-RE" , "[BUSY]" , "Unknown" }; void * __cdecl mymemchr ( const void * buf, int chr, size_t cnt ) { while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) { buf = (unsigned char *)buf + 1; cnt--; } return(cnt ? (void *)buf : NULL); } // end mymemchr() char * __cdecl mystrrchr( const char * string, int ch ) { char *start = (char *)string; while (*string++) {;} while (--string != start && *string != (char)ch) {;} if (*string == (char)ch) { return( (char *)string ); } return(NULL); } // end mystrrchr() char * __cdecl mystrchr( const char * string, int ch ) { while (*string != (char)ch && *string != '\0' ) { string++; } if (*string == (char)ch) { return( (char *)string ); } return(NULL); } // end mystrchr() int __cdecl Exist ( PCHAR path ) { DWORD attr; attr = GetFileAttributes((LPTSTR)path); if (attr == 0xffffffff) { return 0; } return 1; } // end Exist() ULONG MyMessageBox( HINSTANCE hInst, HWND hWnd, LPCSTR pszFormat, LPCSTR pszTitle, UINT fuStyle, ... ) { CHAR szTitle[80]; CHAR szFormat[1024]; LPSTR pszMessage; BOOL fOk; int result; va_list ArgList; if (!HIWORD(pszTitle)) { LoadString(hInst, LOWORD(pszTitle), szTitle, sizeof(szTitle)/sizeof(szTitle[0])); pszTitle = szTitle; } if (!HIWORD(pszFormat)) { // Allow this to be a resource ID LoadString(hInst, LOWORD(pszFormat), szFormat, sizeof(szFormat)/sizeof(szFormat[0])); pszFormat = szFormat; } va_start(ArgList, fuStyle); fOk = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, (LPTSTR)&pszMessage, 0, &ArgList); va_end(ArgList); if (fOk && pszMessage) { result = MessageBox(hWnd, pszMessage, pszTitle, fuStyle | MB_SETFOREGROUND); LocalFree(pszMessage); } else { return -1; } return result; } // end MyMessageBox() /// Return service status by service name. JS_SERVICE_STATE ServiceInfo( LPCTSTR ServiceName ) { SC_HANDLE schService; DWORD RC; SERVICE_STATUS ssStatus; JS_SERVICE_STATE return_value; SC_HANDLE schSCManager; schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if (!schSCManager) { schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_CONNECT // access required ); } if (!schSCManager) return JS_ERROR_STATUS; schService = OpenService(schSCManager, ServiceName, SERVICE_QUERY_STATUS); if (!schService) { RC = GetLastError(); CloseServiceHandle(schSCManager); if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return JS_SERVICE_NOT_PRESENT; else return JS_ERROR_STATUS; } QueryServiceStatus(schService, &ssStatus); if(ssStatus.dwCurrentState == SERVICE_RUNNING) { return_value = JS_SERVICE_RUNNING; } else { return_value = JS_SERVICE_NOT_RUNNING; } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return return_value; } // end ServiceInfo() BOOL CheckCdrwFilter( BOOL ReInstall ) { char CdromUpperFilters[1024]; bool found = false; if (LOBYTE(LOWORD(GetVersion())) < 5) { return true; } if (GetRegString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],arraylen(CdromUpperFilters))) { char *token = &CdromUpperFilters[0]; while (*token) { if (!strcmp(token,CDRW_SERVICE)) { found = true; break; } token += strlen(token)+1; } if (!found) { memcpy(token,CDRW_SERVICE,sizeof(CDRW_SERVICE)); *(token+sizeof(CDRW_SERVICE)) = '\0'; *(token+sizeof(CDRW_SERVICE)+1) = '\0'; if(ReInstall) { RegisterString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],TRUE,token-&CdromUpperFilters[0]+sizeof(CDRW_SERVICE)+1); found = true; } } } else { memcpy(CdromUpperFilters,CDRW_SERVICE,sizeof(CDRW_SERVICE)); CdromUpperFilters[sizeof(CDRW_SERVICE)] = '\0'; CdromUpperFilters[sizeof(CDRW_SERVICE)+1] = '\0'; if(ReInstall) { RegisterString(CDROM_CLASS_PATH,REG_UPPER_FILTER_NAME,&CdromUpperFilters[0],TRUE,sizeof(CDRW_SERVICE)+1); found = true; } } return found; } // end CheckCdrwFilter() BOOL RegisterString( LPSTR pszKey, LPSTR pszValue, LPSTR pszData, BOOLEAN MultiSz, DWORD size ) { HKEY hKey; DWORD dwDisposition; // Create the key, if it exists it will be opened if (ERROR_SUCCESS != RegCreateKeyEx( HKEY_LOCAL_MACHINE, // handle of an open key pszKey, // address of subkey name 0, // reserved NULL, // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure &hKey, // address of buffer for opened handle &dwDisposition)) // address of disposition value buffer { return FALSE; } // Write the value and it's data to the key if (ERROR_SUCCESS != RegSetValueEx( hKey, // handle of key to set value for pszValue, // address of value to set 0, // reserved MultiSz ? REG_MULTI_SZ : REG_SZ, // flag for value type (CONST BYTE *)pszData, // address of value data MultiSz ? size : strlen(pszData) )) // size of value data { RegCloseKey(hKey); return FALSE; } // Close the key RegCloseKey(hKey); return TRUE; } // end RegisterString() BOOL RegDelString( LPSTR pszKey, LPSTR pszValue ) { HKEY hKey; DWORD dwDisposition; // Create the key, if it exists it will be opened if (ERROR_SUCCESS != RegCreateKeyEx( HKEY_LOCAL_MACHINE, // handle of an open key pszKey, // address of subkey name 0, // reserved NULL, // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure &hKey, // address of buffer for opened handle &dwDisposition)) // address of disposition value buffer { return FALSE; } // Write the value and it's data to the key if (ERROR_SUCCESS != RegDeleteValue( hKey, // handle of key to set value for pszValue)) { RegCloseKey(hKey); return FALSE; } // Close the key RegCloseKey(hKey); return TRUE; } // end RegDelString() /// Get string from registry by Key path and Value name BOOL GetRegString( LPSTR pszKey, LPSTR pszValue, LPSTR pszData, DWORD dwBufSize ) { HKEY hKey; DWORD dwDataSize = dwBufSize; DWORD dwValueType = REG_SZ; if(!dwBufSize) return FALSE; RegOpenKeyEx( HKEY_LOCAL_MACHINE, // handle of open key pszKey, // address of name of subkey to open 0, // reserved KEY_QUERY_VALUE, // security access mask &hKey // address of handle of open key ); if (ERROR_SUCCESS != RegQueryValueEx( hKey, // handle of key to query pszValue, // address of name of value to query 0, // reserved &dwValueType, // address of buffer for value type (BYTE *)pszData, // address of data buffer &dwDataSize // address of data buffer size )) return FALSE; if (pszData[dwDataSize-1] != '\0') pszData[dwDataSize-1] = '\0'; return TRUE; } // end GetRegString() BOOL RegisterDword( LPSTR pszKey, LPSTR pszValue, DWORD dwData ) { HKEY hKey; DWORD dwDisposition; // Create the key, if it exists it will be opened if (ERROR_SUCCESS != RegCreateKeyEx( HKEY_LOCAL_MACHINE, // handle of an open key pszKey, // address of subkey name 0, // reserved NULL, // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure &hKey, // address of buffer for opened handle &dwDisposition)) // address of disposition value buffer { return FALSE; } // Write the value and it's data to the key if (ERROR_SUCCESS != RegSetValueEx( hKey, // handle of key to set value for pszValue, // address of value to set 0, // reserved REG_DWORD, // flag for value type (CONST BYTE *)&dwData, // address of value data 4 )) // size of value data { RegCloseKey(hKey); return FALSE; } // Close the key RegCloseKey(hKey); return TRUE; } // end RegisterDword() BOOL GetRegUlong( LPSTR pszKey, LPSTR pszValue, PULONG pszData ) { HKEY hKey; DWORD dwDataSize = 4; DWORD dwValueType = REG_DWORD; ULONG origValue = *pszData; if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, // handle of open key pszKey, // address of name of subkey to open 0, // reserved KEY_QUERY_VALUE, // security access mask &hKey // address of handle of open key ) != ERROR_SUCCESS) { (*pszData) = origValue; return FALSE; } if(RegQueryValueEx( hKey, // handle of key to query pszValue, // address of name of value to query 0, // reserved &dwValueType,// address of buffer for value type (BYTE *)pszData, // address of data buffer &dwDataSize // address of data buffer size ) != ERROR_SUCCESS) { (*pszData) = origValue; } RegCloseKey(hKey); return TRUE; } // end GetRegUlong() BOOL SetRegUlong( LPSTR pszKey, LPSTR pszValue, PULONG pszData ) { HKEY hKey; DWORD dwDataSize = 4; DWORD dwValueType = REG_DWORD; LPVOID lpMsgBuf; LONG RC; if (!(ERROR_SUCCESS == (RC = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // handle of open key pszKey, // address of name of subkey to open 0, // reserved KEY_ALL_ACCESS , // security access mask &hKey // address of handle of open key )))) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RC, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); // Display the string. MessageBox( NULL, (CCHAR*)lpMsgBuf, "Error", MB_OK|MB_ICONHAND ); // Free the buffer. LocalFree( lpMsgBuf ); return FALSE; } if (!(ERROR_SUCCESS == (RC = RegSetValueEx( hKey, // handle of key to query pszValue, // address of name of value to query 0, // reserved REG_DWORD,// address of buffer for value type (BYTE *)pszData, // address of data buffer sizeof(ULONG) // data buffer size )))) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RC, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); // Display the string. MessageBox( NULL, (CCHAR*)lpMsgBuf, "Error", MB_OK|MB_ICONHAND ); // Free the buffer. LocalFree( lpMsgBuf ); } RegCloseKey(hKey); return TRUE; } // end SetRegUlong() BOOL Privilege( LPTSTR pszPrivilege, BOOL bEnable ) { HANDLE hToken; TOKEN_PRIVILEGES tp; // // obtain the token, first check the thread and then the process // if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hToken)){ if (GetLastError() == ERROR_NO_TOKEN) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; } else return FALSE; } // // get the luid for the privilege // if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) return FALSE; tp.PrivilegeCount = 1; if (bEnable) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // // enable or disable the privilege // if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) return FALSE; if (!CloseHandle(hToken)) return FALSE; return TRUE; } // end Privilege() typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); BOOL IsWow64(VOID) { BOOL bIsWow64 = FALSE; LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process"); if (NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { return FALSE; } } return bIsWow64; } // end IsWow64() HANDLE CreatePublicEvent( PWCHAR EventName ) { SECURITY_DESCRIPTOR sdPublic; SECURITY_ATTRIBUTES saPublic; InitializeSecurityDescriptor( &sdPublic, SECURITY_DESCRIPTOR_REVISION ); SetSecurityDescriptorDacl( &sdPublic, TRUE, NULL, FALSE ); saPublic.nLength = sizeof(saPublic); saPublic.lpSecurityDescriptor = &sdPublic; return CreateEventW( &saPublic, TRUE, FALSE, EventName); } // end CreatePublicEvent() /// Send Device IO Controls to undelaying level via handle ULONG UDFPhSendIOCTL( IN ULONG IoControlCode, IN HANDLE DeviceObject, IN PVOID InputBuffer , IN ULONG InputBufferLength, OUT PVOID OutputBuffer , IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, IN PVOID Dummy ) { ULONG real_read; ULONG ret; LONG offh=0; ULONG RC = DeviceIoControl(DeviceObject,IoControlCode, InputBuffer,InputBufferLength, OutputBuffer,OutputBufferLength, &real_read,NULL); if (!RC) { ret = GetLastError(); } return RC ? 1 : -1; } // end UDFPhSendIOCTL() CHAR RealDeviceName[MAX_PATH+1]; PCHAR UDFGetDeviceName( PCHAR szDeviceName ) { HANDLE hDevice; WCHAR DeviceName[MAX_PATH+1]; ULONG RC; ODS(" UDFGetDeviceName\r\n"); hDevice = CreateFile(szDeviceName, GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == ((HANDLE)-1)) { strcpy(RealDeviceName,""); return (PCHAR)&RealDeviceName; } RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_NAME,hDevice, &DeviceName,(MAX_PATH+1)*sizeof(WCHAR), &DeviceName,(MAX_PATH+1)*sizeof(WCHAR), FALSE,NULL); if(RC == 1) { wcstombs((PCHAR)&RealDeviceName,&DeviceName[1],(USHORT)DeviceName[0]); RealDeviceName[(USHORT)DeviceName[0]/sizeof(USHORT)] = '\0'; } else { strcpy(RealDeviceName, szDeviceName+4); } CloseHandle(hDevice); return (PCHAR)(strrchr(RealDeviceName, '\\')+1); } // end UDFGetDeviceName() BOOL GetOptUlong( PCHAR Path, PCHAR OptName, PULONG OptVal ) { if(!Path) { return FALSE; } if(Path[0] && Path[1] == ':') { CHAR SettingFile[MAX_PATH]; CHAR Setting[16]; sprintf(SettingFile, "%s\\%s", Path, UDF_CONFIG_STREAM_NAME); GetPrivateProfileString("DiskSettings", OptName, "d", &Setting[0], 10, SettingFile); Setting[15]=0; if (Setting[0] != 'd') { if(Setting[0] == '0' && Setting[1] == 'x') { sscanf(Setting+2, "%x", OptVal); } else { sscanf(Setting, "%d", OptVal); } return TRUE; } return FALSE; } return GetRegUlong(Path, OptName, OptVal); } // end GetOptUlong() BOOL SetOptUlong( PCHAR Path, PCHAR OptName, PULONG OptVal ) { if(!Path) { return FALSE; } if(Path[0] && Path[1] == ':') { CHAR SettingFile[MAX_PATH]; CHAR Setting[16]; if(Path[2] != '\\') { sprintf(SettingFile, "%s\\%s", Path, UDF_CONFIG_STREAM_NAME); } else { sprintf(SettingFile, "%s%s", Path, UDF_CONFIG_STREAM_NAME); } sprintf(Setting, "%d\n", (*OptVal)); return WritePrivateProfileString("DiskSettings", OptName, Setting, SettingFile); } return SetRegUlong(Path, OptName, OptVal); } // end SetOptUlong() ULONG UDFGetOptUlongInherited( PCHAR Drive, PCHAR OptName, PULONG OptVal, ULONG CheckDepth ) { CHAR LocalPath[1024]; ULONG retval = 0; ODS(" UDFGetOptUlongInherited\r\n"); if(GetOptUlong(UDF_SERVICE_PARAM_PATH, OptName, OptVal)) { retval = UDF_OPTION_GLOBAL; } if(CheckDepth <= UDF_OPTION_GLOBAL) { return retval; } strcpy(LocalPath,UDF_SERVICE_PARAM_PATH); strcat(LocalPath,"\\"); strcat(LocalPath,UDFGetDeviceName(Drive)); if(GetOptUlong(LocalPath, OptName, OptVal)) { retval = UDF_OPTION_DEVSPEC; } if(CheckDepth <= UDF_OPTION_DEVSPEC) { return retval; } if(GetOptUlong(Drive, OptName, OptVal)) retval = UDF_OPTION_DISKSPEC; return retval; } // end UDFGetOptUlongInherited() HANDLE OpenOurVolume( PCHAR szDeviceName ) { HANDLE hDevice; // Open device volume hDevice = CreateFile(szDeviceName, GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == ((HANDLE)-1)) { hDevice = CreateFile(szDeviceName, GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } return hDevice; } // end OpenOurVolume() ULONG drv_letter_to_index( WCHAR a ) { if(a >= 'a' && a <= 'z') { return a - 'a'; } if(a >= 'A' && a <= 'Z') { return a - 'A'; } return -1; } // end drv_letter_to_index() /// Start app with desired parameters DWORD WINAPI LauncherRoutine2( LPVOID lpParameter ) { PCHAR ParamStr = (PCHAR)lpParameter; STARTUPINFO proc_startup_info; PROCESS_INFORMATION proc_info; CHAR szLaunchPath[MAX_PATH],ErrMes[50]; INT index; ULONG MkUdfRetCode; CHAR szTemp[256]; GetRegString(UDF_KEY,"ToolsPath",szLaunchPath, sizeof(szLaunchPath)); SetCurrentDirectory(szLaunchPath); strcat(szLaunchPath,"\\"); //strcat(szLaunchPath,UDFFMT); strcat(szLaunchPath,ParamStr); //strcpy(MkUdfStatus,""); #ifndef TESTMODE proc_startup_info.cb = sizeof(proc_startup_info); proc_startup_info.lpReserved = 0; proc_startup_info.lpReserved2 = 0; proc_startup_info.cbReserved2 = 0; proc_startup_info.lpDesktop = 0; proc_startup_info.lpTitle = 0; proc_startup_info.dwFlags = 0; proc_startup_info.hStdInput = NULL; proc_startup_info.hStdOutput = NULL; proc_startup_info.hStdError = NULL; if(CreateProcess(NULL, szLaunchPath, 0,0, TRUE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, 0,0, &proc_startup_info, &proc_info)) { //hFmtProc[i] = proc_info.hProcess; WaitForSingleObject(proc_info.hProcess, -1); GetExitCodeProcess(proc_info.hProcess, &MkUdfRetCode); index=0; /* while (mkudf_err_msg[index].err_code != 0xffffffff){ if (mkudf_err_msg[index].err_code == MkUdfRetCode) break; index++; } */ //strcpy(MkUdfStatus,mkudf_err_msg[index].err_msg); CloseHandle(proc_info.hThread); CloseHandle(proc_info.hProcess); } else { strcpy(ErrMes,"Stop: Cannot launch "); strcat(ErrMes,szLaunchPath); sprintf(szTemp," error %d",GetLastError()); strcat(ErrMes,szTemp); MessageBox(NULL,ErrMes,"UDFFormat",MB_OK | MB_ICONHAND); } #else MessageBox(NULL,szLaunchPath,"Message",MB_OK); Sleep(500); MkUdfRetCode = MKUDF_OK; // MkUdfRetCode = MKUDF_FORMAT_REQUIRED; // MkUdfRetCode = MKUDF_CANT_BLANK; index = 0; while (mkudf_err_msg[index].err_code != 0xffffffff){ if (mkudf_err_msg[index].err_code == MkUdfRetCode) break; index++; } //strcpy(MkUdfStatus,mkudf_err_msg[index].err_msg); #endif return MkUdfRetCode; } // end LauncherRoutine2() #endif // __USER_LIB_CPP__