From 7058333f1706c0dbc26b674f562e20d09340158e Mon Sep 17 00:00:00 2001 From: Paparoni Alvardo Date: Sun, 14 Jul 2019 23:59:25 +0300 Subject: [PATCH] Add get_module_filename --- vlib/os/const.v | 6 ++++++ vlib/os/os_win.v | 36 +++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/vlib/os/const.v b/vlib/os/const.v index fcbe6fb368..584a539347 100644 --- a/vlib/os/const.v +++ b/vlib/os/const.v @@ -1,5 +1,11 @@ module os +// Ref - winnt.h +const ( + SUCCESS = 0 // ERROR_SUCCESS + ERROR_INSUFFICIENT_BUFFER = 130 +) + const ( FILE_SHARE_READ = 1 FILE_SHARE_WRITE = 2 diff --git a/vlib/os/os_win.v b/vlib/os/os_win.v index c58830b8b4..359d1566c7 100644 --- a/vlib/os/os_win.v +++ b/vlib/os/os_win.v @@ -2,16 +2,38 @@ module os // Ref - https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types // A handle to an object. -/* -type HANDLE voidptr // C.HANDLE +type HANDLE voidptr +// Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019 +// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor. pub fn get_file_handle(path string) HANDLE { mode := 'rb' - _fh := C.fopen(path.cstr(), mode.cstr()) - if isnil(_fh) { - return HANDLE(INVALID_HANDLE_VALUE) + _fd := C.fopen(path.cstr(), mode.cstr()) + if _fd == 0 { + return HANDLE(INVALID_HANDLE_VALUE) } - _handle := C._get_osfhandle(C._fileno(_fh)) // CreateFile? - hah, no -_- + _handle := C._get_osfhandle(C._fileno(_fd)) // CreateFile? - hah, no -_- return _handle } -*/ + +// Ref - https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea +// get_module_filename retrieves the fully qualified path for the file that contains the specified module. +// The module must have been loaded by the current process. +pub fn get_module_filename(handle HANDLE) ?string { + mut sz := int(1024) // Optimized length + mut buf := [byte(0); sz] // Not work for GetModuleFileNameW :( + for { + status := C.GetModuleFileName(handle, &buf, sz) + switch status { + case SUCCESS: + _filename := tos(buf.data, sz) + return _filename + case ERROR_INSUFFICIENT_BUFFER: + sz += 1024 // increment buffer cluster by 1024 + buf = [byte(0); sz] // clear buffer + default: + // Must handled with GetLastError and converted by FormatMessage + return error('Cannot get file name from handle.') + } + } +}