WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
Cred.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
7#pragma once
8
9#include "Common.h"
10#include <wincred.h>
11#include <memory>
12
18
20template<class _Traits, class _Ax>
21static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
22{
23 char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
24 DWORD dwSize = _countof(buf);
25
26 // Try with the stack buffer first.
27 if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
28 // Copy from stack.
29 sProtectedCredentials.assign(buf, dwSize - 1);
30 return TRUE;
31 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
32 // Allocate on heap and retry.
33 std::unique_ptr<char[]> buf(new char[dwSize]);
34 if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
35 sProtectedCredentials.assign(buf.get(), dwSize - 1);
36 return TRUE;
37 }
38 }
39
40 return FALSE;
41}
42
48template<class _Traits, class _Ax>
49static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
50{
51 wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
52 DWORD dwSize = _countof(buf);
53
54 // Try with the stack buffer first.
55 if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
56 // Copy from stack.
57 sProtectedCredentials.assign(buf, dwSize - 1);
58 return TRUE;
59 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
60 // Allocate on heap and retry.
61 std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
62 if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
63 sProtectedCredentials.assign(buf.get(), dwSize - 1);
64 return TRUE;
65 }
66 }
67
68 return FALSE;
69}
70
72template<class _Traits, class _Ax>
73static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sCredentials)
74{
75 char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
76 DWORD dwSize = _countof(buf);
77
78 // Try with the stack buffer first.
79 if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
80 // Copy from stack.
81 sCredentials.assign(buf, dwSize);
82 return TRUE;
83 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
84 // Allocate on heap and retry.
85 std::unique_ptr<char[]> buf(new char[dwSize]);
86 if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
87 sCredentials.assign(buf.get(), dwSize);
88 return TRUE;
89 }
90 }
91
92 return FALSE;
93}
94
100template<class _Traits, class _Ax>
101static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sCredentials)
102{
103 wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
104 DWORD dwSize = _countof(buf);
105
106 // Try with the stack buffer first.
107 if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
108 // Copy from stack.
109 sCredentials.assign(buf, dwSize);
110 return TRUE;
111 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
112 // Allocate on heap and retry.
113 std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
114 if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
115 sCredentials.assign(buf.get(), dwSize);
116 return TRUE;
117 }
118 }
119
120 return FALSE;
121}
122
124
125namespace winstd
126{
129
133 template <class _Ty> struct CredFree_delete
134 {
136
141
145 template <class _Ty2> CredFree_delete(const CredFree_delete<_Ty2>&) {}
146
152 void operator()(_Ty *_Ptr) const
153 {
154 CredFree(_Ptr);
155 }
156 };
157
161 template <class _Ty> struct CredFree_delete<_Ty[]>
162 {
164
169
175 void operator()(_Ty *_Ptr) const noexcept
176 {
177 CredFree(_Ptr);
178 }
179
185 template<class _Other>
186 void operator()(_Other *) const
187 {
188 CredFree(_Ptr);
189 }
190 };
191
193}
194
197
203#pragma warning(suppress: 4505) // Don't warn on unused code
204static BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Inout_ std::unique_ptr<PCREDENTIAL[], winstd::CredFree_delete<PCREDENTIAL[]> > &cCredentials) noexcept
205{
206 PCREDENTIAL *pCredentials;
207 if (CredEnumerate(Filter, Flags, Count, &pCredentials)) {
208 cCredentials.reset(pCredentials);
209 return TRUE;
210 }
211
212 return FALSE;
213}
214
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:79
CredFree_delete< _Ty > _Myt
This type.
Definition: Cred.h:163
CredFree_delete()
Default construct.
Definition: Cred.h:168
void operator()(_Other *) const
Delete a pointer of another type.
Definition: Cred.h:186
void operator()(_Ty *_Ptr) const noexcept
Delete a pointer.
Definition: Cred.h:175
Deleter for unique_ptr using CredFree.
Definition: Cred.h:134
void operator()(_Ty *_Ptr) const
Delete a pointer.
Definition: Cred.h:152
CredFree_delete()
Default construct.
Definition: Cred.h:140
CredFree_delete< _Ty > _Myt
This type.
Definition: Cred.h:135
CredFree_delete(const CredFree_delete< _Ty2 > &)
Construct from another CredFree_delete.
Definition: Cred.h:145