Compare commits

...

3 Commits

Author SHA1 Message Date
chn
9531f60b05 archive 2024-07-26 17:30:51 +08:00
chn
e0e9ae9ad3 try some 2024-07-26 15:35:36 +08:00
chn
599776b33d 暂存 2024-07-25 21:43:14 +08:00
10 changed files with 198 additions and 92 deletions

100
flake.nix
View File

@@ -77,55 +77,49 @@
(builtins.attrNames (builtins.readDir ./devices));
in
{
packages = rec
packages.x86_64-linux = rec
{
x86_64-linux = rec
pkgs = (import inputs.nixpkgs
{
pkgs = (import inputs.nixpkgs
system = "x86_64-linux";
config.allowUnfree = true;
overlays = [ inputs.self.overlays.default ];
crossOverlays = [(final: prev:
{
system = "x86_64-linux";
config.allowUnfree = true;
overlays = [ inputs.self.overlays.default ];
crossOverlays = [(final: prev:
{
boost = prev.boost.override { zstd = null; };
magic-enum = prev.magic-enum.overrideAttrs (prev: { cmakeFlags = prev.cmakeFlags ++
[ "-DMAGIC_ENUM_OPT_BUILD_EXAMPLES=OFF" "-DMAGIC_ENUM_OPT_BUILD_TESTS=OFF" ]; });
range-v3 = prev.range-v3.overrideAttrs (prev: { cmakeFlags = prev.cmakeFlags ++
[ "-DRANGE_V3_DOCS=OFF" "-DRANGE_V3_TESTS=OFF" "-DRANGE_V3_EXAMPLES=OFF" ]; });
abseil-cpp = prev.abseil-cpp.overrideAttrs (prev: { buildInputs = prev.buildInputs ++
[ final.windows.pthreads ]; });
})];
});
default = inputs.nixpkgs.legacyPackages.x86_64-linux.writeText "systems"
(builtins.concatStringsSep "\n" (builtins.map
(system: builtins.toString inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel)
devices));
hpcstat =
let
openssh = (pkgs.pkgsStatic.openssh.override { withLdns = false; etcDir = null; }).overrideAttrs
(prev: { doCheck = false; patches = prev.patches ++ [ ./local/pkgs/hpcstat/openssh.patch ];});
duc = pkgs.pkgsStatic.duc.override { enableCairo = false; cairo = null; pango = null; };
in pkgs.pkgsStatic.localPackages.hpcstat.override
{ inherit openssh duc; standalone = true; version = inputs.self.rev or "dirty"; };
ufo = pkgs.pkgsStatic.localPackages.ufo.override { version = inputs.self.rev or "dirty"; };
chn-bsub = pkgs.pkgsStatic.localPackages.chn-bsub;
}
// (
builtins.listToAttrs (builtins.map
(system:
{
name = system;
value = inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel;
})
devices)
);
x86_64-w64-mingw32 = rec
{
pkgs = x86_64-linux.pkgs.pkgsCross.mingwW64Static;
winjob = pkgs.localPackages.winjob;
};
};
boost = (prev.boost.override { zstd = null; }).overrideAttrs (prev:
{ patches = prev.patches or [] ++ [ ./local/pkgs/winjob/boost.patch ]; });
magic-enum = prev.magic-enum.overrideAttrs (prev: { cmakeFlags = prev.cmakeFlags ++
[ "-DMAGIC_ENUM_OPT_BUILD_EXAMPLES=OFF" "-DMAGIC_ENUM_OPT_BUILD_TESTS=OFF" ]; });
range-v3 = prev.range-v3.overrideAttrs (prev: { cmakeFlags = prev.cmakeFlags ++
[ "-DRANGE_V3_DOCS=OFF" "-DRANGE_V3_TESTS=OFF" "-DRANGE_V3_EXAMPLES=OFF" ]; });
abseil-cpp = prev.abseil-cpp.overrideAttrs (prev: { buildInputs = prev.buildInputs ++
[ final.windows.pthreads ]; });
})];
});
default = inputs.nixpkgs.legacyPackages.x86_64-linux.writeText "systems"
(builtins.concatStringsSep "\n" (builtins.map
(system: builtins.toString inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel)
devices));
hpcstat =
let
openssh = (pkgs.pkgsStatic.openssh.override { withLdns = false; etcDir = null; }).overrideAttrs
(prev: { doCheck = false; patches = prev.patches ++ [ ./local/pkgs/hpcstat/openssh.patch ];});
duc = pkgs.pkgsStatic.duc.override { enableCairo = false; cairo = null; pango = null; };
in pkgs.pkgsStatic.localPackages.hpcstat.override
{ inherit openssh duc; standalone = true; version = inputs.self.rev or "dirty"; };
ufo = pkgs.pkgsStatic.localPackages.ufo.override { version = inputs.self.rev or "dirty"; };
chn-bsub = pkgs.pkgsStatic.localPackages.chn-bsub;
winjob = pkgs.pkgsCross.mingwW64Static.localPackages.winjob;
}
// (
builtins.listToAttrs (builtins.map
(system:
{
name = system;
value = inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel;
})
devices)
);
nixosConfigurations =
(
(builtins.listToAttrs (builtins.map
@@ -198,14 +192,12 @@
packages = [ pkgs.clang-tools_18 ];
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
};
winjob =
let inherit (pkgs) clang-tools_18; in let inherit (inputs.self.packages.x86_64-w64-mingw32) pkgs winjob;
in pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; }
{
inputsFrom = [ winjob ];
packages = [ clang-tools_18 ];
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
};
winjob = pkgs.mkShell
{
inputsFrom = [ pkgs.pkgsCross.mingwW64Static.winjob ];
packages = [ pkgs.clang-tools_18 ];
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
};
};
};
}

View File

@@ -70,7 +70,7 @@ inputs: rec
ufo = inputs.pkgs.callPackage ./ufo
{ inherit concurrencpp biu glad matplotplusplus zpp-bits; tbb = inputs.pkgs.tbb_2021_11; };
chn-bsub = inputs.pkgs.callPackage ./chn-bsub { inherit biu; };
winjob = inputs.pkgs.callPackage ./winjob { stdenv = inputs.pkgs.gcc14Stdenv; };
winjob = inputs.pkgs.callPackage ./winjob {};
sockpp = inputs.pkgs.callPackage ./sockpp.nix { src = inputs.topInputs.sockpp; };
git-lfs-transfer = inputs.pkgs.callPackage ./git-lfs-transfer.nix { src = inputs.topInputs.git-lfs-transfer; };

View File

@@ -13,17 +13,17 @@ endif()
set(WINJOB_VERSION "unknown" CACHE STRING "Version of the winjob")
find_package(Boost REQUIRED COMPONENTS headers filesystem)
find_package(nlohmann_json REQUIRED)
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_compile_features(winjob PRIVATE cxx_std_23)
target_include_directories(winjob PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(winjob PRIVATE Boost::headers Boost::filesystem ws2_32 wsock32)
target_compile_definitions(winjob PRIVATE winjob_VERSION="${winjob_VERSION}")
add_executable(winjobd src/winjobd.cpp)
# target_compile_features(winjob PRIVATE cxx_std_26)
target_compile_options(winjobd PRIVATE "-std=c++26")
add_executable(winjobd src/winjobd.cpp src/windows.cpp)
target_compile_features(winjob PRIVATE cxx_std_23)
target_compile_options(winjobd PRIVATE -fpermissive)
target_include_directories(winjobd PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(winjobd PRIVATE Boost::headers Boost::filesystem ws2_32 wsock32)
target_compile_definitions(winjobd PRIVATE winjob_VERSION="${winjob_VERSION}")

View File

@@ -0,0 +1,12 @@
diff --color -ur a/boost/process/v2/detail/impl/utf8.ipp b/boost/process/v2/detail/impl/utf8.ipp
--- a/boost/process/v2/detail/impl/utf8.ipp 2024-07-26 15:50:15.844632780 +0800
+++ b/boost/process/v2/detail/impl/utf8.ipp 2024-07-26 15:50:09.036567016 +0800
@@ -11,7 +11,7 @@
#include <boost/process/v2/error.hpp>
#if defined(BOOST_PROCESS_V2_WINDOWS)
-#include <Windows.h>
+#include <windows.h>
#endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE

View File

@@ -1,11 +1,11 @@
{
stdenv, cmake, pkg-config, version ? null, lib,
boost
boost, nlohmann_json
}: stdenv.mkDerivation
{
name = "winjob";
src = ./.;
buildInputs = [ boost ];
buildInputs = [ boost nlohmann_json ];
nativeBuildInputs = [ cmake pkg-config ];
cmakeFlags = lib.optionals (version != null) [ "-DWINJOB_VERSION=${version}" ];
}

View File

@@ -4,5 +4,6 @@
namespace winjob
{
std::optional<std::pair<std::string, std::string>> get_owner(const std::string& file_name);
std::optional<std::pair<std::wstring, std::wstring>> get_owner(std::wstring file_name);
bool set_permission(std::wstring fileName);
}

View File

@@ -0,0 +1,13 @@
REM run as admin
set "params=%*"
cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/c cd ""%~sdp0"" && %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B )
REM copy files
if not exist "C:\Program Files\winjob" mkdir "C:\Program Files\winjob"
copy winjob.exe "C:\Program Files\winjob\winjob.exe"
copy winjobd.exe "C:\Program Files\winjob\winjobd.exe"
REM create task scheduler
schtasks /create /tn "winjob" /tr "C:\Program Files\winjob\winjobd.exe" /sc onstart /ru system /f
pause

View File

@@ -6,20 +6,20 @@
namespace winjob
{
std::optional<std::pair<std::string, std::string>> get_owner(const std::string& file_name)
std::optional<std::pair<std::wstring, std::wstring>> get_owner(std::wstring file_name)
{
DWORD dwRtnCode = 0;
PSID pSidOwner = NULL;
BOOL bRtnBool = TRUE;
LPTSTR AcctName = NULL;
LPTSTR DomainName = NULL;
LPWSTR AcctName = NULL;
LPWSTR 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
hFile = CreateFileW
(file_name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Check GetLastError for CreateFile error code.
@@ -32,27 +32,74 @@ namespace winjob
if (dwRtnCode != ERROR_SUCCESS) return {};
// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid
bRtnBool = LookupAccountSidW
(NULL, pSidOwner, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse);
// Reallocate memory for the buffers.
AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName * sizeof(wchar_t));
AcctName = (LPWSTR)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));
DomainName = (LPWSTR)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
bRtnBool = LookupAccountSidW
(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));
return std::make_pair(std::wstring(DomainName), std::wstring(AcctName));
}
bool set_permission(std::wstring fileName)
{
// Define the SID for the Users group
PSID pUsersSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS,
0, 0, 0, 0, 0, 0, &pUsersSID))
return false;
// Initialize an EXPLICIT_ACCESS structure for an ACE
EXPLICIT_ACCESS ea;
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = GENERIC_WRITE;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.ptstrName = (LPTSTR)pUsersSID;
// Create a new ACL that contains the new ACE
PACL pACL = NULL;
DWORD dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes) { FreeSid(pUsersSID); return false; }
// Initialize a security descriptor
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD) { FreeSid(pUsersSID); LocalFree(pACL); return false; }
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{ FreeSid(pUsersSID); LocalFree(pACL); LocalFree(pSD); return false; }
// Add the ACL to the security descriptor
if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
{ FreeSid(pUsersSID); LocalFree(pACL); LocalFree(pSD); return false; }
// Change the security attributes
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
if (!SetFileSecurityW(fileName.c_str(), DACL_SECURITY_INFORMATION, pSD))
{ FreeSid(pUsersSID); LocalFree(pACL); LocalFree(pSD); return false; }
else { FreeSid(pUsersSID); LocalFree(pACL); LocalFree(pSD); return true; }
}
}

View File

@@ -1,22 +1,24 @@
# include <boost/asio.hpp>
# include <iostream>
# include <fstream>
int main()
{
boost::asio::io_context io_context;
boost::asio::local::stream_protocol::endpoint ep("winjobd.sock");
// send a message to the server
boost::asio::local::stream_protocol::socket socket(io_context);
socket.connect(ep);
std::string message;
std::getline(std::cin, message);
boost::asio::write(socket, boost::asio::buffer(message));
// receive a message from the server
boost::asio::streambuf buf;
boost::asio::read_until(socket, buf, '\n');
std::istream is(&buf);
std::string line;
std::getline(is, line);
std::cout << "Received: " << line << '\n';
std::ofstream test(R"(C:\Users\chn\Desktop\test.txt)");
// boost::asio::io_context io_context;
// boost::asio::local::stream_protocol::endpoint ep(R"(C:\ProgramData\winjob\winjobd.sock)");
// // send a message to the server
// boost::asio::local::stream_protocol::socket socket(io_context);
// socket.connect(ep);
// std::string message;
// std::getline(std::cin, message);
// message += '\n';
// boost::asio::write(socket, boost::asio::buffer(message));
// // receive a message from the server
// boost::asio::streambuf buf;
// boost::asio::read_until(socket, buf, '\n');
// std::istream is(&buf);
// std::string line;
// std::getline(is, line);
// std::cout << "Received: " << line << '\n';
return 0;
}

View File

@@ -1,26 +1,65 @@
# include <winjob/windows.hpp>
# include <boost/asio.hpp>
# include <boost/process/v2/windows/with_logon_launcher.hpp>
# include <boost/process/v2/process.hpp>
# include <iostream>
# include <filesystem>
# include <fstream>
# include <windows.h>
using namespace std::literals;
int main()
{
// clear temp files
std::filesystem::create_directories(LR"(C:\ProgramData\winjob)");
if (std::filesystem::exists(LR"(C:\ProgramData\winjob\winjobd.sock)"))
std::filesystem::remove(LR"(C:\ProgramData\winjob\winjobd.sock)");
if (std::filesystem::exists(LR"(C:\ProgramData\winjob\auth)"))
std::filesystem::remove(LR"(C:\ProgramData\winjob\auth)");
std::filesystem::create_directories(LR"(C:\ProgramData\winjob\auth)");
winjob::set_permission(LR"(C:\ProgramData\winjob\auth)");
// log file
std::ofstream log(LR"(C:\ProgramData\winjob\log.txt)", std::ios::app);
auto user = winjob::get_owner(LR"(C:\Users\chn\Desktop\winjob.exe)");
if (!user)
{
log << "Failed to get owner\n" << std::flush;
return 1;
}
if (user)
{
log << "Owner: " << user->first << "\\" << user->second << '\n' << std::flush;
auto launcher = boost::process::v2::windows::with_logon_launcher(user->second, L"", user->first,
LOGON_WITH_PROFILE);
boost::asio::io_context ctx;
boost::process::v2::error_code ec;
std::wstring program = LR"(C:\Users\chn\Desktop\winjob.exe)";
auto process = launcher(ctx, ec, program, std::vector<std::wstring>{});
}
boost::asio::io_context io_context;
boost::asio::local::stream_protocol::endpoint ep("winjobd.sock");
boost::asio::local::stream_protocol::endpoint ep(R"(C:\ProgramData\winjob\winjobd.sock)");
boost::asio::local::stream_protocol::acceptor acceptor(io_context, ep, false);
winjob::set_permission(LR"(C:\ProgramData\winjob\winjobd.sock)");
std::function<void(const boost::system::error_code&, boost::asio::local::stream_protocol::socket)> func =
[&](const boost::system::error_code& ec, boost::asio::local::stream_protocol::socket socket)
{
if (ec)
{
std::cerr << "Failed to accept connection\n";
log << "Failed to accept connection\n" << std::flush;
return;
}
std::cout << "Accepted connection\n";
log << "Accepted connection\n" << std::flush;
boost::asio::streambuf buf;
boost::asio::read_until(socket, buf, '\n');
std::istream is(&buf);
std::string line;
std::getline(is, line);
std::cout << "Received: " << line << '\n';
log << "Received: " << line << '\n' << std::flush;
// write a message to the client
std::string message = "thanks for the message\n";
boost::asio::write(socket, boost::asio::buffer(message));