...
1 // Windows platform specifica
3 #define WIN32_LEAN_AND_MEAN
7 #define _WIN32_WINNT 0x0600
15 #include "platform_windows.h"
17 #ifndef WC_ERR_INVALID_CHARS
18 #define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
23 static string utf8_string(wstring wstr) {
27 int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
28 wstr.c_str(), -1, NULL, 0, NULL, NULL);
31 char *buf = new char[size];
32 WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr.c_str(),
33 -1, buf, size, NULL, NULL);
37 throw out_of_range("input wstring is not valid"
38 " while converting UTF-16 to UTF-8.");
44 static wstring utf16_string(string str) {
48 int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
49 str.c_str(), -1, NULL, 0);
52 wchar_t * buf = new wchar_t[size];
53 MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1,
58 throw out_of_range("input string is not valid"
59 " while converting UTF-8 to UTF-16.");
65 static bool readRegistryString(
66 HKEY hKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPTSTR lpResult,
67 DWORD dwSize, LPCTSTR lpDefault
74 DWORD bytesCopied = dwSize;
77 result = RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ, &theKey);
78 if (result != ERROR_SUCCESS) {
80 wcsncpy_s(lpResult, dwSize, lpDefault, _TRUNCATE);
87 result = RegQueryValueEx(theKey, lpValueName, NULL, &type,
88 (LPBYTE) lpResult, &bytesCopied);
89 if (result != ERROR_SUCCESS || (type != REG_EXPAND_SZ && type != REG_SZ)) {
91 wcsncpy_s(lpResult, dwSize, lpDefault, _TRUNCATE);
105 static const DWORD PATH_BUF_SIZE = 32768;
107 static inline string managementPath(const char *file_path, const char *file_name)
110 static TCHAR tPath[PATH_BUF_SIZE];
112 DWORD length = ExpandEnvironmentStringsW(utf16_string(file_path).c_str(),
113 tPath, PATH_BUF_SIZE);
116 throw bad_alloc(); // BUG: there are other errors possible beside out of memory
118 CreateDirectory(tPath, NULL);
119 DWORD error = GetLastError();
120 assert(error == 0 || error == ERROR_ALREADY_EXISTS);
122 path = utf8_string(tPath);
131 void *dlopen(const char *filename, int flag) {
132 static TCHAR path[PATH_BUF_SIZE];
135 assert(flag == RTLD_LAZY); // only lazy binding is implemented
137 bool result = readRegistryString(HKEY_LOCAL_MACHINE,
138 TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
139 PATH_BUF_SIZE, NULL);
144 SetDllDirectory(TEXT(""));
145 BOOL _result = SetDllDirectory(path);
146 assert(_result != 0);
150 HMODULE module = LoadLibrary(utf16_string(filename).c_str());
151 SetDllDirectory(NULL);
155 return (void *) module;
158 int dlclose(void *handle) {
159 if (FreeLibrary((HMODULE) handle))
165 void *dlsym(void *handle, const char *symbol) {
166 return (void *) (intptr_t) GetProcAddress((HMODULE) handle, symbol);
169 const char *windoze_local_db(void) {
171 if (path.length() == 0)
172 path = managementPath("%LOCALAPPDATA%\\pEp", "management.db");
176 const char *windoze_system_db(void) {
178 if (path.length() == 0)
179 path = managementPath("%ALLUSERSPROFILE%\\pEp", "system.db");
183 const char *gpg_conf(void)
186 if (path.length() == 0)
187 path = managementPath("%APPDATA%\\gnupg", "gpg.conf");
196 assert(sizeof(unsigned int) == sizeof(long)); // this is Windoze
202 return (long) (r & ((1<<31)-1));