/* * @unimplemented */ UINT WINAPI GetSystemWow64DirectoryA( LPSTR lpBuffer, UINT uSize ) { #ifdef _WIN64 WCHAR BufferW[MAX_PATH]; UINT ret; ret = GetSystemWow64DirectoryW(BufferW, MAX_PATH); if (!ret) return 0; if (ret > MAX_PATH) { SetLastError(ERROR_FILENAME_EXCED_RANGE); return 0; } return FilenameW2A_FitOrFail(lpBuffer, uSize, BufferW, ret+1); #else SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; #endif }
static HANDLE start_rundll32( const char *inf_path, BOOL wow64 ) { static const WCHAR rundll[] = {'\\','r','u','n','d','l','l','3','2','.','e','x','e',0}; static const WCHAR setupapi[] = {' ','s','e','t','u','p','a','p','i',',', 'I','n','s','t','a','l','l','H','i','n','f','S','e','c','t','i','o','n',0}; static const WCHAR definstall[] = {' ','D','e','f','a','u','l','t','I','n','s','t','a','l','l',0}; static const WCHAR wowinstall[] = {' ','W','o','w','6','4','I','n','s','t','a','l','l',0}; static const WCHAR inf[] = {' ','1','2','8',' ','\\','\\','?','\\','u','n','i','x',0 }; WCHAR app[MAX_PATH + sizeof(rundll)/sizeof(WCHAR)]; STARTUPINFOW si; PROCESS_INFORMATION pi; WCHAR *buffer; DWORD inf_len, cmd_len; memset( &si, 0, sizeof(si) ); si.cb = sizeof(si); if (wow64) { if (!GetSystemWow64DirectoryW( app, MAX_PATH )) return 0; /* not on 64-bit */ } else GetSystemDirectoryW( app, MAX_PATH ); strcatW( app, rundll ); cmd_len = strlenW(app) * sizeof(WCHAR) + sizeof(setupapi) + sizeof(definstall) + sizeof(inf); inf_len = MultiByteToWideChar( CP_UNIXCP, 0, inf_path, -1, NULL, 0 ); if (!(buffer = HeapAlloc( GetProcessHeap(), 0, cmd_len + inf_len * sizeof(WCHAR) ))) return 0; strcpyW( buffer, app ); strcatW( buffer, setupapi ); strcatW( buffer, wow64 ? wowinstall : definstall ); strcatW( buffer, inf ); MultiByteToWideChar( CP_UNIXCP, 0, inf_path, -1, buffer + strlenW(buffer), inf_len ); if (CreateProcessW( app, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) CloseHandle( pi.hThread ); else pi.hProcess = 0; HeapFree( GetProcessHeap(), 0, buffer ); return pi.hProcess; }
static bool get_32bit_system_dll_ver(const wchar_t *system_lib, struct win_version_info *ver) { wchar_t path[MAX_PATH]; UINT ret; #ifdef _WIN64 ret = GetSystemWow64DirectoryW(path, MAX_PATH); #else ret = GetSystemDirectoryW(path, MAX_PATH); #endif if (!ret) { blog(LOG_ERROR, "Failed to get windows 32bit system path: " "%lu", GetLastError()); return false; } wcscat(path, L"\\"); wcscat(path, system_lib); return get_dll_ver(path, ver); }
static DWORD service_start_process(struct service_entry *service_entry, HANDLE *process) { PROCESS_INFORMATION pi; STARTUPINFOW si; LPWSTR path = NULL; DWORD size; BOOL r; service_lock_exclusive(service_entry); if (!env) { HANDLE htok; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok)) CreateEnvironmentBlock(&env, htok, FALSE); if (!env) WINE_ERR("failed to create services environment\n"); } size = ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,NULL,0); path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR)); if (!path) { service_unlock(service_entry); return ERROR_NOT_ENOUGH_SERVER_MEMORY; } ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,path,size); if (service_entry->config.dwServiceType == SERVICE_KERNEL_DRIVER) { static const WCHAR winedeviceW[] = {'\\','w','i','n','e','d','e','v','i','c','e','.','e','x','e',' ',0}; WCHAR system_dir[MAX_PATH]; DWORD type, len; GetSystemDirectoryW( system_dir, MAX_PATH ); if (is_win64) { if (!GetBinaryTypeW( path, &type )) { HeapFree( GetProcessHeap(), 0, path ); service_unlock(service_entry); return GetLastError(); } if (type == SCS_32BIT_BINARY) GetSystemWow64DirectoryW( system_dir, MAX_PATH ); } len = strlenW( system_dir ) + sizeof(winedeviceW)/sizeof(WCHAR) + strlenW(service_entry->name); HeapFree( GetProcessHeap(), 0, path ); if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) { service_unlock(service_entry); return ERROR_NOT_ENOUGH_SERVER_MEMORY; } lstrcpyW( path, system_dir ); lstrcatW( path, winedeviceW ); lstrcatW( path, service_entry->name ); } ZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); if (!(service_entry->config.dwServiceType & SERVICE_INTERACTIVE_PROCESS)) { static WCHAR desktopW[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n','\\','D','e','f','a','u','l','t',0}; si.lpDesktop = desktopW; } service_entry->status.dwCurrentState = SERVICE_START_PENDING; service_unlock(service_entry); r = CreateProcessW(NULL, path, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi); HeapFree(GetProcessHeap(),0,path); if (!r) { service_lock_exclusive(service_entry); service_entry->status.dwCurrentState = SERVICE_STOPPED; service_unlock(service_entry); return GetLastError(); } service_entry->status.dwProcessId = pi.dwProcessId; service_entry->process = pi.hProcess; *process = pi.hProcess; CloseHandle( pi.hThread ); return ERROR_SUCCESS; }