⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nspsrvc.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*****************************************************************************/
/**                            Microsoft Windows                            **/
/*****************************************************************************/

/*

nspsrvc.c

pass-through calls from the CE WSP to the PM (afd) layer


FILE HISTORY:
	OmarM     02-Oct-2000
	

*/

#include "nspmp.h"
#include "ws2tcpip.h"


// temporary service-list
typedef struct Services {
	char	*pName;
	int		Port;
	char	*pProtocol;
} Services;

Services s_Serv = {"ftp", 21, "tcp"};

Services s_aServices[] = {
	{"ftp",		21,		"tcp"},
	{"telnet",	23,		"tcp"},
	{"tftp",	69,		"udp"},
	{"login",	513,	"tcp"}
};


GUID HostnameGuid = SVCID_HOSTNAME;
GUID AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING;
GUID InetHostName = SVCID_INET_HOSTADDRBYNAME;
GUID IANAGuid = SVCID_INET_SERVICEBYNAME;
GUID AtmaGuid = SVCID_DNS_TYPE_ATMA;
GUID Ipv6Guid = SVCID_DNS_TYPE_AAAA;

#define DNS_F_END_CALLED	0x1             // generic  cancel
#define REVERSE_LOOKUP		0x2
#define LOCAL_LOOKUP		0x4
#define NEED_DOMAIN			0x8
#define IANA_LOOKUP			0x10
#define LOOP_LOOKUP			0x20
#define V6_LOOKUP			0x100
#define DONE_LOOKUP			0x1000


#define T_A     1
#define T_CNAME 5
#define T_AAAA  28
#define T_PTR   12
#define T_ALL   255


typedef struct QueryContext {
	struct QueryContext *pNext;
	GUID				Id;
	DWORD				Flags;
	int					cRefs;
	DWORD				ControlFlags;
	WCHAR				pwszSvcName[1];
} QueryContext;

typedef struct _SOCK_THREAD {
    CHAR            st_ntoa_buffer[20];

#define MAXALIASES		15		// We only support 15 aliases
#define AVG_HOST_LEN	40		// To calculate buff space
#define MAXADDRS		15		// Max of 15 IP addrs
    HOSTENT GETHOST_host;
	// The array of host alias names
    LPSTR GETHOST_host_aliases[MAXALIASES+1];
	// Some buffer space for host name and alias names
	char GETHOST_hostbuf[(MAXALIASES+1)*AVG_HOST_LEN];
	// The array of addresses
    LPSTR GETHOST_h_addr_ptrs[MAXADDRS + 1];
	// Some space for the addresses
    unsigned char GETHOST_hostaddr[MAXADDRS*20];	// sizeof(IPv6Addr)==16, sizeof(scopeid)==4

} SOCK_THREAD;


typedef struct AfdOptions {
	ushort	Type;
} AFD_OPTIONS;


typedef struct _SOCK_THREAD FAR * LPSOCK_THREAD;

QueryContext		*v_pQueryList;
CRITICAL_SECTION	v_ServicesCS;

QueryContext **_FindQuery(void *hHandle) {
	QueryContext	**ppQuery;
	
	
	for (ppQuery = &v_pQueryList; *ppQuery; ppQuery = &((*ppQuery)->pNext))
		if (*ppQuery == (QueryContext *)hHandle)
			break;

	return ppQuery;

}	// FindQuery()

                        
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif

HANDLE g_hWs2;
typedef unsigned long (*PINET_ADDR)(unsigned char * addr);
PINET_ADDR g_pInet_Addr;

unsigned long MyInetAddrW (const WCHAR * cp) {
	unsigned long	RetAddr = INADDR_NONE;
	unsigned int	i;
	char	mbs[INET_ADDRSTRLEN+1];

    if (NULL == g_hWs2) {
        g_hWs2 = LoadLibrary(L"ws2.dll");
        if (NULL == g_hWs2) {
            return RetAddr;
        }
    }

    if (NULL == g_pInet_Addr) {
        g_pInet_Addr = (PINET_ADDR)GetProcAddress(g_hWs2, L"inet_addr");
        if (NULL == g_pInet_Addr) {
            return RetAddr;
        }
    }

	i = wcslen(cp) + 1;
	if (i <= INET_ADDRSTRLEN) {
		if (wcstombs(mbs, cp, i) != -1) {
			RetAddr = g_pInet_Addr(mbs);
		}
	}
	return RetAddr;

}	// MyInetAddrW()


// returns TRUE if success otherwise false
int MyInetNtoaW(WCHAR *pszwAddr, struct in_addr Addr) {

    register unsigned char	*p;
	volatile WCHAR			*pBuf;
	int						i;
	WCHAR					c;

	pBuf = pszwAddr;
    p = (unsigned char *)&Addr;

	for (i = 3; i >= 0; i--) {
		do {
			*pBuf++ = p[i] % 10 + TEXT('0');
		} while (p[i] /= 10);
		*pBuf++ = TEXT('.');
	}
	*(--pBuf) = TEXT('\0');	// gets rid of last period & ends string
	// now reverse it...
	for (--pBuf ; pszwAddr < pBuf; pBuf--, pszwAddr++) {
		c = *pBuf;
		*pBuf = *pszwAddr;
		*pszwAddr = c;
	}
	return TRUE;
	
}	// MyInetNtoaW()


// returns TRUE if strings are equal except for possbile trailing dot
// ignores case
int DnsNameCompare_W(WCHAR *p1, WCHAR *p2) {
	int	Ret, cLen1, cLen2;

	Ret = TRUE;
	
	if (p1 != p2) {
		if (! p1 || ! p2)
			Ret = FALSE;
		else {
			cLen1 = wcslen(p1);
			cLen2 = wcslen(p2);
			if (cLen1 != cLen2) {
				if (cLen1 == cLen2 + 1) {
					if (p1[cLen1] != TEXT('.'))
						Ret = FALSE;
					else
						cLen1--;
					
				} else if (cLen1 == cLen2 - 1) {
					if (p2[cLen2] != TEXT('.'))
						Ret = FALSE;
				} else
					Ret = FALSE;
			}
			if (Ret) {
				Ret = !_wcsnicmp(p1, p2, cLen1);
			}
		}
	}

	return Ret;
	
}	// DnsNameCompare_W()


void PointerToOffset(HOSTENT *pHost) {
	int		i;
	char	*p;

	// if we use ptrs instead of i (an array) it should be a little more
	// efficient, but it makes the code harder to read

	p = (char *)pHost;

	pHost->h_name = (char *)(pHost->h_name - p);
	if (pHost->h_aliases) {
		for (i = 0; pHost->h_aliases[i]; i++) {
			pHost->h_aliases[i] = (char *)(pHost->h_aliases[i] - p);
		}
		pHost->h_aliases = (char **)((char *)pHost->h_aliases - p);
	}
	for (i = 0; pHost->h_addr_list[i]; i++)
		pHost->h_addr_list[i] = (char *) (pHost->h_addr_list[i] -p);
	pHost->h_addr_list = (char **)((char *)pHost->h_addr_list - p);	

}	// PointerToOffset


int CopyHostentToBlob(HOSTENT *pHost, char *pBuf, int cBuf, int *pcSize) {

	int			Err, i;
	int			cSize, cAddr;
	HOSTENT		*pMyHost;
	char 		*p, *p2, **ppAlias;

	cSize = sizeof(HOSTENT);
	if (cSize <= cBuf) {
		pMyHost = (HOSTENT *)pBuf;
		p = (char *)(pMyHost + 1);
	} else
		p = (char *)pMyHost = NULL;
	
	// to keep alignment for addresses, copy the addresses first
	if (pMyHost) {
		pMyHost->h_length = pHost->h_length;
		pMyHost->h_addrtype = pHost->h_addrtype;
//		pMyHost->h_addr_list = (char **)p;
	}

	// count how many pointer stuff we need to store the arrays
	if (pHost->h_aliases) {
		
		i = 0;
		// note i will be 1 more than # of aliases -- for NULL termination
		while(pHost->h_aliases[i++])
			;

		i <<= 2;
	} else
		i = 4;
	
	if (pMyHost) {
		pMyHost->h_aliases = (char **)p;
		p += i;
	}
	cSize += i;

	// now count addresses
	for (i = 0; pHost->h_addr_list[i++];)
		;
	i <<= 2;
	
	if (pMyHost) {
		pMyHost->h_addr_list = (char **)p;
		p += i;
	}
	cSize += i;

	// ok now copy the arrays, start with addresses first since they are more
	// like to be nicely aligned--maybe maybe not...
	cAddr = (pHost->h_length + 3) & ~3;
	for (i = 0; pHost->h_addr_list[i]; i++) {
		if (pMyHost)
			pMyHost->h_addr_list[i] = p;
			
		cSize += cAddr;
		if (cSize <= cBuf) {
			memcpy(p, pHost->h_addr_list[i], cAddr);
			p += cAddr;
		}
	}

	if (pHost->h_name) {
		if (pMyHost)
			pMyHost->h_name = p;
		// instead of calling strlen first then strcpy
		for (p2 = pHost->h_name; *p2; p2++) {
			if (++cSize <= cBuf)
				*p++ = *p2;
		}
		if (++cSize <= cBuf)
			*p++ = '\0';
	}	// if (pHost->h_name)

	// now copy the aliases
	if (ppAlias = pHost->h_aliases) {

		for (i = 0; *ppAlias; ppAlias++) {
			if (pMyHost)
				pMyHost->h_aliases[i] = p;
		
			// instead of calling strlen first then strcpy
			for (p2 = *ppAlias; *p2; p2++) {
				if (++cSize <= cBuf)
					*p++ = *p2;
			}
			if (++cSize <= cBuf)
				*p++ = '\0';
		}
	}	// if (ppAlias = pHost->h_aliases)

	*pcSize = cSize;
	if (cSize > cBuf)
		Err = WSAEFAULT;
	else {
		Err = 0;
	}

	return Err;

}	// CopyHostentToBlob()


int CheckAddressFamily(LPWSAQUERYSETW pQuery) {
	uint				i;
	LPAFPROTOCOLS	pProt;

	ASSERT(pQuery->dwNumberOfProtocols);
	pProt = pQuery->lpafpProtocols;
	for (i = 0; i < pQuery->dwNumberOfProtocols; i++, pProt++) {
		if ((pProt->iAddressFamily == AF_UNSPEC) ||
			(	((pProt->iAddressFamily == AF_INET) ||
				 (pProt->iAddressFamily == AF_INET6)) &&
					
			 	((pProt->iProtocol == IPPROTO_IP) ||
			  	 (pProt->iProtocol == IPPROTO_TCP) ||
			  	 (pProt->iProtocol == IPPROTO_UDP))))
			return TRUE;
	}

	return FALSE;
}


INT WSAAPI NSPLookupServiceBegin(
	LPGUID					pProviderId,
	LPWSAQUERYSETW			pRestrict,
	LPWSASERVICECLASSINFOW	pServiceClass,
	DWORD					ControlFlags,
	LPHANDLE				phLookup) {

	WCHAR			*pwszTemp, *pwszSvcName;
	GUID			*pSvcClassId;
	DWORD			Flags;
	SOCKADDR_IN		*pSAddr;
	WCHAR			pwszSockAddr[18];
	int				Err, Family, fNameLookup;
	QueryContext	*pQuery;
	int				cSvcName;
	DWORD			Protocols=0x0, cProtocols;
	int				AddrFamily, Prot;
	LPAFPROTOCOLS	pAfProtocols;

 	Family = 0;
	Err = 0;
	
	// we assume if ws2_32 called us that the GUID is correct
	
	if (pRestrict->dwSize < sizeof(WSAQUERYSET)) {
		Err = WSAEFAULT;
	} else if (! (pSvcClassId = pRestrict->lpServiceClassId)) {
		Err = WSAEINVAL;
	} else if ((ControlFlags & LUP_CONTAINERS) && (ControlFlags & LUP_NOCONTAINERS)) {
		Err = WSAEINVAL;
	} else if (ControlFlags & LUP_CONTAINERS) {
		Err = WSANO_DATA;
	} else if (pRestrict->dwNumberOfProtocols && 
		(!CheckAddressFamily(pRestrict))) {
		Err = WSAEINVAL;
	} else if ((pRestrict->lpszContext) && (pRestrict->lpszContext[0]) &&
				wcscmp(pRestrict->lpszContext, TEXT("\\"))) {
		// if there is a context and it's not the default context then fail
		Err = WSANO_DATA;
	} else if (! (pwszTemp = LocalAlloc(LPTR, 1024*sizeof(WCHAR)))) {
		Err = WSA_NOT_ENOUGH_MEMORY;
	} else {
		// ok finally do the work...
		Flags = 0;

		if (0 == memcmp(pSvcClassId, &AddressGuid, sizeof(GUID))) {
			Flags |= REVERSE_LOOKUP;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -