Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenns.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WinSock 2 DLL 00004 * FILE: misc/ns.c 00005 * PURPOSE: Namespace APIs 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 01/09-2000 Created 00009 */ 00010 00011 #include "ws2_32.h" 00012 00013 #ifndef BUFSIZ 00014 #define BUFSIZ 1024 00015 #endif/*BUFSIZ*/ 00016 00017 #ifndef MAX_HOSTNAME_LEN 00018 #define MAX_HOSTNAME_LEN 256 00019 #endif 00020 00021 /* Name resolution APIs */ 00022 00023 /* 00024 * @unimplemented 00025 */ 00026 INT 00027 EXPORT 00028 WSAAddressToStringA(IN LPSOCKADDR lpsaAddress, 00029 IN DWORD dwAddressLength, 00030 IN LPWSAPROTOCOL_INFOA lpProtocolInfo, 00031 OUT LPSTR lpszAddressString, 00032 IN OUT LPDWORD lpdwAddressStringLength) 00033 { 00034 DWORD size; 00035 CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ 00036 CHAR *p; 00037 00038 if (!lpsaAddress) return SOCKET_ERROR; 00039 if (!lpszAddressString || !lpdwAddressStringLength) return SOCKET_ERROR; 00040 00041 switch(lpsaAddress->sa_family) 00042 { 00043 case AF_INET: 00044 if (dwAddressLength < sizeof(SOCKADDR_IN)) return SOCKET_ERROR; 00045 sprintf( buffer, "%u.%u.%u.%u:%u", 00046 (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 24 & 0xff), 00047 (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 16 & 0xff), 00048 (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 8 & 0xff), 00049 (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) & 0xff), 00050 ntohs( ((SOCKADDR_IN *)lpsaAddress)->sin_port ) ); 00051 00052 p = strchr( buffer, ':' ); 00053 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port) *p = 0; 00054 break; 00055 default: 00056 WSASetLastError(WSAEINVAL); 00057 return SOCKET_ERROR; 00058 } 00059 00060 size = strlen( buffer ) + 1; 00061 00062 if (*lpdwAddressStringLength < size) 00063 { 00064 *lpdwAddressStringLength = size; 00065 WSASetLastError(WSAEFAULT); 00066 return SOCKET_ERROR; 00067 } 00068 00069 *lpdwAddressStringLength = size; 00070 strcpy( lpszAddressString, buffer ); 00071 return 0; 00072 } 00073 00074 00075 /* 00076 * @unimplemented 00077 */ 00078 INT 00079 EXPORT 00080 WSAAddressToStringW(IN LPSOCKADDR lpsaAddress, 00081 IN DWORD dwAddressLength, 00082 IN LPWSAPROTOCOL_INFOW lpProtocolInfo, 00083 OUT LPWSTR lpszAddressString, 00084 IN OUT LPDWORD lpdwAddressStringLength) 00085 { 00086 INT ret; 00087 DWORD size; 00088 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ 00089 CHAR bufAddr[54]; 00090 00091 size = *lpdwAddressStringLength; 00092 ret = WSAAddressToStringA(lpsaAddress, dwAddressLength, NULL, bufAddr, &size); 00093 00094 if (ret) return ret; 00095 00096 MultiByteToWideChar( CP_ACP, 0, bufAddr, size, buffer, sizeof( buffer )/sizeof(WCHAR)); 00097 00098 if (*lpdwAddressStringLength < size) 00099 { 00100 *lpdwAddressStringLength = size; 00101 WSASetLastError(WSAEFAULT); 00102 return SOCKET_ERROR; 00103 } 00104 00105 *lpdwAddressStringLength = size; 00106 lstrcpyW( lpszAddressString, buffer ); 00107 return 0; 00108 } 00109 00110 00111 /* 00112 * @unimplemented 00113 */ 00114 INT 00115 EXPORT 00116 WSAEnumNameSpaceProvidersA(IN OUT LPDWORD lpdwBufferLength, 00117 OUT LPWSANAMESPACE_INFOA lpnspBuffer) 00118 { 00119 UNIMPLEMENTED 00120 00121 WSASetLastError(WSASYSCALLFAILURE); 00122 return SOCKET_ERROR; 00123 } 00124 00125 00126 /* 00127 * @unimplemented 00128 */ 00129 INT 00130 EXPORT 00131 WSAEnumNameSpaceProvidersW(IN OUT LPDWORD lpdwBufferLength, 00132 OUT LPWSANAMESPACE_INFOW lpnspBuffer) 00133 { 00134 UNIMPLEMENTED 00135 00136 WSASetLastError(WSASYSCALLFAILURE); 00137 return SOCKET_ERROR; 00138 } 00139 00140 00141 /* 00142 * @unimplemented 00143 */ 00144 INT 00145 EXPORT 00146 WSAGetServiceClassInfoA(IN LPGUID lpProviderId, 00147 IN LPGUID lpServiceClassId, 00148 IN OUT LPDWORD lpdwBufferLength, 00149 OUT LPWSASERVICECLASSINFOA lpServiceClassInfo) 00150 { 00151 UNIMPLEMENTED 00152 00153 WSASetLastError(WSASYSCALLFAILURE); 00154 return SOCKET_ERROR; 00155 } 00156 00157 00158 /* 00159 * @unimplemented 00160 */ 00161 INT 00162 EXPORT 00163 WSAGetServiceClassInfoW(IN LPGUID lpProviderId, 00164 IN LPGUID lpServiceClassId, 00165 IN OUT LPDWORD lpdwBufferLength, 00166 OUT LPWSASERVICECLASSINFOW lpServiceClassInfo) 00167 { 00168 UNIMPLEMENTED 00169 00170 WSASetLastError(WSASYSCALLFAILURE); 00171 return SOCKET_ERROR; 00172 } 00173 00174 00175 /* 00176 * @unimplemented 00177 */ 00178 INT 00179 EXPORT 00180 WSAGetServiceClassNameByClassIdA(IN LPGUID lpServiceClassId, 00181 OUT LPSTR lpszServiceClassName, 00182 IN OUT LPDWORD lpdwBufferLength) 00183 { 00184 UNIMPLEMENTED 00185 00186 WSASetLastError(WSASYSCALLFAILURE); 00187 return SOCKET_ERROR; 00188 } 00189 00190 00191 /* 00192 * @unimplemented 00193 */ 00194 INT 00195 EXPORT 00196 WSAGetServiceClassNameByClassIdW(IN LPGUID lpServiceClassId, 00197 OUT LPWSTR lpszServiceClassName, 00198 IN OUT LPDWORD lpdwBufferLength) 00199 { 00200 UNIMPLEMENTED 00201 00202 WSASetLastError(WSASYSCALLFAILURE); 00203 return SOCKET_ERROR; 00204 } 00205 00206 00207 /* 00208 * @unimplemented 00209 */ 00210 INT 00211 EXPORT 00212 WSAInstallServiceClassA(IN LPWSASERVICECLASSINFOA lpServiceClassInfo) 00213 { 00214 UNIMPLEMENTED 00215 00216 WSASetLastError(WSASYSCALLFAILURE); 00217 return SOCKET_ERROR; 00218 } 00219 00220 00221 /* 00222 * @unimplemented 00223 */ 00224 INT 00225 EXPORT 00226 WSAInstallServiceClassW(IN LPWSASERVICECLASSINFOW lpServiceClassInfo) 00227 { 00228 UNIMPLEMENTED 00229 00230 WSASetLastError(WSASYSCALLFAILURE); 00231 return SOCKET_ERROR; 00232 } 00233 00234 00235 /* 00236 * @unimplemented 00237 */ 00238 INT 00239 EXPORT 00240 WSALookupServiceBeginA(IN LPWSAQUERYSETA lpqsRestrictions, 00241 IN DWORD dwControlFlags, 00242 OUT LPHANDLE lphLookup) 00243 { 00244 UNIMPLEMENTED 00245 00246 WSASetLastError(WSASYSCALLFAILURE); 00247 return SOCKET_ERROR; 00248 } 00249 00250 00251 /* 00252 * @unimplemented 00253 */ 00254 INT 00255 EXPORT 00256 WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions, 00257 IN DWORD dwControlFlags, 00258 OUT LPHANDLE lphLookup) 00259 { 00260 UNIMPLEMENTED 00261 00262 WSASetLastError(WSASYSCALLFAILURE); 00263 return SOCKET_ERROR; 00264 } 00265 00266 00267 /* 00268 * @unimplemented 00269 */ 00270 INT 00271 EXPORT 00272 WSALookupServiceEnd(IN HANDLE hLookup) 00273 { 00274 UNIMPLEMENTED 00275 00276 WSASetLastError(WSASYSCALLFAILURE); 00277 return SOCKET_ERROR; 00278 } 00279 00280 00281 /* 00282 * @unimplemented 00283 */ 00284 INT 00285 EXPORT 00286 WSALookupServiceNextA(IN HANDLE hLookup, 00287 IN DWORD dwControlFlags, 00288 IN OUT LPDWORD lpdwBufferLength, 00289 OUT LPWSAQUERYSETA lpqsResults) 00290 { 00291 UNIMPLEMENTED 00292 00293 WSASetLastError(WSASYSCALLFAILURE); 00294 return SOCKET_ERROR; 00295 } 00296 00297 00298 /* 00299 * @unimplemented 00300 */ 00301 INT 00302 EXPORT 00303 WSALookupServiceNextW(IN HANDLE hLookup, 00304 IN DWORD dwControlFlags, 00305 IN OUT LPDWORD lpdwBufferLength, 00306 OUT LPWSAQUERYSETW lpqsResults) 00307 { 00308 UNIMPLEMENTED 00309 00310 WSASetLastError(WSASYSCALLFAILURE); 00311 return SOCKET_ERROR; 00312 } 00313 00314 00315 /* 00316 * @unimplemented 00317 */ 00318 INT 00319 EXPORT 00320 WSARemoveServiceClass(IN LPGUID lpServiceClassId) 00321 { 00322 UNIMPLEMENTED 00323 00324 WSASetLastError(WSASYSCALLFAILURE); 00325 return SOCKET_ERROR; 00326 } 00327 00328 00329 /* 00330 * @unimplemented 00331 */ 00332 INT 00333 EXPORT 00334 WSASetServiceA(IN LPWSAQUERYSETA lpqsRegInfo, 00335 IN WSAESETSERVICEOP essOperation, 00336 IN DWORD dwControlFlags) 00337 { 00338 UNIMPLEMENTED 00339 00340 WSASetLastError(WSASYSCALLFAILURE); 00341 return SOCKET_ERROR; 00342 } 00343 00344 00345 /* 00346 * @unimplemented 00347 */ 00348 INT 00349 EXPORT 00350 WSASetServiceW(IN LPWSAQUERYSETW lpqsRegInfo, 00351 IN WSAESETSERVICEOP essOperation, 00352 IN DWORD dwControlFlags) 00353 { 00354 UNIMPLEMENTED 00355 00356 WSASetLastError(WSASYSCALLFAILURE); 00357 return SOCKET_ERROR; 00358 } 00359 00360 00361 /* 00362 * @unimplemented 00363 */ 00364 INT 00365 EXPORT 00366 WSAStringToAddressA(IN LPSTR AddressString, 00367 IN INT AddressFamily, 00368 IN LPWSAPROTOCOL_INFOA lpProtocolInfo, 00369 OUT LPSOCKADDR lpAddress, 00370 IN OUT LPINT lpAddressLength) 00371 { 00372 INT ret, len; 00373 LPWSTR szTemp; 00374 WSAPROTOCOL_INFOW ProtoInfoW; 00375 00376 len = MultiByteToWideChar(CP_ACP, 00377 0, 00378 AddressString, 00379 -1, 00380 NULL, 00381 0); 00382 00383 szTemp = HeapAlloc(GetProcessHeap(), 00384 0, 00385 len * sizeof(WCHAR)); 00386 00387 MultiByteToWideChar(CP_ACP, 00388 0, 00389 AddressString, 00390 -1, 00391 szTemp, 00392 len); 00393 00394 if (lpProtocolInfo) 00395 { 00396 memcpy(&ProtoInfoW, 00397 lpProtocolInfo, 00398 FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol)); 00399 00400 MultiByteToWideChar(CP_ACP, 00401 0, 00402 lpProtocolInfo->szProtocol, 00403 -1, 00404 ProtoInfoW.szProtocol, 00405 WSAPROTOCOL_LEN + 1); 00406 } 00407 00408 ret = WSAStringToAddressW(szTemp, 00409 AddressFamily, 00410 &ProtoInfoW, 00411 lpAddress, 00412 lpAddressLength); 00413 00414 HeapFree(GetProcessHeap(), 00415 0, 00416 szTemp ); 00417 00418 WSASetLastError(ret); 00419 return ret; 00420 } 00421 00422 00423 00424 /* 00425 * @implemented 00426 */ 00427 INT 00428 EXPORT 00429 WSAStringToAddressW(IN LPWSTR AddressString, 00430 IN INT AddressFamily, 00431 IN LPWSAPROTOCOL_INFOW lpProtocolInfo, 00432 OUT LPSOCKADDR lpAddress, 00433 IN OUT LPINT lpAddressLength) 00434 { 00435 int pos=0; 00436 int res=0; 00437 LONG inetaddr = 0; 00438 LPWSTR *bp=NULL; 00439 SOCKADDR_IN *sockaddr; 00440 00441 if (!lpAddressLength || !lpAddress || !AddressString) 00442 { 00443 WSASetLastError(WSAEINVAL); 00444 return SOCKET_ERROR; 00445 } 00446 00447 sockaddr = (SOCKADDR_IN *) lpAddress; 00448 00449 /* Set right adress family */ 00450 if (lpProtocolInfo!=NULL) 00451 sockaddr->sin_family = lpProtocolInfo->iAddressFamily; 00452 else 00453 sockaddr->sin_family = AddressFamily; 00454 00455 /* Report size */ 00456 if (AddressFamily == AF_INET) 00457 { 00458 if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN)) 00459 { 00460 *lpAddressLength = sizeof(SOCKADDR_IN); 00461 res = WSAEFAULT; 00462 } 00463 else 00464 { 00465 // translate ip string to ip 00466 00467 /* rest sockaddr.sin_addr.s_addr 00468 for we need to be sure it is zero when we come to while */ 00469 memset(lpAddress,0,sizeof(SOCKADDR_IN)); 00470 00471 /* Set right adress family */ 00472 sockaddr->sin_family = AF_INET; 00473 00474 /* Get port number */ 00475 pos = wcscspn(AddressString,L":") + 1; 00476 00477 if (pos < (int)wcslen(AddressString)) 00478 sockaddr->sin_port = wcstol(&AddressString[pos], 00479 bp, 00480 10); 00481 00482 else 00483 sockaddr->sin_port = 0; 00484 00485 /* Get ip number */ 00486 pos=0; 00487 inetaddr=0; 00488 00489 while (pos < (int)wcslen(AddressString)) 00490 { 00491 inetaddr = (inetaddr<<8) + ((UCHAR)wcstol(&AddressString[pos], 00492 bp, 00493 10)); 00494 pos += wcscspn( &AddressString[pos],L".") +1 ; 00495 } 00496 00497 res = 0; 00498 sockaddr->sin_addr.s_addr = inetaddr; 00499 00500 } 00501 } 00502 00503 WSASetLastError(res); 00504 if (!res) return 0; 00505 return SOCKET_ERROR; 00506 } 00507 00508 void check_hostent(struct hostent **he) 00509 { 00510 struct hostent *new_he; 00511 00512 WS_DbgPrint(MID_TRACE,("*he: %x\n",*he)); 00513 00514 if(!*he) 00515 { 00516 new_he = HeapAlloc(GlobalHeap, 00517 0, 00518 sizeof(struct hostent) + MAX_HOSTNAME_LEN + 1); 00519 00520 new_he->h_name = (PCHAR)(new_he + 1); 00521 new_he->h_aliases = 0; 00522 new_he->h_addrtype = 0; // AF_INET 00523 new_he->h_length = 0; // sizeof(in_addr) 00524 new_he->h_addr_list = HeapAlloc(GlobalHeap, 00525 0, 00526 sizeof(char *) * 2); 00527 00528 RtlZeroMemory(new_he->h_addr_list, 00529 sizeof(char *) * 2); 00530 *he = new_he; 00531 } 00532 } 00533 00534 void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr) 00535 { 00536 ASSERT(he); 00537 00538 //he = HeapAlloc(GlobalHeap, 0, sizeof(struct hostent)); 00539 //he->h_name = HeapAlloc(GlobalHeap, 0, MAX_HOSTNAME_LEN+1); 00540 00541 strncpy(he->h_name, 00542 name, 00543 MAX_HOSTNAME_LEN); 00544 00545 if( !he->h_aliases ) { 00546 he->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *)); 00547 he->h_aliases[0] = 0; 00548 } 00549 he->h_addrtype = AF_INET; 00550 he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr); 00551 00552 if( he->h_addr_list[0] ) 00553 { 00554 HeapFree(GlobalHeap, 00555 0, 00556 he->h_addr_list[0]); 00557 } 00558 00559 he->h_addr_list[0] = HeapAlloc(GlobalHeap, 00560 0, 00561 MAX_HOSTNAME_LEN + 1); 00562 00563 WS_DbgPrint(MID_TRACE,("he->h_addr_list[0] %x\n", he->h_addr_list[0])); 00564 00565 RtlCopyMemory(he->h_addr_list[0], 00566 (char*)&addr.IpAddress, 00567 sizeof(addr.IpAddress)); 00568 00569 he->h_addr_list[1] = 0; 00570 } 00571 00572 00573 #define HFREE(x) if(x) { HeapFree(GlobalHeap, 0, (x)); x=0; } 00574 void free_hostent(struct hostent *he) 00575 { 00576 if(he) 00577 { 00578 char *next = 0; 00579 HFREE(he->h_name); 00580 if(he->h_aliases) 00581 { 00582 next = he->h_aliases[0]; 00583 while(next) { HFREE(next); next++; } 00584 } 00585 if(he->h_addr_list) 00586 { 00587 next = he->h_addr_list[0]; 00588 while(next) { HFREE(next); next++; } 00589 } 00590 HFREE(he->h_addr_list); 00591 HFREE(he->h_aliases); 00592 HFREE(he); 00593 } 00594 } 00595 00596 /* WinSock 1.1 compatible name resolution APIs */ 00597 00598 /* 00599 * @unimplemented 00600 */ 00601 LPHOSTENT 00602 EXPORT 00603 gethostbyaddr(IN CONST CHAR FAR* addr, 00604 IN INT len, 00605 IN INT type) 00606 { 00607 UNIMPLEMENTED 00608 00609 return (LPHOSTENT)NULL; 00610 } 00611 00612 /* 00613 Assumes rfc 1123 - adam * 00614 addr[1] = 0; 00615 addr[0] = inet_addr(name); 00616 strcpy( hostname, name ); 00617 if(addr[0] == 0xffffffff) return NULL; 00618 he.h_addr_list = (void *)addr; 00619 he.h_name = hostname; 00620 he.h_aliases = NULL; 00621 he.h_addrtype = AF_INET; 00622 he.h_length = sizeof(addr); 00623 return &he; 00624 00625 <RANT> 00626 From the MSDN Platform SDK: Windows Sockets 2 00627 "The gethostbyname function cannot resolve IP address strings passed to it. 00628 Such a request is treated exactly as if an unknown host name were passed." 00629 </RANT> 00630 00631 Defferring to the the documented behaviour, rather than the unix behaviour 00632 What if the hostname is in the HOSTS file? see getservbyname 00633 00634 * @implemented 00635 */ 00636 00637 /* DnsQuery -- lib/dnsapi/dnsapi/query.c */ 00638 /* see ws2_32.h, winsock2.h*/ 00639 /*getnetworkparameters - iphlp api */ 00640 /* 00641 REFERENCES 00642 00643 servent -- w32api/include/winsock2.h 00644 PWINSOCK_THREAD_BLOCK -- ws2_32.h 00645 dllmain.c -- threadlocal memory allocation / deallocation 00646 lib/dnsapi 00647 00648 00649 */ 00650 /* lib/adns/src/adns.h XXX */ 00651 00652 00653 /* 00654 struct hostent { 00655 char *h_name; 00656 char **h_aliases; 00657 short h_addrtype; 00658 short h_length; 00659 char **h_addr_list; 00660 #define h_addr h_addr_list[0] 00661 }; 00662 struct servent { 00663 char *s_name; 00664 char **s_aliases; 00665 short s_port; 00666 char *s_proto; 00667 }; 00668 00669 00670 struct hostent defined in w32api/include/winsock2.h 00671 */ 00672 00673 void free_servent(struct servent* s) 00674 { 00675 char* next; 00676 HFREE(s->s_name); 00677 next = s->s_aliases[0]; 00678 while(next) { HFREE(next); next++; } 00679 s->s_port = 0; 00680 HFREE(s->s_proto); 00681 HFREE(s); 00682 } 00683 00684 /* This function is far from perfect but it works enough */ 00685 static 00686 LPHOSTENT 00687 FindEntryInHosts(IN CONST CHAR FAR* name) 00688 { 00689 BOOL Found = FALSE; 00690 HANDLE HostsFile; 00691 CHAR HostsDBData[BUFSIZ] = { 0 }; 00692 PCHAR SystemDirectory = HostsDBData; 00693 PCHAR HostsLocation = "\\drivers\\etc\\hosts"; 00694 PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt, NextLine, ThisLine, Comment; 00695 UINT SystemDirSize = sizeof(HostsDBData) - 1, ValidData = 0; 00696 DWORD ReadSize; 00697 ULONG Address; 00698 PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData; 00699 00700 /* We assume that the parameters are valid */ 00701 00702 if (!GetSystemDirectoryA(SystemDirectory, SystemDirSize)) 00703 { 00704 WSASetLastError(WSANO_RECOVERY); 00705 WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n")); 00706 return NULL; /* Can't get system directory */ 00707 } 00708 00709 strncat(SystemDirectory, 00710 HostsLocation, 00711 SystemDirSize ); 00712 00713 HostsFile = CreateFileA(SystemDirectory, 00714 GENERIC_READ, 00715 FILE_SHARE_READ, 00716 NULL, 00717 OPEN_EXISTING, 00718 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 00719 NULL); 00720 if (HostsFile == INVALID_HANDLE_VALUE) 00721 { 00722 WSASetLastError(WSANO_RECOVERY); 00723 return NULL; 00724 } 00725 00726 while(!Found && 00727 ReadFile(HostsFile, 00728 HostsDBData + ValidData, 00729 sizeof(HostsDBData) - ValidData, 00730 &ReadSize, 00731 NULL)) 00732 { 00733 ValidData += ReadSize; 00734 ReadSize = 0; 00735 NextLine = ThisLine = HostsDBData; 00736 00737 /* Find the beginning of the next line */ 00738 while(NextLine < HostsDBData + ValidData && 00739 *NextLine != '\r' && *NextLine != '\n' ) 00740 { 00741 NextLine++; 00742 } 00743 00744 /* Zero and skip, so we can treat what we have as a string */ 00745 if( NextLine > HostsDBData + ValidData ) 00746 break; 00747 00748 *NextLine = 0; NextLine++; 00749 00750 Comment = strchr( ThisLine, '#' ); 00751 if( Comment ) *Comment = 0; /* Terminate at comment start */ 00752 00753 AddressStr = ThisLine; 00754 /* Find the first space separating the IP address from the DNS name */ 00755 AddrTerm = strchr(ThisLine, ' '); 00756 if (AddrTerm) 00757 { 00758 /* Terminate the address string */ 00759 *AddrTerm = 0; 00760 00761 /* Find the last space before the DNS name */ 00762 NameSt = strrchr(ThisLine, ' '); 00763 00764 /* If there is only one space (the one we removed above), then just use the address terminator */ 00765 if (!NameSt) 00766 NameSt = AddrTerm; 00767 00768 /* Move from the space to the first character of the DNS name */ 00769 NameSt++; 00770 00771 DnsName = NameSt; 00772 00773 if (!strcmp(name, DnsName)) 00774 { 00775 Found = TRUE; 00776 break; 00777 } 00778 } 00779 00780 /* Get rid of everything we read so far */ 00781 while( NextLine <= HostsDBData + ValidData && 00782 isspace (*NextLine)) 00783 { 00784 NextLine++; 00785 } 00786 00787 if (HostsDBData + ValidData - NextLine <= 0) 00788 break; 00789 00790 WS_DbgPrint(MAX_TRACE,("About to move %d chars\n", 00791 HostsDBData + ValidData - NextLine)); 00792 00793 memmove(HostsDBData, 00794 NextLine, 00795 HostsDBData + ValidData - NextLine ); 00796 ValidData -= NextLine - HostsDBData; 00797 WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData)); 00798 } 00799 00800 CloseHandle(HostsFile); 00801 00802 if (!Found) 00803 { 00804 WS_DbgPrint(MAX_TRACE,("Not found\n")); 00805 WSASetLastError(WSANO_DATA); 00806 return NULL; 00807 } 00808 00809 if( !p->Hostent ) 00810 { 00811 p->Hostent = HeapAlloc(GlobalHeap, 0, sizeof(*p->Hostent)); 00812 if( !p->Hostent ) 00813 { 00814 WSASetLastError( WSATRY_AGAIN ); 00815 return NULL; 00816 } 00817 } 00818 00819 p->Hostent->h_name = HeapAlloc(GlobalHeap, 0, strlen(DnsName)); 00820 if( !p->Hostent->h_name ) 00821 { 00822 WSASetLastError( WSATRY_AGAIN ); 00823 return NULL; 00824 } 00825 00826 RtlCopyMemory(p->Hostent->h_name, 00827 DnsName, 00828 strlen(DnsName)); 00829 00830 p->Hostent->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *)); 00831 if( !p->Hostent->h_aliases ) 00832 { 00833 WSASetLastError( WSATRY_AGAIN ); 00834 return NULL; 00835 } 00836 00837 p->Hostent->h_aliases[0] = 0; 00838 00839 if (strstr(AddressStr, ":")) 00840 { 00841 DbgPrint("AF_INET6 NOT SUPPORTED!\n"); 00842 WSASetLastError(WSAEINVAL); 00843 return NULL; 00844 } 00845 else 00846 p->Hostent->h_addrtype = AF_INET; 00847 00848 p->Hostent->h_addr_list = HeapAlloc(GlobalHeap, 0, sizeof(char *)); 00849 if( !p->Hostent->h_addr_list ) 00850 { 00851 WSASetLastError( WSATRY_AGAIN ); 00852 return NULL; 00853 } 00854 00855 Address = inet_addr(AddressStr); 00856 if (Address == INADDR_NONE) 00857 { 00858 WSASetLastError(WSAEINVAL); 00859 return NULL; 00860 } 00861 00862 p->Hostent->h_addr_list[0] = HeapAlloc(GlobalHeap, 0, sizeof(Address)); 00863 if( !p->Hostent->h_addr_list[0] ) 00864 { 00865 WSASetLastError( WSATRY_AGAIN ); 00866 return NULL; 00867 } 00868 00869 RtlCopyMemory(p->Hostent->h_addr_list[0], 00870 &Address, 00871 sizeof(Address)); 00872 00873 p->Hostent->h_length = sizeof(Address); 00874 00875 return p->Hostent; 00876 } 00877 00878 LPHOSTENT 00879 EXPORT 00880 gethostbyname(IN CONST CHAR FAR* name) 00881 { 00882 enum addr_type 00883 { 00884 GH_INVALID, 00885 GH_IPV6, 00886 GH_IPV4, 00887 GH_RFC1123_DNS 00888 }; 00889 typedef enum addr_type addr_type; 00890 addr_type addr; 00891 int ret = 0; 00892 char* found = 0; 00893 DNS_STATUS dns_status = {0}; 00894 /* include/WinDNS.h -- look up DNS_RECORD on MSDN */ 00895 PDNS_RECORD dp = 0; 00896 PWINSOCK_THREAD_BLOCK p; 00897 LPHOSTENT Hostent; 00898 00899 addr = GH_INVALID; 00900 00901 p = NtCurrentTeb()->WinSockData; 00902 00903 if( !p ) 00904 { 00905 WSASetLastError( WSANOTINITIALISED ); 00906 return NULL; 00907 } 00908 00909 check_hostent(&p->Hostent); /*XXX alloc_hostent*/ 00910 00911 /* Hostname NULL - behave like gethostname */ 00912 if(name == NULL) 00913 { 00914 ret = gethostname(p->Hostent->h_name, MAX_HOSTNAME_LEN); 00915 if(ret) 00916 { 00917 WSASetLastError( WSAHOST_NOT_FOUND ); //WSANO_DATA ?? 00918 return NULL; 00919 } 00920 return p->Hostent; 00921 } 00922 00923 /* Is it an IPv6 address? */ 00924 found = strstr(name, ":"); 00925 if( found != NULL ) 00926 { 00927 addr = GH_IPV6; 00928 goto act; 00929 } 00930 00931 /* Is it an IPv4 address? */ 00932 if (!isalpha(name[0])) 00933 { 00934 addr = GH_IPV4; 00935 goto act; 00936 } 00937 00938 addr = GH_RFC1123_DNS; 00939 00940 /* Broken out in case we want to get fancy later */ 00941 act: 00942 switch(addr) 00943 { 00944 case GH_IPV6: 00945 WSASetLastError(STATUS_NOT_IMPLEMENTED); 00946 return NULL; 00947 break; 00948 00949 case GH_INVALID: 00950 WSASetLastError(WSAEFAULT); 00951 return NULL; 00952 break; 00953 00954 /* Note: If passed an IP address, MSDN says that gethostbyname() 00955 treats it as an unknown host. 00956 This is different from the unix implementation. Use inet_addr() 00957 */ 00958 case GH_IPV4: 00959 case GH_RFC1123_DNS: 00960 /* DNS_TYPE_A: include/WinDNS.h */ 00961 /* DnsQuery -- lib/dnsapi/dnsapi/query.c */ 00962 00963 /* Look for the DNS name in the hosts file */ 00964 Hostent = FindEntryInHosts(name); 00965 if (Hostent) 00966 return Hostent; 00967 00968 dns_status = DnsQuery_A(name, 00969 DNS_TYPE_A, 00970 DNS_QUERY_STANDARD, 00971 0, 00972 /* extra dns servers */ &dp, 00973 0); 00974 00975 if(dns_status == 0) 00976 { 00977 //ASSERT(dp->wType == DNS_TYPE_A); 00978 //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA)); 00979 PDNS_RECORD curr; 00980 for(curr=dp; 00981 curr != NULL && curr->wType != DNS_TYPE_A; 00982 curr = curr->pNext ) 00983 { 00984 WS_DbgPrint(MID_TRACE,("wType: %i\n", curr->wType)); 00985 /*empty */ 00986 } 00987 00988 if(curr) 00989 { 00990 WS_DbgPrint(MID_TRACE,("populating hostent\n")); 00991 WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName)); 00992 populate_hostent(p->Hostent, (PCHAR)curr->pName, curr->Data.A); 00993 DnsRecordListFree(dp, DnsFreeRecordList); 00994 return p->Hostent; 00995 } 00996 else 00997 { 00998 DnsRecordListFree(dp, DnsFreeRecordList); 00999 } 01000 } 01001 01002 WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not found. Err: %i\n", 01003 dns_status)); 01004 WSASetLastError(WSAHOST_NOT_FOUND); 01005 return NULL; 01006 01007 break; 01008 01009 default: 01010 WSASetLastError(WSANO_RECOVERY); 01011 return NULL; 01012 break; 01013 } 01014 01015 WSASetLastError(WSANO_RECOVERY); 01016 return NULL; 01017 } 01018 01019 /* 01020 * @implemented 01021 */ 01022 INT 01023 EXPORT 01024 gethostname(OUT CHAR FAR* name, 01025 IN INT namelen) 01026 { 01027 DWORD size = namelen; 01028 01029 int ret = GetComputerNameExA(ComputerNameDnsHostname, 01030 name, 01031 &size); 01032 if(ret == 0) 01033 { 01034 WSASetLastError(WSAEFAULT); 01035 return SOCKET_ERROR; 01036 } 01037 else 01038 { 01039 name[namelen-1] = '\0'; 01040 return 0; 01041 } 01042 } 01043 01044 01045 /* 01046 * XXX arty -- Partial implementation pending a better one. This one will 01047 * do for normal purposes.#include <ws2_32.h> 01048 * 01049 * Return the address of a static LPPROTOENT corresponding to the named 01050 * protocol. These structs aren't very interesting, so I'm not too ashamed 01051 * to have this function work on builtins for now. 01052 * 01053 * @unimplemented 01054 */ 01055 01056 static CHAR *no_aliases = 0; 01057 static PROTOENT protocols[] = 01058 { 01059 {"icmp",&no_aliases, IPPROTO_ICMP}, 01060 {"tcp", &no_aliases, IPPROTO_TCP}, 01061 {"udp", &no_aliases, IPPROTO_UDP}, 01062 {NULL, NULL, 0} 01063 }; 01064 01065 LPPROTOENT 01066 EXPORT 01067 getprotobyname(IN CONST CHAR FAR* name) 01068 { 01069 UINT i; 01070 for (i = 0; protocols[i].p_name; i++) 01071 { 01072 if (_stricmp(protocols[i].p_name, name) == 0) 01073 return &protocols[i]; 01074 } 01075 return NULL; 01076 } 01077 01078 /* 01079 * @unimplemented 01080 */ 01081 LPPROTOENT 01082 EXPORT 01083 getprotobynumber(IN INT number) 01084 { 01085 UINT i; 01086 for (i = 0; protocols[i].p_name; i++) 01087 { 01088 if (protocols[i].p_proto == number) 01089 return &protocols[i]; 01090 } 01091 return NULL; 01092 } 01093 01094 #define SKIPWS(ptr,act) \ 01095 {while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;} 01096 #define SKIPANDMARKSTR(ptr,act) \ 01097 {while(*ptr && !isspace(*ptr)) ptr++; \ 01098 if(!*ptr) {act;} else { *ptr = 0; ptr++; }} 01099 01100 01101 static BOOL 01102 DecodeServEntFromString(IN PCHAR ServiceString, 01103 OUT PCHAR *ServiceName, 01104 OUT PCHAR *PortNumberStr, 01105 OUT PCHAR *ProtocolStr, 01106 IN PCHAR *Aliases, 01107 IN DWORD MaxAlias) 01108 { 01109 UINT NAliases = 0; 01110 01111 WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString)); 01112 01113 SKIPWS(ServiceString, return FALSE); 01114 *ServiceName = ServiceString; 01115 SKIPANDMARKSTR(ServiceString, return FALSE); 01116 SKIPWS(ServiceString, return FALSE); 01117 *PortNumberStr = ServiceString; 01118 SKIPANDMARKSTR(ServiceString, ;); 01119 01120 while( *ServiceString && NAliases < MaxAlias - 1 ) 01121 { 01122 SKIPWS(ServiceString, break); 01123 if( *ServiceString ) 01124 { 01125 SKIPANDMARKSTR(ServiceString, ;); 01126 if( strlen(ServiceString) ) 01127 { 01128 WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString)); 01129 *Aliases++ = ServiceString; 01130 NAliases++; 01131 } 01132 } 01133 } 01134 *Aliases = NULL; 01135 01136 *ProtocolStr = strchr(*PortNumberStr,'/'); 01137 if( !*ProtocolStr ) return FALSE; 01138 **ProtocolStr = 0; (*ProtocolStr)++; 01139 01140 WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n", 01141 *ServiceName, *ProtocolStr, *PortNumberStr, 01142 NAliases)); 01143 01144 return TRUE; 01145 } 01146 01147 #define ADJ_PTR(p,b1,b2) p = (p - b1) + b2 01148 01149 /* 01150 * @implemented 01151 */ 01152 LPSERVENT 01153 EXPORT 01154 getservbyname(IN CONST CHAR FAR* name, 01155 IN CONST CHAR FAR* proto) 01156 { 01157 BOOL Found = FALSE; 01158 HANDLE ServicesFile; 01159 CHAR ServiceDBData[BUFSIZ] = { 0 }; 01160 PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */ 01161 PCHAR ServicesFileLocation = "\\drivers\\etc\\services"; 01162 PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0, 01163 ProtocolStr = 0, Comment = 0, EndValid; 01164 PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; 01165 UINT i,SizeNeeded = 0, 01166 SystemDirSize = sizeof(ServiceDBData) - 1; 01167 DWORD ReadSize = 0; 01168 PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData; 01169 01170 if( !p ) 01171 { 01172 WSASetLastError( WSANOTINITIALISED ); 01173 return NULL; 01174 } 01175 01176 if( !name ) 01177 { 01178 WSASetLastError( WSANO_RECOVERY ); 01179 return NULL; 01180 } 01181 01182 if( !GetSystemDirectoryA( SystemDirectory, SystemDirSize ) ) 01183 { 01184 WSASetLastError( WSANO_RECOVERY ); 01185 WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n")); 01186 return NULL; /* Can't get system directory */ 01187 } 01188 01189 strncat(SystemDirectory, 01190 ServicesFileLocation, 01191 SystemDirSize ); 01192 01193 ServicesFile = CreateFileA(SystemDirectory, 01194 GENERIC_READ, 01195 FILE_SHARE_READ, 01196 NULL, 01197 OPEN_EXISTING, 01198 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 01199 NULL ); 01200 01201 if( ServicesFile == INVALID_HANDLE_VALUE ) 01202 { 01203 WSASetLastError( WSANO_RECOVERY ); 01204 return NULL; 01205 } 01206 01207 /* Scan the services file ... 01208 * 01209 * We will be share the buffer on the lines. If the line does not fit in 01210 * the buffer, then moving it to the beginning of the buffer and read 01211 * the remnants of line from file. 01212 */ 01213 01214 /* Initial Read */ 01215 ReadFile(ServicesFile, 01216 ServiceDBData, 01217 sizeof( ServiceDBData ) - 1, 01218 &ReadSize, NULL ); 01219 ThisLine = NextLine = ServiceDBData; 01220 EndValid = ServiceDBData + ReadSize; 01221 ServiceDBData[sizeof(ServiceDBData) - 1] = '\0'; 01222 01223 while(ReadSize) 01224 { 01225 for(; *NextLine != '\r' && *NextLine != '\n'; NextLine++) 01226 { 01227 if(NextLine == EndValid) 01228 { 01229 int LineLen = NextLine - ThisLine; 01230 01231 if(ThisLine == ServiceDBData) 01232 { 01233 WS_DbgPrint(MIN_TRACE,("Line too long")); 01234 WSASetLastError( WSANO_RECOVERY ); 01235 return NULL; 01236 } 01237 01238 memmove(ServiceDBData, ThisLine, LineLen); 01239 01240 ReadFile(ServicesFile, ServiceDBData + LineLen, 01241 sizeof( ServiceDBData )-1 - LineLen, 01242 &ReadSize, NULL ); 01243 01244 EndValid = ServiceDBData + LineLen + ReadSize; 01245 NextLine = ServiceDBData + LineLen; 01246 ThisLine = ServiceDBData; 01247 01248 if(!ReadSize) break; 01249 } 01250 } 01251 01252 *NextLine = '\0'; 01253 Comment = strchr( ThisLine, '#' ); 01254 if( Comment ) *Comment = '\0'; /* Terminate at comment start */ 01255 01256 if(DecodeServEntFromString(ThisLine, 01257 &ServiceName, 01258 &PortNumberStr, 01259 &ProtocolStr, 01260 Aliases, 01261 WS2_INTERNAL_MAX_ALIAS) && 01262 !strcmp( ServiceName, name ) && 01263 (proto ? !strcmp( ProtocolStr, proto ) : TRUE) ) 01264 { 01265 01266 WS_DbgPrint(MAX_TRACE,("Found the service entry.\n")); 01267 Found = TRUE; 01268 SizeNeeded = sizeof(WINSOCK_GETSERVBYNAME_CACHE) + 01269 (NextLine - ThisLine); 01270 break; 01271 } 01272 NextLine++; 01273 ThisLine = NextLine; 01274 } 01275 01276 /* This we'll do no matter what */ 01277 CloseHandle( ServicesFile ); 01278 01279 if( !Found ) 01280 { 01281 WS_DbgPrint(MAX_TRACE,("Not found\n")); 01282 WSASetLastError( WSANO_DATA ); 01283 return NULL; 01284 } 01285 01286 if( !p->Getservbyname || p->Getservbyname->Size < SizeNeeded ) 01287 { 01288 /* Free previous getservbyname buffer, allocate bigger */ 01289 if( p->Getservbyname ) 01290 HeapFree(GlobalHeap, 0, p->Getservbyname); 01291 p->Getservbyname = HeapAlloc(GlobalHeap, 0, SizeNeeded); 01292 if( !p->Getservbyname ) 01293 { 01294 WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n", 01295 SizeNeeded)); 01296 WSASetLastError( WSATRY_AGAIN ); 01297 return NULL; 01298 } 01299 p->Getservbyname->Size = SizeNeeded; 01300 } 01301 01302 /* Copy the data */ 01303 memmove(p->Getservbyname->Data, 01304 ThisLine, 01305 NextLine - ThisLine ); 01306 01307 ADJ_PTR(ServiceName,ThisLine,p->Getservbyname->Data); 01308 ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyname->Data); 01309 WS_DbgPrint(MAX_TRACE, ("ServiceName: %s, Protocol: %s\n", 01310 ServiceName, 01311 ProtocolStr)); 01312 01313 for( i = 0; Aliases[i]; i++ ) 01314 { 01315 ADJ_PTR(Aliases[i],ThisLine,p->Getservbyname->Data); 01316 WS_DbgPrint(MAX_TRACE,("Aliase %d: %s\n", i, Aliases[i])); 01317 } 01318 01319 memcpy(p->Getservbyname, 01320 Aliases, 01321 sizeof(Aliases)); 01322 01323 /* Create the struct proper */ 01324 p->Getservbyname->ServerEntry.s_name = ServiceName; 01325 p->Getservbyname->ServerEntry.s_aliases = p->Getservbyname->Aliases; 01326 p->Getservbyname->ServerEntry.s_port = htons(atoi(PortNumberStr)); 01327 p->Getservbyname->ServerEntry.s_proto = ProtocolStr; 01328 01329 return &p->Getservbyname->ServerEntry; 01330 } 01331 01332 01333 /* 01334 * @implemented 01335 */ 01336 LPSERVENT 01337 EXPORT 01338 getservbyport(IN INT port, 01339 IN CONST CHAR FAR* proto) 01340 { 01341 BOOL Found = FALSE; 01342 HANDLE ServicesFile; 01343 CHAR ServiceDBData[BUFSIZ] = { 0 }; 01344 PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */ 01345 PCHAR ServicesFileLocation = "\\drivers\\etc\\services"; 01346 PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0, 01347 ProtocolStr = 0, Comment = 0; 01348 PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; 01349 UINT i,SizeNeeded = 0, 01350 SystemDirSize = sizeof(ServiceDBData) - 1; 01351 DWORD ReadSize = 0, ValidData = 0; 01352 PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData; 01353 01354 if( !p ) 01355 { 01356 WSASetLastError( WSANOTINITIALISED ); 01357 return NULL; 01358 } 01359 01360 if ( !port ) 01361 { 01362 WSASetLastError( WSANO_RECOVERY ); 01363 return NULL; 01364 } 01365 01366 if( !GetSystemDirectoryA( SystemDirectory, SystemDirSize ) ) 01367 { 01368 WSASetLastError( WSANO_RECOVERY ); 01369 WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n")); 01370 return NULL; /* Can't get system directory */ 01371 } 01372 01373 strncat(SystemDirectory, 01374 ServicesFileLocation, 01375 SystemDirSize ); 01376 01377 ServicesFile = CreateFileA(SystemDirectory, 01378 GENERIC_READ, 01379 FILE_SHARE_READ, 01380 NULL, 01381 OPEN_EXISTING, 01382 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 01383 NULL ); 01384 01385 if( ServicesFile == INVALID_HANDLE_VALUE ) 01386 { 01387 WSASetLastError( WSANO_RECOVERY ); 01388 return NULL; 01389 } 01390 01391 /* Scan the services file ... 01392 * 01393 * We will read up to BUFSIZ bytes per pass, until the buffer does not 01394 * contain a full line, then we will try to read more. 01395 * 01396 * We fall from the loop if the buffer does not have a line terminator. 01397 */ 01398 01399 /* Initial Read */ 01400 while(!Found && 01401 ReadFile(ServicesFile, 01402 ServiceDBData + ValidData, 01403 sizeof( ServiceDBData ) - ValidData, 01404 &ReadSize, NULL ) ) 01405 { 01406 ValidData += ReadSize; 01407 ReadSize = 0; 01408 NextLine = ThisLine = ServiceDBData; 01409 01410 /* Find the beginning of the next line */ 01411 while( NextLine < ServiceDBData + ValidData && 01412 *NextLine != '\r' && *NextLine != '\n' ) NextLine++; 01413 01414 /* Zero and skip, so we can treat what we have as a string */ 01415 if( NextLine > ServiceDBData + ValidData ) 01416 break; 01417 01418 *NextLine = 0; NextLine++; 01419 01420 Comment = strchr( ThisLine, '#' ); 01421 if( Comment ) *Comment = 0; /* Terminate at comment start */ 01422 01423 if(DecodeServEntFromString(ThisLine, 01424 &ServiceName, 01425 &PortNumberStr, 01426 &ProtocolStr, 01427 Aliases, 01428 WS2_INTERNAL_MAX_ALIAS ) && 01429 (htons(atoi( PortNumberStr )) == port ) && 01430 (proto ? !strcmp( ProtocolStr, proto ) : TRUE) ) 01431 { 01432 01433 WS_DbgPrint(MAX_TRACE,("Found the port entry.\n")); 01434 01435 Found = TRUE; 01436 SizeNeeded = sizeof(WINSOCK_GETSERVBYPORT_CACHE) + 01437 (NextLine - ThisLine); 01438 break; 01439 } 01440 01441 /* Get rid of everything we read so far */ 01442 while( NextLine <= ServiceDBData + ValidData && 01443 isspace( *NextLine ) ) 01444 { 01445 NextLine++; 01446 } 01447 01448 WS_DbgPrint(MAX_TRACE,("About to move %d chars\n", 01449 ServiceDBData + ValidData - NextLine)); 01450 01451 memmove(ServiceDBData, 01452 NextLine, 01453 ServiceDBData + ValidData - NextLine ); 01454 ValidData -= NextLine - ServiceDBData; 01455 WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData)); 01456 } 01457 01458 /* This we'll do no matter what */ 01459 CloseHandle( ServicesFile ); 01460 01461 if( !Found ) 01462 { 01463 WS_DbgPrint(MAX_TRACE,("Not found\n")); 01464 WSASetLastError( WSANO_DATA ); 01465 return NULL; 01466 } 01467 01468 if( !p->Getservbyport || p->Getservbyport->Size < SizeNeeded ) 01469 { 01470 /* Free previous getservbyport buffer, allocate bigger */ 01471 if( p->Getservbyport ) 01472 HeapFree(GlobalHeap, 0, p->Getservbyport); 01473 p->Getservbyport = HeapAlloc(GlobalHeap, 01474 0, 01475 SizeNeeded); 01476 if( !p->Getservbyport ) 01477 { 01478 WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n", 01479 SizeNeeded)); 01480 WSASetLastError( WSATRY_AGAIN ); 01481 return NULL; 01482 } 01483 p->Getservbyport->Size = SizeNeeded; 01484 } 01485 /* Copy the data */ 01486 memmove(p->Getservbyport->Data, 01487 ThisLine, 01488 NextLine - ThisLine ); 01489 01490 ADJ_PTR(PortNumberStr,ThisLine,p->Getservbyport->Data); 01491 ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyport->Data); 01492 WS_DbgPrint(MAX_TRACE, ("Port Number: %s, Protocol: %s\n", 01493 PortNumberStr, ProtocolStr)); 01494 01495 for( i = 0; Aliases[i]; i++ ) 01496 { 01497 ADJ_PTR(Aliases[i],ThisLine,p->Getservbyport->Data); 01498 WS_DbgPrint(MAX_TRACE,("Aliases %d: %s\n", i, Aliases[i])); 01499 } 01500 01501 memcpy(p->Getservbyport,Aliases,sizeof(Aliases)); 01502 01503 /* Create the struct proper */ 01504 p->Getservbyport->ServerEntry.s_name = ServiceName; 01505 p->Getservbyport->ServerEntry.s_aliases = p->Getservbyport->Aliases; 01506 p->Getservbyport->ServerEntry.s_port = port; 01507 p->Getservbyport->ServerEntry.s_proto = ProtocolStr; 01508 01509 WS_DbgPrint(MID_TRACE,("s_name: %s\n", ServiceName)); 01510 01511 return &p->Getservbyport->ServerEntry; 01512 01513 } 01514 01515 01516 /* 01517 * @implemented 01518 */ 01519 ULONG 01520 EXPORT 01521 inet_addr(IN CONST CHAR FAR* cp) 01522 /* 01523 * FUNCTION: Converts a string containing an IPv4 address to an unsigned long 01524 * ARGUMENTS: 01525 * cp = Pointer to string with address to convert 01526 * RETURNS: 01527 * Binary representation of IPv4 address, or INADDR_NONE 01528 */ 01529 { 01530 UINT i; 01531 PCHAR p; 01532 ULONG u = 0; 01533 01534 p = (PCHAR)cp; 01535 01536 if (!p) 01537 { 01538 WSASetLastError(WSAEFAULT); 01539 return INADDR_NONE; 01540 } 01541 01542 if (strlen(p) == 0) 01543 return INADDR_NONE; 01544 01545 if (strcmp(p, " ") == 0) 01546 return 0; 01547 01548 for (i = 0; i <= 3; i++) 01549 { 01550 u += (strtoul(p, &p, 0) << (i * 8)); 01551 01552 if (strlen(p) == 0) 01553 return u; 01554 01555 if (p[0] != '.') 01556 return INADDR_NONE; 01557 01558 p++; 01559 } 01560 01561 return u; 01562 } 01563 01564 01565 /* 01566 * @implemented 01567 */ 01568 CHAR FAR* 01569 EXPORT 01570 inet_ntoa(IN IN_ADDR in) 01571 { 01572 CHAR b[10]; 01573 PCHAR p; 01574 01575 p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa; 01576 _itoa(in.S_un.S_addr & 0xFF, b, 10); 01577 strcpy(p, b); 01578 _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10); 01579 strcat(p, "."); 01580 strcat(p, b); 01581 _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10); 01582 strcat(p, "."); 01583 strcat(p, b); 01584 _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10); 01585 strcat(p, "."); 01586 strcat(p, b); 01587 01588 return (CHAR FAR*)p; 01589 } 01590 01591 01592 /* 01593 * @implemented 01594 */ 01595 VOID 01596 EXPORT 01597 freeaddrinfo(struct addrinfo *pAddrInfo) 01598 { 01599 struct addrinfo *next, *cur; 01600 cur = pAddrInfo; 01601 while (cur) 01602 { 01603 next = cur->ai_next; 01604 if (cur->ai_addr) 01605 HeapFree(GetProcessHeap(), 0, cur->ai_addr); 01606 if (cur->ai_canonname) 01607 HeapFree(GetProcessHeap(), 0, cur->ai_canonname); 01608 HeapFree(GetProcessHeap(), 0, cur); 01609 cur = next; 01610 } 01611 } 01612 01613 01614 struct addrinfo * 01615 new_addrinfo(struct addrinfo *prev) 01616 { 01617 struct addrinfo *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct addrinfo)); 01618 if (prev) 01619 prev->ai_next = ret; 01620 return ret; 01621 } 01622 01623 /* 01624 * @implemented 01625 */ 01626 INT 01627 EXPORT 01628 getaddrinfo(const char FAR * nodename, 01629 const char FAR * servname, 01630 const struct addrinfo FAR * hints, 01631 struct addrinfo FAR * FAR * res) 01632 { 01633 struct addrinfo *ret = NULL, *ai; 01634 ULONG addr; 01635 USHORT port; 01636 struct servent *se; 01637 char *proto; 01638 LPPROTOENT pent; 01639 DNS_STATUS dns_status; 01640 PDNS_RECORD dp, currdns; 01641 struct sockaddr_in *sin; 01642 01643 if (res == NULL) 01644 return WSAEINVAL; 01645 if (nodename == NULL && servname == NULL) 01646 return WSAHOST_NOT_FOUND; 01647 01648 if (!WSAINITIALIZED) 01649 return WSANOTINITIALISED; 01650 01651 if (servname) 01652 { 01653 /* converting port number */ 01654 port = strtoul(servname, NULL, 10); 01655 /* service name was specified? */ 01656 if (port == 0) 01657 { 01658 /* protocol was specified? */ 01659 if (hints && hints->ai_protocol) 01660 { 01661 pent = getprotobynumber(hints->ai_protocol); 01662 if (pent == NULL) 01663 return WSAEINVAL; 01664 proto = pent->p_name; 01665 } 01666 else 01667 proto = NULL; 01668 se = getservbyname(servname, proto); 01669 if (se == NULL) 01670 return WSATYPE_NOT_FOUND; 01671 port = se->s_port; 01672 } 01673 else 01674 port = htons(port); 01675 } 01676 else 01677 port = 0; 01678 01679 if (nodename) 01680 { 01681 /* Is it an IPv6 address? */ 01682 if (strstr(nodename, ":")) 01683 return WSAHOST_NOT_FOUND; 01684 01685 /* Is it an IPv4 address? */ 01686 addr = inet_addr(nodename); 01687 if (addr != INADDR_NONE) 01688 { 01689 ai = new_addrinfo(NULL); 01690 ai->ai_family = PF_INET; 01691 ai->ai_addrlen = sizeof(struct sockaddr_in); 01692 ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen); 01693 sin = (struct sockaddr_in *)ai->ai_addr; 01694 sin->sin_family = AF_INET; 01695 sin->sin_port = port; 01696 RtlCopyMemory(&sin->sin_addr, &addr, sizeof(sin->sin_addr)); 01697 if (hints) 01698 { 01699 if (ai->ai_socktype == 0) 01700 ai->ai_socktype = hints->ai_socktype; 01701 if (ai->ai_protocol == 0) 01702 ai->ai_protocol = hints->ai_protocol; 01703 } 01704 ret = ai; 01705 } 01706 else 01707 { 01708 /* resolving host name */ 01709 dns_status = DnsQuery_A(nodename, 01710 DNS_TYPE_A, 01711 DNS_QUERY_STANDARD, 01712 0, 01713 /* extra dns servers */ &dp, 01714 0); 01715 01716 if (dns_status == 0) 01717 { 01718 ai = NULL; 01719 for (currdns = dp; currdns; currdns = currdns->pNext ) 01720 { 01721 /* accept only A records */ 01722 if (currdns->wType != DNS_TYPE_A) continue; 01723 01724 ai = new_addrinfo(ai); 01725 if (ret == NULL) 01726 ret = ai; 01727 ai->ai_family = PF_INET; 01728 ai->ai_addrlen = sizeof(struct sockaddr_in); 01729 ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen); 01730 sin = (struct sockaddr_in *)ret->ai_addr; 01731 sin->sin_family = AF_INET; 01732 sin->sin_port = port; 01733 RtlCopyMemory(&sin->sin_addr, &currdns->Data.A.IpAddress, sizeof(sin->sin_addr)); 01734 if (hints) 01735 { 01736 if (ai->ai_socktype == 0) 01737 ai->ai_socktype = hints->ai_socktype; 01738 if (ai->ai_protocol == 0) 01739 ai->ai_protocol = hints->ai_protocol; 01740 } 01741 } 01742 DnsRecordListFree(dp, DnsFreeRecordList); 01743 } 01744 } 01745 } 01746 else 01747 { 01748 ai = new_addrinfo(NULL); 01749 ai->ai_family = PF_INET; 01750 ai->ai_addrlen = sizeof(struct sockaddr_in); 01751 ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen); 01752 sin = (struct sockaddr_in *)ai->ai_addr; 01753 sin->sin_family = AF_INET; 01754 sin->sin_port = port; 01755 if (hints) 01756 { 01757 if (!(hints->ai_flags & AI_PASSIVE)) 01758 { 01759 sin->sin_addr.S_un.S_un_b.s_b1 = 127; 01760 sin->sin_addr.S_un.S_un_b.s_b2 = 0; 01761 sin->sin_addr.S_un.S_un_b.s_b3 = 0; 01762 sin->sin_addr.S_un.S_un_b.s_b4 = 1; 01763 } 01764 if (ai->ai_socktype == 0) 01765 ai->ai_socktype = hints->ai_socktype; 01766 if (ai->ai_protocol == 0) 01767 ai->ai_protocol = hints->ai_protocol; 01768 } 01769 ret = ai; 01770 } 01771 01772 if (ret == NULL) 01773 return WSAHOST_NOT_FOUND; 01774 01775 if (hints && hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET) 01776 { 01777 freeaddrinfo(ret); 01778 return WSAEAFNOSUPPORT; 01779 } 01780 01781 *res = ret; 01782 return 0; 01783 } 01784 01785 /* EOF */ Generated on Sun May 27 2012 04:27:08 for ReactOS by
1.7.6.1
|