From b17e520be70d78f812ac5c616309571c6f565f40 Mon Sep 17 00:00:00 2001 From: Matthew LeGendre Date: Fri, 13 Mar 2020 17:52:25 -0700 Subject: [PATCH 1/3] Initial windows port of Adiak --- CMakeLists.txt | 1 + include/adiak.h | 6 + include/adiak_internal.hpp | 2 +- src/CMakeLists.txt | 7 +- src/adiak.c | 31 +++-- src/adksys.h | 2 +- src/adksys_windows.c | 241 +++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 17 +++ tests/testapp.c | 30 ++--- tests/testapp.cpp | 24 ++-- tests/testlib.c | 24 +++- 11 files changed, 342 insertions(+), 43 deletions(-) create mode 100644 src/adksys_windows.c create mode 100644 tests/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index c681fc5..1e49d3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ endif() include(${BLT_SOURCE_DIR}/SetupBLT.cmake) add_subdirectory(src) +add_subdirectory(tests) include(CMakePackageConfigHelpers) diff --git a/include/adiak.h b/include/adiak.h index 62557f0..ac2efdd 100644 --- a/include/adiak.h +++ b/include/adiak.h @@ -8,6 +8,12 @@ #include +#if defined(_MSC_VER) +#include +#else +#include +#endif + #if defined(__cplusplus) extern "C" { #endif diff --git a/include/adiak_internal.hpp b/include/adiak_internal.hpp index 659dc23..103f345 100644 --- a/include/adiak_internal.hpp +++ b/include/adiak_internal.hpp @@ -203,7 +203,7 @@ namespace adiak return false; } element_type::set(*value, valarray); - dtype->num_elements = c.size(); + dtype->num_elements = (int) c.size(); return true; } }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2694d1..6324af6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,8 +5,13 @@ set(adiak_public_headers ../include/adiak.h ../include/adiak.hpp ../include/adia if (APPLE) set(adiak_sys_sources adksys_posix.c adksys_unix.c adksys_osx.c) +set(adiak_sys_depends) elseif (UNIX) set(adiak_sys_sources adksys_glibc.c adksys_posix.c adksys_procfs.c adksys_unix.c) +set(adiak_sys_depends) +elseif (WIN32) +set(adiak_sys_sources adksys_windows.c) +set(adiak_sys_depends Secur32 Ws2_32) endif () if (MPI_FOUND) @@ -21,7 +26,7 @@ endif() blt_add_library( NAME adiak HEADERS ${adiak_public_headers} SOURCES adiak.c ${adiak_sys_sources} ${adiak_mpi_source} - DEPENDS_ON ${adiak_mpi_depends}) + DEPENDS_ON ${adiak_mpi_depends} ${adiak_sys_depends}) install(FILES ${adiak_public_headers} diff --git a/src/adiak.c b/src/adiak.c index d110f9a..6e2cb17 100644 --- a/src/adiak.c +++ b/src/adiak.c @@ -3,6 +3,10 @@ // // SPDX-License-Identifier: MIT +#if defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif + #include #include #include @@ -354,7 +358,7 @@ static adiak_datatype_t *parse_typestr(const char *typestr, va_list *ap) int end = 0; int len; - len = strlen(typestr); + len = (int) strlen(typestr); return parse_typestr_helper(typestr, 0, len, ap, &end); } @@ -768,6 +772,12 @@ int adiak_launchday() return 0; } +#if defined(_MSC_VER) +#define FILESEP '\\' +#else +#define FILESEP '/' +#endif + int adiak_executable() { char path[MAX_PATH_LEN+1]; @@ -778,7 +788,7 @@ int adiak_executable() if (result == -1) return -1; - filepart = strrchr(path, '/'); + filepart = strrchr(path, FILESEP); if (!filepart) filepart = path; else @@ -966,9 +976,9 @@ int adiak_hostlist() { char **hostlist_array = NULL; int num_hosts = 0, result = -1; - char *name_buffer = NULL; - + #if defined(USE_MPI) + char* name_buffer = NULL; if (adiak_config->use_mpi) result = adksys_hostlist(&hostlist_array, &num_hosts, &name_buffer, adiak_config->report_on_all_ranks); #endif @@ -985,9 +995,9 @@ int adiak_num_hosts() { char **hostlist_array = NULL; int num_hosts = 0, result = -1; - char *name_buffer = NULL; - + #if defined(USE_MPI) + char* name_buffer = NULL; if (adiak_config->use_mpi) result = adksys_hostlist(&hostlist_array, &num_hosts, &name_buffer, adiak_config->report_on_all_ranks); #endif @@ -1002,9 +1012,10 @@ int adiak_num_hosts() int adiak_job_size() { - int result = -1, size = 1; + int size = 1; #if defined(USE_MPI) + int result = -1; if (adiak_config->use_mpi) result = adksys_jobsize(&size); if (result == -1) @@ -1123,7 +1134,7 @@ static int adiak_type_string_helper(adiak_datatype_t *t, char *str, int len, int if (!size_calc_only) result = snprintf(str + pos, len - pos, "%s", simple); else - result = strlen(simple); + result = (int) strlen(simple); if (result != -1) pos += result; } @@ -1131,7 +1142,7 @@ static int adiak_type_string_helper(adiak_datatype_t *t, char *str, int len, int if (!size_calc_only) result = snprintf(str + pos, len - pos, "%s", lbracket); else - result = strlen(lbracket); + result = (int) strlen(lbracket); if (result > 0) pos += result; for (i = 0; i < t->num_subtypes; i++) { pos += adiak_type_string_helper(t->subtype[i], str, len, pos, long_form, size_calc_only); @@ -1146,7 +1157,7 @@ static int adiak_type_string_helper(adiak_datatype_t *t, char *str, int len, int if (!size_calc_only) result = snprintf(str + pos, len - pos, "%s", rbracket); else - result = strlen(rbracket); + result = (int) strlen(rbracket); if (result > 0) pos += result; } return pos - start_pos; diff --git a/src/adksys.h b/src/adksys.h index b2dccf2..f1ace4e 100644 --- a/src/adksys.h +++ b/src/adksys.h @@ -6,7 +6,7 @@ #if !defined(ADKSYS_H_) #define ADKSYS_H_ -#include /* struct timeval */ +#include "adiak.h" int adksys_get_libraries(char ***libraries, int *libraries_size, int *libnames_need_free); int adksys_hostlist(char ***out_hostlist_array, int *out_num_hosts, char **out_name_buffer, int all_ranks); diff --git a/src/adksys_windows.c b/src/adksys_windows.c new file mode 100644 index 0000000..d681cd7 --- /dev/null +++ b/src/adksys_windows.c @@ -0,0 +1,241 @@ +#include "adksys.h" +#include +#include +#include +#include + +#define SECURITY_WIN32 +#include + +#if defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif + +int adksys_get_libraries(char*** libraries, int* libraries_size, int* libnames_need_free) +{ + BOOL result; + HMODULE *module_handles = NULL; + HANDLE proc; + int fresult = -1, libs_size = 0, nresult; + DWORD bytes_needed; + char** lib_names = NULL, lib_name_buffer[MAX_PATH]; + + proc = GetCurrentProcess(); + if (!proc) + goto done; + + result = EnumProcessModules(proc, NULL, 0, &bytes_needed); + if (!result) + goto done; + + module_handles = (HMODULE *) malloc(bytes_needed); + if (!result) + goto done; + + result = EnumProcessModules(proc, module_handles, bytes_needed, &bytes_needed); + if (!result) + goto done; + + libs_size = bytes_needed / sizeof(HMODULE); + lib_names = (char**) malloc(libs_size * sizeof(char*)); + memset(lib_names, 0, libs_size * sizeof(char*)); + + for (int i = 0; i < libs_size; i++) { + nresult = GetModuleFileName(module_handles[i], lib_name_buffer, sizeof(lib_name_buffer)); + if (!nresult) + goto done; + lib_names[i] = strdup(lib_name_buffer); + } + + *libraries = lib_names; + *libraries_size = libs_size; + *libnames_need_free = 1; + + fresult = 0; +done: + if (module_handles) + free(module_handles); + + if (fresult == -1 && lib_names) { + for (int i = 0; i < libs_size; i++) { + if (lib_names[i]) + free(lib_names[i]); + } + free(lib_names); + } + + return fresult; + +} + +#define EPOCH_DIFFERENCE 11644473600UL +static void filetime_to_timeval(FILETIME ft, struct timeval* tv, BOOL calendar_time) +{ + unsigned long long tmp; + + tmp = (((unsigned long long) ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + tv->tv_sec = (unsigned long) (tmp / 10000000); + tv->tv_usec = (unsigned long) (tmp % 10000000) / 10; + if (calendar_time) + tv->tv_sec = (unsigned long) (tv->tv_sec - EPOCH_DIFFERENCE); +} + +int adksys_get_times(struct timeval* sys, struct timeval* cpu) +{ + HANDLE proc; + FILETIME creation_time, exit_time, user_time, sys_time; + BOOL result; + + proc = GetCurrentProcess(); + + result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); + if (!result) + return -1; + + if (sys) + filetime_to_timeval(sys_time, sys, FALSE); + if (cpu) + filetime_to_timeval(user_time, cpu, FALSE); + + return 0; +} + +int adksys_curtime(struct timeval* tm) +{ + FILETIME curtime; + GetSystemTimeAsFileTime(&curtime); + filetime_to_timeval(curtime, tm, TRUE); + return 0; +} + +int adksys_hostname(char* outbuffer, int buffer_size) +{ + static char* hostname = NULL; + static int err_ret = 0; + WSADATA unused; + int result; + + if (hostname || err_ret) { + if (err_ret) + return err_ret; + strncpy(outbuffer, hostname, buffer_size); + outbuffer[buffer_size - 1] = '\0'; + return 0; + } + + result = WSAStartup(MAKEWORD(1, 0), &unused); + if (result != 0) { + err_ret = -1; + return -1; + } + result = gethostname(outbuffer, buffer_size); + if (result != 0) { + err_ret = -1; + return -1; + } + outbuffer[buffer_size - 1] = '\0'; + + hostname = strdup(outbuffer); + err_ret = 0; + + WSACleanup(); + + return 0; +} + +int adksys_starttime(struct timeval* tv) +{ + HANDLE proc; + FILETIME creation_time, exit_time, user_time, sys_time; + BOOL result; + + proc = GetCurrentProcess(); + + result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); + if (!result) + return -1; + + filetime_to_timeval(creation_time, tv, TRUE); + return 0; +} + +int adksys_get_executable(char* outpath, size_t outpath_size) +{ + HANDLE proc; + int result; + + proc = GetCurrentProcess(); + result = GetProcessImageFileName(proc, outpath, (int) outpath_size); + if (!result) + return -1; + return 0; +} + +int adksys_get_cmdline_buffer(char** output_buffer, int* output_size) +{ + LPWSTR cmdline; + LPWSTR *argv; + char* buffer; + int argc, buffer_size = 0, pos = 0, bytes_written; + + cmdline = GetCommandLineW(); + argv = CommandLineToArgvW(cmdline, &argc); + + for (int i = 0; i < argc; i++) { + buffer_size += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); + buffer_size++; + } + + buffer = (char *) malloc(buffer_size); + for (int i = 0; i < argc; i++) { + bytes_written = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, buffer + pos, buffer_size - pos, NULL, NULL); + pos += bytes_written; + } + assert(pos <= buffer_size); + LocalFree(argv); + + *output_buffer = buffer; + *output_size = pos; + + return 0; +} + +int adksys_get_names(char** uid, char** user) +{ + BOOL result; + char localname[4096]; + unsigned long lname_size = sizeof(localname); + + if (user) { + result = GetUserNameEx(NameDisplay, localname, &lname_size); + if (!result) + return -1; + *user = strdup(localname); + } + + if (uid) { + lname_size = sizeof(localname); + result = GetUserNameEx(NameCanonical, localname, &lname_size); + if (!result) { + free(*user); + return -1; + } + *uid = strdup(localname); + } + + return 0; +} + +int adksys_get_cwd(char* cwd, size_t max_size) +{ + char* p; + p = getcwd(cwd, (int) max_size); + if (!p) + return -1; + return 0; +} + +void* adksys_get_public_adiak_symbol() +{ + return NULL; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..6d99b80 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,17 @@ +include_directories(../include) + +if (MPI_FOUND) +add_definitions("-DUSE_MPI") +endif() + +blt_add_library(NAME testlib + SOURCES testlib.c + DEPENDS_ON adiak) + +blt_add_executable(NAME adiakctest + SOURCES testapp.c + DEPENDS_ON adiak testlib) + +blt_add_executable(NAME adiakcxxtest + SOURCES testapp.cpp + DEPENDS_ON adiak testlib) \ No newline at end of file diff --git a/tests/testapp.c b/tests/testapp.c index 78f7538..5c03816 100644 --- a/tests/testapp.c +++ b/tests/testapp.c @@ -1,18 +1,20 @@ +#if defined(_MSC_VER) +#pragma warning(disable : 4100) +#pragma warning(disable : 4996) +#endif + #include "adiak.h" -#include "testlib.c" #include #include -#include #include #if defined(USE_MPI) #include #endif -void dowork(struct timeval start) +void dowork() { int result; - struct timeval end; double gridarray[4] = { 4.5, 1.18, 0.24, 8.92 }; @@ -66,23 +68,21 @@ void dowork(struct timeval start) if (result != 0) printf("return: %d\n\n", result); #endif - gettimeofday(&end, NULL); - struct timeval *timerange[2]; - timerange[0] = &start; - timerange[1] = &end; - result = adiak_namevalue("computetime", adiak_performance, NULL, "<%t>", &timerange); - result = adiak_flush("stdout"); if (result != 0) printf("return: %d\n\n", result); } -int main(int argc, char *argv[]) +extern void onload(); + +int main(int argc, char* argv[]) { +#if defined(_MSC_VER) + onload(); +#endif + #if defined(USE_MPI) MPI_Comm world = MPI_COMM_WORLD; #endif - struct timeval start; - gettimeofday(&start, NULL); #if defined(USE_MPI) MPI_Init(&argc, &argv); @@ -92,8 +92,8 @@ int main(int argc, char *argv[]) #endif - dowork(start); - dowork(start); + dowork(); + dowork(); adiak_clean(); diff --git a/tests/testapp.cpp b/tests/testapp.cpp index 9b03da9..4cd3951 100644 --- a/tests/testapp.cpp +++ b/tests/testapp.cpp @@ -1,9 +1,13 @@ +#if defined(_MSC_VER) +#pragma warning(disable : 4100) +#pragma warning(disable : 4996) +#endif + #include "adiak.hpp" #include #include #include #include -#include #if defined(USE_MPI) @@ -12,10 +16,9 @@ using namespace std; -void dowork(struct timeval start) +void dowork() { bool result; - struct timeval end; vector grid; grid.push_back(4.5); @@ -132,10 +135,6 @@ void dowork(struct timeval start) if (!result) printf("return: %d\n\n", result); #endif -/* gettimeofday(&end, NULL); - result = adiak::value("computetime", &start, &end); - if (!result) printf("return: %d\n\n", result);*/ - array floatar; floatar[0] = 0.01f; floatar[1] = 0.02f; @@ -144,16 +143,18 @@ void dowork(struct timeval start) if (!result) printf("return: %d\n\n", result); } +extern "C" { void onload(); } + int main(int argc, char *argv[]) { +#if defined(_MSC_VER) + onload(); +#endif + #if defined(USE_MPI) MPI_Comm world = MPI_COMM_WORLD; #endif - struct timeval start; - dowork(start); - - gettimeofday(&start, NULL); #if defined(USE_MPI) MPI_Init(&argc, &argv); adiak::init(&world); @@ -161,6 +162,7 @@ int main(int argc, char *argv[]) adiak::init(NULL); #endif + dowork(); adiak::fini(); adiak::clean(); diff --git a/tests/testlib.c b/tests/testlib.c index a658975..350e230 100644 --- a/tests/testlib.c +++ b/tests/testlib.c @@ -1,14 +1,22 @@ +#if defined(_MSC_VER) +#pragma warning(disable : 4100) +#pragma warning(disable : 4996) +#endif + #include "adiak_tool.h" #include #include -#include #include #include #define XSTR(S) #S #define STR(S) XSTR(S) +#if !defined(TOOLNAME) +#define TOOLNAME tool +#endif + static void print_value(adiak_value_t *val, adiak_datatype_t *t) { if (!t) @@ -35,7 +43,14 @@ static void print_value(adiak_value_t *val, adiak_datatype_t *t) case adiak_date: { char datestr[512]; signed long seconds_since_epoch = (signed long) val->v_long; +#if defined(_MSC_VER) + __time64_t s = (__time64_t) seconds_since_epoch; + struct tm *loc, loc_tmp; + _localtime64_s(&loc_tmp, &s); + loc = &loc_tmp; +#else struct tm *loc = localtime(&seconds_since_epoch); +#endif strftime(datestr, sizeof(datestr), "%a, %d %b %Y %T %z", loc); printf("%s", datestr); break; @@ -126,9 +141,10 @@ static void print_on_flush(const char *name, int category, const char *subcatego adiak_list_namevals(1, adiak_category_all, print_nameval, NULL); } - -static void onload() __attribute__((constructor)); -static void onload() +#if !defined(_MSC_VER) +void onload() __attribute__((constructor)); +#endif +void onload() { if (strcmp(STR(TOOLNAME), "TOOL3") == 0) adiak_register_cb(1, adiak_control, print_on_flush, 0, NULL); From 67dcc39305f927f7c2f56b0c7b88a3d56c81da8b Mon Sep 17 00:00:00 2001 From: Matthew LeGendre Date: Mon, 16 Mar 2020 10:38:35 -0700 Subject: [PATCH 2/3] Fixes from linux testing after windows port --- CMakeLists.txt | 2 ++ include/adiak_internal.hpp | 4 ++-- src/CMakeLists.txt | 2 +- src/adiak.c | 4 ++-- src/adksys_mpi.c | 1 + tests/CMakeLists.txt | 2 +- tests/testapp.c | 14 ++++++++------ tests/testapp.cpp | 14 ++++++++------ tests/testlib.c | 8 ++++++++ 9 files changed, 33 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e49d3f..0497ef2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,9 @@ endif() include(${BLT_SOURCE_DIR}/SetupBLT.cmake) add_subdirectory(src) +if (BUILD_TESTING) add_subdirectory(tests) +endif() include(CMakePackageConfigHelpers) diff --git a/include/adiak_internal.hpp b/include/adiak_internal.hpp index 103f345..c795ed3 100644 --- a/include/adiak_internal.hpp +++ b/include/adiak_internal.hpp @@ -281,9 +281,9 @@ namespace adiak template struct set_tuple_type { - static void settype(adiak_datatype_t **dtypes) { + static void settype(adiak_datatype_t ** /*dtypes*/) { } - static bool setvalue(T &c, adiak_value_t *values, adiak_datatype_t *dtype) { + static bool setvalue(T & /*c*/, adiak_value_t * /*values*/ , adiak_datatype_t * /*dtype*/) { return true; } }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6324af6..a2c07f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ set(adiak_sys_sources adksys_posix.c adksys_unix.c adksys_osx.c) set(adiak_sys_depends) elseif (UNIX) set(adiak_sys_sources adksys_glibc.c adksys_posix.c adksys_procfs.c adksys_unix.c) -set(adiak_sys_depends) +set(adiak_sys_depends dl) elseif (WIN32) set(adiak_sys_sources adksys_windows.c) set(adiak_sys_depends Secur32 Ws2_32) diff --git a/src/adiak.c b/src/adiak.c index 6e2cb17..848bc2d 100644 --- a/src/adiak.c +++ b/src/adiak.c @@ -1175,8 +1175,8 @@ char *adiak_type_to_string(adiak_datatype_t *t, int long_form) buffer = (char *) malloc(len + 1); len2 = adiak_type_string_helper(t, buffer, len+1, 0, long_form, 0); - assert(len == len2); - buffer[len] = '\0'; + assert(len == len2); (void) len2; + buffer[len] = '\0'; return buffer; } diff --git a/src/adksys_mpi.c b/src/adksys_mpi.c index c6d9f41..785ba7b 100644 --- a/src/adksys_mpi.c +++ b/src/adksys_mpi.c @@ -135,6 +135,7 @@ static int gethostlist(char **hostlist, int *num_hosts, int *max_hostlen, int al *hostlist = (char *) malloc(hostlist_size); MPI_Bcast(*hostlist, hostlist_size, MPI_CHAR, 0, adiak_communicator); + (void) all_ranks; return 0; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6d99b80..97b1ac2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,4 +14,4 @@ blt_add_executable(NAME adiakctest blt_add_executable(NAME adiakcxxtest SOURCES testapp.cpp - DEPENDS_ON adiak testlib) \ No newline at end of file + DEPENDS_ON adiak testlib) diff --git a/tests/testapp.c b/tests/testapp.c index 5c03816..34d9b36 100644 --- a/tests/testapp.c +++ b/tests/testapp.c @@ -74,17 +74,19 @@ void dowork() extern void onload(); -int main(int argc, char* argv[]) -{ #if defined(_MSC_VER) - onload(); +static volatile int call_onload_manually = 1; +#else +static volatile int call_onload_manually = 0; #endif -#if defined(USE_MPI) - MPI_Comm world = MPI_COMM_WORLD; -#endif +int main(int argc, char* argv[]) +{ + if (call_onload_manually) + onload(); #if defined(USE_MPI) + MPI_Comm world = MPI_COMM_WORLD; MPI_Init(&argc, &argv); adiak_init(&world); #else diff --git a/tests/testapp.cpp b/tests/testapp.cpp index 4cd3951..dc0c95b 100644 --- a/tests/testapp.cpp +++ b/tests/testapp.cpp @@ -145,17 +145,19 @@ void dowork() extern "C" { void onload(); } -int main(int argc, char *argv[]) -{ #if defined(_MSC_VER) - onload(); +static volatile bool call_onload_manually = true; +#else +static volatile bool call_onload_manually = false; #endif -#if defined(USE_MPI) - MPI_Comm world = MPI_COMM_WORLD; -#endif +int main(int argc, char *argv[]) +{ + if (call_onload_manually) + onload(); #if defined(USE_MPI) + MPI_Comm world = MPI_COMM_WORLD; MPI_Init(&argc, &argv); adiak::init(&world); #else diff --git a/tests/testlib.c b/tests/testlib.c index 350e230..c38961a 100644 --- a/tests/testlib.c +++ b/tests/testlib.c @@ -132,6 +132,9 @@ static void print_nameval(const char *name, int category, const char *subcategor printf("%s - %s: ", STR(TOOLNAME), name); print_value(value, t); printf("\n"); + (void) category; + (void) subcategory; + (void) opaque_value; } static void print_on_flush(const char *name, int category, const char *subcategory, adiak_value_t *value, adiak_datatype_t *t, void *opaque_value) @@ -139,6 +142,11 @@ static void print_on_flush(const char *name, int category, const char *subcatego if (strcmp(name, "fini") != 0) return; adiak_list_namevals(1, adiak_category_all, print_nameval, NULL); + (void) category; + (void) subcategory; + (void) value; + (void) t; + (void) opaque_value; } #if !defined(_MSC_VER) From 567f56fec77d28aa472b7d2510b5405021ee287a Mon Sep 17 00:00:00 2001 From: Matthew LeGendre Date: Wed, 10 Nov 2021 16:51:02 -0800 Subject: [PATCH 3/3] Fixes for windows build --- src/adksys_windows.c | 485 ++++++++++++++++++++++--------------------- 1 file changed, 244 insertions(+), 241 deletions(-) diff --git a/src/adksys_windows.c b/src/adksys_windows.c index d681cd7..1b27ab9 100644 --- a/src/adksys_windows.c +++ b/src/adksys_windows.c @@ -1,241 +1,244 @@ -#include "adksys.h" -#include -#include -#include -#include - -#define SECURITY_WIN32 -#include - -#if defined(_MSC_VER) -#pragma warning(disable : 4996) -#endif - -int adksys_get_libraries(char*** libraries, int* libraries_size, int* libnames_need_free) -{ - BOOL result; - HMODULE *module_handles = NULL; - HANDLE proc; - int fresult = -1, libs_size = 0, nresult; - DWORD bytes_needed; - char** lib_names = NULL, lib_name_buffer[MAX_PATH]; - - proc = GetCurrentProcess(); - if (!proc) - goto done; - - result = EnumProcessModules(proc, NULL, 0, &bytes_needed); - if (!result) - goto done; - - module_handles = (HMODULE *) malloc(bytes_needed); - if (!result) - goto done; - - result = EnumProcessModules(proc, module_handles, bytes_needed, &bytes_needed); - if (!result) - goto done; - - libs_size = bytes_needed / sizeof(HMODULE); - lib_names = (char**) malloc(libs_size * sizeof(char*)); - memset(lib_names, 0, libs_size * sizeof(char*)); - - for (int i = 0; i < libs_size; i++) { - nresult = GetModuleFileName(module_handles[i], lib_name_buffer, sizeof(lib_name_buffer)); - if (!nresult) - goto done; - lib_names[i] = strdup(lib_name_buffer); - } - - *libraries = lib_names; - *libraries_size = libs_size; - *libnames_need_free = 1; - - fresult = 0; -done: - if (module_handles) - free(module_handles); - - if (fresult == -1 && lib_names) { - for (int i = 0; i < libs_size; i++) { - if (lib_names[i]) - free(lib_names[i]); - } - free(lib_names); - } - - return fresult; - -} - -#define EPOCH_DIFFERENCE 11644473600UL -static void filetime_to_timeval(FILETIME ft, struct timeval* tv, BOOL calendar_time) -{ - unsigned long long tmp; - - tmp = (((unsigned long long) ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - tv->tv_sec = (unsigned long) (tmp / 10000000); - tv->tv_usec = (unsigned long) (tmp % 10000000) / 10; - if (calendar_time) - tv->tv_sec = (unsigned long) (tv->tv_sec - EPOCH_DIFFERENCE); -} - -int adksys_get_times(struct timeval* sys, struct timeval* cpu) -{ - HANDLE proc; - FILETIME creation_time, exit_time, user_time, sys_time; - BOOL result; - - proc = GetCurrentProcess(); - - result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); - if (!result) - return -1; - - if (sys) - filetime_to_timeval(sys_time, sys, FALSE); - if (cpu) - filetime_to_timeval(user_time, cpu, FALSE); - - return 0; -} - -int adksys_curtime(struct timeval* tm) -{ - FILETIME curtime; - GetSystemTimeAsFileTime(&curtime); - filetime_to_timeval(curtime, tm, TRUE); - return 0; -} - -int adksys_hostname(char* outbuffer, int buffer_size) -{ - static char* hostname = NULL; - static int err_ret = 0; - WSADATA unused; - int result; - - if (hostname || err_ret) { - if (err_ret) - return err_ret; - strncpy(outbuffer, hostname, buffer_size); - outbuffer[buffer_size - 1] = '\0'; - return 0; - } - - result = WSAStartup(MAKEWORD(1, 0), &unused); - if (result != 0) { - err_ret = -1; - return -1; - } - result = gethostname(outbuffer, buffer_size); - if (result != 0) { - err_ret = -1; - return -1; - } - outbuffer[buffer_size - 1] = '\0'; - - hostname = strdup(outbuffer); - err_ret = 0; - - WSACleanup(); - - return 0; -} - -int adksys_starttime(struct timeval* tv) -{ - HANDLE proc; - FILETIME creation_time, exit_time, user_time, sys_time; - BOOL result; - - proc = GetCurrentProcess(); - - result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); - if (!result) - return -1; - - filetime_to_timeval(creation_time, tv, TRUE); - return 0; -} - -int adksys_get_executable(char* outpath, size_t outpath_size) -{ - HANDLE proc; - int result; - - proc = GetCurrentProcess(); - result = GetProcessImageFileName(proc, outpath, (int) outpath_size); - if (!result) - return -1; - return 0; -} - -int adksys_get_cmdline_buffer(char** output_buffer, int* output_size) -{ - LPWSTR cmdline; - LPWSTR *argv; - char* buffer; - int argc, buffer_size = 0, pos = 0, bytes_written; - - cmdline = GetCommandLineW(); - argv = CommandLineToArgvW(cmdline, &argc); - - for (int i = 0; i < argc; i++) { - buffer_size += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); - buffer_size++; - } - - buffer = (char *) malloc(buffer_size); - for (int i = 0; i < argc; i++) { - bytes_written = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, buffer + pos, buffer_size - pos, NULL, NULL); - pos += bytes_written; - } - assert(pos <= buffer_size); - LocalFree(argv); - - *output_buffer = buffer; - *output_size = pos; - - return 0; -} - -int adksys_get_names(char** uid, char** user) -{ - BOOL result; - char localname[4096]; - unsigned long lname_size = sizeof(localname); - - if (user) { - result = GetUserNameEx(NameDisplay, localname, &lname_size); - if (!result) - return -1; - *user = strdup(localname); - } - - if (uid) { - lname_size = sizeof(localname); - result = GetUserNameEx(NameCanonical, localname, &lname_size); - if (!result) { - free(*user); - return -1; - } - *uid = strdup(localname); - } - - return 0; -} - -int adksys_get_cwd(char* cwd, size_t max_size) -{ - char* p; - p = getcwd(cwd, (int) max_size); - if (!p) - return -1; - return 0; -} - -void* adksys_get_public_adiak_symbol() -{ - return NULL; -} +#include "adksys.h" +#include +#include +#include +#include + +#define SECURITY_WIN32 +#include + +#if defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif + +int adksys_get_libraries(char*** libraries, int* libraries_size, int* libnames_need_free) +{ + BOOL result; + HMODULE *module_handles = NULL; + HANDLE proc; + int fresult = -1, libs_size = 0, nresult; + DWORD bytes_needed = 0; + char** lib_names = NULL, lib_name_buffer[4096]; + + proc = GetCurrentProcess(); + if (!proc) + goto done; + + result = EnumProcessModules(proc, NULL, 0, &bytes_needed); + if (!result) + goto done; + + module_handles = (HMODULE *) malloc(bytes_needed); + if (!module_handles) + goto done; + + result = EnumProcessModules(proc, module_handles, bytes_needed, &bytes_needed); + if (!result) + goto done; + + libs_size = bytes_needed / sizeof(HMODULE); + lib_names = (char**) malloc(libs_size * sizeof(char*)); + if (!lib_names) + goto done; + + memset(lib_names, 0, libs_size * sizeof(char*)); + + for (int i = 0; i < libs_size; i++) { + nresult = GetModuleFileName(module_handles[i], lib_name_buffer, sizeof(lib_name_buffer)); + if (!nresult) + goto done; + lib_names[i] = strdup(lib_name_buffer); + } + + *libraries = lib_names; + *libraries_size = libs_size; + *libnames_need_free = 1; + + fresult = 0; +done: + if (module_handles) + free(module_handles); + + if (fresult == -1 && lib_names) { + for (int i = 0; i < libs_size; i++) { + if (lib_names[i]) + free(lib_names[i]); + } + free(lib_names); + } + + return fresult; + +} + +#define EPOCH_DIFFERENCE 11644473600UL +static void filetime_to_timeval(FILETIME ft, struct timeval* tv, BOOL calendar_time) +{ + unsigned long long tmp; + + tmp = (((unsigned long long) ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + tv->tv_sec = (unsigned long) (tmp / 10000000); + tv->tv_usec = (unsigned long) (tmp % 10000000) / 10; + if (calendar_time) + tv->tv_sec = (unsigned long) (tv->tv_sec - EPOCH_DIFFERENCE); +} + +int adksys_get_times(struct timeval* sys, struct timeval* cpu) +{ + HANDLE proc; + FILETIME creation_time, exit_time, user_time, sys_time; + BOOL result; + + proc = GetCurrentProcess(); + + result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); + if (!result) + return -1; + + if (sys) + filetime_to_timeval(sys_time, sys, FALSE); + if (cpu) + filetime_to_timeval(user_time, cpu, FALSE); + + return 0; +} + +int adksys_curtime(struct timeval* tm) +{ + FILETIME curtime; + GetSystemTimeAsFileTime(&curtime); + filetime_to_timeval(curtime, tm, TRUE); + return 0; +} + +int adksys_hostname(char* outbuffer, int buffer_size) +{ + static char* hostname = NULL; + static int err_ret = 0; + WSADATA unused; + int result; + + if (hostname || err_ret) { + if (err_ret) + return err_ret; + strncpy(outbuffer, hostname, buffer_size); + outbuffer[buffer_size - 1] = '\0'; + return 0; + } + + result = WSAStartup(MAKEWORD(1, 0), &unused); + if (result != 0) { + err_ret = -1; + return -1; + } + result = gethostname(outbuffer, buffer_size); + if (result != 0) { + err_ret = -1; + return -1; + } + outbuffer[buffer_size - 1] = '\0'; + + hostname = strdup(outbuffer); + err_ret = 0; + + WSACleanup(); + + return 0; +} + +int adksys_starttime(struct timeval* tv) +{ + HANDLE proc; + FILETIME creation_time, exit_time, user_time, sys_time; + BOOL result; + + proc = GetCurrentProcess(); + + result = GetProcessTimes(proc, &creation_time, &exit_time, &sys_time, &user_time); + if (!result) + return -1; + + filetime_to_timeval(creation_time, tv, TRUE); + return 0; +} + +int adksys_get_executable(char* outpath, size_t outpath_size) +{ + HANDLE proc; + int result; + + proc = GetCurrentProcess(); + result = GetProcessImageFileName(proc, outpath, (int) outpath_size); + if (!result) + return -1; + return 0; +} + +int adksys_get_cmdline_buffer(char** output_buffer, int* output_size) +{ + LPWSTR cmdline; + LPWSTR *argv; + char* buffer; + int argc, buffer_size = 0, pos = 0, bytes_written; + + cmdline = GetCommandLineW(); + argv = CommandLineToArgvW(cmdline, &argc); + + for (int i = 0; i < argc; i++) { + buffer_size += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); + buffer_size++; + } + + buffer = (char *) malloc(buffer_size); + for (int i = 0; i < argc; i++) { + bytes_written = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, buffer + pos, buffer_size - pos, NULL, NULL); + pos += bytes_written; + } + assert(pos <= buffer_size); + LocalFree(argv); + + *output_buffer = buffer; + *output_size = pos; + + return 0; +} + +int adksys_get_names(char** uid, char** user) +{ + BOOL result; + char localname[4096]; + unsigned long lname_size = sizeof(localname); + + if (user) { + result = GetUserNameEx(NameDisplay, localname, &lname_size); + if (!result) + return -1; + *user = strdup(localname); + } + + if (uid) { + lname_size = sizeof(localname); + result = GetUserNameEx(NameCanonical, localname, &lname_size); + if (!result) { + free(*user); + return -1; + } + *uid = strdup(localname); + } + + return 0; +} + +int adksys_get_cwd(char* cwd, size_t max_size) +{ + char* p; + p = getcwd(cwd, (int) max_size); + if (!p) + return -1; + return 0; +} + +void* adksys_get_public_adiak_symbol() +{ + return NULL; +}