11#include " TempFile.h"
22#include " ../win/WinAPI.h"
33#include " ../win/Utilities.h"
4+ #include " ../win/HrError.h"
45#include " ../str/String.h"
56#include " ../Exception.h"
67#include < fstream>
8+ #include < random>
9+ #include < format>
710#include < rpc.h>
811#include < sddl.h>
912#include < aclapi.h>
@@ -52,8 +55,8 @@ namespace pmon::util::file
5255 }
5356 TempFile& TempFile::MoveTo (const std::filesystem::path& dest)
5457 {
55- if (path_. empty ()) {
56- throw Except<Exception>(" MoveTo failed: source path is empty" );
58+ if (Empty ()) {
59+ throw Except<Exception>(" MoveTo failed: this object is empty" );
5760 }
5861 if (dest.empty ()) {
5962 throw Except<Exception>(" MoveTo failed: destination folder is empty" );
@@ -92,13 +95,25 @@ namespace pmon::util::file
9295 std::string TempFile::MakeRandomName ()
9396 {
9497 UUID uuid;
95- if (UuidCreate (&uuid) ! = RPC_S_OK) {
96- throw Except<Exception>( " Failed creating uuid" );
98+ if (UuidCreate (&uuid) = = RPC_S_OK) {
99+ return str::ToNarrow ( win::GuidToString ( uuid) );
97100 }
98- // TODO: fallback to <random>
99- return str::ToNarrow (win::GuidToString (uuid));
101+
102+ // Fallback: generate a pseudo-random GUID-like string.
103+ static thread_local std::mt19937_64 rng{ std::random_device{}() };
104+ std::uniform_int_distribution<uint32_t > dist32;
105+ std::uniform_int_distribution<uint16_t > dist16;
106+
107+ return std::format (
108+ " {{{:08x}-{:04x}-{:04x}-{:04x}-{:012x}}}" ,
109+ dist32 (rng), // 32 bits
110+ dist16 (rng), // 16 bits
111+ (dist16 (rng) & 0x0FFF ) | 0x4000 , // version 4
112+ (dist16 (rng) & 0x3FFF ) | 0x8000 , // variant 1
113+ (static_cast <uint64_t >(dist32 (rng)) << 32 ) | dist32 (rng) // 48 bits from 64
114+ );
100115 }
101- inline bool TempFile::Empty () const
116+ bool TempFile::Empty () const
102117 {
103118 return path_.empty ();
104119 }
@@ -108,42 +123,42 @@ namespace pmon::util::file
108123 }
109124 TempFile& TempFile::MakePublic ()
110125 {
111- if (path_. empty ()) {
112- throw std::runtime_error (" No file to make public" );
126+ if (Empty ()) {
127+ throw Except<Exception> (" No file to make public" );
113128 }
114129
115130 // Build ACEs
116- EXPLICIT_ACCESSW ea[3 ]{};
131+ EXPLICIT_ACCESSA ea[3 ]{};
117132
118133 // SYSTEM full
119- BuildExplicitAccessWithNameW (&ea[0 ], (LPWSTR) L " SYSTEM" ,
134+ BuildExplicitAccessWithNameA (&ea[0 ], (LPSTR) " SYSTEM" ,
120135 GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
121136
122137 // Administrators full
123- BuildExplicitAccessWithNameW (&ea[1 ], (LPWSTR) L " BUILTIN\\ Administrators" ,
138+ BuildExplicitAccessWithNameA (&ea[1 ], (LPSTR) " BUILTIN\\ Administrators" ,
124139 GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
125140
126141 // Authenticated Users modify (RWX + delete)
127142 DWORD modifyMask = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
128- BuildExplicitAccessWithNameW (&ea[2 ], (LPWSTR) L " Authenticated Users" ,
143+ BuildExplicitAccessWithNameA (&ea[2 ], (LPSTR) " Authenticated Users" ,
129144 modifyMask, SET_ACCESS, NO_INHERITANCE);
130145
131146 PACL newDacl = nullptr ;
132- DWORD dwRes = SetEntriesInAclW (3 , ea, nullptr , &newDacl);
147+ DWORD dwRes = SetEntriesInAclA (3 , ea, nullptr , &newDacl);
133148 if (dwRes != ERROR_SUCCESS) {
134- throw std::system_error (dwRes, std::system_category (), " SetEntriesInAclW failed" );
149+ throw Except<win::HrError> (dwRes, " SetEntriesInAcl failed" );
135150 }
136151
137- dwRes = SetNamedSecurityInfoW (
138- (LPWSTR )path_.c_str (),
152+ dwRes = SetNamedSecurityInfoA (
153+ (LPSTR )path_. string () .c_str (),
139154 SE_FILE_OBJECT,
140155 DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION,
141156 nullptr , nullptr , newDacl, nullptr );
142157
143158 LocalFree (newDacl);
144159
145160 if (dwRes != ERROR_SUCCESS) {
146- throw std::system_error (dwRes, std::system_category (), " SetNamedSecurityInfoW failed" );
161+ throw Except<win::HrError> (dwRes, " SetNamedSecurityInfo failed" );
147162 }
148163
149164 return *this ;
0 commit comments