diff --git a/local/pkgs/winjob/CMakeLists.txt b/local/pkgs/winjob/CMakeLists.txt index 01fccd44..4d7fdf8e 100644 --- a/local/pkgs/winjob/CMakeLists.txt +++ b/local/pkgs/winjob/CMakeLists.txt @@ -16,7 +16,7 @@ find_package(Boost REQUIRED COMPONENTS headers filesystem) find_package(nlohmann_json REQUIRED) find_package(range-v3 REQUIRED) -add_executable(winjob src/winjob.cpp) +add_executable(winjob src/winjob.cpp src/windows.cpp) # target_compile_features(winjob PRIVATE cxx_std_26) target_compile_options(winjob PRIVATE "-std=c++26") target_include_directories(winjob PRIVATE ${PROJECT_SOURCE_DIR}/include) diff --git a/local/pkgs/winjob/include/winjob/windows.hpp b/local/pkgs/winjob/include/winjob/windows.hpp new file mode 100644 index 00000000..ccded104 --- /dev/null +++ b/local/pkgs/winjob/include/winjob/windows.hpp @@ -0,0 +1,8 @@ +# include +# include +# include + +namespace winjob +{ + std::optional> get_owner(const std::string& file_name); +} diff --git a/local/pkgs/winjob/src/windows.cpp b/local/pkgs/winjob/src/windows.cpp new file mode 100644 index 00000000..72724485 --- /dev/null +++ b/local/pkgs/winjob/src/windows.cpp @@ -0,0 +1,58 @@ +# include +# include +# include +# include +# include + +namespace winjob +{ + std::optional> get_owner(const std::string& file_name) + { + DWORD dwRtnCode = 0; + PSID pSidOwner = NULL; + BOOL bRtnBool = TRUE; + LPTSTR AcctName = NULL; + LPTSTR DomainName = NULL; + DWORD dwAcctName = 1, dwDomainName = 1; + SID_NAME_USE eUse = SidTypeUnknown; + HANDLE hFile; + PSECURITY_DESCRIPTOR pSD = NULL; + + // Get the handle of the file object. + hFile = CreateFile + (file_name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + // Check GetLastError for CreateFile error code. + if (hFile == INVALID_HANDLE_VALUE) return {}; + + // Get the owner SID of the file. + dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD); + + // Check GetLastError for GetSecurityInfo error condition. + if (dwRtnCode != ERROR_SUCCESS) return {}; + + // First call to LookupAccountSid to get the buffer sizes. + bRtnBool = LookupAccountSid + (NULL, pSidOwner, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse); + + // Reallocate memory for the buffers. + AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName * sizeof(wchar_t)); + + // Check GetLastError for GlobalAlloc error condition. + if (AcctName == NULL) return {}; + + DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName * sizeof(wchar_t)); + + // Check GetLastError for GlobalAlloc error condition. + if (DomainName == NULL) return {}; + + // Second call to LookupAccountSid to get the account name. + bRtnBool = LookupAccountSid + (NULL, pSidOwner, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse); + + // Check GetLastError for LookupAccountSid error condition. + if (bRtnBool == FALSE) return {}; + + return std::make_pair(std::string(DomainName), std::string(AcctName)); + } +}