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

📄 rnr.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -