Kovid Goyal ab3e048a95
Use only win32 functions in the launcher, no CRT functions
Reduces the size of the executables a little
2017-05-21 13:39:06 +05:30

103 lines
3.1 KiB
C

/*
* Copyright 2009 Kovid Goyal
*/
#define UNICODE
#define WINDOWS_LEAN_AND_MEAN
#include<windows.h>
#include<strsafe.h>
size_t mystrlen(const wchar_t *buf) {
size_t ans = 0;
if (FAILED(StringCbLengthW(buf, 500, &ans))) return 0;
return ans;
}
static int show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
wchar_t *buf;
buf = (wchar_t*)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)*
(mystrlen(msg) + mystrlen(preamble) + 80));
if (!buf) {
MessageBox(NULL, preamble, NULL, MB_OK|MB_ICONERROR);
return code;
}
MessageBeep(MB_ICONERROR);
if (FAILED(StringCbPrintfW(buf, LocalSize(buf), L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code)))
MessageBox(NULL, preamble, NULL, MB_OK|MB_ICONERROR);
else
MessageBox(NULL, buf, NULL, MB_OK|MB_ICONERROR);
LocalFree(buf);
return code;
}
int show_last_error(wchar_t *preamble) {
wchar_t *msg = NULL;
DWORD dw = GetLastError();
int ret;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&msg,
0,
NULL );
ret = show_error(preamble, msg, (int)dw);
if (msg != NULL) LocalFree(msg);
return ret;
}
typedef int (__cdecl *ENTRYPROC)(const char*, const char*, const char*, int);
static ENTRYPROC load_launcher_dll() {
wchar_t buf[MAX_PATH] = {0};
wchar_t drive[4] = L"\0\0\0";
DWORD sz;
HMODULE dll;
ENTRYPROC entrypoint;
if ((sz = GetModuleFileNameW(NULL, buf, MAX_PATH)) >= MAX_PATH - 30)
ExitProcess(show_error(L"Installation directory path too long", L"", 1));
while (sz > 0) {
if (buf[sz] == L'\\' || buf[sz] == L'/') break;
sz--;
}
if (sz <= 0)
ExitProcess(show_error(L"Executable path has no path separators", L"", 1));
buf[sz+1] = L'a'; buf[sz+2] = L'p'; buf[sz+3] = L'p'; buf[sz+4] = L'\\';
buf[sz+5] = L'D'; buf[sz+6] = L'L'; buf[sz+7] = L'L'; buf[sz+8] = L's';
buf[sz+9] = 0; buf[sz+10] = 0;
if (SetDllDirectoryW(buf) == 0) {
show_last_error(L"Failed to set DLL directory");
ExitProcess(1);
}
dll = LoadLibraryW(L"calibre-launcher.dll");
if (!dll) ExitProcess(show_last_error(L"Failed to get the calibre-launcher dll handle"));
entrypoint = (ENTRYPROC) GetProcAddress(dll, "execute_python_entrypoint");
if (!entrypoint) ExitProcess(show_last_error(L"Failed to get the calibre-launcher dll entry point"));
return entrypoint;
}
#ifdef GUI_APP
int WINAPI
wWinMain(HINSTANCE Inst, HINSTANCE PrevInst, wchar_t *CmdLine, int CmdShow) {
load_launcher_dll()(BASENAME, MODULE, FUNCTION, 1);
return 0; // This should really be returning the value set in the WM_QUIT message, but I cannot be bothered figuring out how to get that.
}
#else
int wmain(int argc, wchar_t *argv) {
return load_launcher_dll()(BASENAME, MODULE, FUNCTION, 0);
}
#endif