📄 gxy.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 **/
/*****************************************************************************/
/*
gxy.c
get x by y functions
FILE HISTORY:
OmarM 11-Oct-2000
OmarM 20-May-2001
implemented getaddrinfo getnameinfo--copied NT's architecture for these
*/
#include "winsock2p.h"
#include "ws2tcpip.h"
#include "svcguid.h"
#include "windev.h"
#include "wscntl.h"
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 DEFAULT_QUERY_SIZE (sizeof(WSAQUERYSET) + 1024)
extern void MatchCurrentThreadPriority(HANDLE hThd);
AFPROTOCOLS AfProtocols[2] = {{AF_INET, IPPROTO_UDP}, {AF_INET, IPPROTO_TCP}};
// *ppResults must be properly (DWORD) aligned
BLOB *getxyDataEnt(
IN OUT CHAR **ppResults,
IN DWORD cLen,
IN const char *pszName,
IN LPGUID pType,
OUT LPWSTR *ppName OPTIONAL) {
int Err, fNewBuf;
WSAQUERYSETW *pQuery;
HANDLE hQuery;
DWORD cQuery;
BLOB *pBlob;
int cName;
WCHAR *pwszName;
int cConverted;
// make sure it is dword aligned
ASSERT(0 == ((DWORD)(*ppResults) & 0x3));
if (ppName)
*ppName = NULL;
pBlob = NULL;
pQuery = (WSAQUERYSETW *)*ppResults;
cQuery = cLen;
cName = strlen(pszName) + 1;
if (pwszName = LocalAlloc(LPTR, sizeof(WCHAR) * cName)) {
cConverted = MultiByteToWideChar(CP_ACP, 0, pszName, -1, pwszName, cName);
if (cConverted) {
memset(pQuery, 0, sizeof(*pQuery));
pQuery->dwSize = sizeof(*pQuery);
pQuery->lpszServiceInstanceName = pwszName;
pQuery->lpServiceClassId = pType;
if (pType == &InetHostName) {
pQuery->dwNameSpace = NS_DNS;
} else {
pQuery->dwNameSpace = NS_ALL;
}
pQuery->dwNumberOfProtocols = 2;
pQuery->lpafpProtocols = AfProtocols;
Err = WSALookupServiceBegin(pQuery,
LUP_RETURN_BLOB | LUP_RETURN_NAME, &hQuery);
if (! Err) {
do {
fNewBuf = FALSE;
Err = WSALookupServiceNext(hQuery, 0, &cLen, pQuery);
if (Err) {
Err = GetLastError();
// check if buffer was too small
if (WSAEFAULT == Err && cLen > cQuery) {
LocalFree(*ppResults);
*ppResults = (char *)pQuery =
LocalAlloc(LPTR, cLen);
if (pQuery) {
cQuery = cLen;
fNewBuf = TRUE;
} else {
Err = WSA_NOT_ENOUGH_MEMORY;
}
}
} else {
if (pBlob = pQuery->lpBlob) {
if (ppName)
*ppName = pQuery->lpszServiceInstanceName;
} else {
if (&HostnameGuid == pType) {
if (ppName)
*ppName = pQuery->lpszServiceInstanceName;
} else
Err = WSANO_DATA;
}
} // else Err = WSALookupServiceNext
} while (fNewBuf);
WSALookupServiceEnd(hQuery);
} else {
Err = GetLastError(); // WSALookupServiceBegin failed
}
} else { // if MultiByteToWideChar
Err = WSANO_RECOVERY;
}
LocalFree(pwszName);
} else { // if pwszName = LocalAlloc...
Err = WSA_NOT_ENOUGH_MEMORY;
}
if (Err) {
SetLastError(Err);
}
return pBlob;
} // getxyDataEnt()
void OffsetToPointer(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 = p + (int)pHost->h_name;
if (pHost->h_aliases) {
pHost->h_aliases = (char **)(p + (int)pHost->h_aliases);
for (i = 0; pHost->h_aliases[i]; i++) {
pHost->h_aliases[i] = p + (int)pHost->h_aliases[i];
}
}
pHost->h_addr_list = (char **)(p + (int)pHost->h_addr_list);
for (i = 0; pHost->h_addr_list[i]; i++)
pHost->h_addr_list[i] = p + (int)pHost->h_addr_list[i];
} // OffsetToPointer()
void CopyHostentToThread(HOSTENT *pHost, SOCK_THREAD *pThread) {
HOSTENT *pTHost;
char *p;
int i, cRemaining, cLen;
pTHost = &pThread->GETHOST_host;
pTHost->h_addrtype = pHost->h_addrtype;
pTHost->h_length = pHost->h_length;
// copy the addresses first
p = pThread->GETHOST_hostaddr;
pTHost->h_addr_list = pThread->GETHOST_h_addr_ptrs;
for (i = 0; pHost->h_addr_list[i]; i++) {
pThread->GETHOST_h_addr_ptrs[i] = p;
memcpy(p, pHost->h_addr_list[i], 4);
p += 4;
}
pThread->GETHOST_h_addr_ptrs[i] = NULL;
// copy the name
pTHost->h_name = pThread->GETHOST_hostbuf;
strcpy(pTHost->h_name, pHost->h_name);
// copy the aliases
cLen = strlen(pTHost->h_name) + 1;
cRemaining = sizeof(pThread->GETHOST_hostbuf) - cLen;
p = pThread->GETHOST_hostbuf + cLen;
pTHost->h_aliases = pThread->GETHOST_host_aliases;
for (i = 0; pHost->h_aliases[i]; i++) {
cLen = strlen(pHost->h_aliases[i]) + 1;
if (cRemaining >= cLen) {
strcpy(p, pHost->h_aliases[i]);
pThread->GETHOST_host_aliases[i] = p;
} else {
break;
}
p += cLen;
cRemaining -= cLen;
}
pThread->GETHOST_host_aliases[i] = NULL;
} // CopyHostentToThread()
struct servent * WSAAPI getservbyname(
IN const char *pszName,
IN const char *pszProto) {
SetLastError(WSANO_RECOVERY);
return NULL;
// we don't actually implement this right now, but if we did, this is what
// we'd have to do at the Ws2 layer.
} // getservbyname()
struct servent * WSAAPI getservbyport(
IN int port,
IN const char *pszProto) {
SetLastError(WSANO_RECOVERY);
return NULL;
// we don't actually implement this right now, but if we did, this is what
// we'd have to do at the Ws2 layer.
} // getservbyport()
struct hostent *WSAAPI gethostbyaddr (
IN const char FAR * addr,
IN int len,
IN int type) {
int Err;
struct hostent *pHost;
BLOB *pBlob;
char *pResults;
SOCK_THREAD *pThread;
char aName[32]; // 16 is all that is needed for INET addresses
Err = 0;
pHost = NULL;
// check if we've been started up.
if (addr) {
sprintf(aName, "%u.%u.%u.%u", ((unsigned)addr[0] & 0xff),
((unsigned)addr[1] & 0xff), ((unsigned)addr[2] & 0xff),
((unsigned)addr[3] & 0xff));
if (GetThreadData(&pThread)) {
if (pResults = LocalAlloc(LPTR, DEFAULT_QUERY_SIZE)) {
pBlob = getxyDataEnt(&pResults, DEFAULT_QUERY_SIZE, aName,
&AddressGuid, NULL);
if (pBlob) {
// copy the info into TLS mem
pHost = (HOSTENT *)pBlob->pBlobData;
OffsetToPointer(pHost);
CopyHostentToThread(pHost, pThread);
pHost = &pThread->GETHOST_host;
} else {
if (WSASERVICE_NOT_FOUND == (Err = GetLastError()))
Err = WSAHOST_NOT_FOUND;
}
LocalFree(pResults);
} else
Err = WSA_NOT_ENOUGH_MEMORY;
} else
Err = WSA_NOT_ENOUGH_MEMORY;
} else // if (addr)
Err = WSAEINVAL;
if (Err) {
ASSERT(!pHost);
SetLastError(Err);
}
return pHost;
} // gethostbyaddr()
struct hostent *WSAAPI gethostbyname (
IN const char *pName) {
int Err;
struct hostent *pHost;
BLOB *pBlob;
char *pResults, *pszName;
SOCK_THREAD *pThread;
Err = 0;
pHost = NULL;
// check if we've been started up.
pszName = (char *)pName;
if (GetThreadData(&pThread)) {
if (pResults = LocalAlloc(LPTR, DEFAULT_QUERY_SIZE)) {
pBlob = getxyDataEnt(&pResults, DEFAULT_QUERY_SIZE, pszName,
&InetHostName, NULL);
if (pBlob) {
// copy the info into TLS mem
pHost = (HOSTENT *)pBlob->pBlobData;
OffsetToPointer(pHost);
CopyHostentToThread(pHost, pThread);
pHost = &pThread->GETHOST_host;
} else {
if (WSASERVICE_NOT_FOUND == (Err = GetLastError()))
Err = WSAHOST_NOT_FOUND;
}
LocalFree(pResults);
} else
Err = WSA_NOT_ENOUGH_MEMORY;
} else
Err = WSA_NOT_ENOUGH_MEMORY;
if (Err) {
ASSERT(!pHost);
SetLastError(Err);
}
return pHost;
} // gethostbyname()
#define MAX_NB_NAME 16
// this call is not defined in the winsock spec., we have it so that we can
// validate the name that is being assigned to the host, perhaps in the future
// we may also make some sort of notification mechanism
// note: to be consistent with gethostname cName is actually the # of bytes
// of storage used in pName and is therefore strlen(pName) + 1 and pName must
// include the terminating null
//
// This originally matched RFC 10035, now changed to allow _ (underscore) in name
//
int SOCKAPI sethostname(IN char FAR *pName, IN int cName) {
int Status = 0;
DEBUGMSG(0, (TEXT("+sethostname\r\n")));
if (!pName) {
Status = WSAEFAULT;
} else if (cName < 2 || cName > MAX_NB_NAME) {
Status = WSAEINVAL;
} else if (IsAPIReady(SH_COMM)) {
Status = AFDControl (-1, WSCNTL_AFD_SET_MACHINE_NAME, pName, &cName, NULL, NULL);
} else {
Status = WSAENETDOWN;
}
if (Status) {
DEBUGMSG(ZONE_WARN,
(TEXT("*sethostname: had error %d, make sure cName==strlen(pName)+1\r\n")
TEXT("and that pName ends w/ NULL and 1st must be alpha, last must be\r\n")
TEXT("alphanumeric and in between alphanum, _ or - \r\n"),
Status));
SetLastError(Status);
Status = SOCKET_ERROR;
}
return Status;
} // sethostname
int WSAAPI gethostname(
OUT char *pName,
IN int cName) {
int Err = WSAEFAULT;
WCHAR aDftName[] = TEXT("WindowsCE");
WCHAR *p, CompName[128];
DWORD Type;
int cSize;
HKEY hKey;
LONG hRet;
if (cName > 0 && pName) {
p = NULL;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE,
TEXT("Ident"), 0, 0, &hKey)) {
cSize = sizeof(CompName);
hRet = RegQueryValueEx(hKey, TEXT("Name"), 0, &Type,
(char *)CompName, &cSize);
RegCloseKey (hKey);
if ((hRet == ERROR_SUCCESS) && (Type == REG_SZ)) {
p = CompName;
cSize >>= 1;
}
}
if (!p) {
p = aDftName;
cSize = 10;
}
if (cName >= cSize) {
__try {
wcstombs (pName, p, cSize);
pName[cName-1] = '\0';
Err = 0;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
; // don't have anything to do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -