[KERNEL32] Try to read 'DhcpDomain' registry value if present, otherwise return ...
[reactos.git] / reactos / dll / win32 / kernel32 / client / compname.c
index aadd745..e9bcfc7 100644 (file)
@@ -20,7 +20,7 @@
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * PURPOSE:         Computer name functions
- * FILE:            lib/kernel32/misc/computername.c
+ * FILE:            dll/win32/kernel32/client/compname.c
  * PROGRAMER:       Eric Kohl
  */
 
@@ -50,6 +50,9 @@ GetComputerNameFromRegistry(LPWSTR RegistryKey,
     ULONG ReturnSize;
     NTSTATUS Status;
 
+    if (lpBuffer != NULL && *nSize > 0)
+        lpBuffer[0] = 0;
+
     RtlInitUnicodeString(&KeyName, RegistryKey);
     InitializeObjectAttributes(&ObjectAttributes,
                                &KeyName,
@@ -88,7 +91,7 @@ GetComputerNameFromRegistry(LPWSTR RegistryKey,
 
     if (!NT_SUCCESS(Status))
     {
-        *nSize = ReturnSize;
+        *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR);
         goto failed;
     }
 
@@ -100,7 +103,7 @@ GetComputerNameFromRegistry(LPWSTR RegistryKey,
 
     if (!lpBuffer || *nSize < (KeyInfo->DataLength / sizeof(WCHAR)))
     {
-        *nSize = ReturnSize;
+        *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR);
         Status = STATUS_BUFFER_OVERFLOW;
         goto failed;
     }
@@ -134,6 +137,14 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
     NTSTATUS Status;
     BOOL ret = TRUE;
     DWORD HostSize;
+    DWORD nBufferSize;
+
+    if ((nSize == NULL) ||
+        (lpBuffer == NULL && *nSize > 0))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
     switch (NameType)
     {
@@ -145,11 +156,27 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
                                                nSize);
 
         case ComputerNameDnsDomain:
-            return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet"
-                                               L"\\Services\\Tcpip\\Parameters",
-                                               L"Domain",
-                                               lpBuffer,
-                                               nSize);
+            /* Save original buffer size for the second call if neccessery */
+            nBufferSize = *nSize;
+            if (!GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet"
+                                             L"\\Services\\Tcpip\\Parameters",
+                                             L"DhcpDomain",
+                                             lpBuffer,
+                                             nSize))
+            {
+                /* The value is there, just the buffer is insufficient in length */
+                if (GetLastError() == ERROR_MORE_DATA)
+                    return FALSE;
+                /* Restore original buffer size for the second call */
+                *nSize = nBufferSize;
+                return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet"
+                                                   L"\\Services\\Tcpip\\Parameters",
+                                                   L"Domain",
+                                                   lpBuffer,
+                                                   nSize);
+            }
+            else
+                return TRUE;
 
         case ComputerNameDnsFullyQualified:
             ResultString.Length = 0;
@@ -185,7 +212,7 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
                 RtlFreeUnicodeString(&DomainPart);
 
                 RtlInitUnicodeString(&DomainPart, NULL);
-                QueryTable[0].Name = L"Domain";
+                QueryTable[0].Name = L"DhcpDomain";
                 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
                 QueryTable[0].EntryContext = &DomainPart;
 
@@ -197,7 +224,9 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
                                                 NULL,
                                                 NULL);
 
-                if (NT_SUCCESS(Status))
+                if ((NT_SUCCESS(Status)) &&
+                    (DomainPart.Buffer != NULL) &&
+                    (wcslen(DomainPart.Buffer) > 0))
                 {
                     Status = RtlAppendUnicodeStringToString(&ResultString, &DomainPart);
                     if ((!NT_SUCCESS(Status)) || (!ret))
@@ -211,6 +240,36 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
                     *nSize = ResultString.Length / sizeof(WCHAR) - 1;
                     return TRUE;
                 }
+                else
+                {
+                    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;
 
@@ -222,11 +281,9 @@ GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
                                                nSize);
 
         case ComputerNamePhysicalDnsDomain:
-            return GetComputerNameFromRegistry(L"\\Registry\\Machine\\System\\CurrentControlSet"
-                                               L"\\Services\\Tcpip\\Parameters",
-                                               L"Domain",
-                                               lpBuffer,
-                                               nSize);
+            return GetComputerNameExW(ComputerNameDnsDomain,
+                                      lpBuffer,
+                                      nSize);
 
         /* XXX Redo these */
         case ComputerNamePhysicalDnsFullyQualified:
@@ -263,14 +320,25 @@ GetComputerNameExA(COMPUTER_NAME_FORMAT NameType,
     UNICODE_STRING UnicodeString;
     ANSI_STRING AnsiString;
     BOOL Result;
-    PWCHAR TempBuffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, *nSize * sizeof(WCHAR) );
+    PWCHAR TempBuffer = NULL;
 
-    if (!TempBuffer)
+    if ((nSize == NULL) ||
+        (lpBuffer == NULL && *nSize > 0))
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        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;
@@ -280,7 +348,7 @@ GetComputerNameExA(COMPUTER_NAME_FORMAT NameType,
     if (Result)
     {
         UnicodeString.MaximumLength = (USHORT)*nSize * sizeof(WCHAR) + sizeof(WCHAR);
-        UnicodeString.Length = (USHORT)*nSize * sizeof(WCHAR) + sizeof(WCHAR);
+        UnicodeString.Length = (USHORT)*nSize * sizeof(WCHAR);
         UnicodeString.Buffer = TempBuffer;
 
         RtlUnicodeStringToAnsiString(&AnsiString,