Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenresinfo_reactos.c
Go to the documentation of this file.
00001 /* 00002 * iphlpapi dll implementation -- Setting and storing route information 00003 * 00004 * These are stubs for functions that set routing information on the target 00005 * operating system. They are grouped here because their implementation will 00006 * vary widely by operating system. 00007 * 00008 * Copyright (C) 2004 Art Yerkes 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #include "config.h" 00025 #include "iphlpapi_private.h" 00026 00027 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); 00028 00029 typedef struct _NAME_SERVER_LIST_PRIVATE { 00030 UINT NumServers; 00031 IP_ADDR_STRING * pCurrent; 00032 } NAME_SERVER_LIST_PRIVATE, *PNAME_SERVER_LIST_PRIVATE; 00033 00034 typedef VOID (*ENUM_INTERFACE_CALLBACK)( 00035 HKEY ChildKeyHandle, 00036 LPWSTR ChildKeyName, 00037 PVOID CallbackContext); 00038 00039 LSTATUS 00040 QueryNameServer( 00041 IN HKEY hInterface, 00042 IN LPCWSTR NameServerKey, 00043 OUT LPWSTR * OutNameServer) 00044 { 00045 DWORD dwLength, dwType; 00046 LPWSTR NameServer; 00047 LSTATUS Status; 00048 00049 /* query ns */ 00050 dwLength = 0; 00051 Status = RegQueryValueExW(hInterface, NameServerKey, NULL, &dwType, NULL, &dwLength); 00052 00053 if (Status != ERROR_SUCCESS) 00054 { 00055 /* failed to retrieve size */ 00056 TRACE("Status %x\n", Status); 00057 return Status; 00058 } 00059 00060 /* add terminating null */ 00061 dwLength += sizeof(WCHAR); 00062 00063 /* allocate name server */ 00064 NameServer = HeapAlloc(GetProcessHeap(), 0, dwLength); 00065 00066 if (!NameServer) 00067 { 00068 /* no memory */ 00069 return ERROR_OUTOFMEMORY; 00070 } 00071 00072 /* query ns */ 00073 Status = RegQueryValueExW(hInterface, NameServerKey, NULL, &dwType, (LPBYTE)NameServer, &dwLength); 00074 00075 if (Status != ERROR_SUCCESS || dwType != REG_SZ) 00076 { 00077 /* failed to retrieve ns */ 00078 HeapFree(GetProcessHeap(), 0, NameServer); 00079 return Status; 00080 } 00081 00082 /* null terminate it */ 00083 NameServer[dwLength / sizeof(WCHAR)] = L'\0'; 00084 00085 /* store result */ 00086 *OutNameServer = NameServer; 00087 00088 return STATUS_SUCCESS; 00089 } 00090 00091 00092 LSTATUS 00093 EnumNameServers( 00094 IN HKEY hInterface, 00095 IN LPWSTR InterfaceName, 00096 PVOID ServerCallbackContext, 00097 EnumNameServersFunc CallbackRoutine) 00098 { 00099 LSTATUS Status; 00100 LPWSTR NameServer; 00101 WCHAR Buffer[50]; 00102 DWORD Length; 00103 LPWSTR Start, Comma; 00104 00105 /* query static assigned name server */ 00106 Status = QueryNameServer(hInterface, L"NameServer", &NameServer); 00107 if (Status != ERROR_SUCCESS) 00108 { 00109 /* query dynamic assigned name server */ 00110 Status = QueryNameServer(hInterface, L"DhcpNameServer", &NameServer); 00111 00112 if (Status != ERROR_SUCCESS) 00113 { 00114 /* failed to retrieve name servers */ 00115 return Status; 00116 } 00117 } 00118 00119 /* enumerate all name servers, terminated by comma */ 00120 Start = NameServer; 00121 00122 do 00123 { 00124 /* find next terminator */ 00125 Comma = wcschr(Start, L','); 00126 00127 if (Comma) 00128 { 00129 /* calculate length */ 00130 Length = Comma - Start; 00131 00132 /* copy name server */ 00133 RtlMoveMemory(Buffer, Start, Length * sizeof(WCHAR)); 00134 00135 /* null terminate it */ 00136 Buffer[Length] = L'\0'; 00137 00138 /* perform callback */ 00139 CallbackRoutine(InterfaceName, Buffer, ServerCallbackContext); 00140 00141 } 00142 else 00143 { 00144 /* perform callback */ 00145 CallbackRoutine(InterfaceName, Start, ServerCallbackContext); 00146 00147 /* last entry */ 00148 break; 00149 } 00150 00151 /* increment offset */ 00152 Start = Comma + 1; 00153 00154 }while(TRUE); 00155 00156 /* free name server string */ 00157 HeapFree(GetProcessHeap(), 0, NameServer); 00158 00159 /* done */ 00160 return ERROR_SUCCESS; 00161 } 00162 00163 LSTATUS 00164 EnumInterfaces( 00165 ENUM_INTERFACE_CALLBACK CallbackRoutine, 00166 PVOID InterfaceCallbackContext) 00167 { 00168 HKEY hKey, hInterface; 00169 LSTATUS Status; 00170 DWORD NumInterfaces, InterfaceNameLen, Index, Length; 00171 LPWSTR InterfaceName; 00172 00173 /* first open interface key */ 00174 Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", 0, KEY_READ, &hKey); 00175 00176 /* check for success */ 00177 if (Status != ERROR_SUCCESS) 00178 { 00179 /* failed to open interface key */ 00180 return Status; 00181 } 00182 00183 /* now get maximum interface name length and number of interfaces */ 00184 Status = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &NumInterfaces, &InterfaceNameLen, NULL, NULL, NULL, NULL, NULL, NULL); 00185 if (Status != ERROR_SUCCESS) 00186 { 00187 /* failed to get key info */ 00188 RegCloseKey(hKey); 00189 return Status; 00190 } 00191 00192 /* RegQueryInfoKey does not include terminating null */ 00193 InterfaceNameLen++; 00194 00195 /* allocate interface name */ 00196 InterfaceName = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, InterfaceNameLen * sizeof(WCHAR)); 00197 00198 if (!InterfaceName) 00199 { 00200 /* no memory */ 00201 RegCloseKey(hKey); 00202 return ERROR_OUTOFMEMORY; 00203 } 00204 00205 /* no enumerate all interfaces */ 00206 for(Index = 0; Index < NumInterfaces; Index++) 00207 { 00208 /* query interface name */ 00209 Length = InterfaceNameLen; 00210 Status = RegEnumKeyExW(hKey, Index, InterfaceName, &Length, NULL, NULL, NULL, NULL); 00211 00212 if (Status == ERROR_SUCCESS) 00213 { 00214 /* make sure it is null terminated */ 00215 InterfaceName[Length] = L'\0'; 00216 00217 /* now open child key */ 00218 Status = RegOpenKeyExW(hKey, InterfaceName, 0, KEY_READ, &hInterface); 00219 00220 if (Status == ERROR_SUCCESS) 00221 { 00222 /* perform enumeration callback */ 00223 CallbackRoutine(hInterface, InterfaceName, InterfaceCallbackContext); 00224 00225 /* close interface key */ 00226 RegCloseKey(hInterface); 00227 } 00228 } 00229 } 00230 00231 /* free interface name */ 00232 HeapFree(GetProcessHeap(), 0, InterfaceName); 00233 00234 /* close root interface key */ 00235 RegCloseKey(hKey); 00236 00237 /* done */ 00238 return Status; 00239 } 00240 00241 VOID 00242 CountNameServerCallback( 00243 IN LPWSTR InterfaceName, 00244 IN LPWSTR Server, 00245 IN PVOID CallbackContext) 00246 { 00247 /* get context */ 00248 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)CallbackContext; 00249 00250 /* increment server count */ 00251 Data->NumServers++; 00252 } 00253 00254 VOID 00255 CountServerCallbackTrampoline( 00256 HKEY ChildKeyHandle, 00257 LPWSTR ChildKeyName, 00258 PVOID CallbackContext) 00259 { 00260 EnumNameServers(ChildKeyHandle, ChildKeyName, CallbackContext, CountNameServerCallback); 00261 } 00262 00263 LSTATUS 00264 CountNameServers( 00265 IN PNAME_SERVER_LIST_PRIVATE PrivateData ) 00266 { 00267 return EnumInterfaces(CountServerCallbackTrampoline, (PVOID)PrivateData); 00268 } 00269 00270 VOID 00271 CreateNameServerListCallback( 00272 IN LPWSTR InterfaceName, 00273 IN LPWSTR Server, 00274 IN PVOID CallbackContext) 00275 { 00276 /* get context */ 00277 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)CallbackContext; 00278 00279 /* convert to ansi ns string */ 00280 if (WideCharToMultiByte(CP_ACP, 0, Server, -1, Data->pCurrent->IpAddress.String, 16, NULL, NULL)) 00281 { 00282 /* store offset to next name server struct */ 00283 Data->pCurrent->Next = (struct _IP_ADDR_STRING*)(Data->pCurrent + 1); 00284 00285 /* move to next entry */ 00286 Data->pCurrent = Data->pCurrent->Next; 00287 00288 /* increment server count */ 00289 Data->NumServers++; 00290 } 00291 else 00292 { 00293 /* failed to convert dns server */ 00294 Data->pCurrent->IpAddress.String[0] = '\0'; 00295 } 00296 } 00297 00298 VOID 00299 CreateNameServerListCallbackTrampoline( 00300 HKEY ChildKeyHandle, 00301 LPWSTR ChildKeyName, 00302 PVOID CallbackContext) 00303 { 00304 EnumNameServers(ChildKeyHandle, ChildKeyName, CallbackContext, CreateNameServerListCallback); 00305 } 00306 00307 LSTATUS 00308 MakeNameServerList( 00309 PNAME_SERVER_LIST_PRIVATE PrivateData ) 00310 { 00311 return EnumInterfaces(CreateNameServerListCallbackTrampoline, (PVOID)PrivateData); 00312 } 00313 00314 PIPHLP_RES_INFO 00315 getResInfo() 00316 { 00317 NAME_SERVER_LIST_PRIVATE PrivateNSEnum; 00318 PIPHLP_RES_INFO ResInfo; 00319 IP_ADDR_STRING * DnsList = NULL; 00320 LSTATUS Status; 00321 00322 PrivateNSEnum.NumServers = 0; 00323 00324 /* count name servers */ 00325 Status = CountNameServers(&PrivateNSEnum); 00326 00327 if (Status != ERROR_SUCCESS) 00328 { 00329 /* failed to enumerate name servers */ 00330 return NULL; 00331 } 00332 00333 /* are there any servers */ 00334 if (PrivateNSEnum.NumServers) 00335 { 00336 /* allocate dns servers */ 00337 DnsList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivateNSEnum.NumServers * sizeof(IP_ADDR_STRING)); 00338 00339 if (!DnsList) 00340 { 00341 /* no memory */ 00342 return NULL; 00343 } 00344 } 00345 00346 /* allocate private struct */ 00347 ResInfo = (PIPHLP_RES_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IPHLP_RES_INFO)); 00348 00349 if(!ResInfo) 00350 { 00351 /* no memory */ 00352 if (DnsList) 00353 { 00354 /* free dns list */ 00355 HeapFree( GetProcessHeap(), 0, DnsList); 00356 } 00357 return NULL; 00358 } 00359 00360 /* are there any servers */ 00361 if (PrivateNSEnum.NumServers) 00362 { 00363 /* initialize enumeration context */ 00364 PrivateNSEnum.NumServers = 0; 00365 PrivateNSEnum.pCurrent = DnsList; 00366 00367 /* enumerate servers */ 00368 MakeNameServerList( &PrivateNSEnum ); 00369 00370 /* store result */ 00371 ResInfo->DnsList = DnsList; 00372 ResInfo->riCount = PrivateNSEnum.NumServers; 00373 } 00374 00375 /* done */ 00376 return ResInfo; 00377 } 00378 00379 VOID disposeResInfo( PIPHLP_RES_INFO InfoPtr ) 00380 { 00381 HeapFree(GetProcessHeap(), 0, InfoPtr->DnsList); 00382 RtlFreeHeap( GetProcessHeap(), 0, InfoPtr ); 00383 } Generated on Fri May 25 2012 04:22:09 for ReactOS by
1.7.6.1
|