Reactos
at master 159 lines 5.2 kB view raw
1/* 2 * PROJECT: ReactOS API Tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Tests for SHGetComputerDisplayNameW 5 * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8#include "shelltest.h" 9#include <lmserver.h> 10#include <undocshell.h> 11#include <strsafe.h> 12#include <versionhelpers.h> 13 14typedef HRESULT (WINAPI *FN_SHGetComputerDisplayNameW)(PWSTR, DWORD, PWSTR, DWORD); 15typedef NET_API_STATUS (WINAPI *FN_NetServerGetInfo)(LPWSTR, DWORD, PBYTE*); 16typedef NET_API_STATUS (WINAPI *FN_NetApiBufferFree)(PVOID); 17 18static FN_SHGetComputerDisplayNameW s_pSHGetComputerDisplayNameW = NULL; 19static FN_NetServerGetInfo s_pNetServerGetInfo = NULL; 20static FN_NetApiBufferFree s_pNetApiBufferFree = NULL; 21 22#define COMPUTER_DESCRIPTIONS_KEY \ 23 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComputerDescriptions" 24 25static PCWSTR 26SHELL_SkipServerSlashes( 27 _In_ PCWSTR pszPath) 28{ 29 PCWSTR pch; 30 for (pch = pszPath; *pch == L'\\'; ++pch) 31 ; 32 return pch; 33} 34 35static VOID 36SHELL_CacheComputerDescription( 37 _In_ PCWSTR pszServerName, 38 _In_ PCWSTR pszDesc) 39{ 40 if (!pszDesc) 41 return; 42 43 SIZE_T cbDesc = (wcslen(pszDesc) + 1) * sizeof(WCHAR); 44 SHSetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, 45 SHELL_SkipServerSlashes(pszServerName), REG_SZ, pszDesc, (DWORD)cbDesc); 46} 47 48static HRESULT 49SHELL_GetCachedComputerDescription( 50 _Out_writes_z_(cchDescMax) PWSTR pszDesc, 51 _In_ DWORD cchDescMax, 52 _In_ PCWSTR pszServerName) 53{ 54 cchDescMax *= sizeof(WCHAR); 55 DWORD error = SHGetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, 56 SHELL_SkipServerSlashes(pszServerName), NULL, pszDesc, &cchDescMax); 57 return HRESULT_FROM_WIN32(error); 58} 59 60static HRESULT 61SHELL_BuildDisplayMachineName( 62 _Out_writes_z_(cchNameMax) PWSTR pszName, 63 _In_ DWORD cchNameMax, 64 _In_ PCWSTR pszServerName, 65 _In_ PCWSTR pszDescription) 66{ 67 if (!pszDescription || !*pszDescription) 68 return E_FAIL; 69 70 PCWSTR pszFormat = (SHRestricted(REST_ALLOWCOMMENTTOGGLE) ? L"%2 (%1)" : L"%1 (%2)"); 71 PCWSTR args[] = { pszDescription , SHELL_SkipServerSlashes(pszServerName) }; 72 return (FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, 73 pszFormat, 0, 0, pszName, cchNameMax, (va_list *)args) ? S_OK : E_FAIL); 74} 75 76static VOID 77TEST_SHGetComputerDisplayNameW(VOID) 78{ 79 WCHAR szCompName[MAX_COMPUTERNAME_LENGTH + 1], szDesc[256], szDisplayName[MAX_PATH]; 80 WCHAR szName[MAX_PATH], szServerName[] = L"DummyServerName"; 81 82 DWORD cchCompName = _countof(szCompName); 83 BOOL ret = GetComputerNameW(szCompName, &cchCompName); 84 ok_int(ret, TRUE); 85 trace("%s\n", wine_dbgstr_w(szCompName)); 86 87 SHELL_CacheComputerDescription(szServerName, L"DummyDescription"); 88 89 HRESULT hr = SHELL_GetCachedComputerDescription(szDesc, _countof(szDesc), szServerName); 90 if (FAILED(hr)) 91 szDesc[0] = UNICODE_NULL; 92 trace("%s\n", wine_dbgstr_w(szDesc)); 93 94 StringCchCopyW(szDisplayName, _countof(szDisplayName), L"@"); 95 hr = s_pSHGetComputerDisplayNameW(NULL, SHGCDN_NOCACHE, szDisplayName, _countof(szDisplayName)); 96 ok_hex(hr, S_OK); 97 trace("%s\n", wine_dbgstr_w(szDisplayName)); 98 ok_wstr(szDisplayName, szCompName); 99 100 StringCchCopyW(szDisplayName, _countof(szDisplayName), L"@"); 101 hr = s_pSHGetComputerDisplayNameW(szServerName, 0, szDisplayName, _countof(szDisplayName)); 102 ok_hex(hr, S_OK); 103 trace("%s\n", wine_dbgstr_w(szServerName)); 104 ok_wstr(szServerName, L"DummyServerName"); 105 106 hr = SHELL_BuildDisplayMachineName(szName, _countof(szName), szServerName, szDesc); 107 ok_hex(hr, S_OK); 108 109 trace("%s\n", wine_dbgstr_w(szDisplayName)); 110 trace("%s\n", wine_dbgstr_w(szName)); 111 ok_wstr(szDisplayName, szName); 112 113 // Delete registry value 114 HKEY hKey; 115 LSTATUS error = RegOpenKeyExW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, 0, KEY_WRITE, &hKey); 116 if (error == ERROR_SUCCESS) 117 { 118 RegDeleteValueW(hKey, L"DummyServerName"); 119 RegCloseKey(hKey); 120 } 121} 122 123START_TEST(SHGetComputerDisplayNameW) 124{ 125 if (IsWindowsVistaOrGreater()) 126 { 127 skip("Tests on Vista+ will cause exception\n"); 128 return; 129 } 130 131 HINSTANCE hShell32 = GetModuleHandleW(L"shell32.dll"); 132 s_pSHGetComputerDisplayNameW = 133 (FN_SHGetComputerDisplayNameW)GetProcAddress(hShell32, MAKEINTRESOURCEA(752)); 134 if (!s_pSHGetComputerDisplayNameW) 135 { 136 skip("SHGetComputerDisplayNameW not found\n"); 137 return; 138 } 139 140 HINSTANCE hNetApi32 = LoadLibraryW(L"netapi32.dll"); 141 if (!hNetApi32) 142 { 143 skip("netapi32.dll not found\n"); 144 return; 145 } 146 147 s_pNetServerGetInfo = (FN_NetServerGetInfo)GetProcAddress(hNetApi32, "NetServerGetInfo"); 148 s_pNetApiBufferFree = (FN_NetApiBufferFree)GetProcAddress(hNetApi32, "NetApiBufferFree"); 149 if (!s_pNetServerGetInfo || !s_pNetApiBufferFree) 150 { 151 skip("NetServerGetInfo or NetApiBufferFree not found\n"); 152 FreeLibrary(hNetApi32); 153 return; 154 } 155 156 TEST_SHGetComputerDisplayNameW(); 157 158 FreeLibrary(hNetApi32); 159}