1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WinSock 2 API 4 * FILE: dll/win32/ws2_32/src/getproto.c 5 * PURPOSE: GetProtoByY Functions. 6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include <ws2_32.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS *****************************************************************/ 17 18 HANDLE 19 WSAAPI 20 GetProtoOpenNetworkDatabase(PCHAR Name) 21 { 22 PCHAR ExpandedPath; 23 PCHAR DatabasePath; 24 INT ErrorCode; 25 HKEY DatabaseKey; 26 DWORD RegType; 27 DWORD RegSize = 0; 28 HANDLE ret; 29 30 ExpandedPath = HeapAlloc(WsSockHeap, 0, MAX_PATH); 31 if (!ExpandedPath) 32 return INVALID_HANDLE_VALUE; 33 34 /* Open the database path key */ 35 ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 36 "System\\CurrentControlSet\\Services\\Tcpip\\Parameters", 37 0, 38 KEY_READ, 39 &DatabaseKey); 40 if (ErrorCode == NO_ERROR) 41 { 42 /* Read the actual path */ 43 ErrorCode = RegQueryValueEx(DatabaseKey, 44 "DatabasePath", 45 NULL, 46 &RegType, 47 NULL, 48 &RegSize); 49 50 DatabasePath = HeapAlloc(WsSockHeap, 0, RegSize); 51 if (!DatabasePath) 52 { 53 HeapFree(WsSockHeap, 0, ExpandedPath); 54 return INVALID_HANDLE_VALUE; 55 } 56 57 /* Read the actual path */ 58 ErrorCode = RegQueryValueEx(DatabaseKey, 59 "DatabasePath", 60 NULL, 61 &RegType, 62 (LPBYTE)DatabasePath, 63 &RegSize); 64 65 66 /* Close the key */ 67 RegCloseKey(DatabaseKey); 68 69 /* Expand the name */ 70 ExpandEnvironmentStrings(DatabasePath, ExpandedPath, MAX_PATH); 71 72 HeapFree(WsSockHeap, 0, DatabasePath); 73 } 74 else 75 { 76 /* Use default path */ 77 GetSystemDirectory(ExpandedPath, MAX_PATH); 78 if (ExpandedPath[strlen(ExpandedPath) - 1] != '\\') 79 { 80 /* It isn't, so add it ourselves */ 81 strncat(ExpandedPath, "\\", MAX_PATH); 82 } 83 strncat(ExpandedPath, "DRIVERS\\ETC\\", MAX_PATH); 84 } 85 86 /* Make sure that the path is backslash-terminated */ 87 if (ExpandedPath[strlen(ExpandedPath) - 1] != '\\') 88 { 89 /* It isn't, so add it ourselves */ 90 strncat(ExpandedPath, "\\", MAX_PATH); 91 } 92 93 /* Add the database name */ 94 strncat(ExpandedPath, Name, MAX_PATH); 95 96 /* Return a handle to the file */ 97 ret = CreateFile(ExpandedPath, 98 FILE_READ_ACCESS, 99 0, 100 NULL, 101 OPEN_EXISTING, 102 FILE_ATTRIBUTE_NORMAL, 103 NULL); 104 105 HeapFree(WsSockHeap, 0, ExpandedPath); 106 return ret; 107 } 108 109 PCHAR 110 WSAAPI 111 GetProtoPatternMatch(IN PCHAR Buffer, 112 IN PCHAR Lookup) 113 { 114 CHAR ScanChar; 115 116 /* Loop as long as we have data */ 117 while ((ScanChar = *Buffer)) 118 { 119 /* Check for a match and return its pointer if found */ 120 if (strchr(Lookup, ScanChar)) return Buffer; 121 122 /* Keep going */ 123 Buffer++; 124 } 125 126 /* Nothing found */ 127 return NULL; 128 } 129 130 PPROTOENT 131 WSAAPI 132 GetProtoGetNextEnt(IN HANDLE DbHandle, 133 IN PWSPROTO_BUFFER Buffer) 134 { 135 DWORD Read; 136 LONG n; 137 PCHAR p, p1, Entry, *Aliases; 138 PPROTOENT ReturnedProtoent; 139 140 /* Find out where we currently are in the file */ 141 n = SetFilePointer(DbHandle, 0, 0, FILE_CURRENT); 142 143 while (TRUE) 144 { 145 /* Read 512 bytes */ 146 if (!ReadFile(DbHandle, 147 Buffer->LineBuffer, 148 sizeof(Buffer->LineBuffer) - 1, 149 &Read, 150 NULL)) return NULL; 151 152 /* Find out where the line ends */ 153 p1 = Buffer->LineBuffer; 154 Buffer->LineBuffer[Read] = ANSI_NULL; 155 p = strchr(Buffer->LineBuffer, '\n'); 156 157 /* Bail out if the file is parsed */ 158 if (!p) return NULL; 159 160 /* Calculate our new position */ 161 n += (LONG)(p - p1) + 1; 162 163 /* Make it so we read from there next time */ 164 SetFilePointer(DbHandle, n, 0, FILE_BEGIN); 165 166 /* Null-terminate the buffer so it only contains this line */ 167 *p = ANSI_NULL; 168 169 /* If this line is a comment, skip it */ 170 if (*p1 == '#') continue; 171 172 /* Get the entry in this line and null-terminate it */ 173 Entry = GetProtoPatternMatch(p1, "#\n"); 174 if (!Entry) continue; 175 *Entry = ANSI_NULL; 176 177 /* Start with the name */ 178 Buffer->Protoent.p_name = p1; 179 180 /* Get the first tab and null-terminate */ 181 Entry = GetProtoPatternMatch(p1, " \t"); 182 if (!Entry) continue; 183 *Entry++ = ANSI_NULL; 184 185 /* Handle remaining tabs or spaces */ 186 while (*Entry == ' ' || *Entry == '\t') Entry++; 187 188 /* Now move our read pointer */ 189 p1 = GetProtoPatternMatch(Entry, " \t"); 190 if (p1) *p1++ = ANSI_NULL; 191 192 /* This is where the address is */ 193 Buffer->Protoent.p_proto = (short)atoi(Entry); 194 195 /* Setup the alias buffer */ 196 Buffer->Protoent.p_aliases = Buffer->Aliases; 197 Aliases = Buffer->Protoent.p_aliases; 198 199 /* Check if the pointer is stil valid */ 200 if (p1) 201 { 202 /* The first entry is here */ 203 Entry = p1; 204 205 /* Loop while there are non-null entries */ 206 while (Entry && *Entry) 207 { 208 /* Handle tabs and spaces */ 209 while (*Entry == ' ' || *Entry == '\t') Entry++; 210 211 /* Make sure we don't go over the buffer */ 212 if (Aliases < &Buffer->Protoent.p_aliases[MAXALIASES - 1]) 213 { 214 /* Write the alias */ 215 *Aliases++ = Entry; 216 } 217 218 /* Get to the next entry */ 219 Entry = GetProtoPatternMatch(Entry, " \t"); 220 if (Entry) *Entry++ = ANSI_NULL; 221 } 222 } 223 224 /* Terminate the list */ 225 *Aliases = NULL; 226 227 /* Return to caller */ 228 ReturnedProtoent = &Buffer->Protoent; 229 break; 230 } 231 232 /* Return whatever we got */ 233 return ReturnedProtoent; 234 } 235 236 /* 237 * @implemented 238 */ 239 LPPROTOENT 240 WSAAPI 241 getprotobynumber(IN INT number) 242 { 243 PWSPROCESS Process; 244 PWSTHREAD Thread; 245 INT ErrorCode; 246 PPROTOENT Protoent; 247 PVOID GetProtoBuffer; 248 HANDLE DbHandle; 249 DPRINT("getprotobynumber: %lx\n", number); 250 251 /* Enter prolog */ 252 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) 253 { 254 /* Leave now */ 255 SetLastError(ErrorCode); 256 return NULL; 257 } 258 259 /* Get our buffer */ 260 GetProtoBuffer = WsThreadGetProtoBuffer(Thread); 261 if (!GetProtoBuffer) 262 { 263 /* Fail */ 264 SetLastError(WSANO_DATA); 265 return NULL; 266 } 267 268 /* Open the network database */ 269 DbHandle = GetProtoOpenNetworkDatabase("protocol"); 270 if (DbHandle == INVALID_HANDLE_VALUE) 271 { 272 /* Couldn't open the DB; fail */ 273 SetLastError(WSANO_DATA); 274 return NULL; 275 } 276 277 /* Start the scan loop */ 278 while (TRUE) 279 { 280 /* Get a protoent entry */ 281 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer); 282 283 /* Break if we didn't get any new one */ 284 if (!Protoent) break; 285 286 /* Break if we have a match */ 287 if (Protoent->p_proto == number) break; 288 } 289 290 /* Close the network database */ 291 CloseHandle(DbHandle); 292 293 /* Set error if we don't have a protoent */ 294 if (!Protoent) SetLastError(WSANO_DATA); 295 296 /* Return it */ 297 return Protoent; 298 } 299 300 /* 301 * @implemented 302 */ 303 LPPROTOENT 304 WSAAPI 305 getprotobyname(IN CONST CHAR FAR *name) 306 { 307 PWSPROCESS Process; 308 PWSTHREAD Thread; 309 INT ErrorCode; 310 PPROTOENT Protoent; 311 PVOID GetProtoBuffer; 312 HANDLE DbHandle; 313 DPRINT("getprotobyname: %s\n", name); 314 315 /* Enter prolog */ 316 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) 317 { 318 /* Leave now */ 319 SetLastError(ErrorCode); 320 return NULL; 321 } 322 323 /* Get our buffer */ 324 GetProtoBuffer = WsThreadGetProtoBuffer(Thread); 325 if (!GetProtoBuffer) 326 { 327 /* Fail */ 328 SetLastError(WSANO_DATA); 329 return NULL; 330 } 331 332 /* Open the network database */ 333 DbHandle = GetProtoOpenNetworkDatabase("protocol"); 334 if (DbHandle == INVALID_HANDLE_VALUE) 335 { 336 /* Couldn't open the DB; fail */ 337 SetLastError(WSANO_DATA); 338 return NULL; 339 } 340 341 /* Start the scan loop */ 342 while (TRUE) 343 { 344 /* Get a protoent entry */ 345 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer); 346 347 /* Break if we didn't get any new one */ 348 if (!Protoent) break; 349 350 /* Break if we have a match */ 351 if (!_stricmp(Protoent->p_name, name)) break; 352 } 353 354 /* Close the network database */ 355 CloseHandle(DbHandle); 356 357 /* Set error if we don't have a protoent */ 358 if (!Protoent) SetLastError(WSANO_DATA); 359 360 /* Return it */ 361 return Protoent; 362 } 363