diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c index 8d21eb919..9ccbb7211 100644 --- a/winpr/libwinpr/library/library.c +++ b/winpr/libwinpr/library/library.c @@ -299,65 +299,92 @@ static DWORD module_from_proc(const char* proc, LPSTR lpFilename, DWORD nSize) DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize) { + if (hModule) + { + WLog_ERR(TAG, "is not implemented"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; + } + #if defined(__linux__) - if (!hModule) - return module_from_proc("/proc/self/exe", lpFilename, nSize); + return module_from_proc("/proc/self/exe", lpFilename, nSize); #elif defined(__FreeBSD__) int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; size_t cb = nSize; - const int rc = sysctl(mib, ARRAYSIZE(mib), lpFilename, &cb, NULL, 0); - if ((rc != 0) || (cb > nSize)) + { + const int rc = sysctl(mib, ARRAYSIZE(mib), NULL, &cb, NULL, 0); + if (rc != 0) + { + SetLastError(ERROR_INTERNAL_ERROR); + return 0; + } + } + + char* fullname = calloc(cb + 1, sizeof(char)); + if (!fullname) { SetLastError(ERROR_INTERNAL_ERROR); return 0; } - return (DWORD)cb; -#elif defined(__NetBSD__) - if (!hModule) - return module_from_proc("/proc/curproc/exe", lpFilename, nSize); -#elif defined(__DragonFly__) - if (!hModule) - return module_from_proc("/proc/curproc/file", lpFilename, nSize); -#elif defined(__MACOSX__) - int status; - size_t length; - - if (!hModule) { - char path[4096]; - char buffer[4096]; - uint32_t size = sizeof(path); - status = _NSGetExecutablePath(path, &size); - - if (status != 0) + size_t cb2 = cb; + const int rc = sysctl(mib, ARRAYSIZE(mib), fullname, &cb2, NULL, 0); + if ((rc != 0) || (cb2 != cb)) { - /* path too small */ SetLastError(ERROR_INTERNAL_ERROR); + free(fullname); return 0; } - - /* - * _NSGetExecutablePath may not return the canonical path, - * so use realpath to find the absolute, canonical path. - */ - realpath(path, buffer); - length = strnlen(buffer, sizeof(buffer)); - - if (length < nSize) - { - CopyMemory(lpFilename, buffer, length); - lpFilename[length] = '\0'; - return (DWORD)length; - } - - CopyMemory(lpFilename, buffer, nSize - 1); - lpFilename[nSize - 1] = '\0'; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return nSize; } + if (nSize > 0) + { + strncpy(lpFilename, fullname, nSize - 1); + lpFilename[nSize - 1] = '\0'; + } + free(fullname); + + if (nSize < cb) + SetLastError(ERROR_INSUFFICIENT_BUFFER); + + return (DWORD)MIN(nSize, cb); +#elif defined(__NetBSD__) + return module_from_proc("/proc/curproc/exe", lpFilename, nSize); +#elif defined(__DragonFly__) + return module_from_proc("/proc/curproc/file", lpFilename, nSize); +#elif defined(__MACOSX__) + char path[4096] = { 0 }; + char buffer[4096] = { 0 }; + uint32_t size = sizeof(path); + const int status = _NSGetExecutablePath(path, &size); + + if (status != 0) + { + /* path too small */ + SetLastError(ERROR_INTERNAL_ERROR); + return 0; + } + + /* + * _NSGetExecutablePath may not return the canonical path, + * so use realpath to find the absolute, canonical path. + */ + realpath(path, buffer); + const size_t length = strnlen(buffer, sizeof(buffer)); + + if (length < nSize) + { + CopyMemory(lpFilename, buffer, length); + lpFilename[length] = '\0'; + return (DWORD)length; + } + + CopyMemory(lpFilename, buffer, nSize - 1); + lpFilename[nSize - 1] = '\0'; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return nSize; #endif WLog_ERR(TAG, "is not implemented"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);