📄 rnr.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 **/
/*****************************************************************************/
/*
rnr.c
registration and name resolution winsock functions
FILE HISTORY:
OmarM 04-Oct-2000
*/
#include "winsock2p.h"
#include <cxport.h>
extern int v_fProcessDetached;
typedef struct NsProvider {
struct NsProvider *pNext;
int cRefs;
HINSTANCE hLibrary;
GUID Id;
NSP_ROUTINE ProcTable;
} NsProvider;
#define LOOKUP_SVC_BEGIN_FAILED 0x0001
#define LOOKUP_SVC_ERROR 0x0002
typedef struct LookupProvList {
struct LookupProvList *pNext;
NsProvider *pNsProv;
int Flags;
HANDLE hLookup;
} LookupProvList;
#define NAME_SPACE_ID_LEN 32
// this need to be the same as that define in pm namespc.c
typedef struct NameSpaces {
DWORD Flags; WSANAMESPACE_INFOW Info; // if not used remove--we may only need GUID
WCHAR LibPath[MAX_PATH];
WCHAR szId[NAME_SPACE_ID_LEN]; // if not used remove
} NameSpaces;
typedef struct NsLookup {
struct NsLookup *pNext;
LookupProvList *pNsProvList;
CTELock Lock;
int cRefs;
} NsLookup;
DEFINE_LOCK_STRUCTURE(s_NsProvListLock);
DEFINE_LOCK_STRUCTURE(s_NsLookupsLock);
NsProvider *s_pNsProviders;
NsLookup *s_pNsLookups;
NsProvider *FindNsProvider(GUID *pId) {
NsProvider *pNsProv;
for (pNsProv = s_pNsProviders; pNsProv; pNsProv = pNsProv->pNext)
if (0 == memcmp(&pNsProv->Id, pId, sizeof(GUID)))
break;
return pNsProv;
} // FindNsProvider()
void DeleteNsProvider(NsProvider *pNsProv) {
int Err;
ASSERT(0 == pNsProv->cRefs);
// this could supposedly fail...
if (! v_fProcessDetached) {
Err = pNsProv->ProcTable.NSPCleanup(&pNsProv->Id);
if (Err) {
Err = GetLastError();
}
ASSERT(NO_ERROR == Err);
}
if (pNsProv->hLibrary && (! v_fProcessDetached))
FreeLibrary(pNsProv->hLibrary);
LocalFree(pNsProv);
} // DeleteNsProvider()
void DerefNsProvider(NsProvider *pNsProv) {
int Err;
NsProvider **ppNsProv, *pCurProv;
CTEGetLock(&v_DllCS, 0);
if (v_fProcessDetached)
Err = WSAENETDOWN;
else
Err = Started();
CTEFreeLock(&v_DllCS, 0);
// for efficiency purposes we only unload the providers
// if we've been cleaned up.
pCurProv = NULL;
CTEGetLock(&s_NsProvListLock, 0);
if (0 == --(pNsProv->cRefs)) {
if (Err) {
// we're going away, so we need to get rid of the provider
ppNsProv = &s_pNsProviders;
while (pCurProv = *ppNsProv) {
if (pCurProv == pNsProv) {
break;
}
ppNsProv = &pCurProv->pNext;
} // while ()
ASSERT(pCurProv == pNsProv);
if (pCurProv) {
*ppNsProv = pCurProv->pNext;
// we'll delete below, now that it is out of the list
}
}
}
ASSERT(0 <= pNsProv->cRefs);
CTEFreeLock(&s_NsProvListLock, 0);
if (pCurProv == pNsProv) {
DeleteNsProvider(pNsProv);
}
} // DerefNsProvider()
void FreeNsProviders() {
NsProvider *pNsProv, **ppNsProv;
CTEGetLock(&s_NsProvListLock, 0);
ppNsProv = &s_pNsProviders;
while (pNsProv = *ppNsProv) {
if (pNsProv->cRefs) {
ppNsProv = &(pNsProv->pNext);
} else {
*ppNsProv = pNsProv->pNext;
CTEFreeLock(&s_NsProvListLock, 0);
DeleteNsProvider(pNsProv);
CTEGetLock(&s_NsProvListLock, 0);
}
}
CTEFreeLock(&s_NsProvListLock, 0);
} // FreeNsProviders()
int LoadNsProviders(NameSpaces *pNs, int cNs, NsLookup *pLookup) {
NsProvider *pNsProv;
int Err, i, cLoaded;
LPNSPSTARTUP pfnStartup;
LookupProvList *pLookupProvList, **ppProvList;
Err = cLoaded = 0;
// this is so that we query the providers in order
// so the pPrivNext of the lookup should be in the order that the
// providers were given to us by PM
ppProvList = &pLookup->pNsProvList;
CTEGetLock(&s_NsProvListLock, 0);
for (i = 0; i < cNs; i++, pNs++) {
if (pLookupProvList = LocalAlloc(LPTR, sizeof(*pLookupProvList))) {
if (pNsProv = FindNsProvider(&pNs->Info.NSProviderId)) {
pNsProv->cRefs++;
} else {
if (pNsProv = LocalAlloc(LPTR, sizeof(*pNsProv))) {
pNsProv->pNext = s_pNsProviders;
pNsProv->cRefs = 1;
pNsProv->Id = pNs->Info.NSProviderId;
pNsProv->ProcTable.cbSize = sizeof(pNsProv->ProcTable);
if (pNsProv->hLibrary = LoadLibrary(pNs->LibPath)) {
pfnStartup = (LPNSPSTARTUP)GetProcAddress(
pNsProv->hLibrary, TEXT("NSPStartup"));
if (!pfnStartup) {
Err = WSAEPROVIDERFAILEDINIT;
} else if (Err = (*pfnStartup)(&pNs->Info.NSProviderId,
&pNsProv->ProcTable)) {
CloseHandle(pNsProv->hLibrary);
pNsProv->hLibrary = NULL; // just to be safe
} else { // should we check version info here?
// Partial SUCCESS
s_pNsProviders = pNsProv;
Err = 0;
}
} else
Err = WSAEPROVIDERFAILEDINIT;
if (Err) {
LocalFree(pNsProv);
pNsProv = NULL;
}
} else {
Err = WSA_NOT_ENOUGH_MEMORY;
}
} // else FindNsProvider()
if (pNsProv) {
pLookupProvList->pNsProv = pNsProv;
*ppProvList = pLookupProvList;
ppProvList = &pLookupProvList->pNext;
cLoaded++;
} else {
// couldn't find a provider or provider failed
LocalFree(pLookupProvList);
}
} else { // if (pLookupProvList = LocalAlloc...)
Err = WSA_NOT_ENOUGH_MEMORY;
}
} // for (i < cNs)
CTEFreeLock(&s_NsProvListLock, 0);
return cLoaded;
} // LoadNsProviders()
int CallNsProviders(NsLookup *pNsLookup, WSAQUERYSETW *pRest,
WSASERVICECLASSINFOW *pSvcClass, DWORD Flags, WSAESETSERVICEOP essOperation, BOOL fWSSetServiceCaller) {
LookupProvList *pLkpProvList;
NsProvider *pNsProv;
int Err=0, cOK=0;
cOK = 0;
pLkpProvList = pNsLookup->pNsProvList;
while (pLkpProvList) {
pNsProv = pLkpProvList->pNsProv;
ASSERT(pNsProv);
if (fWSSetServiceCaller) {
// WSASetService
Err = pNsProv->ProcTable.NSPSetService(&pNsProv->Id, pSvcClass, pRest,
essOperation,Flags);
}
else {
// WSALookupServiceBegin
Err = pNsProv->ProcTable.NSPLookupServiceBegin(&pNsProv->Id, pRest,
pSvcClass, Flags, &pLkpProvList->hLookup);
if (Err)
pLkpProvList->Flags |= LOOKUP_SVC_BEGIN_FAILED;
else
cOK++;
}
pLkpProvList = pLkpProvList->pNext;
}
if (cOK)
Err = 0;
return Err;
} // CallNsProviders()
//
// Called from error paths in WSASetOrLookupBeginService
//
void FreeNsLookup(NsLookup * pLookup)
{
LookupProvList *pProvList;
LookupProvList *pProvList2;
pProvList = pLookup->pNsProvList;
while (pProvList) {
pProvList2 = pProvList;
DerefNsProvider(pProvList2->pNsProv);
pProvList = pProvList->pNext;
LocalFree(pProvList2);
}
LocalFree(pLookup);
}
// Since the code paths are nearly identical for WSASetService and WSALookupServiceBegin,
// have them go through one function.
INT WSAAPI WSASetOrLookupBeginService(
LPWSAQUERYSET pRestrictions,
WSAESETSERVICEOP essOperation,
DWORD dwControlFlags,
OUT LPHANDLE phLookup,
BOOL fWSSetServiceCaller) {
int Err, cNs, cLoaded, fNewBuf;
int cLen, cBuf;
NsLookup *pLookup;
NameSpaces *pNs;
pNs = NULL;
// check if we were successfully started up
CTEGetLock(&v_DllCS, 0);
if (!(Err = Started())) {
CTEFreeLock(&v_DllCS, 0);
if (pRestrictions && (fWSSetServiceCaller || phLookup)) {
// let us find the providers...
cBuf = sizeof(*pNs) * 10;
do {
fNewBuf = FALSE;
if (pNs = LocalAlloc(LPTR, cBuf)) {
cLen = cBuf;
cNs = PMFindNameSpaces(pRestrictions, pNs, &cLen, &Err);
if (SOCKET_ERROR == cNs &&
WSAEFAULT == Err && cLen > cBuf) {
LocalFree(pNs);
cBuf = cLen;
fNewBuf = TRUE;
Err = 0;
}
} else
Err = WSA_NOT_ENOUGH_MEMORY;
} while (fNewBuf);
} else {
Err = WSAEFAULT;
}
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -