diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index ace8b128605..e979141aff5 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -12,6 +12,7 @@ DLLMAIN = MAIN_KernelInit C_SRCS = \ $(TOPOBJDIR)/ole/ole2nls.c \ comm.c \ + computername.c \ console.c \ debugger.c \ editline.c \ diff --git a/dlls/kernel/computername.c b/dlls/kernel/computername.c new file mode 100644 index 00000000000..c8845a9ff1f --- /dev/null +++ b/dlls/kernel/computername.c @@ -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 +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include + +#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; + } +} diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index cec24355140..a782603310f 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -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 diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c index 3fa26f25b09..c549e1fee47 100644 --- a/dlls/kernel/kernel_main.c +++ b/dlls/kernel/kernel_main.c @@ -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)); @@ -68,6 +69,9 @@ static BOOL process_attach(void) /* Initialize DOS memory */ if (!DOSMEM_Init(0)) return FALSE; + /* Setup computer name */ + COMPUTERNAME_Init(); + if ((hModule = LoadLibrary16( "krnl386.exe" )) >= 32) { /* Initialize special KERNEL entry points */ diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index cf0895bbb1b..2cd26bdef22 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -80,7 +80,6 @@ C_SRCS = \ $(TOPOBJDIR)/scheduler/timer.c \ $(TOPOBJDIR)/win32/device.c \ $(TOPOBJDIR)/win32/except.c \ - $(TOPOBJDIR)/win32/init.c \ $(TOPOBJDIR)/win32/kernel32.c \ $(TOPOBJDIR)/win32/newfns.c \ $(TOPOBJDIR)/win32/time.c \ diff --git a/documentation/configuring.sgml b/documentation/configuring.sgml index 7c3185c012f..b7a7534ce70 100644 --- a/documentation/configuring.sgml +++ b/documentation/configuring.sgml @@ -893,7 +893,7 @@ OPTIONAL: The [WinMM] Section [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. @@ -931,6 +931,43 @@ OPTIONAL: + + The [Network] Section + + [Network] contains settings related to + networking. Currently there is only one value that can be set. + + + + UseDnsComputerName + + + A boolean setting (default: Y) + that affects the way Wine sets the computer name. The computer + name in the Windows world is the so-called NetBIOS name. + It is contained in the ComputerName in the registry entry + HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ComputerName\ComputerName. + + + 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 hostname, 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. + + + 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. + + + + + + The [AppDefaults] Section diff --git a/documentation/samples/config b/documentation/samples/config index c9f674befd4..7c04ca41ac9 100644 --- a/documentation/samples/config +++ b/documentation/samples/config @@ -268,6 +268,13 @@ WINE REGISTRY Version 2 ;; 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" diff --git a/documentation/wine.conf.man b/documentation/wine.conf.man index 19b3f995e5d..e2fd3ecdec4 100644 --- a/documentation/wine.conf.man +++ b/documentation/wine.conf.man @@ -303,6 +303,13 @@ booleans: Y/y/T/t/1 are true, N/n/F/f/0 are false. .br Defaults are read all, write to home files. .PP +.B [Network] +.br +.I format: """UseDnsComputerName""=""""" +.br +If Y, always override the registry setting for ComputerName +with the Unix hostname. +.PP .B [AppDefaults\\\\\\\\\\\\\\\\...] .PP This section allows specifying application-specific values for diff --git a/include/winbase.h b/include/winbase.h index 87592375f4b..90ee9968f1d 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1453,9 +1453,12 @@ BOOL WINAPI SetCommBreak(HANDLE); BOOL WINAPI SetCommMask(HANDLE,DWORD); BOOL WINAPI SetCommState(HANDLE,LPDCB); BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); -BOOL WINAPI SetComputerNameA(LPCSTR); -BOOL WINAPI SetComputerNameW(LPCWSTR); +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) diff --git a/misc/registry.c b/misc/registry.c index 8eae5438711..270361d37b5 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -1119,22 +1119,12 @@ static void _init_registry_saving( HKEY hkey_local_machine, HKEY hkey_current_us */ 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 @@ static void _allocate_default_keys(void) 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 diff --git a/win32/init.c b/win32/init.c deleted file mode 100644 index e870a2eef77..00000000000 --- a/win32/init.c +++ /dev/null @@ -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 -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include - -#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); -} diff --git a/win32/newfns.c b/win32/newfns.c index f2ef642e117..eadae6327ae 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -286,36 +286,6 @@ DWORD WINAPI GetCompressedFileSizeW( } -/****************************************************************************** - * 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.@) */