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

#include <windows.h>
#include <svcguid.h>
#include <winsock2.h>
#include <dbgtrace.h>
#include <dnsapi.h>
#include <dbgtrace.h>
#include <cpool.h>
#include <address.hxx>
#include <rwnew.h>
#include <dnsreci.h>
#include <listmacr.h>
//shamelessy stolen from the NT winsock code....
GUID HostnameGuid = SVCID_INET_HOSTADDRBYNAME;
GUID AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING;
GUID IANAGuid = SVCID_INET_SERVICEBYNAME;
//
// Utility to turn a list of offsets into a list of addresses. Used
// to convert structures returned as BLOBs.
//
VOID
FixList(PCHAR ** List, PCHAR Base)
{
if(*List)
{
PCHAR * Addr;
Addr = *List = (PCHAR *)( ((ULONG_PTR)*List + Base) );
while(*Addr)
{
*Addr = (PCHAR)(((ULONG_PTR)*Addr + Base));
Addr++;
}
}
}
//
// Routine to convert a hostent returned in a BLOB to one with
// usable pointers. The structure is converted in-place.
//
VOID
UnpackHostEnt(struct hostent * hostent)
{
PCHAR pch;
pch = (PCHAR)hostent;
if(hostent->h_name)
{
hostent->h_name = (PCHAR)((ULONG_PTR)hostent->h_name + pch);
}
FixList(&hostent->h_aliases, pch);
FixList(&hostent->h_addr_list, pch);
}
//
// The protocol restrictions list for all emulation operations. This should
// limit the invoked providers to the set that know about hostents and
// servents. If not, then the special SVCID_INET GUIDs should take care
// of the remainder.
//
AFPROTOCOLS afp[2] = {
{AF_INET, IPPROTO_UDP},
{AF_INET, IPPROTO_TCP}
};
LPBLOB GetGostByNameI(PCHAR pResults,
DWORD dwLength,
LPSTR lpszName,
LPGUID lpType,
LPSTR * lppName)
{
PWSAQUERYSETA pwsaq = (PWSAQUERYSETA)pResults;
int err;
HANDLE hRnR;
LPBLOB pvRet = 0;
INT Err = 0;
//
// create the query
//
ZeroMemory(pwsaq,sizeof(*pwsaq));
pwsaq->dwSize = sizeof(*pwsaq);
pwsaq->lpszServiceInstanceName = lpszName;
pwsaq->lpServiceClassId = lpType;
pwsaq->dwNameSpace = NS_ALL;
pwsaq->dwNumberOfProtocols = 2;
pwsaq->lpafpProtocols = &afp[0];
//don't go though the cache
err = WSALookupServiceBeginA(pwsaq,
LUP_RETURN_BLOB | LUP_RETURN_NAME | LUP_FLUSHCACHE,
&hRnR);
if(err == NO_ERROR)
{
//
// The query was accepted, so execute it via the Next call.
//
err = WSALookupServiceNextA(
hRnR,
0,
&dwLength,
pwsaq);
//
// if NO_ERROR was returned and a BLOB is present, this
// worked, just return the requested information. Otherwise,
// invent an error or capture the transmitted one.
//
if(err == NO_ERROR)
{
if(pvRet = pwsaq->lpBlob)
{
if(lppName)
{
*lppName = pwsaq->lpszServiceInstanceName;
}
}
else
{
err = WSANO_DATA;
}
}
else
{
//
// WSALookupServiceEnd clobbers LastError so save
// it before closing the handle.
//
err = GetLastError();
}
WSALookupServiceEnd(hRnR);
//
// if an error happened, stash the value in LastError
//
if(err != NO_ERROR)
{
SetLastError(err);
}
}
return(pvRet);
}
struct hostent FAR * GetHostByName(PCHAR Buffer, DWORD BuffSize, DWORD dwFlags, char * HostName)
{
struct hostent * hent = NULL;
LPBLOB pBlob = NULL;
pBlob = GetGostByNameI(Buffer, BuffSize, HostName, &HostnameGuid, 0);
if(pBlob)
{
hent = (struct hostent *) pBlob;
UnpackHostEnt(hent);
}
else
{
if(GetLastError() == WSASERVICE_NOT_FOUND)
{
SetLastError(WSAHOST_NOT_FOUND);
}
}
return hent;
}
BOOL GetIpAddressFromDns(char * HostName, PSMTPDNS_RECS pDnsRec, DWORD Index)
{
TraceFunctEnter("GetIpAddressFromDns");
PDNS_RECORD pDnsRecord = NULL;
MXIPLIST_ENTRY * pEntry = NULL;
PDNS_RECORD pTempDnsRecord;
DNS_STATUS DnsStatus = 0;
DWORD Error = NO_ERROR;
BOOL fReturn = TRUE;
DnsStatus = DnsQuery_A(HostName, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, NULL, &pDnsRecord, NULL);
pTempDnsRecord = pDnsRecord;
while ( pTempDnsRecord )
{
if(pTempDnsRecord->wType == DNS_TYPE_A)
{
pEntry = new MXIPLIST_ENTRY;
if(pEntry != NULL)
{
pDnsRec->DnsArray[Index]->NumEntries++;
pEntry->IpAddress = pTempDnsRecord->Data.A.ipAddress;
InsertTailList(&pDnsRec->DnsArray[Index]->IpListHead, &pEntry->ListEntry);
}
else
{
fReturn = FALSE;
Error = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}
pTempDnsRecord = pTempDnsRecord->pNext;
}
DnsFreeRRSet( pDnsRecord, TRUE );
if(Error)
{
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
}
TraceFunctLeave();
return fReturn;
}