2 #define _BIND_TO_CURRENT_VCLIBS_VERSION 1 7 #pragma comment(lib, "Psapi") 8 #pragma comment(lib, "Ws2_32") 9 #pragma comment(lib, "Advapi32") 10 #pragma comment(lib, "Shell32") 11 #elif defined(__unix__) || defined(__APPLE__) 13 #include <sys/types.h> 15 #include <sys/sysctl.h> 24 #include <mach-o/dyld.h> 38 #include "../icedb/error.h" 39 #include "../icedb/error_context.h" 40 #include "../icedb/misc/os_functions.h" 41 #include "../icedb/misc/os_functions.hpp" 44 #include "../icedb/util.h" 47 namespace os_functions {
60 std::map<std::string, std::string>
mmods;
64 BOOL WINAPI _CloseHandlerRoutine(DWORD dwCtrlType) {
70 std::string convertStr(
const LPTSTR instr)
73 size_t origsize = wcslen(instr) + 1;
75 const size_t newsize = origsize * 4;
76 size_t convertedChars = 0;
77 std::unique_ptr<char[]> nstring(
new char[newsize]);
78 wcstombs_s(&convertedChars, nstring.get(), origsize, instr, _TRUNCATE);
80 std::string res(nstring.get());
82 std::string res(instr);
84 return std::move(res);
87 std::string convertStr(
const PWSTR instr)
89 size_t origsize = wcslen(instr) + 1;
91 const size_t newsize = origsize * 4;
92 size_t convertedChars = 0;
93 std::unique_ptr<char[]> nstring(
new char[newsize]);
95 wcstombs_s(&convertedChars, nstring.get(), origsize, instr, _TRUNCATE);
97 std::string res(nstring.get());
99 return std::move(res);
102 HMODULE GetCurrentModule()
111 HMODULE hModule = NULL;
113 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
114 (LPCTSTR)GetCurrentModule,
120 std::string GetModulePath(HMODULE mod)
123 bool freeAtEnd =
false;
126 mod = GetCurrentModule();
127 if (!mod)
return std::move(out);
130 const DWORD nSize = MAX_PATH * 4;
131 TCHAR filename[nSize];
132 DWORD sz = GetModuleFileName(mod, filename, nSize);
133 out = convertStr(filename);
136 return std::move(out);
139 bool getPathWIN32(DWORD pid, std::string &modPath, std::string &filename)
141 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
142 if (NULL == h)
return false;
145 h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
148 if (NULL == h)
return false;
149 TCHAR szModName[MAX_PATH];
151 DWORD sz =
sizeof(szModName) /
sizeof(TCHAR);
152 success = QueryFullProcessImageName(h, 0, szModName, &sz);
155 modPath = convertStr(szModName);
156 size_t lp = modPath.find_last_of(
"/\\");
157 if (lp == std::string::npos) filename = modPath;
158 else if (lp < modPath.size()-1) filename = modPath.substr(lp + 1);
159 else filename = modPath;
165 const size_t mxErrorMsg = 500;
166 char es[mxErrorMsg] =
"";
167 success = GetLastError();
168 snprintf(es, mxErrorMsg,
"%d", success);
175 bool IsAppRunningAsAdminMode()
177 BOOL fIsRunAsAdmin = FALSE;
178 DWORD dwError = ERROR_SUCCESS;
179 PSID pAdministratorsGroup = NULL;
182 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
183 if (!AllocateAndInitializeSid(
186 SECURITY_BUILTIN_DOMAIN_RID,
187 DOMAIN_ALIAS_RID_ADMINS,
189 &pAdministratorsGroup))
191 dwError = GetLastError();
197 if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
199 dwError = GetLastError();
205 if (pAdministratorsGroup)
207 FreeSid(pAdministratorsGroup);
208 pAdministratorsGroup = NULL;
212 if (ERROR_SUCCESS != dwError)
215 const size_t mxErrorMsg = 500;
216 char es[mxErrorMsg] =
"";
217 snprintf(es, mxErrorMsg,
"%d", dwError);
222 if (fIsRunAsAdmin)
return true;
228 #if defined(__linux__) || defined(__unix__) 229 int moduleCallback(dl_phdr_info *info,
size_t sz,
void* data)
232 std::string name(info->dlpi_name);
233 if (!name.size())
return 0;
238 #if defined(__unix__) || defined(__APPLE__) 239 bool dirExists(
const char *p) {
242 bool res = (d) ?
true :
false;
247 #if defined(__APPLE__) || defined(__linux__) || defined(__unix__) 248 std::string GetModulePath(
void *addr)
253 if (!addrb) addrb = (
void*)GetModulePath;
254 if (dladdr(addrb, &info))
256 out = std::string(info.dli_fname);
272 #if defined(ICEDB_OS_WINDOWS) 274 const DWORD clen = 256;
277 res = GetUserName(hname, &len);
278 if (res)
username = win::convertStr(hname);
279 else goto funcErrorOS;
281 res = GetComputerName(hname, &len);
282 if (res)
hostname = win::convertStr(hname);
283 else goto funcErrorOS;
285 HRESULT resl =
false;
286 wchar_t* happname =
nullptr;
287 res = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &happname);
288 if (resl == S_OK)
appConfigDir = win::convertStr(happname);
289 else goto funcErrorOS;
291 wchar_t* hhomename =
nullptr;
292 res = SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &hhomename);
293 if (resl == S_OK)
homeDir = win::convertStr(hhomename);
294 else goto funcErrorOS;
298 DWORD errn = GetLastError();
303 snprintf(errns, 50,
"%d", errn);
310 if (happname) CoTaskMemFree(static_cast<void*>(happname));
311 if (hhomename) CoTaskMemFree(static_cast<void*>(hhomename));
313 #elif defined(__unix__) || defined(__APPLE__) 314 const size_t len = 65536;
319 if ((envres = getenv(
"USER")))
username = std::string(envres);
320 else if ((envres = getenv(
"LOGNAME")))
username = std::string(envres);
322 #if defined(_POSIX_C_SOURCE) 323 #if _POSIX_C_SOURCE >= 199506L 324 res = getlogin_r(hname, len);
325 if (!res)
username = std::string(hname);
327 if ((envres = getlogin()))
username = std::string(envres);
331 uid_t uid = geteuid();
332 struct passwd* ps = (passwd*)
ICEDB_malloc(
sizeof(passwd));
333 struct passwd** pres;
334 res = getpwuid_r(uid, ps, hname, len, pres);
335 if ((res == 0) && pres) {
336 username = std::string(ps->pw_name);
343 uid_t uid = geteuid();
344 struct passwd* ps = getpwuid(uid);
345 if (ps)
username = std::string(ps->pw_name);
350 res = gethostname(hname, len);
351 if (hname[0])
hostname = std::string(hname);
354 if ((envres = getenv(
"HOME")))
homeDir = std::string(envres);
357 #if defined(_POSIX_C_SOURCE) || defined(_BSD_SOURCE) || defined(_SVID_SOURCE) 358 struct passwd pw, *pwp;
359 int res = getpwuid_r(geteuid(), &pw, hname, len, &pwp);
361 const char *homedir = pw.pw_dir;
362 homeDir = std::string(homedir);
365 struct passwd* ps = getpwuid(geteuid());
366 if (ps)
homeDir = std::string(ps->pw_dir);
369 if (!
homeDir.size())
goto funcErrorOS;
372 if ((envres = getenv(
"XDG_CONFIG_HOME")))
appConfigDir = std::string(envres);
405 #if defined(ICEDB_OS_WINDOWS) 406 HANDLE h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
410 if (GetExitCodeProcess(h, &code))
413 if (code == STILL_ACTIVE)
433 #elif defined(ICEDB_OS_LINUX) 435 std::ostringstream pname;
436 pname <<
"/proc/" << pid;
437 if (icedb::os_functions::unix::dirExists(pname.str().c_str())) {
443 #elif defined(__FreeBSD__) || defined (__APPLE__) 448 struct kinfo_proc kp;
452 sysctlnametomib(
"kern.proc.pid", mib, &len);
455 int sres = sysctl(mib, 4, &kp, &len, NULL, 0);
458 if (errno == ENOENT) {
459 res =
false;
return true;
464 const int buflen = 200;
465 char strerrbuf[buflen] =
"\0";
466 snprintf(strerrbuf, buflen,
"%d", errno);
472 else if ((sres == 0) && (len > 0)) res =
true;
482 #if defined(__unix__) 483 return (
int)getpid();
484 #elif defined(ICEDB_OS_WINDOWS) 487 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
488 if (NULL == h)
return false;
489 PROCESSENTRY32 pe = { 0 };
490 pe.dwSize =
sizeof(PROCESSENTRY32);
491 pid = GetCurrentProcessId();
502 #if defined(__unix__) 503 return (
int)getppid();
504 #elif defined(ICEDB_OS_WINDOWS) 505 DWORD Dpid = pid, ppid = 0;
506 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
507 if (NULL == h)
return false;
508 PROCESSENTRY32 pe = { 0 };
509 pe.dwSize =
sizeof(PROCESSENTRY32);
510 if (!pid) Dpid = GetCurrentProcessId();
511 if (Process32First(h, &pe)) {
513 if (pe.th32ProcessID == Dpid) {
514 ppid = pe.th32ParentProcessID;
517 }
while (Process32Next(h, &pe));
531 #if defined(ICEDB_OS_WINDOWS) 533 DWORD pid = 0, ppid = 0;
534 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
535 if (NULL == h)
return false;
536 PROCESSENTRY32 pe = { 0 };
537 pe.dwSize =
sizeof(PROCESSENTRY32);
538 pid = GetCurrentProcessId();
539 if (Process32First(h, &pe)) {
541 if (pe.th32ProcessID == pid) {
542 ppid = pe.th32ParentProcessID;
544 }
while (Process32Next(h, &pe));
549 std::string filepath, filename;
550 icedb::os_functions::win::getPathWIN32(ppid, filepath, filename);
554 if (filename ==
"cmd.exe")
return false;
556 if (filename ==
"bash.exe")
return false;
557 if (filename ==
"tcsh.exe")
return false;
599 for (
int i = 0; i < p->
sz; ++i) {
611 HANDLE h = NULL, snapshot = NULL;
612 h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
613 std::shared_ptr<MODULEENTRY32> mod(
new MODULEENTRY32);
614 if (!h || h == INVALID_HANDLE_VALUE)
goto err;
615 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
616 if (!snapshot || snapshot == INVALID_HANDLE_VALUE)
goto err;
617 mod->dwSize =
sizeof(MODULEENTRY32);
618 if (!Module32First(snapshot, mod.get()))
goto err;
620 std::string modName = icedb::os_functions::win::convertStr(mod->szModule);
621 std::string modPath = icedb::os_functions::win::convertStr(mod->szExePath);
623 }
while (Module32Next(snapshot, mod.get()));
630 if (!h || h == INVALID_HANDLE_VALUE)
632 else if (!snapshot || snapshot == INVALID_HANDLE_VALUE)
637 if (snapshot && snapshot != INVALID_HANDLE_VALUE) CloseHandle(snapshot);
638 if (h && h != INVALID_HANDLE_VALUE) CloseHandle(h);
639 #elif defined(__linux__) || defined(__unix__) 648 dl_iterate_phdr(icedb::os_functions::unix::moduleCallback, NULL);
650 #elif defined(__APPLE__) 651 uint32_t count = _dyld_image_count();
652 for (uint32_t i=0; i<count; ++i) {
653 std::string modName(_dyld_get_image_name(i));
655 char *ccmodPath = realpath(modName.c_str(), NULL);
656 if (ccmodPath != NULL) {
657 strncpy(cmodPath,ccmodPath,2048);
660 std::string modPath(ccmodPath);
669 for (
auto &s :
mmods) {
673 p->
modules =
const_cast<const char**
>(nmods);
686 BOOL success =
false;
689 DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
690 LPCTSTR lpModuleName = (LPCTSTR)ptr;
692 success = GetModuleHandleEx(flags, lpModuleName, &mod);
693 if (!success)
return nullptr;
694 modpath = icedb::os_functions::win::GetModulePath(mod);
696 }
else modpath = icedb::os_functions::win::GetModulePath(NULL);
697 #elif defined(__unix__) || defined(__APPLE__) 698 modpath = icedb::os_functions::unix::GetModulePath(ptr);
708 libPath = icedb::os_functions::win::GetModulePath(NULL);
709 #elif defined(__unix__) || defined(__APPLE__) 724 std::string &appd =
appDir;
727 std::string filename;
728 icedb::os_functions::win::getPathWIN32(pid,
appPath, filename);
730 #elif defined(__APPLE__) 731 char exePath[PATH_MAX];
732 uint32_t len =
sizeof(exePath);
733 if (_NSGetExecutablePath(exePath, &len) != 0) {
738 char *canonicalPath = realpath(exePath, NULL);
739 if (canonicalPath != NULL) {
740 strncpy(exePath, canonicalPath, len);
744 appPath = std::string(exePath);
746 #elif defined(__linux__) 747 char exePath[PATH_MAX];
748 ssize_t len = ::readlink(
"/proc/self/exe", exePath,
sizeof(exePath));
749 if (len == -1 || len ==
sizeof(exePath)) len = 0;
751 appPath = std::string(exePath);
753 #elif defined(__unix__) 755 int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1;
756 size_t len =
sizeof(exePath);
757 if (sysctl(mib, 4, exePath, &len, NULL, 0) != 0)
759 appPath = std::string(exePath);
775 std::string &cwd =
CWD;
777 DWORD sz = GetCurrentDirectory(0, NULL);
778 LPTSTR cd =
new TCHAR[sz];
779 DWORD result = GetCurrentDirectory(2500, cd);
780 cwd = std::string(cd);
784 char* res = getcwd(ccwd, 4096);
791 cwd = std::string(ccwd);
852 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
853 if (NULL == h)
return;
854 PROCESSENTRY32 pe = { 0 };
855 pe.dwSize =
sizeof(PROCESSENTRY32);
856 pid = GetCurrentProcessId();
860 h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION
863 if (NULL == h)
return;
864 TCHAR szModName[600];
866 DWORD sz =
sizeof(szModName) /
sizeof(TCHAR);
867 success = QueryFullProcessImageName(h, 0, szModName, &sz);
870 SetConsoleTitle(szModName);
878 SetConsoleCtrlHandler(icedb::os_functions::win::_CloseHandlerRoutine,
true);
909 cerr << endl <<
"Program terminated. Press return to exit." << endl;
918 std::getline(cin, ln);
924 OutputDebugStringA(c);
936 namespace os_functions {
std::map< std::string, std::string > mmods
const char * ICEDB_getCWDC()
#define ICEDB_DEBUG_RAISE_EXCEPTION()
const char * ICEDB_getAppPathC()
const char * getHomeDir()
std::string moduleCallbackBuffer
char * ICEDB_getLibPath(size_t sz, char *res)
const char * getUserName()
const char * ICEDB_getLibPathC()
bool ICEDB_waitOnExitGet()
ICEDB_SYMBOL_SHARED void ICEDB_free(void *obj)
Free memory region. Should not be double-freed.
bool doWaitOnExit
Private flag that determines if the app waits for the user to press 'Enter' to terminate it at the en...
const char * getAppConfigDir()
const char * ICEDB_getAppConfigDir()
void ICEDB_getPluginDirI()
Unimplemented function path.
char * ICEDB_getAppPath(size_t sz, char *res)
const char * ICEDB_getAppDirC()
DL_ICEDB ICEDB_error_getOSname_f ICEDB_error_getOSname
void ICEDB_free_enumModulesRes(ICEDB_enumModulesRes *p)
bool ICEDB_waitOnExitGetDefault()
char * ICEDB_getPluginDir(size_t sz, char *res)
bool doWaitOnExitQueriedDefault
int ICEDB_getPPID(int pid)
ICEDB_BEGIN_DECL_C ICEDB_SYMBOL_SHARED size_t ICEDB_COMPAT_strncpy_s(char *dest, size_t destSz, const char *src, size_t srcSz)
const char * getPluginDir()
char * ICEDB_getAppDir(size_t sz, char *res)
char * ICEDB_getLibDir(size_t sz, char *res)
const char * ICEDB_getPluginDirC()
ICEDB_SYMBOL_SHARED char * ICEDB_COMPAT_strdup_s(const char *src, size_t srcSz)
const char * getAppPath()
const char * ICEDB_getUserName()
const char * getHostName()
ICEDB_SYMBOL_SHARED void * ICEDB_malloc(size_t numBytes)
Allocate memory in bytes. Generally this is just malloced, but a custom allocator may be substituted...
char * ICEDB_getCWD(size_t ssz, char *res)
std::vector< std::pair< std::string, std::string > > loadedModulesList
void ICEDB_writeDebugString(const char *c)
const char * ICEDB_getHostName()
const char * getLibPath()
bool ICEDB_pidExists(int pid, bool &res)
void waitOnExit(bool val)
Error returned by an os subsystem (general)
char * ICEDB_findModuleByFunc(void *ptr, size_t sz, char *res)
void ICEDB_libEntry(int, char **)
Entry function that gets called when a debugged application first loads.
#define ICEDB_error_context_add_string2
ICEDB_enumModulesRes * ICEDB_enumModules(int pid)
void libEntry(int argc, char **argv)
const char * ICEDB_getLibDirC()
#define ICEDB_error_context_create(x)
void ICEDB_waitOnExitSet(bool val)
const char * ICEDB_getHomeDir()
#define ICEDB_COMPAT_fprintf_s