Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835/* * ReactOS kernel * Copyright (C) 2003 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * PURPOSE: Computer name functions * FILE: dll/win32/kernel32/client/compname.c * PROGRAMERS: Eric Kohl * Katayama Hirofumi MZ */
/* INCLUDES ******************************************************************/
#include <k32.h>#include <windns.h>
#define NDEBUG#include <debug.h>
typedef NTSTATUS (WINAPI *FN_DnsValidateName_W)(LPCWSTR, DNS_NAME_FORMAT);
/* FUNCTIONS *****************************************************************/
staticBOOLGetComputerNameFromRegistry(LPWSTR RegistryKey, LPWSTR ValueNameStr, LPWSTR lpBuffer, LPDWORD nSize){ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; ULONG KeyInfoSize; ULONG ReturnSize; NTSTATUS Status;
if (lpBuffer != NULL && *nSize > 0) lpBuffer[0] = 0;
RtlInitUnicodeString(&KeyName, RegistryKey); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { BaseSetLastNTError (Status); return FALSE; }
KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *nSize * sizeof(WCHAR); KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize); if (KeyInfo == NULL) { NtClose(KeyHandle); SetLastError(ERROR_OUTOFMEMORY); return FALSE; }
RtlInitUnicodeString(&ValueName, ValueNameStr);
Status = NtQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, KeyInfo, KeyInfoSize, &ReturnSize);
NtClose(KeyHandle);
if (!NT_SUCCESS(Status)) { *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR); goto failed; }
if (KeyInfo->Type != REG_SZ) { Status = STATUS_UNSUCCESSFUL; goto failed; }
if (!lpBuffer || *nSize < (KeyInfo->DataLength / sizeof(WCHAR))) { *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR); Status = STATUS_BUFFER_OVERFLOW; goto failed; }
*nSize = KeyInfo->DataLength / sizeof(WCHAR) - 1; RtlCopyMemory(lpBuffer, KeyInfo->Data, KeyInfo->DataLength); lpBuffer[*nSize] = 0;
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
return TRUE;
failed: RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo); BaseSetLastNTError(Status); return FALSE;}
staticBOOLSetActiveComputerNameToRegistry(LPCWSTR RegistryKey, LPCWSTR SubKey, LPCWSTR ValueNameStr, LPCWSTR lpBuffer){ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle, SubKeyHandle; SIZE_T StringLength; ULONG Disposition; NTSTATUS Status;
StringLength = wcslen(lpBuffer); if (StringLength > ((MAXULONG / sizeof(WCHAR)) - 1)) { return FALSE; }
RtlInitUnicodeString(&KeyName, RegistryKey); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; }
RtlInitUnicodeString(&KeyName, SubKey); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, KeyHandle, NULL);
Status = NtCreateKey(&SubKeyHandle, KEY_WRITE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { NtClose(KeyHandle); BaseSetLastNTError(Status); return FALSE; }
RtlInitUnicodeString(&ValueName, ValueNameStr);
Status = NtSetValueKey(SubKeyHandle, &ValueName, 0, REG_SZ, (PVOID)lpBuffer, (StringLength + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { NtClose(SubKeyHandle); NtClose(KeyHandle); BaseSetLastNTError(Status); return FALSE; }
NtFlushKey(SubKeyHandle); NtClose(SubKeyHandle); NtClose(KeyHandle);
return TRUE;}
/* * @implemented */BOOLWINAPIGetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize){ UNICODE_STRING ResultString; UNICODE_STRING DomainPart; RTL_QUERY_REGISTRY_TABLE QueryTable[2]; NTSTATUS Status; BOOL ret = TRUE; DWORD HostSize;
if ((nSize == NULL) || (lpBuffer == NULL && *nSize > 0)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
switch (NameType) { case ComputerNameNetBIOS: ret = GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\ComputerName\\ActiveComputerName", L"ComputerName", lpBuffer, nSize); if ((ret == FALSE) && (GetLastError() != ERROR_MORE_DATA)) { ret = GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\ComputerName\\ComputerName", L"ComputerName", lpBuffer, nSize); if (ret) { ret = SetActiveComputerNameToRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\ComputerName", L"ActiveComputerName", L"ComputerName", lpBuffer); } } return ret;
case ComputerNameDnsDomain: return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"Domain", lpBuffer, nSize);
case ComputerNameDnsFullyQualified: ResultString.Length = 0; ResultString.MaximumLength = (USHORT)*nSize * sizeof(WCHAR); ResultString.Buffer = lpBuffer;
RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlInitUnicodeString(&DomainPart, NULL);
QueryTable[0].Name = L"HostName"; QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].EntryContext = &DomainPart;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\System" L"\\CurrentControlSet\\Services\\Tcpip" L"\\Parameters", QueryTable, NULL, NULL);
if (NT_SUCCESS(Status)) { Status = RtlAppendUnicodeStringToString(&ResultString, &DomainPart); HostSize = DomainPart.Length;
if (!NT_SUCCESS(Status)) { ret = FALSE; }
RtlAppendUnicodeToString(&ResultString, L"."); RtlFreeUnicodeString(&DomainPart);
RtlInitUnicodeString(&DomainPart, NULL); QueryTable[0].Name = L"Domain"; QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].EntryContext = &DomainPart;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\System" L"\\CurrentControlSet\\Services\\Tcpip" L"\\Parameters", QueryTable, NULL, NULL);
if (NT_SUCCESS(Status)) { Status = RtlAppendUnicodeStringToString(&ResultString, &DomainPart); if ((!NT_SUCCESS(Status)) || (!ret)) { *nSize = HostSize + DomainPart.Length; SetLastError(ERROR_MORE_DATA); RtlFreeUnicodeString(&DomainPart); return FALSE; } RtlFreeUnicodeString(&DomainPart); *nSize = ResultString.Length / sizeof(WCHAR) - 1; return TRUE; } } return FALSE;
case ComputerNameDnsHostname: return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"Hostname", lpBuffer, nSize);
case ComputerNamePhysicalDnsDomain: return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"NV Domain", lpBuffer, nSize);
/* XXX Redo this */ case ComputerNamePhysicalDnsFullyQualified: return GetComputerNameExW(ComputerNameDnsFullyQualified, lpBuffer, nSize);
case ComputerNamePhysicalDnsHostname: return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"NV Hostname", lpBuffer, nSize);
/* XXX Redo this */ case ComputerNamePhysicalNetBIOS: return GetComputerNameExW(ComputerNameNetBIOS, lpBuffer, nSize);
case ComputerNameMax: return FALSE; }
return FALSE;}
/* * @implemented */BOOLWINAPIGetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD nSize){ UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; BOOL Result; PWCHAR TempBuffer = NULL;
if ((nSize == NULL) || (lpBuffer == NULL && *nSize > 0)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if (*nSize > 0) { TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, *nSize * sizeof(WCHAR)); if (!TempBuffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } }
AnsiString.MaximumLength = (USHORT)*nSize; AnsiString.Length = 0; AnsiString.Buffer = lpBuffer;
Result = GetComputerNameExW(NameType, TempBuffer, nSize);
if (Result) { UnicodeString.MaximumLength = (USHORT)*nSize * sizeof(WCHAR) + sizeof(WCHAR); UnicodeString.Length = (USHORT)*nSize * sizeof(WCHAR); UnicodeString.Buffer = TempBuffer;
RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); }
RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer);
return Result;}
/* * @implemented */BOOLWINAPIGetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize){ BOOL ret;
ret = GetComputerNameExA(ComputerNameNetBIOS, lpBuffer, lpnSize); if (!ret && GetLastError() == ERROR_MORE_DATA) SetLastError(ERROR_BUFFER_OVERFLOW);
return ret;}
/* * @implemented */BOOLWINAPIGetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize){ BOOL ret;
ret = GetComputerNameExW(ComputerNameNetBIOS, lpBuffer, lpnSize); if (!ret && GetLastError() == ERROR_MORE_DATA) SetLastError(ERROR_BUFFER_OVERFLOW);
return ret;}
staticBOOLBaseVerifyDnsName(LPCWSTR lpDnsName){ HINSTANCE hDNSAPI; FN_DnsValidateName_W fnValidate; NTSTATUS Status; BOOL ret = FALSE;
hDNSAPI = LoadLibraryW(L"dnsapi.dll"); if (hDNSAPI == NULL) return FALSE;
fnValidate = (FN_DnsValidateName_W)GetProcAddress(hDNSAPI, "DnsValidateName_W"); if (fnValidate) { Status = (*fnValidate)(lpDnsName, DnsNameHostnameLabel); if (Status == STATUS_SUCCESS || Status == DNS_ERROR_NON_RFC_NAME) ret = TRUE; }
FreeLibrary(hDNSAPI);
return ret;}
/* * @implemented */staticBOOLIsValidComputerName(COMPUTER_NAME_FORMAT NameType, LPCWSTR lpComputerName){ size_t Length; static const WCHAR s_szInvalidChars[] = L"\"/\\[]:|<>+=;,?" L"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
if (lpComputerName == NULL) return FALSE;
#define MAX_COMPUTER_NAME_EX 64 /* Get string length */ if (!NT_SUCCESS(RtlStringCchLengthW(lpComputerName, MAX_COMPUTER_NAME_EX + 1, &Length))) return FALSE;#undef MAX_COMPUTER_NAME_EX
/* An empty name is invalid, except a DNS name */ if (Length == 0 && NameType != ComputerNamePhysicalDnsDomain) return FALSE;
/* Leading or trailing spaces are invalid */ if (Length > 0 && (lpComputerName[0] == L' ' || lpComputerName[Length - 1] == L' ')) { return FALSE; }
/* Check whether the name contains any invalid character */ if (wcscspn(lpComputerName, s_szInvalidChars) < Length) return FALSE;
switch (NameType) { case ComputerNamePhysicalNetBIOS: if (Length > MAX_COMPUTERNAME_LENGTH) return FALSE; return TRUE;
case ComputerNamePhysicalDnsDomain: /* An empty DNS name is valid */ if (Length != 0) return BaseVerifyDnsName(lpComputerName); return TRUE;
case ComputerNamePhysicalDnsHostname: return BaseVerifyDnsName(lpComputerName);
default: return FALSE; }}
staticBOOLSetComputerNameToRegistry(LPCWSTR RegistryKey, LPCWSTR ValueNameStr, LPCWSTR lpBuffer){ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; SIZE_T StringLength; NTSTATUS Status;
StringLength = wcslen(lpBuffer); if (StringLength > ((MAXULONG / sizeof(WCHAR)) - 1)) { return FALSE; }
RtlInitUnicodeString(&KeyName, RegistryKey); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; }
RtlInitUnicodeString(&ValueName, ValueNameStr);
Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)lpBuffer, (StringLength + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { NtClose(KeyHandle); BaseSetLastNTError(Status); return FALSE; }
NtFlushKey(KeyHandle); NtClose(KeyHandle);
SetLastError(ERROR_SUCCESS); return TRUE;}
/* * @implemented */BOOLWINAPISetComputerNameA(LPCSTR lpComputerName){ return SetComputerNameExA(ComputerNamePhysicalNetBIOS, lpComputerName);}
/* * @implemented */BOOLWINAPISetComputerNameW(LPCWSTR lpComputerName){ return SetComputerNameExW(ComputerNamePhysicalNetBIOS, lpComputerName);}
/* * @implemented */BOOLWINAPISetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPCSTR lpBuffer){ UNICODE_STRING Buffer; BOOL bResult;
RtlCreateUnicodeStringFromAsciiz(&Buffer, (LPSTR)lpBuffer);
bResult = SetComputerNameExW(NameType, Buffer.Buffer);
RtlFreeUnicodeString(&Buffer);
return bResult;}
/* * @implemented */BOOLWINAPISetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPCWSTR lpBuffer){ WCHAR szShortName[MAX_COMPUTERNAME_LENGTH + 1]; BOOL ret1, ret2;
if (!IsValidComputerName(NameType, lpBuffer)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
switch (NameType) { case ComputerNamePhysicalDnsDomain: return SetComputerNameToRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"NV Domain", lpBuffer);
case ComputerNamePhysicalDnsHostname: ret1 = SetComputerNameToRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Services\\Tcpip\\Parameters", L"NV Hostname", lpBuffer);
RtlStringCchCopyNW(szShortName, ARRAYSIZE(szShortName), lpBuffer, MAX_COMPUTERNAME_LENGTH); ret2 = SetComputerNameToRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\ComputerName\\ComputerName", L"ComputerName", szShortName); return (ret1 && ret2);
case ComputerNamePhysicalNetBIOS: RtlStringCchCopyNW(szShortName, ARRAYSIZE(szShortName), lpBuffer, MAX_COMPUTERNAME_LENGTH); return SetComputerNameToRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\ComputerName\\ComputerName", L"ComputerName", szShortName);
default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }}
/* * @implemented */BOOLWINAPIDnsHostnameToComputerNameA(LPCSTR Hostname, LPSTR ComputerName, LPDWORD nSize){ DWORD len;
DPRINT("(%s, %p, %p)\n", Hostname, ComputerName, nSize);
if (!Hostname || !nSize) return FALSE;
len = lstrlenA(Hostname);
if (len > MAX_COMPUTERNAME_LENGTH) len = MAX_COMPUTERNAME_LENGTH;
if (*nSize < len) { *nSize = len; return FALSE; }
if (!ComputerName) return FALSE;
memcpy(ComputerName, Hostname, len); ComputerName[len + 1] = 0; return TRUE;}
/* * @implemented */BOOLWINAPIDnsHostnameToComputerNameW(LPCWSTR hostname, LPWSTR computername, LPDWORD size){ DWORD len;
DPRINT("(%s, %p, %p): stub\n", hostname, computername, size);
if (!hostname || !size) return FALSE; len = lstrlenW(hostname);
if (len > MAX_COMPUTERNAME_LENGTH) len = MAX_COMPUTERNAME_LENGTH;
if (*size < len) { *size = len; return FALSE; } if (!computername) return FALSE;
memcpy(computername, hostname, len * sizeof(WCHAR)); computername[len + 1] = 0; return TRUE;}
DWORDWINAPIAddLocalAlternateComputerNameA(LPSTR lpName, PNTSTATUS Status){ STUB; return 0;}
DWORDWINAPIAddLocalAlternateComputerNameW(LPWSTR lpName, PNTSTATUS Status){ STUB; return 0;}
DWORDWINAPIEnumerateLocalComputerNamesA(PVOID pUnknown, DWORD Size, LPSTR lpBuffer, LPDWORD lpnSize){ STUB; return ERROR_CALL_NOT_IMPLEMENTED;}
DWORDWINAPIEnumerateLocalComputerNamesW(PVOID pUnknown, DWORD Size, LPWSTR lpBuffer, LPDWORD lpnSize){ STUB; return ERROR_CALL_NOT_IMPLEMENTED;}
DWORDWINAPIRemoveLocalAlternateComputerNameA(LPSTR lpName, DWORD Unknown){ STUB; return ERROR_CALL_NOT_IMPLEMENTED;}
DWORDWINAPIRemoveLocalAlternateComputerNameW(LPWSTR lpName, DWORD Unknown){ STUB; return ERROR_CALL_NOT_IMPLEMENTED;}
/* * @unimplemented */BOOLWINAPISetLocalPrimaryComputerNameA(IN DWORD Unknown1, IN DWORD Unknown2){ STUB; return FALSE;}
/* * @unimplemented */BOOLWINAPISetLocalPrimaryComputerNameW(IN DWORD Unknown1, IN DWORD Unknown2){ STUB; return FALSE;}
/* EOF */