Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.2 KiB

  1. #include <windows.h>
  2. #include <svcguid.h>
  3. #include <winsock2.h>
  4. #include <dbgtrace.h>
  5. #include <dnsapi.h>
  6. #include <dbgtrace.h>
  7. #include <cpool.h>
  8. #include <address.hxx>
  9. #include <rwnew.h>
  10. #include <dnsreci.h>
  11. #include <listmacr.h>
  12. //shamelessy stolen from the NT winsock code....
  13. GUID HostnameGuid = SVCID_INET_HOSTADDRBYNAME;
  14. GUID AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING;
  15. GUID IANAGuid = SVCID_INET_SERVICEBYNAME;
  16. //
  17. // Utility to turn a list of offsets into a list of addresses. Used
  18. // to convert structures returned as BLOBs.
  19. //
  20. VOID
  21. FixList(PCHAR ** List, PCHAR Base)
  22. {
  23. if(*List)
  24. {
  25. PCHAR * Addr;
  26. Addr = *List = (PCHAR *)( ((ULONG_PTR)*List + Base) );
  27. while(*Addr)
  28. {
  29. *Addr = (PCHAR)(((ULONG_PTR)*Addr + Base));
  30. Addr++;
  31. }
  32. }
  33. }
  34. //
  35. // Routine to convert a hostent returned in a BLOB to one with
  36. // usable pointers. The structure is converted in-place.
  37. //
  38. VOID
  39. UnpackHostEnt(struct hostent * hostent)
  40. {
  41. PCHAR pch;
  42. pch = (PCHAR)hostent;
  43. if(hostent->h_name)
  44. {
  45. hostent->h_name = (PCHAR)((ULONG_PTR)hostent->h_name + pch);
  46. }
  47. FixList(&hostent->h_aliases, pch);
  48. FixList(&hostent->h_addr_list, pch);
  49. }
  50. //
  51. // The protocol restrictions list for all emulation operations. This should
  52. // limit the invoked providers to the set that know about hostents and
  53. // servents. If not, then the special SVCID_INET GUIDs should take care
  54. // of the remainder.
  55. //
  56. AFPROTOCOLS afp[2] = {
  57. {AF_INET, IPPROTO_UDP},
  58. {AF_INET, IPPROTO_TCP}
  59. };
  60. LPBLOB GetGostByNameI(PCHAR pResults,
  61. DWORD dwLength,
  62. LPSTR lpszName,
  63. LPGUID lpType,
  64. LPSTR * lppName)
  65. {
  66. PWSAQUERYSETA pwsaq = (PWSAQUERYSETA)pResults;
  67. int err;
  68. HANDLE hRnR;
  69. LPBLOB pvRet = 0;
  70. INT Err = 0;
  71. //
  72. // create the query
  73. //
  74. ZeroMemory(pwsaq,sizeof(*pwsaq));
  75. pwsaq->dwSize = sizeof(*pwsaq);
  76. pwsaq->lpszServiceInstanceName = lpszName;
  77. pwsaq->lpServiceClassId = lpType;
  78. pwsaq->dwNameSpace = NS_ALL;
  79. pwsaq->dwNumberOfProtocols = 2;
  80. pwsaq->lpafpProtocols = &afp[0];
  81. //don't go though the cache
  82. err = WSALookupServiceBeginA(pwsaq,
  83. LUP_RETURN_BLOB | LUP_RETURN_NAME | LUP_FLUSHCACHE,
  84. &hRnR);
  85. if(err == NO_ERROR)
  86. {
  87. //
  88. // The query was accepted, so execute it via the Next call.
  89. //
  90. err = WSALookupServiceNextA(
  91. hRnR,
  92. 0,
  93. &dwLength,
  94. pwsaq);
  95. //
  96. // if NO_ERROR was returned and a BLOB is present, this
  97. // worked, just return the requested information. Otherwise,
  98. // invent an error or capture the transmitted one.
  99. //
  100. if(err == NO_ERROR)
  101. {
  102. if(pvRet = pwsaq->lpBlob)
  103. {
  104. if(lppName)
  105. {
  106. *lppName = pwsaq->lpszServiceInstanceName;
  107. }
  108. }
  109. else
  110. {
  111. err = WSANO_DATA;
  112. }
  113. }
  114. else
  115. {
  116. //
  117. // WSALookupServiceEnd clobbers LastError so save
  118. // it before closing the handle.
  119. //
  120. err = GetLastError();
  121. }
  122. WSALookupServiceEnd(hRnR);
  123. //
  124. // if an error happened, stash the value in LastError
  125. //
  126. if(err != NO_ERROR)
  127. {
  128. SetLastError(err);
  129. }
  130. }
  131. return(pvRet);
  132. }
  133. struct hostent FAR * GetHostByName(PCHAR Buffer, DWORD BuffSize, DWORD dwFlags, char * HostName)
  134. {
  135. struct hostent * hent = NULL;
  136. LPBLOB pBlob = NULL;
  137. pBlob = GetGostByNameI(Buffer, BuffSize, HostName, &HostnameGuid, 0);
  138. if(pBlob)
  139. {
  140. hent = (struct hostent *) pBlob;
  141. UnpackHostEnt(hent);
  142. }
  143. else
  144. {
  145. if(GetLastError() == WSASERVICE_NOT_FOUND)
  146. {
  147. SetLastError(WSAHOST_NOT_FOUND);
  148. }
  149. }
  150. return hent;
  151. }
  152. BOOL GetIpAddressFromDns(char * HostName, PSMTPDNS_RECS pDnsRec, DWORD Index)
  153. {
  154. TraceFunctEnter("GetIpAddressFromDns");
  155. PDNS_RECORD pDnsRecord = NULL;
  156. MXIPLIST_ENTRY * pEntry = NULL;
  157. PDNS_RECORD pTempDnsRecord;
  158. DNS_STATUS DnsStatus = 0;
  159. DWORD Error = NO_ERROR;
  160. BOOL fReturn = TRUE;
  161. DnsStatus = DnsQuery_A(HostName, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, NULL, &pDnsRecord, NULL);
  162. pTempDnsRecord = pDnsRecord;
  163. while ( pTempDnsRecord )
  164. {
  165. if(pTempDnsRecord->wType == DNS_TYPE_A)
  166. {
  167. pEntry = new MXIPLIST_ENTRY;
  168. if(pEntry != NULL)
  169. {
  170. pDnsRec->DnsArray[Index]->NumEntries++;
  171. pEntry->IpAddress = pTempDnsRecord->Data.A.ipAddress;
  172. InsertTailList(&pDnsRec->DnsArray[Index]->IpListHead, &pEntry->ListEntry);
  173. }
  174. else
  175. {
  176. fReturn = FALSE;
  177. Error = ERROR_NOT_ENOUGH_MEMORY;
  178. break;
  179. }
  180. }
  181. pTempDnsRecord = pTempDnsRecord->pNext;
  182. }
  183. DnsFreeRRSet( pDnsRecord, TRUE );
  184. if(Error)
  185. {
  186. SetLastError (ERROR_NOT_ENOUGH_MEMORY);
  187. }
  188. TraceFunctLeave();
  189. return fReturn;
  190. }