/*********************************************************************** * get_use_dns_option */ static BOOL get_use_dns_option(void) { static const WCHAR NetworkW[] = {'S','o','f','t','w','a','r','e','\\', 'W','i','n','e','\\','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}; char tmp[80]; HANDLE root, hkey; DWORD dummy; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; BOOL ret = TRUE; _init_attr( &attr, &nameW ); RtlOpenCurrentUser( KEY_READ, &root ); attr.RootDirectory = root; RtlInitUnicodeString( &nameW, NetworkW ); /* @@ Wine registry key: HKCU\Software\Wine\Network */ if (!NtOpenKey( &hkey, KEY_READ, &attr )) { RtlInitUnicodeString( &nameW, UseDNSW ); if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) { WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; ret = IS_OPTION_TRUE( str[0] ); } NtClose( hkey ); } NtClose( root ); return ret; }
/*********************************************************************** * GetComputerNameW (KERNEL32.@) */ BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size) { UNICODE_STRING nameW; OBJECT_ATTRIBUTES attr; HANDLE 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 %u)\n", debugstr_w ( theName ), len); if ( *size < len + 1 ) { *size = len + 1; st = STATUS_MORE_ENTRIES; } else { memcpy ( name, theName, len * sizeof (WCHAR) ); name[len] = 0; *size = len; st = STATUS_SUCCESS; } out: NtClose ( hsubkey ); NtClose ( hkey ); if ( st == STATUS_SUCCESS ) return TRUE; else { SetLastError ( RtlNtStatusToDosError ( st ) ); WARN ( "Status %u reading computer name from registry\n", st ); return FALSE; } }
/****************************************************************************** * SetComputerNameW [KERNEL32.@] * * Set a new NetBIOS name for the local computer. * * PARAMS * lpComputerName [I] Address of new computer name * * RETURNS * Success: TRUE * Failure: FALSE */ BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName ) { UNICODE_STRING nameW; OBJECT_ATTRIBUTES attr; HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE; int plen = strlenW ( lpComputerName ); int i; NTSTATUS st = STATUS_INTERNAL_ERROR; if (get_use_dns_option()) { /* This check isn't necessary, but may help debugging problems. */ WARN( "Disabled by Wine Configuration.\n" ); WARN( "Set \"UseDnsComputerName\" = \"N\" in HKCU\\Software\\Wine\\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 %u\n", st ); return FALSE; } }
/*********************************************************************** * COMPUTERNAME_Init (INTERNAL) */ void COMPUTERNAME_Init (void) { HANDLE 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_SUCCESS || get_use_dns_option() ) { 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_UNIXCP, 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\n" ); } else { len = (len - offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )); TRACE( "found in registry\n" ); } NtClose( hsubkey ); TRACE(" ComputerName: %s (%u)\n", debugstr_w (computer_name), len); 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: %x\n", st ); SetLastError ( RtlNtStatusToDosError ( st ) ); } }