int CreateShortcuts(const char *run_cfg_fn, json_t *games) { #ifdef _DEBUG const char *loader_exe = "thcrap_loader_d.exe"; #else const char *loader_exe = "thcrap_loader.exe"; #endif int ret = 0; size_t self_fn_len = GetModuleFileNameU(NULL, NULL, 0) + 1; VLA(char, self_fn, self_fn_len); GetModuleFileNameU(NULL, self_fn, self_fn_len); PathRemoveFileSpec(self_fn); PathAddBackslashA(self_fn); // Yay, COM. CoInitializeEx(NULL, COINIT_MULTITHREADED); { const char *key = NULL; json_t *cur_game = NULL; VLA(char, self_path, self_fn_len); strcpy(self_path, self_fn); strcat(self_fn, loader_exe); log_printf("Creating shortcuts"); json_object_foreach(games, key, cur_game) { const char *game_fn = json_string_value(cur_game); const char *link_fn = strings_sprintf(LINK_FN, "%s (%s).lnk", key, run_cfg_fn); const char *link_args = strings_sprintf(LINK_ARGS, "\"%s.js\" %s", run_cfg_fn, key); log_printf("."); if( CreateLink(link_fn, self_fn, link_args, self_path, game_fn) && !file_write_error(link_fn) ) { ret = 1; break; } } VLA_FREE(self_path); } VLA_FREE(self_fn); CoUninitialize(); return ret; }
int thcrap_inject_into_running(HANDLE hProcess, const char *run_cfg_fn) { int ret = -1; HMODULE inj_mod = NULL; if(GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPTSTR)thcrap_inject_into_running, &inj_mod )) { size_t cur_dir_len = GetCurrentDirectory(0, NULL) + 1; size_t inj_dir_len = GetModuleFileNameU(inj_mod, NULL, 0) + 1; VLA(char, inj_dll, inj_dir_len); VLA(char, inj_dir, inj_dir_len); STRLEN_DEC(run_cfg_fn); size_t param_len = cur_dir_len + run_cfg_fn_len; VLA(char, abs_run_cfg_fn, param_len); const char *param; GetModuleFileNameU(inj_mod, inj_dir, inj_dir_len); strncpy(inj_dll, inj_dir, inj_dir_len); PathRemoveFileSpec(inj_dir); PathAddBackslashA(inj_dir); // Allow for relative directory names if(PathIsRelativeA(run_cfg_fn)) { GetCurrentDirectory(cur_dir_len, abs_run_cfg_fn); PathAppendA(abs_run_cfg_fn, run_cfg_fn); param = abs_run_cfg_fn; } else { param = run_cfg_fn; param_len = run_cfg_fn_len; } ret = Inject(hProcess, inj_dir, inj_dll, "thcrap_init", param, param_len); VLA_FREE(abs_run_cfg_fn); VLA_FREE(inj_dir); VLA_FREE(inj_dll); } return ret; }
/* * Initial update check setup */ BOOL SetUpdateCheck(void) { BOOL enable_updates; DWORD commcheck = GetTickCount(); notification_info more_info = { IDD_UPDATE_POLICY, UpdateCallback }; char filename[MAX_PATH] = "", exename[] = APPLICATION_NAME ".exe"; size_t fn_len, exe_len; // Test if we have access to the registry. If not, forget it. WriteRegistryKey32(REGKEY_HKCU, REGKEY_COMM_CHECK, commcheck); if (ReadRegistryKey32(REGKEY_HKCU, REGKEY_COMM_CHECK) != commcheck) return FALSE; reg_commcheck = TRUE; // If the update interval is not set, this is the first time we run so prompt the user if (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) { // Add a hack for people who'd prefer the app not to prompt about update settings on first run. // If the executable is called "<app_name>.exe", without version, we disable the prompt GetModuleFileNameU(NULL, filename, sizeof(filename)); fn_len = safe_strlen(filename); exe_len = safe_strlen(exename); if ((fn_len > exe_len) && (safe_stricmp(&filename[fn_len-exe_len], exename) == 0)) { dprintf("Short name used - Disabling initial update policy prompt\n"); enable_updates = TRUE; } else { enable_updates = notification(MSG_QUESTION, &more_info, APPLICATION_NAME " update policy", "Do you want to allow " APPLICATION_NAME " to check for application updates online?"); } if (!enable_updates) { WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, -1); return FALSE; } // If the user hasn't set the interval in the dialog, set to default if ( (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) || ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) ) WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, 86400); } return TRUE; }