https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cc6e444ceb7f6b7b107d45e5e18579b14cf9f4c1

commit cc6e444ceb7f6b7b107d45e5e18579b14cf9f4c1
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Sep 24 07:11:38 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Sep 24 07:11:38 2023 +0900

    [SHELL32][SDK] Implement SHInvokePrivilegedFunctionW (#5718)
    
    Add it to <undocshell.h>. Modify shell32.spec.
---
 dll/win32/shell32/shell32.spec   |  2 +-
 dll/win32/shell32/utils.cpp      | 41 ++++++++++++++++++++++++++++++++++++++++
 sdk/include/reactos/undocshell.h |  8 ++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/dll/win32/shell32/shell32.spec b/dll/win32/shell32/shell32.spec
index c050a87a122..a89d475a913 100644
--- a/dll/win32/shell32/shell32.spec
+++ b/dll/win32/shell32/shell32.spec
@@ -242,7 +242,7 @@
 243 stdcall -noname SHSetShellWindowEx(ptr ptr) user32.SetShellWindowEx
 244 stdcall -noname SHSettingsChanged(ptr ptr)
 245 stdcall SHTestTokenMembership(ptr ptr)
-246 stub -noname SHInvokePrivilegedFunctionW
+246 stdcall -noname SHInvokePrivilegedFunctionW(wstr ptr ptr)
 247 stub -noname SHGetActiveConsoleSessionId
 248 stdcall -noname SHGetUserSessionId(ptr)
 249 stdcall -noname PathParseIconLocation(wstr) PathParseIconLocationW
diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp
index 537f23a6504..5f3e38175ec 100644
--- a/dll/win32/shell32/utils.cpp
+++ b/dll/win32/shell32/utils.cpp
@@ -62,6 +62,47 @@ EXTERN_C DWORD WINAPI SHGetUserSessionId(_In_opt_ HANDLE 
hToken)
     return dwSessionId;
 }
 
+/*************************************************************************
+ *                SHInvokePrivilegedFunctionW (SHELL32.246)
+ */
+EXTERN_C
+HRESULT WINAPI
+SHInvokePrivilegedFunctionW(
+    _In_z_ LPCWSTR pszName,
+    _In_ PRIVILEGED_FUNCTION fn,
+    _In_opt_ LPARAM lParam)
+{
+    TRACE("(%s %p %p)\n", debugstr_w(pszName), fn, lParam);
+
+    if (!pszName || !fn)
+        return E_INVALIDARG;
+
+    HANDLE hToken = NULL;
+    TOKEN_PRIVILEGES NewPriv, PrevPriv;
+    BOOL bAdjusted = FALSE;
+
+    if (SHOpenEffectiveToken(&hToken) &&
+        ::LookupPrivilegeValueW(NULL, pszName, &NewPriv.Privileges[0].Luid))
+    {
+        NewPriv.PrivilegeCount = 1;
+        NewPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+        DWORD dwReturnSize;
+        bAdjusted = ::AdjustTokenPrivileges(hToken, FALSE, &NewPriv,
+                                            sizeof(PrevPriv), &PrevPriv, 
&dwReturnSize);
+    }
+
+    HRESULT hr = fn(lParam);
+
+    if (bAdjusted)
+        ::AdjustTokenPrivileges(hToken, FALSE, &PrevPriv, 0, NULL, NULL);
+
+    if (hToken)
+        ::CloseHandle(hToken);
+
+    return hr;
+}
+
 /*************************************************************************
  *                SHGetShellStyleHInstance (SHELL32.749)
  */
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index 9c74f8d9b00..312804e7d73 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -687,6 +687,14 @@ LargeIntegerToString(
 BOOL WINAPI SHOpenEffectiveToken(_Out_ LPHANDLE phToken);
 DWORD WINAPI SHGetUserSessionId(_In_opt_ HANDLE hToken);
 
+typedef HRESULT (CALLBACK *PRIVILEGED_FUNCTION)(LPARAM lParam);
+
+HRESULT WINAPI
+SHInvokePrivilegedFunctionW(
+    _In_z_ LPCWSTR pszName,
+    _In_ PRIVILEGED_FUNCTION fn,
+    _In_opt_ LPARAM lParam);
+
 /*****************************************************************************
  * Shell32 resources
  */

Reply via email to