Module: wine Branch: master Commit: 7822b854110dd1da0471489beab8f6ce04eb418b URL: https://source.winehq.org/git/wine.git/?a=commit;h=7822b854110dd1da0471489be...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Dec 12 19:18:15 2019 +0100
kernelbase: Implement the Get/SetComputerName functions.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/kernelbase.spec | 12 +-- dlls/kernelbase/registry.c | 216 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 221 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 5b3e10f85b..afa3b0192f 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -437,8 +437,8 @@ @ stdcall GetCommandLineW() @ stdcall GetCompressedFileSizeA(long ptr) @ stdcall GetCompressedFileSizeW(long ptr) -@ stdcall GetComputerNameExA(long ptr ptr) kernel32.GetComputerNameExA -@ stdcall GetComputerNameExW(long ptr ptr) kernel32.GetComputerNameExW +@ stdcall GetComputerNameExA(long ptr ptr) +@ stdcall GetComputerNameExW(long ptr ptr) @ stdcall GetConsoleCP() @ stdcall GetConsoleCursorInfo(long ptr) @ stdcall GetConsoleInputExeNameA(long ptr) @@ -1397,11 +1397,11 @@ @ stdcall SetCommMask(long long) @ stdcall SetCommState(long ptr) @ stdcall SetCommTimeouts(long ptr) -@ stdcall SetComputerNameA(str) kernel32.SetComputerNameA +@ stdcall SetComputerNameA(str) # @ stub SetComputerNameEx2W -@ stdcall SetComputerNameExA(long str) kernel32.SetComputerNameExA -@ stdcall SetComputerNameExW(long wstr) kernel32.SetComputerNameExW -@ stdcall SetComputerNameW(wstr) kernel32.SetComputerNameW +@ stdcall SetComputerNameExA(long str) +@ stdcall SetComputerNameExW(long wstr) +@ stdcall SetComputerNameW(wstr) @ stdcall SetConsoleActiveScreenBuffer(long) @ stdcall SetConsoleCP(long) @ stdcall SetConsoleCtrlHandler(ptr long) kernel32.SetConsoleCtrlHandler diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index b3297a3ad5..72b7711714 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -109,6 +109,8 @@ static struct list reg_mui_cache = LIST_INIT(reg_mui_cache); /* MRU */ static unsigned int reg_mui_cache_count; #define REG_MUI_CACHE_SIZE 8
+#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') + /* check if value type needs string conversion (Ansi<->Unicode) */ static inline BOOL is_string( DWORD type ) { @@ -1374,7 +1376,7 @@ static DWORD query_perf_data(const WCHAR *query, DWORD *type, void *data, DWORD data = pdb + 1; pdb->SystemNameOffset = sizeof(*pdb); pdb->SystemNameLength = (data_size - sizeof(*pdb)) / sizeof(WCHAR); - if (!GetComputerNameW(data, &pdb->SystemNameLength)) + if (!GetComputerNameExW(ComputerNameNetBIOS, data, &pdb->SystemNameLength)) return ERROR_MORE_DATA;
pdb->SystemNameLength++; @@ -3078,6 +3080,218 @@ BOOL WINAPI DECLSPEC_HOTPATCH DnsHostnameToComputerNameExW( const WCHAR *hostnam }
+/*********************************************************************** + * GetComputerNameExA (kernelbase.@) + */ +BOOL WINAPI GetComputerNameExA( COMPUTER_NAME_FORMAT type, char *name, DWORD *len ) +{ + BOOL ret = FALSE; + DWORD lenA, lenW = 0; + WCHAR *buffer; + + GetComputerNameExW( type, NULL, &lenW ); + if (GetLastError() != ERROR_MORE_DATA) return FALSE; + + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + if (GetComputerNameExW( type, buffer, &lenW )) + { + lenA = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL ); + if (lenA > *len) + { + *len = lenA; + SetLastError( ERROR_MORE_DATA ); + } + else + { + WideCharToMultiByte( CP_ACP, 0, buffer, -1, name, *len, NULL, NULL ); + *len = lenA - 1; + ret = TRUE; + } + } + HeapFree( GetProcessHeap(), 0, buffer ); + return ret; +} + + +/*********************************************************************** + * GetComputerNameExW (kernelbase.@) + */ +BOOL WINAPI GetComputerNameExW( COMPUTER_NAME_FORMAT type, WCHAR *name, DWORD *len ) +{ + const WCHAR *keyname, *valuename; + LRESULT ret; + HKEY key; + + switch (type) + { + case ComputerNameNetBIOS: + case ComputerNamePhysicalNetBIOS: + keyname = L"System\CurrentControlSet\Control\ComputerName\ActiveComputerName"; + valuename = L"ComputerName"; + break; + case ComputerNameDnsHostname: + case ComputerNamePhysicalDnsHostname: + keyname = L"System\CurrentControlSet\Services\Tcpip\Parameters"; + valuename = L"Hostname"; + break; + case ComputerNameDnsDomain: + case ComputerNamePhysicalDnsDomain: + keyname = L"System\CurrentControlSet\Services\Tcpip\Parameters"; + valuename = L"Domain"; + break; + case ComputerNameDnsFullyQualified: + case ComputerNamePhysicalDnsFullyQualified: + { + WCHAR buffer[256]; + DWORD size = ARRAY_SIZE(buffer); + + if (!GetComputerNameExW( ComputerNameDnsHostname, buffer, &size )) return FALSE; + lstrcatW( buffer, L"." ); + size = ARRAY_SIZE(buffer) - lstrlenW(buffer); + if (!GetComputerNameExW( ComputerNameDnsDomain, buffer + lstrlenW(buffer), &size )) return FALSE; + size = lstrlenW(buffer); + if (name && size < *len) + { + if (name) lstrcpyW( name, buffer ); + *len = size; + return TRUE; + } + *len = size + 1; + SetLastError( ERROR_MORE_DATA ); + return FALSE; + } + default: + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!(ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &key ))) + { + DWORD size = *len * sizeof(WCHAR); + ret = RegQueryValueExW( key, valuename, NULL, NULL, (BYTE *)name, &size ); + if (!name) ret = ERROR_MORE_DATA; + else if (!ret) size -= sizeof(WCHAR); + *len = size / sizeof(WCHAR); + RegCloseKey( key ); + } + TRACE("-> %lu %s\n", ret, debugstr_w(name) ); + if (ret) SetLastError( ret ); + return !ret; +} + + +/*********************************************************************** + * SetComputerNameA (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetComputerNameA( const char *name ) +{ + BOOL ret; + DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); + WCHAR *nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len ); + ret = SetComputerNameExW( ComputerNamePhysicalNetBIOS, nameW ); + HeapFree( GetProcessHeap(), 0, nameW ); + return ret; +} + + +/*********************************************************************** + * SetComputerNameW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetComputerNameW( const WCHAR *name ) +{ + return SetComputerNameExW( ComputerNamePhysicalNetBIOS, name ); +} + + +/*********************************************************************** + * SetComputerNameExA (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetComputerNameExA( COMPUTER_NAME_FORMAT type, const char *name ) +{ + BOOL ret; + DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); + WCHAR *nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len ); + ret = SetComputerNameExW( type, nameW ); + HeapFree( GetProcessHeap(), 0, nameW ); + return ret; +} + + +/*********************************************************************** + * SetComputerNameExW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetComputerNameExW( COMPUTER_NAME_FORMAT type, const WCHAR *name ) +{ + WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD size; + HKEY key; + LRESULT ret; + + TRACE( "%u %s\n", type, debugstr_w( name )); + + switch (type) + { + case ComputerNameDnsHostname: + case ComputerNamePhysicalDnsHostname: + ret = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Services\Tcpip\Parameters", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); + if (ret) break; + ret = RegSetValueExW( key, L"Hostname", 0, REG_SZ, + (BYTE *)name, (lstrlenW(name) + 1) * sizeof(WCHAR) ); + RegCloseKey( key ); + /* fall through */ + + case ComputerNameNetBIOS: + case ComputerNamePhysicalNetBIOS: + /* @@ Wine registry key: HKCU\Software\Wine\Network */ + if (!RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\Wine\Network", 0, KEY_READ, &key )) + { + BOOL use_dns = TRUE; + size = sizeof(buffer); + if (!RegQueryValueExW( key, L"UseDnsComputerName", NULL, NULL, (BYTE *)buffer, &size )) + use_dns = IS_OPTION_TRUE( buffer[0] ); + RegCloseKey( key ); + if (!use_dns) + { + ret = ERROR_ACCESS_DENIED; + break; + } + } + size = ARRAY_SIZE( buffer ); + if (!DnsHostnameToComputerNameExW( name, buffer, &size )) return FALSE; + ret = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Control\ComputerName\ComputerName", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); + if (ret) break; + ret = RegSetValueExW( key, L"ComputerName", 0, REG_SZ, + (BYTE *)buffer, (lstrlenW(buffer) + 1) * sizeof(WCHAR) ); + RegCloseKey( key ); + break; + + case ComputerNameDnsDomain: + case ComputerNamePhysicalDnsDomain: + ret = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Services\Tcpip\Parameters", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); + if (ret) break; + ret = RegSetValueExW( key, L"Domain", 0, REG_SZ, + (BYTE *)name, (lstrlenW(name) + 1) * sizeof(WCHAR) ); + RegCloseKey( key ); + break; + default: + ret = ERROR_INVALID_PARAMETER; + break; + } + if (ret) SetLastError( ret ); + return !ret; +} + struct USKEY { HKEY HKCUstart; /* Start key in CU hive */