mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-11-24 07:23:02 -05:00
103 lines
3.1 KiB
C
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
|