localPackages.winjob: implement read owner of file on Windows

This commit is contained in:
陈浩南 2024-07-24 21:27:13 +08:00
parent 8c6a25906d
commit ae4774d118
3 changed files with 67 additions and 1 deletions

View File

@ -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)

View File

@ -0,0 +1,8 @@
# include <optional>
# include <string>
# include <utility>
namespace winjob
{
std::optional<std::pair<std::string, std::string>> get_owner(const std::string& file_name);
}

View File

@ -0,0 +1,58 @@
# include <winjob/windows.hpp>
# include <windows.h>
# include <tchar.h>
# include <accctrl.h>
# include <aclapi.h>
namespace winjob
{
std::optional<std::pair<std::string, std::string>> 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));
}
}