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

commit fcbcaa10a76c6f5d5f972c842d1b8b1a5a23a30b
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Fri Jan 17 09:33:52 2025 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Fri Jan 17 09:33:52 2025 +0900

    [SHELL32][SHELL32_APITEST][SDK] Implement SHGetUserDisplayName (#7612)
    
    Implemementing missing features...
    JIRA issue: CORE-19278
    - Add netapi32 and secur32 delay importing.
    - Move function definition from stubs.cpp into utils.cpp.
    - Include some security headers in utils.cpp.
    - Adapt <secext.h> to C++.
    - Add prototype to <undocshell.h>.
---
 dll/win32/shell32/CMakeLists.txt                   |  2 +-
 dll/win32/shell32/stubs.cpp                        | 12 ----
 dll/win32/shell32/utils.cpp                        | 65 ++++++++++++++++++++++
 modules/rostests/apitests/shell32/CMakeLists.txt   |  1 +
 .../apitests/shell32/SHGetUserDisplayName.cpp      | 30 ++++++++++
 modules/rostests/apitests/shell32/testlist.c       |  2 +
 sdk/include/psdk/secext.h                          | 11 +++-
 sdk/include/reactos/undocshell.h                   |  5 ++
 8 files changed, 114 insertions(+), 14 deletions(-)

diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt
index 258191318b6..81df5d528ab 100644
--- a/dll/win32/shell32/CMakeLists.txt
+++ b/dll/win32/shell32/CMakeLists.txt
@@ -120,7 +120,7 @@ set_source_files_properties(shell32.rc PROPERTIES 
OBJECT_DEPENDS ${CMAKE_CURRENT
 
 set_module_type(shell32 win32dll UNICODE)
 target_link_libraries(shell32 shellmenu shelldesktop wine uuid recyclebin 
cpprt atl_classes oldnames)
-add_delay_importlibs(shell32 powrprof shdocvw devmgr winspool.drv winmm mpr 
uxtheme ole32 oleaut32 userenv browseui version fmifs)
+add_delay_importlibs(shell32 powrprof shdocvw devmgr winspool.drv winmm mpr 
uxtheme ole32 oleaut32 userenv browseui version fmifs netapi32 secur32)
 add_importlibs(shell32 advapi32 gdi32 user32 comctl32 comdlg32 shlwapi msvcrt 
kernel32 ntdll)
 add_dependencies(shell32 stdole2) # shell32_shldisp.tlb needs stdole2.tlb
 add_pch(shell32 precomp.h "${PCH_SKIP_SOURCE}")
diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp
index 77e674e795f..fa022eb6c07 100644
--- a/dll/win32/shell32/stubs.cpp
+++ b/dll/win32/shell32/stubs.cpp
@@ -920,18 +920,6 @@ PathIsSlowW(
     return FALSE;
 }
 
-/*
- * Unimplemented
- */
-EXTERN_C DWORD
-WINAPI
-SHGetUserDisplayName(LPWSTR lpName, PULONG puSize)
-{
-    FIXME("SHGetUserDisplayName() stub\n");
-    wcscpy(lpName, L"UserName");
-    return ERROR_SUCCESS;
-}
-
 /*
  * Unimplemented
  */
diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp
index 440d22f6460..21e97461c52 100644
--- a/dll/win32/shell32/utils.cpp
+++ b/dll/win32/shell32/utils.cpp
@@ -6,6 +6,10 @@
  */
 
 #include "precomp.h"
+#include <lmcons.h>
+#include <lmapibuf.h>
+#include <lmaccess.h>
+#include <secext.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -1485,3 +1489,64 @@ SHELL_CreateShell32DefaultExtractIcon(int IconIndex, 
REFIID riid, LPVOID *ppvOut
     initIcon->SetNormalIcon(swShell32Name, IconIndex);
     return initIcon->QueryInterface(riid, ppvOut);
 }
+
+/*************************************************************************
+ *  SHGetUserDisplayName [SHELL32.241]
+ *
+ * @see https://undoc.airesoft.co.uk/shell32.dll/SHGetUserDisplayName.php
+ */
+EXTERN_C
+HRESULT WINAPI
+SHGetUserDisplayName(
+    _Out_writes_to_(*puSize, *puSize) PWSTR pName,
+    _Inout_ PULONG puSize)
+{
+    if (!pName || !puSize)
+        return E_INVALIDARG;
+
+    if (GetUserNameExW(NameDisplay, pName, puSize))
+        return S_OK;
+
+    LONG error = GetLastError(); // for ERROR_NONE_MAPPED
+    HRESULT hr = HRESULT_FROM_WIN32(error);
+
+    WCHAR UserName[MAX_PATH];
+    DWORD cchUserName = _countof(UserName);
+    if (!GetUserNameW(UserName, &cchUserName))
+        return HRESULT_FROM_WIN32(GetLastError());
+
+    // Was the user name not available in the specified format (NameDisplay)?
+    if (error == ERROR_NONE_MAPPED)
+    {
+        // Try to get the user name by using Network API
+        PUSER_INFO_2 UserInfo;
+        DWORD NetError = NetUserGetInfo(NULL, UserName, 2, (PBYTE*)&UserInfo);
+        if (NetError)
+        {
+            hr = HRESULT_FROM_WIN32(NetError);
+        }
+        else
+        {
+            if (UserInfo->usri2_full_name)
+            {
+                hr = StringCchCopyW(pName, *puSize, UserInfo->usri2_full_name);
+                if (SUCCEEDED(hr))
+                {
+                    // Include the NUL-terminator
+                    *puSize = lstrlenW(UserInfo->usri2_full_name) + 1;
+                }
+            }
+
+            NetApiBufferFree(UserInfo);
+        }
+    }
+
+    if (FAILED(hr))
+    {
+        hr = StringCchCopyW(pName, *puSize, UserName);
+        if (SUCCEEDED(hr))
+            *puSize = cchUserName;
+    }
+
+    return hr;
+}
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt 
b/modules/rostests/apitests/shell32/CMakeLists.txt
index 2a90a0e009d..cad67b40a19 100644
--- a/modules/rostests/apitests/shell32/CMakeLists.txt
+++ b/modules/rostests/apitests/shell32/CMakeLists.txt
@@ -41,6 +41,7 @@ list(APPEND SOURCE
     ShellInfo.cpp
     ShellState.cpp
     SHGetAttributesFromDataObject.cpp
+    SHGetUserDisplayName.cpp
     SHLimitInputEdit.cpp
     menu.cpp
     shelltest.cpp)
diff --git a/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp 
b/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp
new file mode 100644
index 00000000000..ed2fcc37587
--- /dev/null
+++ b/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp
@@ -0,0 +1,30 @@
+/*
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Test for SHGetUserDisplayName
+ * COPYRIGHT:   Copyright 2025 Katayama Hirofumi MZ 
(katayama.hirofumi...@gmail.com)
+ */
+
+#include "shelltest.h"
+#include <undocshell.h>
+
+START_TEST(SHGetUserDisplayName)
+{
+    HRESULT hr;
+    WCHAR szBuf[MAX_PATH];
+    ULONG cchBuf;
+
+    hr = SHGetUserDisplayName(NULL, NULL);
+    ok_hex(hr, E_INVALIDARG);
+
+    hr = SHGetUserDisplayName(szBuf, NULL);
+    ok_hex(hr, E_INVALIDARG);
+
+    cchBuf = _countof(szBuf);
+    hr = SHGetUserDisplayName(NULL, &cchBuf);
+    ok_hex(hr, E_INVALIDARG);
+
+    cchBuf = _countof(szBuf);
+    hr = SHGetUserDisplayName(szBuf, &cchBuf);
+    ok_hex(hr, S_OK);
+}
diff --git a/modules/rostests/apitests/shell32/testlist.c 
b/modules/rostests/apitests/shell32/testlist.c
index ff06c5a5dc6..87f924f9f23 100644
--- a/modules/rostests/apitests/shell32/testlist.c
+++ b/modules/rostests/apitests/shell32/testlist.c
@@ -42,6 +42,7 @@ extern void func_ShellHook(void);
 extern void func_ShellState(void);
 extern void func_SHGetAttributesFromDataObject(void);
 extern void func_SHGetFileInfo(void);
+extern void func_SHGetUserDisplayName(void);
 extern void func_SHLimitInputEdit(void);
 extern void func_SHParseDisplayName(void);
 extern void func_SHSimpleIDListFromPath(void);
@@ -88,6 +89,7 @@ const struct test winetest_testlist[] =
     { "ShellState", func_ShellState },
     { "SHGetAttributesFromDataObject", func_SHGetAttributesFromDataObject },
     { "SHGetFileInfo", func_SHGetFileInfo },
+    { "SHGetUserDisplayName", func_SHGetUserDisplayName },
     { "SHLimitInputEdit", func_SHLimitInputEdit },
     { "SHParseDisplayName", func_SHParseDisplayName },
     { "SHSimpleIDListFromPath", func_SHSimpleIDListFromPath },
diff --git a/sdk/include/psdk/secext.h b/sdk/include/psdk/secext.h
index b60399241ee..d9397113171 100644
--- a/sdk/include/psdk/secext.h
+++ b/sdk/include/psdk/secext.h
@@ -1,8 +1,13 @@
 #ifndef _SECEXT_H
 #define _SECEXT_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef RC_INVOKED
 #if (_WIN32_WINNT >= 0x0500)
+
 typedef enum
 {
   NameUnknown = 0,
@@ -34,7 +39,11 @@ BOOLEAN WINAPI 
TranslateNameW(LPCWSTR,EXTENDED_NAME_FORMAT,EXTENDED_NAME_FORMAT,
 #define TranslateName TranslateNameA
 #endif
 
-
 #endif /* ! RC_INVOKED */
 #endif /* _WIN32_WINNT >= 0x0500 */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
 #endif /* ! _SECEXT_H */
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index f5bd2cd7f2e..76e78372dd1 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -211,6 +211,11 @@ DWORD WINAPI SHNetConnectionDialog(
 
 BOOL WINAPI SHIsTempDisplayMode(VOID);
 
+HRESULT WINAPI
+SHGetUserDisplayName(
+    _Out_writes_to_(*puSize, *puSize) PWSTR pName,
+    _Inout_ PULONG puSize);
+
 /****************************************************************************
  * Cabinet Window Messages
  */

Reply via email to