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

📄 sdpns.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 4 页
字号:
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}

	if (!CheckQuerySet(pSet,BTHNS_SET_SERVICE,dwFlags,op))  {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsSetService: ERROR_INVALID_PARAMETER\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSAEINVAL);
		return SOCKET_ERROR;
	}

	PBTHNS_SETBLOB pSetBlob = (PBTHNS_SETBLOB) pSet->lpBlob->pBlobData;
	int iRet;

	// Since these BthNsHandles operate loBthNsHandley, they are blocking.
	if (op == RNRSERVICE_REGISTER)
		iRet = gpBthNS->sdp_if.sdp_AddRecord(gpBthNS->hSDP,pSetBlob->pRecord,pSetBlob->ulRecordLength,(HANDLE*)(pSetBlob->pRecordHandle));
	else {
		SVSUTIL_ASSERT(op == RNRSERVICE_DELETE);
		iRet = gpBthNS->sdp_if.sdp_RemoveRecord(gpBthNS->hSDP,(HANDLE)(*(pSetBlob->pRecordHandle)));
	}

	gpBthNS->Unlock();
	if (iRet != ERROR_SUCCESS) {
		iRet = MapErrorCodeToWinsockErr(iRet,TRUE);
		SetLastError(iRet);
		return SOCKET_ERROR;
	}
	
	return ERROR_SUCCESS;
}

//
// WSA Interface functions
//

#define MAX_SEARCH_HANDLES             0xFFFF
#define INQUIRY_GIAC_LAP               0x9e8b33  // unlimited inquiry access mode (GIAC)
#define INQUIRY_DURATION               0x08
#define INQUIRY_MAX_RESPONSES          0x20

int BthNsLookupServiceBegin(LPWSAQUERYSET pQuerySet, DWORD dwFlags, LPHANDLE lphLookup)   {
	int iRes = ERROR_INTERNAL_ERROR;
	unsigned short cid = 0;
	BthNsHandle *pBthNsHandle = NULL;
	
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BthNsLookupServiceBegin entered\r\n"));

	if (! gpBthNS) {
		IFDBG(DebugOut(DEBUG_ERROR, L"BthNsLookupServiceBegin:: WSASERVICE_NOT_FOUND\n"));
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}	

	gpBthNS->Lock();
	if (gpBthNS->eStage != Running) {
		IFDBG(DebugOut(DEBUG_ERROR, L"BthNsLookupServiceBegin:: WSASERVICE_NOT_FOUND\n"));
		gpBthNS->Unlock();
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}

	if (!CheckQuerySet(pQuerySet,BTHNS_LOOKUP_SERVICE_BEGIN,dwFlags) || !lphLookup)  {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceBegin: WSAEINVAL\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSAEINVAL);
		return SOCKET_ERROR;
	}

	if (NULL == (pBthNsHandle = AllocBthNsHandle(pQuerySet, dwFlags,&iRes)))   {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceBegin: ERROR_OUTOFMEMORY\r\n"));
		gpBthNS->Unlock();
		SetLastError(iRes);
		return SOCKET_ERROR;
	}

	if (dwFlags & LUP_CONTAINERS) {
		// device inquiry
		// If pInquiryBlob is NULL, then use default values.
		PBTHNS_INQUIRYBLOB pInquiryBlob = (PBTHNS_INQUIRYBLOB) ( pQuerySet->lpBlob ? pQuerySet->lpBlob->pBlobData : NULL);
		pBthNsHandle->LAP        = pInquiryBlob ? pInquiryBlob->LAP           : INQUIRY_GIAC_LAP;
		pBthNsHandle->cDuration  = pInquiryBlob ? pInquiryBlob->length        : INQUIRY_DURATION;

		// WinXP doesn't support pInquiryBlob->num_responses field.  To avoid
		// potential porting issues (i.e. an app on XP doesn't set this and on porting
		// it's a garbage value on CE) we ignore it.
	    // pBthNsHandle->cMaxResp   = pInquiryBlob ? pInquiryBlob->num_responses : INQUIRY_MAX_RESPONSES;
		pBthNsHandle->cMaxResp   = INQUIRY_MAX_RESPONSES;
		pBthNsHandle->fInquiryStatus = INQUIRY_PENDING;
	}
	gpBthNS->Unlock();

	*lphLookup = (HANDLE) pBthNsHandle;

	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BthNsLookupServiceBegin returns ERROR_SUCCESS\r\n"));
	return ERROR_SUCCESS;
}

int PerformInquiry (BthNsHandle *pBthNsHandle) {
	unsigned long LAP = pBthNsHandle->LAP;
	unsigned int cMaxResp = pBthNsHandle->cMaxResp;
	unsigned int cDuration = pBthNsHandle->cDuration;
	unsigned int cDevices = 0;

	BthInquiryResult *pInquiryResults = (BthInquiryResult *) g_funcAlloc(cMaxResp*sizeof(BthInquiryResult),g_pvAllocData);

	if (!pInquiryResults) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceBegin: ERROR_OUTOFMEMORY\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSA_NOT_ENOUGH_MEMORY);
		return SOCKET_ERROR;
	}

	memset(pInquiryResults,0,cMaxResp*sizeof(BthInquiryResult));

	pBthNsHandle->fInquiryStatus = INQUIRY_INPROGRESS;

	gpBthNS->AddRef();
	gpBthNS->Unlock();

	int iResult = BthPerformInquiry(LAP,cDuration,0,
		                            cMaxResp,&cDevices,pInquiryResults);

	gpBthNS->Lock();
	gpBthNS->DelRef();

	if (! FindBthNsHandle(pBthNsHandle)) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceBegin: handle (0x%08x) invalid after BthPerformInquiry()\r\n",pBthNsHandle));
		g_funcFree(pInquiryResults,g_pvAllocData);
		gpBthNS->Unlock();
		SetLastError(WSA_E_CANCELLED);
		return SOCKET_ERROR;
	}

	pBthNsHandle->fInquiryStatus = INQUIRY_COMPLETED;

	if ((ERROR_SUCCESS != iResult)) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceBegin: BthPerformInquiry returns 0x%08x\r\n",iResult));
		g_funcFree(pInquiryResults,g_pvAllocData);
		gpBthNS->Unlock();
		SetLastError(WSAENETDOWN);
		return SOCKET_ERROR;
	}

	SVSUTIL_ASSERT(cDevices <= cMaxResp);

	if (cDevices > cMaxResp)
		cDevices = cMaxResp;

	pBthNsHandle->cDevices        = cDevices;
	pBthNsHandle->pInquiryResults = pInquiryResults;

	return ERROR_SUCCESS;
}

// supported Contairer flags for dwFlags param in BthNsLookupServiceNext
#define BTHNS_LOOKUP_SERVICE_NEXT_CONTAINER_FLAGS     (LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RETURN_BLOB | BTHNS_LUP_RESET_ITERATOR | BTHNS_LUP_NO_ADVANCE)

int BthNsLookupServiceNext(HANDLE hLookup, DWORD dwFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSET pResults) {
	int                   iRes = ERROR_INTERNAL_ERROR;
	unsigned short        cid  = 0;
	BOOL                  fLocal;
	DWORD                 cbRequired  = 0;
	PBTHNS_RESTRICTIONBLOB  pResBlob    = NULL;
	ULONG                 type;
	BOOL                  fDisconnect = FALSE;
	Call                  *pCall      = NULL;

	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BthNsLookupServiceNext entered\r\n"));

	if (!lpdwBufferLength)  {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: params misformatted, ERROR_INVALID_PARAMETER\r\n"));
		SetLastError(WSAEINVAL);
		return SOCKET_ERROR;
	}

	if (!gpBthNS) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext:: ERROR_SERVICE_DOES_NOT_EXIST\r\n"));
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}
	gpBthNS->Lock();

	if (gpBthNS->eStage != Running) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext:: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}

	BthNsHandle *pBthNsHandle = FindBthNsHandle((BthNsHandle *) hLookup);
	if (!pBthNsHandle) { 
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsSetService: BthNsHandle not found, ERROR_INVALID_PARAMETER\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSA_INVALID_HANDLE);
		return SOCKET_ERROR;
	}

	//
	// Device Inquiry
	//
	if (pBthNsHandle->dwFlags & LUP_CONTAINERS) {
		if (pBthNsHandle->fInquiryStatus == INQUIRY_PENDING) {
			if (PerformInquiry (pBthNsHandle) == SOCKET_ERROR)	// If error, it unlocks
				return SOCKET_ERROR;
		}

		if (! __SDP_IS_ALIGNED(pResults, 8))
			DebugOut(DEBUG_SDP_TRACE, L"SDP: Unaligned remote address in structure - FIX THE APP!\n");

		if (dwFlags & ~(BTHNS_LOOKUP_SERVICE_NEXT_CONTAINER_FLAGS)) {
			IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext flags are invalid (=0x%08x)",dwFlags));
			gpBthNS->Unlock();
			SetLastError(WSAEFAULT);
			return SOCKET_ERROR;
		}

		// WinCE allows iterator list to be reset, allowing list to be traveresed again.
		if (dwFlags & BTHNS_LUP_RESET_ITERATOR) {
			pBthNsHandle->iDeviceIterator = 0;
			gpBthNS->Unlock();
			return ERROR_SUCCESS;
		}

		if (pBthNsHandle->iDeviceIterator >= pBthNsHandle->cDevices) {
			gpBthNS->Unlock();
			SetLastError(WSA_E_NO_MORE); 
			return SOCKET_ERROR;
		}

		cbRequired = sizeof(WSAQUERYSET);

		if (dwFlags & LUP_RETURN_NAME)
			cbRequired += BD_MAXNAME * sizeof(WCHAR);

		if (dwFlags & LUP_RETURN_ADDR) {
			cbRequired = __SDP_ALIGN(cbRequired, 4);
			cbRequired = __SDP_ALIGN((cbRequired + sizeof(CSADDR_INFO)), 8) + 2 * sizeof(SOCKADDR_BTH);
		}

		// Note: WinCE returns a different data structure on this call than NT, by design.
		if (dwFlags & LUP_RETURN_BLOB) {
			cbRequired = __SDP_ALIGN(cbRequired, 4);
			cbRequired = __SDP_ALIGN((cbRequired + sizeof(LPBLOB)), 8) + sizeof(BthInquiryResult);
		}

		if (cbRequired > *lpdwBufferLength) {
			IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BthNsLookupServiceNext: %d bytes passed in, %d required\r\n",*lpdwBufferLength,cbRequired));
			*lpdwBufferLength = cbRequired;
			gpBthNS->Unlock();
			SetLastError(WSA_NOT_ENOUGH_MEMORY);
			return SOCKET_ERROR;
		}

		if (!pResults) {
			IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: params misformatted, ERROR_INVALID_PARAMETER\r\n"));
			gpBthNS->Unlock();
			SetLastError(WSAEINVAL);
			return SOCKET_ERROR;
		}

		__try {
			CHAR *pBase = (CHAR*)pResults;
			unsigned int uiOffsetCounter = sizeof(WSAQUERYSET);

			memset(pResults,0,sizeof(*pResults));
			pResults->dwSize = sizeof(WSAQUERYSETW);
			pResults->lpServiceClassId = 0;
			pResults->dwNameSpace = NS_BTH;

			if (dwFlags & LUP_RETURN_NAME) {
				// we don't query for names in WSALookupBegin, so we need to do it here.
				BT_ADDR ba = pBthNsHandle->pInquiryResults[pBthNsHandle->iDeviceIterator].ba;
				unsigned int cbReceived = 0;
				WCHAR   wszDeviceName[BD_MAXNAME];

				memset (wszDeviceName, 0, sizeof(wszDeviceName));

				gpBthNS->AddRef();
				gpBthNS->Unlock();

				iRes = BthRemoteNameQuery(&ba, SVSUTIL_ARRLEN(wszDeviceName), &cbReceived, wszDeviceName);

				gpBthNS->Lock();
				gpBthNS->DelRef();

				if (! FindBthNsHandle((BthNsHandle *) hLookup)) {
					IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: handle (0x%08x) invalid after BthRemoteNameQuery()\r\n",hLookup));
					gpBthNS->Unlock();
					SetLastError(WSA_E_CANCELLED);
					return SOCKET_ERROR;
				}

				// in the event of error, don't fail, just leave field NULL.
				if (iRes == ERROR_SUCCESS) {
					pResults->lpszServiceInstanceName = (WCHAR *)(pBase + uiOffsetCounter);
					wcsncpy (pResults->lpszServiceInstanceName, wszDeviceName, BD_MAXNAME);
				}
				uiOffsetCounter += BD_MAXNAME * sizeof(WCHAR);
			}

			if (dwFlags & LUP_RETURN_ADDR) {
				int uiOffsetCounterStart = uiOffsetCounter = __SDP_ALIGN(uiOffsetCounter, 4);

				PCSADDR_INFO pAddrInfo = (PCSADDR_INFO)(pBase + uiOffsetCounter);

				pResults->lpcsaBuffer = pAddrInfo;
				pResults->dwNumberOfCsAddrs = 1;

				uiOffsetCounter = __SDP_ALIGN(uiOffsetCounter + sizeof(CSADDR_INFO), 8);

				PSOCKADDR_BTH pLocal = (PSOCKADDR_BTH)(pBase + uiOffsetCounter);
				PSOCKADDR_BTH pRemote = pLocal + 1;

				uiOffsetCounter += 2 * sizeof(SOCKADDR_BTH);
				memset (pBase + uiOffsetCounterStart, 0, uiOffsetCounter - uiOffsetCounterStart);

				pAddrInfo->iSocketType = SOCK_STREAM;
				pAddrInfo->LocalAddr.lpSockaddr = (PSOCKADDR)pLocal;
				pAddrInfo->LocalAddr.iSockaddrLength = sizeof(*pLocal);
				pLocal->addressFamily = AF_BT;

				BthReadLocalAddr (&pLocal->btAddr);

				pAddrInfo->RemoteAddr.lpSockaddr = (PSOCKADDR)pRemote;
				pAddrInfo->RemoteAddr.iSockaddrLength = sizeof(*pRemote);
				pRemote->addressFamily = AF_BT;
				memcpy(&pRemote->btAddr, &pBthNsHandle->pInquiryResults[pBthNsHandle->iDeviceIterator].ba, sizeof(BT_ADDR));
			}

			if (dwFlags & LUP_RETURN_BLOB) {
				uiOffsetCounter = __SDP_ALIGN(uiOffsetCounter, 4);

				pResults->lpBlob = (LPBLOB)(pBase + uiOffsetCounter);
				pResults->lpBlob->cbSize    = sizeof(BthInquiryResult);

				uiOffsetCounter = __SDP_ALIGN(uiOffsetCounter + sizeof(BLOB), 8);

				pResults->lpBlob->pBlobData = (PBYTE) (pBase + uiOffsetCounter);
				memcpy(pResults->lpBlob->pBlobData,(BthInquiryResult *)&pBthNsHandle->pInquiryResults[pBthNsHandle->iDeviceIterator],sizeof(BthInquiryResult));
				uiOffsetCounter += sizeof(BthInquiryResult);
			}

			SVSUTIL_ASSERT (uiOffsetCounter == cbRequired);
		} __except (1) {
			IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: Exception!\n"));
			gpBthNS->Unlock();
			return ERROR_INVALID_PARAMETER;
		}
		// CE offers the option of not advancing iterator, so app may query for
		// more detailed info on this BT addr if it so desires.
		if (! (dwFlags & BTHNS_LUP_NO_ADVANCE))
			pBthNsHandle->iDeviceIterator++;

		gpBthNS->Unlock();

		return ERROR_SUCCESS;
	}

	//
	// Service Search
	//
	if (pBthNsHandle->fNoMoreData) {
		IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: WSA_E_NO_MORE\r\n"));
		gpBthNS->Unlock();
		SetLastError(WSA_E_NO_MORE);
		return SOCKET_ERROR;
	}

	if (! pBthNsHandle->fNetSearchComplete) {
		fLocal = pBthNsHandle->fLocal;

		if (NULL == (pCall = AllocCall(pBthNsHandle))) {
			IFDBG(DebugOut(DEBUG_ERROR,L"BthNsLookupServiceNext: WSA_NOT_ENOUGH_MEMORY\r\n"));
			gpBthNS->Unlock();
			SetLastError(WSA_NOT_ENOUGH_MEMORY);
			return SOCKET_ERROR;
		}

		// Below this point we may have to disconnect, so goto done for common exit pt.
		if (!fLocal) {
			iRes = SDPConnectBlocking(pCall,&pBthNsHandle->b);
			SVSUTIL_ASSERT(gpBthNS->IsLocked());

			if (iRes != ERROR_SUCCESS) {
				iRes = WSASERVICE_NOT_FOUND;
				goto done;
			}
			if (NULL == (pCall = FindCall(pCall)) || (pCall->iResult != ERROR_SUCCESS))   {
				iRes = pCall ? WSASERVICE_NOT_FOUND : WSA_E_CANCELLED;
				goto done;
			}
			fDisconnect = TRUE;
			cid = pCall->cid;

			if (NULL == (pBthNsHandle = FindBthNsHandle(pBthNsHandle))) {
				iRes = WSA_E_CANCELLED;
				goto done;
			}
		}
		pResBlob = pBthNsHandle->pResBlob;

		// To determine which type of inquiery to perform, if we have pResBlob do
		// what's specifed there.  If we don't we use the GUID set in ServiceClassId on
		// BthNsLookupServiceBegin call.  On CE to keep bc we assume SDP_SERVICE_SEARCH_REQUEST,
		// however if we're in XP compat mode then we do a SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST
		// with all attributes.
		if (pResBlob)
			type = pResBlob->type;
		else if (pBthNsHandle->fXPCompatMode)
			type = SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST;
		else
			type = SDP_SERVICE_SEARCH_REQUEST;

		SVSUTIL_ASSERT( (fLocal && !cid) || (!fLocal && cid));

		// If no restrictions were set, use ServiceClassId to fill out a default 
		// restriction blob.
		SdpQueryUuid UUID[2];
		SdpQueryUuid *pUUIDs;

		SdpAttributeRange Range;
		SdpAttributeRange *pRange;
		int numAttributes;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -