1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) 4 * PURPOSE: Tests for Hostname command and Winsock gethostname() function. 5 * COPYRIGHT: Copyright 2019 Doug Lyons <douglyons@douglyons.com> 6 * Copyright 2019 Hermes Belusca-Maito 7 */ 8 9 #include "ws2_32.h" 10 11 #include <winreg.h> 12 13 #define REG_HOSTNAME_KEY L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters" 14 #define REG_COMPUTERNAME_KEY L"System\\CurrentControlSet\\Control\\ComputerName\\ComputerName" 15 16 HKEY 17 OpenRegKey( 18 IN HKEY hRootKey, 19 IN PCWSTR pszSubKey, 20 IN DWORD ulOptions) 21 { 22 HKEY hKey = NULL; 23 LONG Error = RegOpenKeyExW(hRootKey, pszSubKey, 0, ulOptions, &hKey); 24 if (Error == ERROR_SUCCESS) 25 return hKey; 26 return NULL; 27 } 28 29 BOOL 30 GetHostnameFromCommand( 31 OUT PSTR pszHostnameBuffer, 32 IN ULONG ulBufferSize) 33 { 34 PCSTR file_name = "HostName123.txt"; 35 CHAR cmdline[MAX_PATH] = "hostname > "; 36 FILE *fp; 37 INT iResult; 38 INT len; 39 PCSTR ptr; 40 41 ZeroMemory(pszHostnameBuffer, ulBufferSize * sizeof(CHAR)); 42 43 /* Run the 'hostname' command, piping out its result to the temporary file */ 44 strcat(cmdline, file_name); 45 system(cmdline); 46 47 /* Open the temporary file in read mode */ 48 fp = fopen(file_name, "r"); 49 ok(fp != NULL, "An error occurred while opening the file.\n"); 50 if (fp == NULL) 51 return FALSE; 52 53 /* Read its contents */ 54 ptr = fgets(pszHostnameBuffer, ulBufferSize * sizeof(CHAR), fp); 55 ok(ptr != NULL, "An error occurred while reading the file.\n"); 56 if (ptr == NULL) 57 goto Cleanup; 58 59 /* Delete the expected ending line feed character */ 60 len = lstrlenA(pszHostnameBuffer); 61 if (pszHostnameBuffer[len-1] == '\r' || pszHostnameBuffer[len-1] == '\n') 62 pszHostnameBuffer[len-1] = ANSI_NULL; 63 64 Cleanup: 65 /* Close and remove the file */ 66 iResult = fclose(fp); 67 ok(iResult == 0, "An error occurred while closing the file: %i.\n", iResult); 68 iResult = remove(file_name); 69 ok(iResult == 0, "An error occurred while deleting the file: %i.\n", iResult); 70 71 return (ptr ? TRUE : FALSE); 72 } 73 74 START_TEST(gethostname) 75 { 76 INT pos; 77 HKEY hKeyHN; 78 DWORD cbData; 79 LONG Error; 80 INT hnError; 81 INT iResult; 82 WSADATA wsaData; 83 DWORD uApiHostNameSize; 84 CHAR szApiHostName[256] = ""; 85 CHAR szHostNameOld[256] = ""; 86 CHAR szHostNameNew[256] = ""; 87 CHAR hostbuffer[256] = ""; 88 89 /* 90 * Notes about the retrieval of the computer name on Windows. 91 * 92 * - GetComputerName() (equivalently, GetComputerNameEx(ComputerNameNetBIOS)) 93 * retrieves the name cached in the registry value "ComputerName" under 94 * "System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName" . 95 * 96 * - GetComputerNameEx(ComputerNameDnsHostname) as well as the 'hostname' command 97 return the registry value "Hostname" under "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" . 98 * 99 * - In case a new computer name is set, its value is cached in the registry value 100 * "ComputerName" under "System\\CurrentControlSet\\Control\\ComputerName\\ComputerName", 101 * and also in the registry value "NV Hostname" under "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" . 102 */ 103 104 /* Retrieve the current host name using API */ 105 uApiHostNameSize = _countof(szApiHostName); 106 if (!GetComputerNameExA(ComputerNameDnsHostname, szApiHostName, &uApiHostNameSize)) 107 { 108 /* Fail in case of error */ 109 skip("GetComputerNameExA(ComputerNameDnsHostname) failed, error %lu\n", GetLastError()); 110 return; 111 } 112 printf("The Hostname from API is '%s'.\n", szApiHostName); 113 114 /* Retrieve the current host name using the 'hostname' command */ 115 if (!GetHostnameFromCommand(hostbuffer, _countof(hostbuffer))) 116 { 117 /* Fail in case of error */ 118 skip("Error while retrieving the host name using the 'hostname' command!\n"); 119 return; 120 } 121 printf("The Hostname from command is '%s'.\n", hostbuffer); 122 123 pos = strcmp(szApiHostName, hostbuffer); 124 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 125 ok(pos == 0, "hostbuffer '%s' should have been szApiHostName '%s'.\n", hostbuffer, szApiHostName); 126 127 hKeyHN = OpenRegKey(HKEY_LOCAL_MACHINE, REG_HOSTNAME_KEY, KEY_ALL_ACCESS); 128 ok(hKeyHN != NULL, "Error while opening hostname registry key.\n"); 129 if (hKeyHN == NULL) 130 return; 131 132 /* Get Old Hostname */ 133 szHostNameOld[0] = ANSI_NULL; 134 cbData = sizeof(szHostNameOld); 135 Error = RegQueryValueExA(hKeyHN, "Hostname", NULL, NULL, (LPBYTE)szHostNameOld, &cbData); 136 137 printf("Hostname from Registry is '%s'.\n", szHostNameOld); 138 139 pos = strcmp(szHostNameOld, szApiHostName); 140 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 141 ok(pos == 0, "szApiHostName '%s' should have been szHostNameOld '%s'.\n", szApiHostName, szHostNameOld); 142 143 /* Change Hostname in the Registry */ 144 szHostNameNew[0] = ANSI_NULL; 145 strcat(szHostNameNew, "ROSHOSTNAME1"); 146 cbData = lstrlenA(szHostNameNew) + 1; 147 148 Error = RegSetValueExA(hKeyHN, "Hostname", 0, REG_SZ, (LPBYTE)szHostNameNew, cbData); 149 ok(Error == ERROR_SUCCESS, "Error setting new registry value (%ld).\n", GetLastError()); 150 151 /* Retrieve the current host name using API */ 152 uApiHostNameSize = _countof(szApiHostName); 153 if (!GetComputerNameExA(ComputerNameDnsHostname, szApiHostName, &uApiHostNameSize)) 154 { 155 /* Fail in case of error */ 156 skip("GetComputerNameExA(ComputerNameDnsHostname) failed, error %lu\n", GetLastError()); 157 goto Cleanup; 158 } 159 printf("The Hostname from API is '%s'.\n", szApiHostName); 160 161 /* Retrieve the current host name using the 'hostname' command */ 162 if (!GetHostnameFromCommand(hostbuffer, _countof(hostbuffer))) 163 { 164 /* Fail in case of error */ 165 skip("Error while retrieving the host name using the 'hostname' command!\n"); 166 goto Cleanup; 167 } 168 printf("The Hostname from command is '%s'.\n", hostbuffer); 169 170 pos = strcmp(szHostNameNew, szApiHostName); 171 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 172 ok(pos == 0, "szApiHostName '%s' should be szHostNameNew '%s'.\n", szApiHostName, szHostNameNew); 173 174 pos = strcmp(szHostNameNew, hostbuffer); 175 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 176 ok(pos == 0, "hostbuffer '%s' should have been szHostNameNew '%s'.\n", hostbuffer, szHostNameNew); 177 178 /* Reset the original registry entry */ 179 cbData = lstrlenA(szHostNameOld) + 1; 180 181 Error = RegSetValueExA(hKeyHN, "Hostname", 0, REG_SZ, (LPBYTE)szHostNameOld, cbData); 182 ok(Error == ERROR_SUCCESS, "Error resetting new registry value back (%ld).\n", GetLastError()); 183 184 /*============ Winsock Checks ===============*/ 185 186 /* Start up Winsock to use gethostname() */ 187 iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 188 ok(iResult == 0, "Error occurred starting Winsock"); 189 if (iResult != 0) 190 goto Cleanup; 191 192 /* Retrieve gethostname() */ 193 hnError = gethostname(hostbuffer, sizeof(hostbuffer)); 194 ok(!hnError, "Winsock gethostname() Error is '%d'.\n", WSAGetLastError()); 195 196 /* Display results */ 197 if (!hnError) 198 printf("Winsock gethostname() is '%s'.\n", hostbuffer); 199 200 pos = strcmp(szHostNameOld, hostbuffer); 201 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 202 ok(pos == 0, "szHostNameOld '%s' should be hostbuffer '%s'.\n", szHostNameOld, hostbuffer); 203 204 /* Change Hostname in the Registry */ 205 szHostNameNew[0] = ANSI_NULL; 206 strcat(szHostNameNew, "ROSHOSTNAME1"); 207 cbData = lstrlenA(szHostNameNew) + 1; 208 209 Error = RegSetValueExA(hKeyHN, "Hostname", 0, REG_SZ, (LPBYTE)szHostNameNew, cbData); 210 ok(Error == ERROR_SUCCESS, "Error setting new registry value (%ld).\n", GetLastError()); 211 212 /* Retrieve gethostname() */ 213 hnError = gethostname(hostbuffer, sizeof(hostbuffer)); 214 ok(!hnError, "Winsock gethostname() Error is '%d'.\n", WSAGetLastError()); 215 216 /* Display results */ 217 if (!hnError) 218 printf("Winsock gethostname() is '%s'.\n", hostbuffer); 219 220 pos = strcmp(szHostNameNew, hostbuffer); 221 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 222 ok(pos == 0, "szHostNameNew '%s' should be hostbuffer '%s'.\n", szHostNameNew, hostbuffer); 223 224 /* Reset the original registry entry */ 225 cbData = lstrlenA(szHostNameOld) + 1; 226 227 Error = RegSetValueExA(hKeyHN, "Hostname", 0, REG_SZ, (LPBYTE)szHostNameOld, cbData); 228 ok(Error == ERROR_SUCCESS, "Error resetting new registry value back (%ld).\n", GetLastError()); 229 230 /* Retrieve gethostname() */ 231 hnError = gethostname(hostbuffer, sizeof(hostbuffer)); 232 ok(!hnError, "Winsock gethostname() Error is '%d'.\n", WSAGetLastError()); 233 234 /* Display results */ 235 if (!hnError) 236 printf("Winsock gethostname() is '%s'.\n", hostbuffer); 237 238 pos = strcmp(szHostNameOld, hostbuffer); 239 printf("The test results were '%s'.\n", pos==0 ? "good" : "bad"); 240 ok(pos == 0, "szHostNameOld '%s' should be hostbuffer '%s'.\n", szHostNameOld, hostbuffer); 241 242 Cleanup: 243 iResult = WSACleanup(); 244 ok(iResult == 0, "WSACleanup error occurred ending Winsock"); 245 246 Error = RegCloseKey(hKeyHN); 247 ok(Error == ERROR_SUCCESS, "Error closing registry key (%ld).\n", GetLastError()); 248 249 return; 250 } 251