Skip to content

Commit d75f98e

Browse files
committed
utils for local free and security
1 parent 60bb029 commit d75f98e

File tree

9 files changed

+94
-42
lines changed

9 files changed

+94
-42
lines changed

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
<ClInclude Include="win\Privileges.h" />
110110
<ClInclude Include="win\Process.h" />
111111
<ClInclude Include="win\ProcessMapBuilder.h" />
112+
<ClInclude Include="win\Security.h" />
112113
<ClInclude Include="win\Utilities.h" />
113114
<ClInclude Include="win\WinAPI.h" />
114115
</ItemGroup>
@@ -165,9 +166,11 @@
165166
<ClCompile Include="win\Handle.cpp" />
166167
<ClCompile Include="win\HrErrorCodeProvider.cpp" />
167168
<ClCompile Include="win\HrError.cpp" />
169+
<ClCompile Include="Memory.cpp" />
168170
<ClCompile Include="win\MessageBox.cpp" />
169171
<ClCompile Include="win\Privileges.cpp" />
170172
<ClCompile Include="win\ProcessMapBuilder.cpp" />
173+
<ClCompile Include="win\Security.cpp" />
171174
<ClCompile Include="win\Utilities.cpp" />
172175
</ItemGroup>
173176
<ItemGroup>

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@
291291
<ClInclude Include="file\FileUtils.h">
292292
<Filter>Header Files</Filter>
293293
</ClInclude>
294+
<ClInclude Include="win\Security.h">
295+
<Filter>Header Files</Filter>
296+
</ClInclude>
294297
</ItemGroup>
295298
<ItemGroup>
296299
<ClCompile Include="cli\CliFramework.cpp">
@@ -461,6 +464,12 @@
461464
<ClCompile Include="file\FileUtils.cpp">
462465
<Filter>Source Files</Filter>
463466
</ClCompile>
467+
<ClCompile Include="win\Security.cpp">
468+
<Filter>Source Files</Filter>
469+
</ClCompile>
470+
<ClCompile Include="Memory.cpp">
471+
<Filter>Source Files</Filter>
472+
</ClCompile>
464473
</ItemGroup>
465474
<ItemGroup>
466475
<None Include="vcpkg.json" />
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "Memory.h"
2+
#include "win/WinAPI.h"
3+
#include "log/Log.h"
4+
5+
namespace pmon::util
6+
{
7+
void LocalFree(void* p) noexcept
8+
{
9+
if (::LocalFree(p) != NULL) {
10+
pmlog_warn("Failed to free memory via LocalFree");
11+
}
12+
}
13+
}

IntelPresentMon/CommonUtilities/Memory.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,23 @@ namespace pmon::util
100100
OutPtrProxy<SP> OutPtr(SP& smartPtr) {
101101
return OutPtrProxy<SP>(smartPtr);
102102
}
103+
104+
void LocalFree(void* p) noexcept;
105+
106+
// Generic LocalFree deleter
107+
template<class T = void>
108+
struct LocalFreeDeleter
109+
{
110+
using pointer = T*;
111+
void operator()(pointer p) const noexcept
112+
{
113+
if (p) {
114+
util::LocalFree(p);
115+
}
116+
}
117+
};
118+
119+
// unique_ptr that uses LocalFree.
120+
template<class T = void>
121+
using UniqueLocalPtr = std::unique_ptr<T, LocalFreeDeleter<T>>;
103122
}

IntelPresentMon/CommonUtilities/file/TempFile.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../win/HrError.h"
55
#include "../str/String.h"
66
#include "../Exception.h"
7+
#include "../Memory.h"
78
#include <fstream>
89
#include <random>
910
#include <format>
@@ -143,22 +144,18 @@ namespace pmon::util::file
143144
BuildExplicitAccessWithNameA(&ea[2], (LPSTR)"Authenticated Users",
144145
modifyMask, SET_ACCESS, NO_INHERITANCE);
145146

146-
PACL newDacl = nullptr;
147-
DWORD dwRes = SetEntriesInAclA(3, ea, nullptr, &newDacl);
148-
if (dwRes != ERROR_SUCCESS) {
149-
throw Except<win::HrError>(dwRes, "SetEntriesInAcl failed");
147+
UniqueLocalPtr<ACL> pNewDacl;
148+
if (auto res = SetEntriesInAclA(3, ea, nullptr, OutPtr(pNewDacl)); res != ERROR_SUCCESS) {
149+
throw Except<win::HrError>(HRESULT(res), "SetEntriesInAcl failed");
150150
}
151151

152-
dwRes = SetNamedSecurityInfoA(
152+
if (auto res = SetNamedSecurityInfoA(
153153
(LPSTR)path_.string().c_str(),
154154
SE_FILE_OBJECT,
155155
DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION,
156-
nullptr, nullptr, newDacl, nullptr);
157-
158-
LocalFree(newDacl);
159-
160-
if (dwRes != ERROR_SUCCESS) {
161-
throw Except<win::HrError>(dwRes, "SetNamedSecurityInfo failed");
156+
nullptr, nullptr, pNewDacl.get(), nullptr);
157+
res != ERROR_SUCCESS) {
158+
throw Except<win::HrError>(HRESULT(res), "SetNamedSecurityInfo failed");
162159
}
163160

164161
return *this;

IntelPresentMon/CommonUtilities/pipe/Pipe.cpp

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "Pipe.h"
2-
#include <sddl.h>
2+
#include "../win/Security.h"
33
#include <string_view>
44

55
namespace pmon::util::pipe
@@ -144,15 +144,11 @@ namespace pmon::util::pipe
144144
.lpSecurityDescriptor = nullptr,
145145
.bInheritHandle = FALSE,
146146
};
147-
// if we have a security string, create the descriptor and have it owned by above structure
147+
// if we have a security string, create the descriptor
148+
UniqueLocalPtr<void> pSecDesc;
148149
if (!security.empty()) {
149-
if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(
150-
security.c_str(), SDDL_REVISION_1,
151-
&securityAttributes.lpSecurityDescriptor, NULL)) {
152-
pmlog_error(std::format(
153-
"Failed creating security descriptor for pipe [{}], descriptor string was '{}'",
154-
name, security)).hr().raise<PipeError>();
155-
}
150+
pSecDesc = win::MakeSecurityDescriptor(security);
151+
securityAttributes.lpSecurityDescriptor = pSecDesc.get();
156152
}
157153
// if we have a security string, call create pipe with above structure, else call with nullptr
158154
SECURITY_ATTRIBUTES* pSecurityAttributes = security.empty() ? nullptr : &securityAttributes;
@@ -166,12 +162,6 @@ namespace pmon::util::pipe
166162
4096, // in buffer
167163
0, // timeout
168164
pSecurityAttributes)); // security
169-
// regardless of result, if we are using security, free the descriptor owned by above structure
170-
if (!security.empty()) {
171-
if (LocalFree(securityAttributes.lpSecurityDescriptor) != NULL) {
172-
pmlog_warn("Failed freeing memory for security descriptor");
173-
}
174-
}
175165
if (!handle) {
176166
pmlog_error("Server failed to create named pipe instance").hr().raise<PipeError>();
177167
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "Security.h"
2+
#include <sddl.h>
3+
#include "HrError.h"
4+
5+
namespace pmon::util::win
6+
{
7+
UniqueLocalPtr<void> MakeSecurityDescriptor(const std::string& desc)
8+
{
9+
// using <void> and not <SECURITY_DESCRIPTOR> because PSECURITY_DESCRIPTOR is void*
10+
UniqueLocalPtr<void> pDesc;
11+
if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(desc.c_str(), SDDL_REVISION_1,
12+
OutPtr(pDesc), nullptr)) {
13+
throw Except<HrError>("ConvertStringSecurityDescriptorToSecurityDescriptorA failed");
14+
}
15+
return pDesc;
16+
}
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
#include "WinAPI.h"
3+
#include "../Memory.h"
4+
#include <string>
5+
6+
namespace pmon::util::win
7+
{
8+
UniqueLocalPtr<void> MakeSecurityDescriptor(const std::string& desc);
9+
}

IntelPresentMon/CommonUtilities/win/Utilities.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Utilities.h"
22
#include "../log/Log.h"
3+
#include "../Memory.h"
34
#include "HrError.h"
45
#include <chrono>
56
#include <thread>
@@ -12,31 +13,25 @@ namespace pmon::util::win
1213
std::string GetErrorDescription(HRESULT hr) noexcept
1314
{
1415
try {
16+
UniqueLocalPtr<CHAR> descriptionLocal;
1517
char* descriptionWinalloc = nullptr;
16-
const auto result = FormatMessageA(
18+
if (!FormatMessageA(
1719
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1820
nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
19-
reinterpret_cast<LPSTR>(&descriptionWinalloc), 0, nullptr
20-
);
21-
22-
std::string description;
23-
if (!result) {
21+
reinterpret_cast<LPSTR>(static_cast<char**>(OutPtr(descriptionLocal))), 0, nullptr))
22+
{
2423
pmlog_warn("Failed formatting windows error");
24+
return "COULD NOT FORMAT";
2525
}
26-
else {
27-
description = descriptionWinalloc;
28-
if (LocalFree(descriptionWinalloc)) {
29-
pmlog_warn("Failed freeing memory for windows error formatting");
30-
}
31-
if (description.ends_with("\r\n")) {
32-
description.resize(description.size() - 2);
33-
}
26+
std::string description = descriptionLocal.get();
27+
if (description.ends_with("\r\n")) {
28+
description.resize(description.size() - 2);
3429
}
3530
return description;
3631
}
3732
catch (...) {
38-
pmlog_warn(ReportException("Exception in win::GetErrorDescription"));
39-
return {};
33+
pmlog_warn(ReportException("Failed formatting windows error"));
34+
return "COULD NOT FORMAT";
4035
}
4136
}
4237

0 commit comments

Comments
 (0)