diff --git a/UnitTests/SDDL.cpp b/UnitTests/SDDL.cpp
new file mode 100644
index 00000000..f141517a
--- /dev/null
+++ b/UnitTests/SDDL.cpp
@@ -0,0 +1,26 @@
+/*
+ SPDX-License-Identifier: MIT
+ Copyright © 2022 Amebis
+*/
+
+#include "pch.h"
+
+using namespace std;
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+namespace UnitTests
+{
+ TEST_CLASS(SDDL)
+ {
+ public:
+ TEST_METHOD(security_attributes)
+ {
+ winstd::security_attributes sa;
+ Assert::IsTrue(ConvertStringSecurityDescriptorToSecurityDescriptorW(L"O:BAD:PAI(A;;FA;;;BA)", SDDL_REVISION_1, sa, NULL));
+ Assert::IsNotNull(sa.lpSecurityDescriptor);
+ winstd::security_attributes sa2(move(sa));
+ Assert::IsNull(sa.lpSecurityDescriptor);
+ Assert::IsNotNull(sa2.lpSecurityDescriptor);
+ }
+ };
+}
diff --git a/UnitTests/UnitTests.vcxproj b/UnitTests/UnitTests.vcxproj
index e7f537c4..7dea8125 100644
--- a/UnitTests/UnitTests.vcxproj
+++ b/UnitTests/UnitTests.vcxproj
@@ -86,7 +86,7 @@
Windows
$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
- Shlwapi.lib;%(AdditionalDependencies)
+ Advapi32.lib;Shlwapi.lib;%(AdditionalDependencies)
@@ -118,6 +118,7 @@
Create
+
diff --git a/UnitTests/UnitTests.vcxproj.filters b/UnitTests/UnitTests.vcxproj.filters
index d64ef457..31be1bf7 100644
--- a/UnitTests/UnitTests.vcxproj.filters
+++ b/UnitTests/UnitTests.vcxproj.filters
@@ -24,6 +24,9 @@
Source Files
+
+ Source Files
+
diff --git a/UnitTests/pch.h b/UnitTests/pch.h
index 4c4efa3c..2a034f58 100644
--- a/UnitTests/pch.h
+++ b/UnitTests/pch.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/include/WinStd/SDDL.h b/include/WinStd/SDDL.h
new file mode 100644
index 00000000..ce277391
--- /dev/null
+++ b/include/WinStd/SDDL.h
@@ -0,0 +1,111 @@
+/*
+ SPDX-License-Identifier: MIT
+ Copyright © 2022 Amebis
+*/
+
+/// \defgroup WinStdSDDL SDDL
+
+#pragma once
+
+#include "Common.h"
+#include
+
+namespace winstd
+{
+ /// \addtogroup WinStdSDDL
+ /// @{
+
+ class security_attributes : public SECURITY_ATTRIBUTES
+ {
+ WINSTD_NONCOPYABLE(security_attributes)
+
+ public:
+ ///
+ /// Initializes a new SECURITY_ATTRIBUTES.
+ ///
+ security_attributes() noexcept
+ {
+ nLength = sizeof(SECURITY_ATTRIBUTES);
+ lpSecurityDescriptor = NULL;
+ bInheritHandle = FALSE;
+ }
+
+ ///
+ /// Moves an existing SECURITY_ATTRIBUTES.
+ ///
+ security_attributes(_Inout_ security_attributes &&a) noexcept
+ {
+ nLength = sizeof(SECURITY_ATTRIBUTES);
+ lpSecurityDescriptor = a.lpSecurityDescriptor;
+ bInheritHandle = a.bInheritHandle;
+ a.lpSecurityDescriptor = NULL;
+ }
+
+ ///
+ /// Destroys the SECURITY_ATTRIBUTES.
+ ///
+ ~security_attributes()
+ {
+ if (lpSecurityDescriptor)
+ LocalFree(lpSecurityDescriptor);
+ }
+
+ ///
+ /// Moves an existing SECURITY_ATTRIBUTES.
+ ///
+ security_attributes& operator=(_Inout_ security_attributes &&a) noexcept
+ {
+ if (this != &a) {
+ nLength = sizeof(SECURITY_ATTRIBUTES);
+ if (lpSecurityDescriptor)
+ LocalFree(lpSecurityDescriptor);
+ lpSecurityDescriptor = a.lpSecurityDescriptor;
+ bInheritHandle = a.bInheritHandle;
+ a.lpSecurityDescriptor = NULL;
+ }
+ return *this;
+ }
+ };
+
+ /// @}
+}
+
+/// \addtogroup WinStdSDDL
+/// @{
+
+#pragma warning(push)
+#pragma warning(disable: 4505) // Don't warn on unused code
+
+/// @copydoc ConvertStringSecurityDescriptorToSecurityDescriptorW()
+_Success_(return != FALSE) static BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(_In_ LPCSTR StringSecurityDescriptor, _In_ DWORD StringSDRevision, _Inout_ winstd::security_attributes &sa, _Out_opt_ PULONG SecurityDescriptorSize)
+{
+ PSECURITY_DESCRIPTOR sd;
+ BOOL bResult = ConvertStringSecurityDescriptorToSecurityDescriptorA(StringSecurityDescriptor, StringSDRevision, &sd, SecurityDescriptorSize);
+ if (bResult) {
+ if (sa.lpSecurityDescriptor)
+ LocalFree(sa.lpSecurityDescriptor);
+ sa.lpSecurityDescriptor = sd;
+ }
+ return bResult;
+}
+
+///
+/// Converts a string-format security descriptor into a valid, functional security descriptor.
+///
+/// \sa [ConvertStringSecurityDescriptorToSecurityDescriptor function](https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptorw)
+///
+_Success_(return != FALSE) static BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(_In_ LPCWSTR StringSecurityDescriptor, _In_ DWORD StringSDRevision, _Inout_ winstd::security_attributes &sa, _Out_opt_ PULONG SecurityDescriptorSize)
+{
+ PSECURITY_DESCRIPTOR sd;
+ BOOL bResult = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptor, StringSDRevision, &sd, SecurityDescriptorSize);
+ if (bResult) {
+ if (sa.lpSecurityDescriptor)
+ LocalFree(sa.lpSecurityDescriptor);
+ sa.lpSecurityDescriptor = sd;
+ }
+ return bResult;
+}
+
+#pragma warning(pop)
+
+/// @}