Use Slim Reader/Writer lock to replace CRITICAL_SECTION (better performance).
[gdipp.git] / gdipp_loader / gdipp_loader.cpp
blob64f574ecfbb67474e817c8234ba77e7785468f97
1 #include "stdafx.h"
2 #include "gdipp_lib/helper.h"
4 int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
6 BOOL b_ret;
7 NTSTATUS eh_ret;
9 if (lpCmdLine == NULL || wcslen(lpCmdLine) == 0)
11 MessageBox(NULL, L"Drag an exe file to me and I will load it with gdimm.dll.", L"gdipp Loader", MB_OK | MB_ICONINFORMATION);
12 return EXIT_SUCCESS;
15 int argc;
16 LPWSTR *argv = CommandLineToArgvW(lpCmdLine, &argc);
17 assert(argv != NULL);
19 wchar_t working_dir[MAX_PATH];
20 wcsncpy_s(working_dir, argv[0], MAX_PATH);
21 b_ret = PathRemoveFileSpecW(working_dir);
22 assert(b_ret);
24 STARTUPINFO si = {};
25 si.cb = sizeof(STARTUPINFO);
26 PROCESS_INFORMATION pi;
28 b_ret = CreateProcessW(argv[0], lpCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, working_dir, &si, &pi);
29 LocalFree(argv);
31 if (b_ret)
33 #ifdef _M_X64
34 const wchar_t *client_name = L"gdipp_client_64.dll";
35 #else
36 const wchar_t *client_name = L"gdipp_client_32.dll";
37 #endif
39 wchar_t _client_path[MAX_PATH];
40 b_ret = gdipp::get_dir_file_path(NULL, client_name, _client_path);
41 assert(b_ret);
43 #ifdef _M_X64
44 eh_ret = RhInjectLibrary(pi.dwProcessId, pi.dwThreadId, EASYHOOK_INJECT_DEFAULT, NULL, _client_path, NULL, 0);
45 #else
46 eh_ret = RhInjectLibrary(pi.dwProcessId, pi.dwThreadId, EASYHOOK_INJECT_DEFAULT, _client_path, NULL, NULL, 0);
47 #endif
49 if (eh_ret == 0)
51 WaitForSingleObject(pi.hProcess, INFINITE);
52 CloseHandle(pi.hThread);
53 CloseHandle(pi.hProcess);
54 return EXIT_SUCCESS;
56 else
58 b_ret = TerminateProcess(pi.hProcess, 0);
59 assert(b_ret);
61 std::wstring error_msg = L"Unable to inject gdimm.dll to the new process";
63 // STATUS_WOW_ASSERTION
64 if (eh_ret == 0xC0009898L)
65 error_msg += L" due to different bitness. Try the other gdipp Loader";
67 error_msg += L".";
69 MessageBoxW(NULL, error_msg.c_str(), L"gdipp Loader", MB_OK | MB_ICONERROR);
70 return EXIT_FAILURE;
73 else
75 MessageBoxW(NULL, L"Unable to create the target process.", L"gdipp Loader", MB_OK | MB_ICONERROR);
76 return EXIT_FAILURE;