| 126 | } |
| 127 | |
| 128 | HRESULT |
| 129 | SK_Shell32_GetKnownFolderPath ( _In_ REFKNOWNFOLDERID rfid, |
| 130 | std::wstring& dir, |
| 131 | volatile LONG* _RunOnce ) |
| 132 | { |
| 133 | // Use the current directory if COM or permissions are mucking things up |
| 134 | auto _FailFastAndDie = |
| 135 | [&] (void)->HRESULT |
| 136 | { |
| 137 | wchar_t wszCurrentDir [MAX_PATH + 2] = { }; |
| 138 | GetCurrentDirectoryW (MAX_PATH, wszCurrentDir); |
| 139 | dir = wszCurrentDir; |
| 140 | |
| 141 | InterlockedIncrementRelease (_RunOnce); |
| 142 | |
| 143 | return E_ACCESSDENIED; |
| 144 | }; |
| 145 | |
| 146 | auto _TrySHGetKnownFolderPath = |
| 147 | [&](HANDLE hToken, wchar_t** ppStr)->HRESULT |
| 148 | { |
| 149 | HRESULT try_result = |
| 150 | SHGetKnownFolderPath (rfid, 0, hToken, ppStr); |
| 151 | |
| 152 | if (SUCCEEDED (try_result)) |
| 153 | { |
| 154 | dir = *ppStr; |
| 155 | |
| 156 | CoTaskMemFree (*ppStr); |
| 157 | |
| 158 | InterlockedIncrementRelease (_RunOnce); |
| 159 | } |
| 160 | |
| 161 | return try_result; |
| 162 | }; |
| 163 | |
| 164 | |
| 165 | HRESULT hr = |
| 166 | S_OK; |
| 167 | |
| 168 | if (! InterlockedCompareExchangeAcquire (_RunOnce, 1, 0)) |
| 169 | { |
| 170 | SK_AutoHandle hToken (INVALID_HANDLE_VALUE); |
| 171 | wchar_t* str = nullptr; |
| 172 | |
| 173 | if (! OpenProcessToken ( |
| 174 | SK_GetCurrentProcess (), TOKEN_QUERY | TOKEN_IMPERSONATE | |
| 175 | TOKEN_READ, &hToken.m_h ) |
| 176 | ) |
| 177 | { |
| 178 | return |
| 179 | _FailFastAndDie (); |
| 180 | } |
| 181 | |
| 182 | hr = |
| 183 | _TrySHGetKnownFolderPath (hToken.m_h, &str); |
| 184 | |
| 185 | // Second chance |
no test coverage detected