Alexandre Julliard : kernelbase: Implement the Get/SetComputerName functions.
Alexandre Julliard
julliard at winehq.org
Thu Dec 12 16:29:41 CST 2019
Module: wine
Branch: master
Commit: 7822b854110dd1da0471489beab8f6ce04eb418b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7822b854110dd1da0471489beab8f6ce04eb418b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Dec 12 19:18:15 2019 +0100
kernelbase: Implement the Get/SetComputerName functions.
Signed-off-by: Alexandre Julliard <julliard at 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 */
More information about the wine-cvs
mailing list