ComputerName - take 3

Martin Wilck Martin.Wilck at Fujitsu-Siemens.com
Thu Nov 14 10:54:32 CST 2002


Patch: ComputerName.diff

Added files:
        dlls/kernel:    computername.c
Removed files:
        win32:          init.c
Modified files:
        dlls/kernel:    Makefile.in
                        kernel32.spec
                        kernel_main.c
        include:        winbase.h
        misc:           registry.c
        win32:          newfns.c
        documentation:  configuring.sgml
                        wine.conf.man

Log message: Martin Wilck <Martin.Wilck at Fujitsu-Siemens.com>:
        - Allow setting NetBIOS ComputerName through registry.
        - Keep old behavior as default, using new config option to change.
        - Implement SetComputerName(), SetComputerNameEx(), GetComputerNameEx()
        - ComputerName inialization moved to Kernel32 initialization.

License: X11.

Comments:
See http://www.winehq.com/hypermail/wine-patches/2002/11/0080.html

diff -u /dev/null dlls/kernel/computername.c
--- /dev/null	Thu Apr 11 16:25:15 2002
+++ dlls/kernel/computername.c	Thu Nov 14 17:41:15 2002
@@ -0,0 +1,641 @@
+/*
+ * Win32 kernel functions
+ *
+ * Copyright 1995 Martin von Loewis and Cameron Heide
+ * Copyright 1999 Peter Ganten
+ * Copyright 2002 Martin Wilck
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <netdb.h>
+
+#include "winbase.h"
+#include "winerror.h"
+#include "winnls.h" 
+#include "winternl.h"
+#include "wine/unicode.h"
+#include "wine/exception.h"
+#include "msvcrt/excpt.h"
+#include "wine/debug.h"
+#include "file.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(computername);
+
+/* Wine config options */ 
+static const WCHAR NetworkW[] = {'N','e','t','w','o','r','k',0};
+static const WCHAR UseDNSW[] = {'U','s','e','D','n','s','C','o','m','p','u','t','e','r','N','a','m','e',0};
+
+/* Registry key and value names */
+static const WCHAR ComputerW[] = {'M','a','c','h','i','n','e','\\',
+                                  'S','y','s','t','e','m','\\',
+                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+                                  'C','o','n','t','r','o','l','\\',
+                                  'C','o','m','p','u','t','e','r','N','a','m','e',0};
+static const WCHAR ActiveComputerNameW[] =   {'A','c','t','i','v','e','C','o','m','p','u','t','e','r','N','a','m','e',0};
+static const WCHAR ComputerNameW[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
+
+static const char default_ComputerName[] = "WINE";
+
+/* filter for page-fault exceptions */
+static WINE_EXCEPTION_FILTER(page_fault)
+{
+    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
+        return EXCEPTION_EXECUTE_HANDLER;
+    return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*********************************************************************** 
+ *                    dns_gethostbyname (INTERNAL)
+ *
+ *  From hostname(1):
+ *  "The FQDN is the name gethostbyname(2) returns for the host name returned by gethostname(2)."
+ *
+ *  Wine can use this technique only if the thread-safe gethostbyname_r is available.
+ */
+#ifdef  HAVE_LINUX_GETHOSTBYNAME_R_6
+static BOOL dns_gethostbyname ( char *name, int *size )
+{
+    struct hostent* host = NULL;
+    char *extrabuf;
+    int ebufsize = 1024;
+    struct hostent hostentry;
+    int locerr = ENOBUFS, res = ENOMEM;
+
+    extrabuf = HeapAlloc( GetProcessHeap(), 0, ebufsize ) ;
+
+    while( extrabuf ) 
+    {
+        res = gethostbyname_r ( name, &hostentry, extrabuf, ebufsize, &host, &locerr );
+        if( res != ERANGE ) break;
+        ebufsize *= 2;
+        extrabuf = HeapReAlloc( GetProcessHeap(), 0, extrabuf, ebufsize ) ;
+    }
+    
+    if ( res )
+        WARN ("Error in gethostbyname_r %d (%d)\n", res, locerr);
+    else
+    {
+        size_t len = strlen ( host->h_name );
+        if ( len < *size )
+        {
+            strcpy ( name, host->h_name );
+            *size = len;
+        }
+        else
+        {
+            memcpy ( name, host->h_name, *size );
+            name[*size] = 0;
+            SetLastError ( ERROR_MORE_DATA );
+            res = 1;
+        }
+    }
+
+    HeapFree( GetProcessHeap(), 0, extrabuf );
+    return !res;
+}
+#else
+#  define dns_gethostbyname(name,size) 0
+#endif
+
+/*********************************************************************** 
+ *                     dns_fqdn (INTERNAL)
+ */
+static BOOL dns_fqdn ( char *name, int *size )
+{
+    if ( gethostname ( name, *size + 1 ) ) 
+    {
+        switch( errno )
+        {
+        case ENAMETOOLONG:
+            SetLastError ( ERROR_MORE_DATA );
+        default:
+            SetLastError ( ERROR_INVALID_PARAMETER );
+        }
+        return FALSE;
+    }
+
+    if ( !dns_gethostbyname ( name, size ) )
+        *size = strlen ( name );
+
+    return TRUE;
+}
+
+/*********************************************************************** 
+ *                     dns_hostname (INTERNAL)
+ */
+static BOOL dns_hostname ( char *name, int *size )
+{
+    char *c;
+    if ( ! dns_fqdn ( name, size ) ) return FALSE;
+    c = strchr ( name, '.' );
+    if (c)
+    {
+        *c = 0;
+        *size = (c - name);
+    }
+    return TRUE;
+}
+
+/*********************************************************************** 
+ *                     dns_domainname (INTERNAL)
+ */
+static BOOL dns_domainname ( char *name, int *size )
+{
+    char *c;
+    if ( ! dns_fqdn ( name, size ) ) return FALSE;
+    c = strchr ( name, '.' );
+    if (c)
+    {
+        c += 1;
+        *size -= (c - name);
+        memmove ( name, c, *size + 1 );
+    }
+    return TRUE;
+}
+
+/*********************************************************************** 
+ *                      _init_attr    (INTERNAL)
+ */
+inline static void _init_attr ( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *name )
+{
+    attr->Length = sizeof (OBJECT_ATTRIBUTES);
+    attr->RootDirectory = 0;
+    attr->ObjectName = name;
+    attr->Attributes = 0;
+    attr->SecurityDescriptor = NULL;
+    attr->SecurityQualityOfService = NULL;
+}
+
+/*********************************************************************** 
+ *                      COMPUTERNAME_Init    (INTERNAL)
+ */
+void COMPUTERNAME_Init (void)
+{
+    HKEY hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
+    char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )];
+    DWORD len = sizeof( buf );
+    LPWSTR computer_name = (LPWSTR) (buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
+    NTSTATUS st = STATUS_INTERNAL_ERROR;
+
+    TRACE("(void)\n");
+    _init_attr ( &attr, &nameW );
+    
+    RtlInitUnicodeString( &nameW, ComputerW );
+    if ( ( st = NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
+        goto out;
+    
+    attr.RootDirectory = hkey;
+    RtlInitUnicodeString( &nameW, ComputerNameW );
+    if ( (st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS )
+        goto out;
+    
+    st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len );
+
+    if ( st == STATUS_OBJECT_NAME_NOT_FOUND || 
+         ( st == STATUS_SUCCESS && PROFILE_GetWineIniBool( NetworkW, UseDNSW, 1 ) ) )
+    {
+        char hbuf[256];
+        int hlen = sizeof (hbuf);
+        char *dot;
+        TRACE( "retrieving Unix host name\n" );
+        if ( gethostname ( hbuf, hlen ) )
+        {
+            strcpy ( hbuf, default_ComputerName );
+            WARN( "gethostname() error: %d, using host name %s\n", errno, hbuf );
+        }
+        hbuf[MAX_COMPUTERNAME_LENGTH] = 0;
+        dot = strchr ( hbuf, '.' );
+        if ( dot ) *dot = 0;
+        hlen = strlen ( hbuf );
+        len = MultiByteToWideChar( CP_ACP, 0, hbuf, hlen + 1, computer_name, MAX_COMPUTERNAME_LENGTH + 1 )
+            * sizeof( WCHAR );
+        if ( NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len ) != STATUS_SUCCESS )
+            WARN ( "failed to set ComputerName" );
+    }
+    else if ( st == STATUS_SUCCESS)
+    {
+        len = (len - offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
+        TRACE( "found in registry\n" );
+    }
+    else goto out;
+    
+    NtClose( hsubkey );
+    TRACE(" ComputerName: %s (%lu)\n", debugstr_w ( computer_name ), len / sizeof(WCHAR));
+
+    RtlInitUnicodeString( &nameW, ActiveComputerNameW );
+    if ( ( st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, NULL ) )
+         != STATUS_SUCCESS )
+        goto out;
+    
+    RtlInitUnicodeString( &nameW, ComputerNameW );
+    st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len );
+
+out:
+    NtClose( hsubkey );
+    NtClose( hkey );
+
+    if ( st == STATUS_SUCCESS )
+        TRACE( "success\n" );
+    else
+    {
+        WARN( "status trying to set ComputerName: %lx\n", st );
+        SetLastError ( RtlNtStatusToDosError ( st ) );
+    }
+}
+
+
+/***********************************************************************
+ *              GetComputerNameW         (KERNEL32.@)
+ */
+BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size)
+{
+    UNICODE_STRING nameW;
+    OBJECT_ATTRIBUTES attr;
+    HKEY hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
+    char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )];
+    DWORD len = sizeof( buf );
+    LPWSTR theName = (LPWSTR) (buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ));
+    NTSTATUS st = STATUS_INVALID_PARAMETER;
+    
+    TRACE ("%p %p\n", name, size);
+
+    _init_attr ( &attr, &nameW );
+    RtlInitUnicodeString( &nameW, ComputerW );
+    if ( ( st = NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
+        goto out;
+         
+    attr.RootDirectory = hkey;
+    RtlInitUnicodeString( &nameW, ActiveComputerNameW );
+    if ( ( st = NtOpenKey( &hsubkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
+        goto out;
+    
+    RtlInitUnicodeString( &nameW, ComputerNameW );
+    if ( ( st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len ) )
+         != STATUS_SUCCESS )
+        goto out;
+
+    len = (len -offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )) / sizeof (WCHAR) - 1;
+    TRACE ("ComputerName is %s (length %lu)\n", debugstr_w ( theName ), len);
+
+    __TRY
+    {
+        if ( *size < len )
+        {
+            memcpy ( name, theName, *size * sizeof (WCHAR) );
+            name[*size] = 0;
+            *size = len;
+            st = STATUS_MORE_ENTRIES;
+        }
+        else
+        {
+            memcpy ( name, theName, len * sizeof (WCHAR) );
+            name[len] = 0;
+            *size = len;
+            st = STATUS_SUCCESS;
+        }
+    }
+    __EXCEPT(page_fault)
+    {
+        st = STATUS_INVALID_PARAMETER;
+    }
+    __ENDTRY
+
+out:
+    NtClose ( hsubkey );
+    NtClose ( hkey );
+
+    if ( st == STATUS_SUCCESS )
+        return TRUE;
+    else
+    {
+        SetLastError ( RtlNtStatusToDosError ( st ) );
+        WARN ( "Status %lu reading computer name from registry\n", st );
+        return FALSE;
+    }
+}
+
+/***********************************************************************
+ *              GetComputerNameA         (KERNEL32.@)
+ */
+BOOL WINAPI GetComputerNameA(LPSTR name, LPDWORD size)
+{
+    WCHAR nameW[ MAX_COMPUTERNAME_LENGTH + 1 ];
+    DWORD sizeW = MAX_COMPUTERNAME_LENGTH;
+    int len;
+    BOOL ret;
+
+    if ( !GetComputerNameW (nameW, &sizeW) ) return FALSE;
+
+    len = WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, NULL, 0, NULL, 0 );
+    __TRY
+    {
+        if ( *size < len )
+        {
+            WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, *size, NULL, 0 );
+            name[*size] = 0;
+            *size = len;
+            SetLastError( ERROR_MORE_DATA );
+            ret = FALSE;
+        }
+        else 
+        {
+            WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, len, NULL, 0 );
+            name[len] = 0;
+            *size = len;
+            ret = TRUE;
+        }
+    }
+    __EXCEPT(page_fault)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        ret = FALSE;
+    }
+    __ENDTRY
+
+    return ret;
+}
+
+/***********************************************************************
+ *              GetComputerNameExA         (KERNEL32.@)
+ */
+BOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT type, LPSTR name, LPDWORD size)
+{
+    char buf[256];
+    int len = sizeof (buf), ret;
+    TRACE("%d, %p, %p\n", type, name, size);
+    switch( type )
+    {
+    case ComputerNameNetBIOS:
+    case ComputerNamePhysicalNetBIOS:
+        return GetComputerNameA (name, size);
+    case ComputerNameDnsHostname:
+    case ComputerNamePhysicalDnsHostname:
+        ret = dns_hostname (buf, &len);
+        break;
+    case ComputerNameDnsDomain:
+    case ComputerNamePhysicalDnsDomain:
+        ret = dns_domainname (buf, &len);
+        break;
+    case ComputerNameDnsFullyQualified:
+    case ComputerNamePhysicalDnsFullyQualified:
+        ret = dns_fqdn (buf, &len);
+        break;
+    default:
+        SetLastError (ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if ( ret )
+    {
+        TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
+        __TRY
+        {
+            if ( *size < len )
+            {
+                memcpy( name, buf, *size );
+                name[*size] = 0;
+                *size = len;
+                SetLastError( ERROR_MORE_DATA );
+                ret = FALSE;
+            }
+            else
+            {
+                memcpy( name, buf, len );
+                name[len] = 0;
+                *size = len;
+            }
+        }
+        __EXCEPT(page_fault)
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            ret = FALSE;
+        }
+        __ENDTRY
+    }
+
+    return ret;
+}
+
+
+/***********************************************************************
+ *              GetComputerNameExW         (KERNEL32.@)
+ */
+BOOL WINAPI GetComputerNameExW( COMPUTER_NAME_FORMAT type, LPWSTR name, LPDWORD size )
+{
+    char buf[256];
+    int len = sizeof (buf), ret;
+
+    TRACE("%d, %p, %p\n", type, name, size);
+    switch( type )
+    {
+    case ComputerNameNetBIOS:
+    case ComputerNamePhysicalNetBIOS:
+        return GetComputerNameW (name, size);
+    case ComputerNameDnsHostname:
+    case ComputerNamePhysicalDnsHostname:
+        ret = dns_hostname (buf, &len);
+        break;
+    case ComputerNameDnsDomain:
+    case ComputerNamePhysicalDnsDomain:
+        ret = dns_domainname (buf, &len);
+        break;
+    case ComputerNameDnsFullyQualified:
+    case ComputerNamePhysicalDnsFullyQualified:
+        ret = dns_fqdn (buf, &len);
+        break;
+    default:
+        SetLastError (ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if ( ret )
+    {
+        TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
+        __TRY
+        {
+            int len = MultiByteToWideChar( CP_ACP, 0, buf, len, NULL, 0 );
+            if ( *size < len )
+            {
+                MultiByteToWideChar( CP_ACP, 0, buf, len, name, *size );
+                name[*size] = 0;
+                *size = len;
+                SetLastError( ERROR_MORE_DATA );
+                ret = FALSE;
+            }
+            else
+            {
+                MultiByteToWideChar( CP_ACP, 0, buf, len, name, len );
+                name[len] = 0;
+                *size = len;
+            }
+        }
+        __EXCEPT(page_fault)
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            ret = FALSE;
+        }
+        __ENDTRY
+    }
+
+    return ret;
+}
+
+/******************************************************************************
+ * netbios_char (INTERNAL)
+ */
+static WCHAR netbios_char ( WCHAR wc )
+{
+    static const WCHAR special[] = {'!','@','#','$','%','^','&','\'',')','(','-','_','{','}','~'};
+    static const WCHAR deflt = '_';
+    int i;
+    
+    if ( isalnumW ( wc ) ) return wc;
+    for ( i = 0; i < sizeof (special) / sizeof (WCHAR); i++ )
+        if ( wc == special[i] ) return wc;
+    return deflt;
+}
+
+/******************************************************************************
+ * SetComputerNameW [KERNEL32.@]
+ *
+ * PARAMS
+ *    lpComputerName [I] Address of new computer name
+ *
+ * RETURNS STD
+ */
+BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName )
+{
+    UNICODE_STRING nameW;
+    OBJECT_ATTRIBUTES attr;
+    HKEY hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE;
+    int plen = strlenW ( lpComputerName );
+    int i;
+    NTSTATUS st = STATUS_INTERNAL_ERROR;
+
+    if ( PROFILE_GetWineIniBool ( NetworkW, UseDNSW, 1 ) )
+    {
+        /* This check isn't necessary, but may help debugging problems. */
+        WARN( "Disabled by Wine Configuration.\n" );
+        WARN( "Set \"UseDnsComputerName\" = \"N\" in category [Network] to enable.\n" );
+        SetLastError ( ERROR_ACCESS_DENIED );
+        return FALSE;
+    }
+
+    TRACE( "%s\n", debugstr_w (lpComputerName) );
+
+    /* Check parameter */
+    if ( plen > MAX_COMPUTERNAME_LENGTH ) 
+        goto out;
+
+    /* This is NT behaviour. Win 95/98 would coerce characters. */
+    for ( i = 0; i < plen; i++ )
+    {
+        WCHAR wc = lpComputerName[i];
+        if ( wc != netbios_char( wc ) )
+            goto out;
+    }
+    
+    _init_attr ( &attr, &nameW );
+    
+    RtlInitUnicodeString (&nameW, ComputerW);
+    if ( ( st = NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
+        goto out;
+    attr.RootDirectory = hkey;
+    RtlInitUnicodeString( &nameW, ComputerNameW );
+    if ( ( st = NtOpenKey( &hsubkey, KEY_ALL_ACCESS, &attr ) ) != STATUS_SUCCESS )
+        goto out;
+    if ( ( st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, lpComputerName, ( plen + 1) * sizeof(WCHAR) ) )
+         != STATUS_SUCCESS )
+        goto out;
+
+out:
+    NtClose( hsubkey );
+    NtClose( hkey );
+    
+    if ( st == STATUS_SUCCESS )
+    {
+        TRACE( "ComputerName changed\n" );
+        return TRUE;
+    }
+
+    else
+    {
+        SetLastError ( RtlNtStatusToDosError ( st ) );
+        WARN ( "status %lu\n", st );
+        return FALSE;
+    }
+}
+
+/******************************************************************************
+ * SetComputerNameA [KERNEL32.@]
+ */
+BOOL WINAPI SetComputerNameA( LPCSTR lpComputerName )
+{
+    BOOL ret;
+    DWORD len = MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, NULL, 0 );
+    LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+
+    MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, nameW, len );
+    ret = SetComputerNameW( nameW );
+    HeapFree( GetProcessHeap(), 0, nameW );
+    return ret;
+}
+
+/******************************************************************************
+ * SetComputerNameExW [KERNEL32.@]
+ *
+ */
+BOOL WINAPI SetComputerNameExW( COMPUTER_NAME_FORMAT type, LPCWSTR lpComputerName )
+{
+    TRACE("%d, %s\n", type, debugstr_w (lpComputerName));
+    switch( type )
+    {
+    case ComputerNameNetBIOS:
+    case ComputerNamePhysicalNetBIOS:
+        return SetComputerNameW( lpComputerName );
+    default:
+        SetLastError( ERROR_ACCESS_DENIED );
+        return FALSE;
+    }
+}
+
+/******************************************************************************
+ * SetComputerNameExA [KERNEL32.@]
+ *
+ */
+BOOL WINAPI SetComputerNameExA( COMPUTER_NAME_FORMAT type, LPCSTR lpComputerName )
+{
+    TRACE( "%d, %s\n", type, debugstr_a (lpComputerName) );
+    switch( type )
+    {
+    case ComputerNameNetBIOS:
+    case ComputerNamePhysicalNetBIOS:
+        return SetComputerNameA( lpComputerName );
+    default:
+        SetLastError( ERROR_ACCESS_DENIED );
+        return FALSE;
+    }
+}
Index: dlls/kernel/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/kernel/Makefile.in,v
retrieving revision 1.49
diff -u -r1.49 Makefile.in
--- dlls/kernel/Makefile.in	6 Nov 2002 20:03:00 -0000	1.49
+++ dlls/kernel/Makefile.in	14 Nov 2002 16:40:40 -0000
@@ -12,6 +12,7 @@
 C_SRCS = \
 	$(TOPOBJDIR)/ole/ole2nls.c \
 	comm.c \
+	computername.c \
 	console.c \
 	debugger.c \
 	editline.c \
Index: dlls/kernel/kernel32.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v
retrieving revision 1.70
diff -u -r1.70 kernel32.spec
--- dlls/kernel/kernel32.spec	12 Nov 2002 23:29:49 -0000	1.70
+++ dlls/kernel/kernel32.spec	14 Nov 2002 16:40:41 -0000
@@ -663,6 +663,8 @@
 @ stdcall SetCommTimeouts(long ptr) SetCommTimeouts
 @ stdcall SetComputerNameA(str) SetComputerNameA
 @ stdcall SetComputerNameW(wstr) SetComputerNameW
+@ stdcall SetComputerNameExA(long str) SetComputerNameExA
+@ stdcall SetComputerNameExW(long wstr) SetComputerNameExW
 @ stdcall SetConsoleActiveScreenBuffer(long) SetConsoleActiveScreenBuffer
 @ stdcall SetConsoleCP(long) SetConsoleCP
 @ stdcall SetConsoleCtrlHandler(ptr long) SetConsoleCtrlHandler
Index: dlls/kernel/kernel_main.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel_main.c,v
retrieving revision 1.38
diff -u -r1.38 kernel_main.c
--- dlls/kernel/kernel_main.c	2 Oct 2002 02:36:20 -0000	1.38
+++ dlls/kernel/kernel_main.c	14 Nov 2002 16:40:41 -0000
@@ -43,6 +43,7 @@
 
 extern void LOCALE_Init(void);
 extern BOOL RELAY_Init(void);
+extern void COMPUTERNAME_Init(void);
 
 extern  int __wine_set_signal_handler(unsigned, int (*)(unsigned));
 
@@ -67,6 +68,9 @@
 
     /* Initialize DOS memory */
     if (!DOSMEM_Init(0)) return FALSE;
+
+    /* Setup computer name */
+    COMPUTERNAME_Init();
 
     if ((hModule = LoadLibrary16( "krnl386.exe" )) >= 32)
     {
Index: documentation/configuring.sgml
===================================================================
RCS file: /home/wine/wine/documentation/configuring.sgml,v
retrieving revision 1.18
diff -u -r1.18 configuring.sgml
--- documentation/configuring.sgml	29 Oct 2002 23:13:01 -0000	1.18
+++ documentation/configuring.sgml	14 Nov 2002 16:40:43 -0000
@@ -893,7 +893,7 @@
           <title>The [WinMM] Section</title>
           <para>
             [WinMM] is used to define which multimedia drivers have to be loaded. Since
-	    those drivers may depend on the multimedia interfaces available on your sustem
+	    those drivers may depend on the multimedia interfaces available on your system
 	    (OSS, Alsa... to name a few), it's needed to be able to configure which driver
 	    has to be loaded.
           </para>
@@ -930,6 +930,43 @@
 	    </itemizedlist>
           </para>
 	</sect3>
+
+        <sect3 id="network-section">
+          <title>The [Network] Section</title>
+          <para>
+            [Network] contains settings related to
+            networking. Currently there is only one value that can be set.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term>UseDnsComputerName</term>
+              <listitem>
+                <para>
+                  A boolean setting (default: <literal>Y</literal>) 
+                  that affects the way Wine sets the computer name. The computer
+                  name in the Windows world is the so-called <emphasis>NetBIOS name</emphasis>.
+                  It is contained in the <varname>ComputerName</varname> in the registry entry
+                  <varname>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ComputerName\ComputerName</varname>.
+                </para>
+                <para>
+                  If this option is set to "Y" or missing, Wine will set the
+                  NetBIOS name to the Unix host name of your computer, if 
+                  necessary truncated to 31 characters. The Unix hostname is the output
+                  of the shell command <command>hostname</command>, up to and not
+                  including the first dot ('.'). Among other things, this means that
+                  Windows programs running under Wine cannot change the NetBIOS computer name.
+                </para>
+                <para>
+                  If this option is set to "N", Wine will use the registry value above
+                  to set the NetBIOS name. Only if the registry entry doesn't exist (usually
+                  only during the first wine startup) it will use the Unix hostname as
+                  usual. Windows applications can change the NetBIOS name. The change
+                  will be effective after a "Reboot", i.e. after restarting Wine.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </sect3>
 
         <sect3 id="appdefaults-section">
           <title>The [AppDefaults] Section</title>
Index: documentation/wine.conf.man
===================================================================
RCS file: /home/wine/wine/documentation/wine.conf.man,v
retrieving revision 1.6
diff -u -r1.6 wine.conf.man
--- documentation/wine.conf.man	17 Sep 2002 18:27:32 -0000	1.6
+++ documentation/wine.conf.man	14 Nov 2002 16:40:43 -0000
@@ -303,6 +303,13 @@
 .br
 Defaults are read all, write to home files.
 .PP
+.B [Network]
+.br
+.I format: """UseDnsComputerName""=""<boolean>"""
+.br
+If Y, always override the registry setting for ComputerName
+with the Unix hostname.
+.PP
 .B [AppDefaults\\\\\\\\<appname>\\\\\\\\...]
 .PP
 This section allows specifying application-specific values for
Index: documentation/samples/config
===================================================================
RCS file: /home/wine/wine/documentation/samples/config,v
retrieving revision 1.34
diff -u -r1.34 config
--- documentation/samples/config	23 Oct 2002 20:44:14 -0000	1.34
+++ documentation/samples/config	14 Nov 2002 16:40:43 -0000
@@ -256,6 +256,13 @@
 ;; Min number of fragments to prebuffer
 ;"SndQueueMin" = "12"
 
+[Network]
+;; Use the DNS (Unix) host name always as NetBIOS "ComputerName" (boolean, default "Y").
+;; Set to N if you need a persistent NetBIOS ComputerName that possibly differs 
+;; from the Unix host name. You'll need to set ComputerName in 
+;; HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ComputerName\ComputerName, too.
+;"UseDnsComputerName" = "N"
+
 ;; sample AppDefaults entries
 ;[AppDefaults\\iexplore.exe\\DllOverrides]
 ;"shlwapi" = "native"
Index: include/winbase.h
===================================================================
RCS file: /home/wine/wine/include/winbase.h,v
retrieving revision 1.163
diff -u -r1.163 winbase.h
--- include/winbase.h	4 Nov 2002 22:43:24 -0000	1.163
+++ include/winbase.h	14 Nov 2002 16:40:43 -0000
@@ -1456,6 +1456,9 @@
 BOOL      WINAPI SetComputerNameA(LPCSTR);
 BOOL      WINAPI SetComputerNameW(LPCWSTR);
 #define     SetComputerName WINELIB_NAME_AW(SetComputerName)
+BOOL      WINAPI SetComputerNameExA(COMPUTER_NAME_FORMAT,LPCSTR);
+BOOL      WINAPI SetComputerNameExW(COMPUTER_NAME_FORMAT,LPCWSTR);
+#define     SetComputerNameEx WINELIB_NAME_AW(SetComputerNameEx)
 BOOL        WINAPI SetDefaultCommConfigA(LPCSTR,LPCOMMCONFIG,DWORD);
 BOOL        WINAPI SetDefaultCommConfigW(LPCWSTR,LPCOMMCONFIG,DWORD);
 #define     SetDefaultCommConfig WINELIB_NAME_AW(SetDefaultCommConfig)
Index: misc/registry.c
===================================================================
RCS file: /home/wine/wine/misc/registry.c,v
retrieving revision 1.118
diff -u -r1.118 registry.c
--- misc/registry.c	24 Sep 2002 03:07:17 -0000	1.118
+++ misc/registry.c	14 Nov 2002 16:40:43 -0000
@@ -1119,22 +1119,12 @@
  */
 static void _allocate_default_keys(void)
 {
-    HKEY hkey;
-    OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING nameW, valueW;
-    WCHAR computer_name[200];
-    DWORD size = sizeof(computer_name)/sizeof(WCHAR);
-
     static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\',
                                       'P','e','r','f','S','t','a','t','s','\\',
                                       'S','t','a','t','D','a','t','a',0};
-    static const WCHAR ComputerW[] = {'M','a','c','h','i','n','e','\\',
-                                      'S','y','s','t','e','m','\\',
-                                      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                      'C','o','n','t','r','o','l','\\',
-                                      'C','o','m','p','u','t','e','r','N','a','m','e','\\',
-                                      'C','o','m','p','u','t','e','r','N','a','m','e',0};
-    static const WCHAR ComputerNameW[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
+    HKEY hkey;
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
 
     TRACE("(void)\n");
 
@@ -1147,31 +1137,6 @@
 
     RtlInitUnicodeString( &nameW, StatDataW );
     if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey );
-
-    /* \\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion
-     *						CurrentVersion
-     *						CurrentBuildNumber
-     *						CurrentType
-     *					string	RegisteredOwner
-     *					string	RegisteredOrganization
-     *
-     */
-    /* System\\CurrentControlSet\\Services\\SNMP\\Parameters\\RFC1156Agent
-     * 					string	SysContact
-     * 					string	SysLocation
-     * 						SysServices
-     */
-    if (GetComputerNameW( computer_name, &size ))
-    {
-        RtlInitUnicodeString( &nameW, ComputerW );
-        if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
-        {
-            RtlInitUnicodeString( &valueW, ComputerNameW );
-            NtSetValueKey( hkey, &valueW, 0, REG_SZ, computer_name,
-                           (strlenW(computer_name) + 1) * sizeof(WCHAR) );
-            NtClose(hkey);
-        }
-    }
 }
 
 #define REG_DONTLOAD -1
Index: win32/init.c
===================================================================
RCS file: /home/wine/wine/win32/init.c,v
retrieving revision 1.23
diff -u -r1.23 init.c
--- win32/init.c	17 Aug 2002 00:43:20 -0000	1.23
+++ win32/init.c	14 Nov 2002 16:40:44 -0000
@@ -1,108 +0,0 @@
-/*
- * Win32 kernel functions
- *
- * Copyright 1995 Martin von Loewis and Cameron Heide
- * 1999 Peter Ganten
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <stdlib.h>
-#include <errno.h>
-
-#include "winnls.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/exception.h"
-#include "msvcrt/excpt.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(win32);
-
-/* filter for page-fault exceptions */
-static WINE_EXCEPTION_FILTER(page_fault)
-{
-    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
-        return EXCEPTION_EXECUTE_HANDLER;
-    return EXCEPTION_CONTINUE_SEARCH;
-}
-
-/***********************************************************************
- *              GetComputerNameA         (KERNEL32.@)
- */
-BOOL WINAPI GetComputerNameA(LPSTR name,LPDWORD size)
-{
-    /* At least Win95OSR2 survives if size is not a pointer (NT crashes though) */
-    BOOL ret;
-    __TRY
-    {
-	char host_name[256];
-	TRACE("*size = %ld\n", *size);
-	ret = (gethostname(host_name, sizeof(host_name)) != -1);
-	if (ret)
-	{
-	    lstrcpynA(name, host_name, *size);
-	    *size = strlen(name);
-	}
-	else
-	    WARN("gethostname: %s\n", strerror(errno));
-    }
-    __EXCEPT(page_fault)
-    {
-      SetLastError( ERROR_INVALID_PARAMETER );
-      return FALSE;
-    }
-    __ENDTRY
-
-    TRACE("returning (%ld) %s\n", *size, debugstr_a(name));
-    return ret;
-}
-
-/***********************************************************************
- *              GetComputerNameW         (KERNEL32.@)
- */
-BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size)
-{
-    LPSTR nameA = (LPSTR)HeapAlloc( GetProcessHeap(), 0, *size);
-    BOOL ret = GetComputerNameA(nameA,size);
-    /* FIXME: should set *size in Unicode chars */
-    if (ret) MultiByteToWideChar( CP_ACP, 0, nameA, -1, name, *size+1 );
-    HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
-}
-
-/***********************************************************************
- *              GetComputerNameExA         (KERNEL32.@)
- */
-BOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT type, LPSTR name, LPDWORD size)
-{
-    FIXME("(%d, %p, %p) semi-stub!\n", type, name, size);
-    return GetComputerNameA(name, size);
-}
-
-/***********************************************************************
- *              GetComputerNameExW         (KERNEL32.@)
- */
-BOOL WINAPI GetComputerNameExW(COMPUTER_NAME_FORMAT type, LPWSTR name, LPDWORD size)
-{
-    FIXME("(%d, %p, %p) semi-stub!\n", type, name, size);
-    return GetComputerNameW(name, size);
-}
Index: win32/newfns.c
===================================================================
RCS file: /home/wine/wine/win32/newfns.c,v
retrieving revision 1.41
diff -u -r1.41 newfns.c
--- win32/newfns.c	21 Sep 2002 01:21:01 -0000	1.41
+++ win32/newfns.c	14 Nov 2002 16:40:44 -0000
@@ -287,36 +287,6 @@
 

 /******************************************************************************
- * SetComputerNameA [KERNEL32.@]
- */
-BOOL WINAPI SetComputerNameA( LPCSTR lpComputerName )
-{
-    BOOL ret;
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, NULL, 0 );
-    LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-
-    MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, nameW, len );
-    ret = SetComputerNameW( nameW );
-    HeapFree( GetProcessHeap(), 0, nameW );
-    return ret;
-}
-
-
-/******************************************************************************
- * SetComputerNameW [KERNEL32.@]
- *
- * PARAMS
- *    lpComputerName [I] Address of new computer name
- *
- * RETURNS STD
- */
-BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName )
-{
-    FIXME("(%s): stub\n", debugstr_w(lpComputerName));
-    return TRUE;
-}
-
-/******************************************************************************
  *		CreateIoCompletionPort (KERNEL32.@)
  */
 HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle,




More information about the wine-patches mailing list