📄 nspsrvc.c
字号:
if (LUP_RETURN_NAME & pQuery->ControlFlags) {
cBuf += cSize;
if (cBuf <= *pcBuf) {
QuerySet.lpszServiceInstanceName = (WCHAR *)p;
memcpy(p, wName, cName);
p += cSize;
ASSERT(!((DWORD)p & 0x3));
}
}
// very silly: copy GUID from LookupServiceBegin
if (LUP_RETURN_TYPE & pQuery->ControlFlags) {
cSize = sizeof(GUID);
cBuf += cSize;
if (cBuf <= *pcBuf) {
QuerySet.lpServiceClassId = (GUID *)p;
memcpy(p, &pQuery->Id, cSize);
p += cSize;
ASSERT(!((DWORD)p & 0x3));
}
}
if (! ((LUP_RETURN_ADDR | LUP_RETURN_BLOB) & pQuery->ControlFlags)) {
if (cBuf > *pcBuf) {
Err = WSAEFAULT;
*pcBuf = cBuf;
} else
memcpy(pResults, &QuerySet, sizeof(QuerySet));
goto Done;
}
} else {
fLocalLookup = FALSE;
}
if (pThread = LocalAlloc(LPTR, sizeof(*pThread))) {
WCHAR *wp;
if (fLocalLookup && (! (LOOP_LOOKUP & pQuery->Flags))) {
wp = wName;
} else {
wp = pQuery->pwszSvcName;
}
if (AFDGetHostentByAttr(pThread,wp,NULL,&AfdOptions)) {
pHost = &(pThread->GETHOST_host);
if (! fLocalLookup) {
p = (char *)(pResults + 1);
cBuf = (DWORD)(pResults + 1) - (DWORD)pResults;
ASSERT(!((DWORD)p & 0x3));
memset(&QuerySet, 0, sizeof(QuerySet));
// copy stuff into the query structure...
QuerySet.dwSize = sizeof(QuerySet);
// very silly: copy GUID from LookupServiceBegin
if (LUP_RETURN_TYPE & pQuery->ControlFlags) {
cSize = sizeof(GUID);
cBuf += cSize;
if (cBuf <= *pcBuf) {
QuerySet.lpServiceClassId = (GUID *)p;
memcpy(p, &pQuery->Id, cSize);
p += cSize;
ASSERT(!((DWORD)p & 0x3));
}
}
// seems to be not set by NT
// QuerySet.lpVersion = NULL;
// QuerySet.lpszComment = NULL;
QuerySet.dwNameSpace = NS_DNS;
cSize = sizeof(GUID);
cBuf += cSize;
if (cBuf <= *pcBuf) {
QuerySet.lpNSProviderId = (GUID *)p;
memcpy(p, &NsId, cSize);
p += cSize;
ASSERT(!((DWORD)p & 0x3));
}
// QuerySet.lpszContext = NULL;
// QuerySet.dwNumberOfProtocols = 0;
// QuerySet.lpafpProtocols = NULL;
// QuerySet.lpszQueryString = NULL;
ASSERT(!((DWORD)p & 0x3));
} // if (!fLocalLookup)
if (LUP_RETURN_ADDR & pQuery->ControlFlags) {
// first count the addresses
for (i = 0; pHost->h_addr_list[i]; i++)
;
ASSERT(i);
// each pCsAddr will have two pointers to
// SOCKADDRS so calculate them in too...
cSize = sizeof(*pCsAddr) + (cAddr << 1);
cBuf += cSize * i;
ASSERT(!((DWORD)cSize & 0x3));
// if they're not all going to fit in, then don't
// return partial info...
if (cBuf <= *pcBuf) {
QuerySet.dwNumberOfCsAddrs = i;
QuerySet.lpcsaBuffer = pCsAddr =
(CSADDR_INFO *)p;
p += sizeof(*pCsAddr) * i;
ASSERT(!((DWORD)p & 0x3));
pSAddr = (SOCKADDR *)p;
// now copy them in...
for (i = 0; pHost->h_addr_list[i]; i++) {
memset(&pCsAddr[i], 0, sizeof(*pCsAddr));
// copy the non-pointer info first
pCsAddr[i].iSocketType = SOCK_STREAM;
pCsAddr[i].iProtocol = IPPROTO_TCP;
pCsAddr[i].LocalAddr.iSockaddrLength =
pCsAddr[i].RemoteAddr.iSockaddrLength
= cAddr;
pCsAddr[i].LocalAddr.lpSockaddr = pSAddr;
memset(pSAddr, 0, cAddr);
pSAddr->sa_family = Family;
// local address will be blank
p += cAddr;
ASSERT(!((DWORD)p & 0x3));
pSAddr = (SOCKADDR *)p;
pCsAddr[i].RemoteAddr.lpSockaddr = pSAddr;
memset(pSAddr, 0, cAddr);
pSAddr->sa_family = Family;
// pSAddrIn->sin_port already memset to 0
if (AF_INET == Family) {
pSAddrIn = (SOCKADDR_IN *)pSAddr;
pSAddrIn->sin_addr.s_addr =
*(DWORD *)pHost->h_addr_list[i];
} else {
pSAddrIn6 = (SOCKADDR_IN6 *)pSAddr;
memcpy(&pSAddrIn6->sin6_addr,
pHost->h_addr_list[i],
sizeof(struct in6_addr) + sizeof(u_long)); // IPv6 address and scope Id
}
p += cAddr;
ASSERT(!((DWORD)p & 0x3));
pSAddr = (SOCKADDR *)p;
} // for (pHost->h_addr_list[i])
} // if (cBuf <= *pcBuf)
} // if (LUP_RETURN_ADDR & pQuery->ControlFlags
// if this is an alias set this to RESULT_IS_ALIAS
// QuerySet.dwOutputFlags = 0;
if (LUP_RETURN_BLOB & pQuery->ControlFlags) {
QuerySet.lpBlob = pBlob = (BLOB *)p;
// make sure this is a SVCID_INET_HOSTADDRBYNAME
cSize = sizeof(BLOB);
cBuf += cSize;
if (cBuf <= *pcBuf) {
p += cSize;
pBlob->pBlobData = p;
ASSERT(!((DWORD)p & 0x3));
}
Err = CopyHostentToBlob(pHost, p, *pcBuf - cBuf,
&cSize);
if (! Err) {
PointerToOffset((HOSTENT*)p);
pBlob->cbSize = cSize;
cSize = (cSize + 3) & ~3;
p += cSize;
cBuf += cSize;
} else {
cSize = (cSize + 3) & ~3;
cBuf += cSize;
}
ASSERT(!((DWORD)p & 0x3));
}
if ((LUP_RETURN_NAME & pQuery->ControlFlags) &&
! fLocalLookup) {
cName = strlen(pHost->h_name) + 1;
cSize = cName << 1;
cSize = (cSize + 3) & (~3);
cBuf += cSize;
if (cBuf <= *pcBuf) {
QuerySet.lpszServiceInstanceName = (WCHAR *)p;
MultiByteToWideChar(CP_ACP, 0, pHost->h_name, -1, (WCHAR *)p, cName);
p += cSize;
ASSERT(!((DWORD)p & 0x3));
}
}
if (cBuf > *pcBuf) {
Err = WSAEFAULT;
*pcBuf = cBuf;
} else
memcpy(pResults, &QuerySet, sizeof(QuerySet));
} else // if (AFDGetHostentByAttr...)
Err = GetLastError();
LocalFree(pThread);
} else
Err = WSA_NOT_ENOUGH_MEMORY;
}
Done:
EnterCriticalSection(&v_NspmCS);
ppQuery = _FindQuery(hLookup);
ASSERT(pQuery == *ppQuery);
if (pQuery = *ppQuery) {
if (--(pQuery->cRefs)) {
if (! Err)
pQuery->Flags |= DONE_LOOKUP;
} else {
ASSERT(pQuery->Flags & DNS_F_END_CALLED);
// no one is using him, so remove him
*ppQuery = pQuery->pNext;
LocalFree(pQuery);
}
} else {
RETAILMSG(1, (TEXT("NSPLookupServiceNext: pQuery dissappeared\r\n")));
}
LeaveCriticalSection(&v_NspmCS);
} else // if (pQuery)
Err = WSA_INVALID_HANDLE;
}
if (Err) {
SetLastError(Err);
Err = SOCKET_ERROR;
}
return Err;
} // NSPLookupServiceNext()
INT WSAAPI NSPLookupServiceEnd(
HANDLE hLookup) {
QueryContext **ppQuery, *pQuery;
int Err = 0;
EnterCriticalSection(&v_NspmCS);
ppQuery = _FindQuery(hLookup);
if (pQuery = *ppQuery) {
if (--(pQuery->cRefs)) {
pQuery->Flags |= DNS_F_END_CALLED;
pQuery = NULL;
} else {
// no one is using him, so remove him
*ppQuery = pQuery->pNext;
}
} else
Err = WSA_INVALID_HANDLE;
LeaveCriticalSection(&v_NspmCS);
if (pQuery)
LocalFree(pQuery);
if (Err) {
SetLastError(Err);
Err = SOCKET_ERROR;
}
return Err;
} // NSPLookupServiceNext()
INT WSAAPI NSPSetService(
LPGUID lpProviderId,
LPWSASERVICECLASSINFOW lpServiceClassInfo,
LPWSAQUERYSETW lpqsRegInfo,
WSAESETSERVICEOP essOperation,
DWORD dwControlFlags) {
// this operation is not supported for DNS
// too bad the spec doesn't really say which error code to return
SetLastError(WSAEOPNOTSUPP);
return SOCKET_ERROR;
} // NSPSetService()
INT WSAAPI NSPInstallServiceClass(
LPGUID pProviderId,
LPWSASERVICECLASSINFOW pServiceClass) {
HKEY hKey, hServiceKey;
LPWSANSCLASSINFOW pClassInfo;
int Err, i;
DWORD dwDisposition;
Err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, NSP_SERVICE_KEY_NAME, 0,
NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL,
&hKey, &dwDisposition );
if (! Err) {
hServiceKey = NULL;
__try {
Err = RegCreateKeyEx(hKey, pServiceClass->lpszServiceClassName,
0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
NULL, &hServiceKey, &dwDisposition);
if (! Err) {
Err = RegSetValueEx(hServiceKey, TEXT("GUID"), 0, REG_BINARY,
(BYTE *)pServiceClass->lpServiceClassId,
sizeof(GUID));
if (! Err) {
pClassInfo = pServiceClass->lpClassInfos;
for (i = pServiceClass->dwCount; i && ! Err; i--) {
if (NS_DNS == pClassInfo->dwNameSpace) {
Err = RegSetValueEx(hServiceKey,
pClassInfo->lpszName, 0,
pClassInfo->dwValueType,
(BYTE *)pClassInfo->lpValue,
pClassInfo->dwValueSize);
}
pClassInfo++;
} // for (i && ! Err)
}
RegCloseKey(hServiceKey);
}
} // __try
__except (EXCEPTION_EXECUTE_HANDLER) {
Err = WSAEFAULT;
if (NULL != hServiceKey)
RegCloseKey(hServiceKey);
ASSERT(0);
}
RegCloseKey(hKey);
}
if (Err) {
SetLastError(Err);
Err = SOCKET_ERROR;
}
return Err;
} // NSPInstallServiceClass()
INT WSAAPI NSPRemoveServiceClass(
LPGUID lpProviderId,
LPGUID lpServiceClassId) {
// NT doesn't implement this though they do implement install
SetLastError(WSAEOPNOTSUPP);
return SOCKET_ERROR;
} // NSPRemoveServiceClass()
INT WSAAPI NSPGetServiceClassInfo(
LPGUID lpProviderId,
LPDWORD lpdwBufSize,
LPWSASERVICECLASSINFOW lpServiceClass) {
// this operation is not supported for DNS
// too bad the spec doesn't really say which error code to return
SetLastError(WSAEOPNOTSUPP);
return SOCKET_ERROR;
} // NSPGetServiceClassInfo()
INT WSAAPI NSPIoctl(
HANDLE hLookup,
DWORD dwControlCode,
LPVOID lpvInBuffer,
DWORD cbInBuffer,
LPVOID lpvOutBuffer,
DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPWSACOMPLETION lpCompletion,
LPWSATHREADID lpThreadId) {
// unspeced function...
SetLastError(WSAEOPNOTSUPP);
return SOCKET_ERROR;
} // NSPIoctl()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -