📄 nspsrvc.c
字号:
//
// 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 + -