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

📄 sdpcommon.cpp

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    while (size) {
		PUCHAR pElementInfo = NULL;
		ULONG recordSize = 0;
		BOOL  fFirstPass = TRUE;

		pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pElementInfo);

		if (type != SDP_TYPE_SEQUENCE) {
			pfnPrint(pvContext,TRUE,L"Protocol stream invalid, element is not a Data Element Sequence\n");
			goto done;
		}

		// Adjust the main traversal pointer
		ULONG fullRecordSize = recordSize + 1 + storageSize; 
		pStream += fullRecordSize;
		size -= fullRecordSize;

		sdpProtocol = SDP_PROTOCOL_UNKNOWN;

		// Walk through the given sequence.
		while (recordSize) {
			ULONG subRecordSize;
			PUCHAR pSubElementInfo = NULL;
			
			pSdpStream->RetrieveElementInfo(pElementInfo,&type,&specType,&subRecordSize,&storageSize,&pSubElementInfo);
			subRecordSize += 1 + storageSize;
			pElementInfo += subRecordSize;
			recordSize -= subRecordSize;

			if (sdpProtocol == SDP_PROTOCOL_UNKNOWN) {
				if (type != SDP_TYPE_UUID) {
					pfnPrint(pvContext,TRUE,L"    First element in sequence is not a protocol UUID, skipping parsing on current sequence\n");
					break;
				}

				SdpPrintUUID(specType,pSdpStream,pSubElementInfo,0,pfnPrint,pvContext,SDP_PRINT_FLAG_INDENT);

				ULONG ulGUID = FindUUIDType(specType, pSdpStream, pSubElementInfo);
				if ((ulGUID != L2CAP_PROTOCOL_UUID16) && (ulGUID != RFCOMM_PROTOCOL_UUID16) && 
				    (ulGUID != OBEX_PROTOCOL_UUID16)) {
					pfnPrint(pvContext,TRUE,L"    Do not know how to parse protocol UUID... skipping.\n");
					break;
				}

				sdpProtocol = ulGUID;
				continue;
			}

			if (sdpProtocol == L2CAP_PROTOCOL_UUID16) {
				if (fFirstPass) {
					if (specType != SDP_ST_UINT16) {
						pfnPrint(pvContext,TRUE,L"    L2CAP Channel ID type is not UINT16, skipping rest of processing of this entry.\n");
						break;
					}
					USHORT cid;

					pSdpStream->RetrieveUint16(pSubElementInfo,&cid);
					pfnPrint(pvContext,FALSE,L"    L2CAP Channel ID = 0x%04x\n",cid);
					fFirstPass = FALSE;
				}
				else {
					pfnPrint(pvContext,TRUE,L"    Do not know how to parse remainder of L2CAP information... skipping.\n");
					break;
				}

			}
			else if (sdpProtocol == RFCOMM_PROTOCOL_UUID16) {
				if (fFirstPass) {
					if (specType != SDP_ST_UINT8) {
						pfnPrint(pvContext,TRUE,L"    RFCOMM Channel ID type is not UINT8, skipping rest of processing of this entry.\n");
						break;
					}
					pfnPrint(pvContext,FALSE,L"    RFCOMM Channel ID = 0x%02x\n",*pSubElementInfo);
					fFirstPass = FALSE;
				}
				else {
					pfnPrint(pvContext,TRUE,L"    Do not know how to parse remainder of RFCOMM information... skipping.\n");
					break;
				}
			}
			else {
				assert(sdpProtocol == OBEX_PROTOCOL_UUID16);
				pfnPrint(pvContext,TRUE,L"    Do not know how to parse remainder of OBEX information... skipping.\n");
				break;
			}
		}
    }
done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}



// Language base is a data element containing one or more group of 3 UINT16's.
void SdpPrintAttribLanguageBase(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
	ISdpStream *pSdpStream = NULL;

	SDP_TYPE type;
	SDP_SPECIFICTYPE specType;
	ULONG storageSize;
	int   iIndex = 0;

	if (! LoadAndValidate(&pSdpStream,&pStream,&size,TRUE)) {
		pfnPrint(pvContext,TRUE,L"Attribute Object misformatted\n");
		goto done;
	}

	while (size) {
		USHORT rgusAttribs[3];
		ULONG recordSize = 0;
		UCHAR *pAttrib;

		for (DWORD i = 0; i < SVSUTIL_ARRLEN(rgusAttribs); i++) {
			if (FAILED(pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pAttrib) ||
			    (specType != SDP_ST_UINT16))) {
				PrintMisformatted(pfnPrint,pvContext);
				goto done;
			}

			pSdpStream->RetrieveUint16(pAttrib,&rgusAttribs[i]);

			recordSize += 1 + storageSize;
			pStream += recordSize;
			size -= recordSize;

			if (size == 0 && i != (SVSUTIL_ARRLEN(rgusAttribs)-1)) {
				PrintMisformatted(pfnPrint,pvContext);
				goto done;
			}
		}

		pfnPrint(pvContext,FALSE,L"  Entry(%d)\n",iIndex);
		pfnPrint(pvContext,FALSE,L"    Language           = 0x%04x\n",RtlUshortByteSwap(rgusAttribs[0]));
		pfnPrint(pvContext,FALSE,L"    Character Encoding = 0x%04x\n",RtlUshortByteSwap(rgusAttribs[1]));
		pfnPrint(pvContext,FALSE,L"    Base AttributeID   = 0x%04x\n",RtlUshortByteSwap(rgusAttribs[2]));
		iIndex++;
	}

done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}

void SdpPrintAttribServiceInfoTTL(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
	ISdpStream *pSdpStream = NULL;
	int iIndex = 0;

	ULONG infoTTL;

	if (! LoadAndValidate(&pSdpStream,&pStream,&size,FALSE)) {
		pfnPrint(pvContext,TRUE,L"Attribute Record misformatted\n");
		goto done;
	}

	if ( ! GetIntFromStream(pSdpStream,pStream,size,&infoTTL)) {
		pfnPrint(pvContext,TRUE,L"  Element is not a UINT32\n");
		goto done;
	}

	pfnPrint(pvContext,FALSE,L"  ServiceInfoTimeToLive = 0x%08x\n",infoTTL);
done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}

void SdpPrintAttribServiceAvailability(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
	SDP_TYPE type;
	SDP_SPECIFICTYPE specType = SDP_ST_NONE;
	ULONG storageSize;
	ULONG recordSize;

	ISdpStream *pSdpStream = NULL;

	if (! LoadAndValidate(&pSdpStream,&pStream,&size,FALSE)) {
		pfnPrint(pvContext,TRUE,L"Attribute Record misformatted\n");
		goto done;
	}

	pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pStream);
	if (specType != SDP_ST_UINT8) {
		pfnPrint(pvContext,TRUE,L"  Element is not a UINT8\n");
		goto done;
	}

	pfnPrint(pvContext,FALSE,L"  Service Availability = 0x%02x\n",*pStream);

done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}

void SdpPrintAttribBluetoothProfileDescriptorList(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
	ISdpStream *pSdpStream = NULL;

	SDP_TYPE type;
	SDP_SPECIFICTYPE specType;
	ULONG storageSize;
	ULONG sdpProtocol;
	int   iIndexNumber = 0;

	if (! LoadAndValidate(&pSdpStream,&pStream,&size,TRUE)) {
		pfnPrint(pvContext,TRUE,L"Attribute Object misformatted\n");
		goto done;
	}

	// The Profile descriptor list is a data element sequence containing 
	// one or more data element sequences containing information about a BT profile
	// supported by this record.  The first element of each list is a UUID specifying
	// the service, the second is a UINT16 representing the version #.

    while (size) {
		PUCHAR pElementInfo = NULL;
		ULONG recordSize = 0;
		BOOL  fFirstPass = TRUE;


		pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pElementInfo);

		if (type != SDP_TYPE_SEQUENCE) {
			pfnPrint(pvContext,TRUE,L"Protocol stream invalid, element is not a Data Element Sequence\n");
			goto done;
		}

		// Adjust the main traversal pointer
		ULONG fullRecordSize = recordSize + 1 + storageSize; 
		pStream += fullRecordSize;
		size -= fullRecordSize;

		sdpProtocol = SDP_PROTOCOL_UNKNOWN;

		pfnPrint(pvContext,FALSE,L"  Protocol Descriptor(%d)\n",iIndexNumber);

		// Walk through the given sequence.
		while (recordSize) {
			ULONG subRecordSize;
			PUCHAR pSubElementInfo = NULL;
			
			pSdpStream->RetrieveElementInfo(pElementInfo,&type,&specType,&subRecordSize,&storageSize,&pSubElementInfo);
			subRecordSize += 1 + storageSize;
			pElementInfo += subRecordSize;
			recordSize -= subRecordSize;

			if (fFirstPass) {
				if (type != SDP_TYPE_UUID) {
					pfnPrint(pvContext,TRUE,L"  First element is not a UUID, skipping this entry\n");
					break;
				}
				SdpPrintUUID(specType, pSdpStream, pSubElementInfo, 0, pfnPrint, pvContext,SDP_PRINT_FLAG_INDENT);
				fFirstPass = FALSE;
			}
			else {
				if (specType != SDP_ST_UINT16) {
					pfnPrint(pvContext,TRUE,L"  Second element is not a UINT16, skipping this entry\n");
					break;
				}
				USHORT usVersion;
				pSdpStream->RetrieveUint16(pSubElementInfo,&usVersion);
				usVersion = RtlUshortByteSwap(usVersion);

				pfnPrint(pvContext,FALSE,L"    Version = %d.%d\n",HIBYTE(usVersion),LOBYTE(usVersion));
			}
		}
		iIndexNumber++;
    }
done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}

void SdpPrintAttribURL(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) { 
	SDP_TYPE type;
	SDP_SPECIFICTYPE specType = SDP_ST_NONE;
	ULONG storageSize;
	ULONG recordSize;

	ISdpStream *pSdpStream = NULL;
	int iIndex = 0;

	if (! LoadAndValidate(&pSdpStream,&pStream,&size,FALSE)) {
		pfnPrint(pvContext,TRUE,L"Attribute Record misformatted\n");
		goto done;
	}

	pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pStream);
	if (type != SDP_TYPE_URL) {
		pfnPrint(pvContext,TRUE,L"  Element is not a URL\n");
		goto done;
	}

	pfnPrint(pvContext,FALSE,L"  URL=");
	SdpPrintString(pStream,recordSize,pfnPrint,pvContext);

done:
	if (pSdpStream)
		FreeSdpStream(pSdpStream);
}

static const PFN_SDPPRINT_ATTRIB g_PrintTable[] = {
	SdpPrintAttribRecordHandle,
	SdpPrintAttribUUIDs, // Class ID is a list of UUIDs
	SdpPrintAttribRecordState,
	SdpPrintAttribServiceId,
	SdpPrintAttribProtDescrList,
	SdpPrintAttribUUIDs, // Browse group list is a list of UUIDs
	SdpPrintAttribLanguageBase,
	SdpPrintAttribServiceInfoTTL,
	SdpPrintAttribServiceAvailability,
	SdpPrintAttribBluetoothProfileDescriptorList,
	SdpPrintAttribURL, // document URL is an URL
	SdpPrintAttribURL, // client exe URL is an URL
	SdpPrintAttribURL  // icon URL is an URL
};



void PrintRecordInfo(ISdpRecord *pRecord, int iRecordIndex, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
	USHORT *pAttributeList = NULL;
	ULONG  nAttributes;
	ULONG  i;

	pfnPrint(pvContext,FALSE,L"*** Record %d ***\n",iRecordIndex+1);

	if (FAILED(pRecord->GetAttributeList(&pAttributeList,&nAttributes))) {
		pfnPrint(pvContext,TRUE,L"Unable to retrieve attributes from record\n");
		goto done;
	}

	for (i = 0; i < nAttributes; i++) {
		USHORT usAttribId = pAttributeList[i];
		UCHAR  *pStream = NULL;
		ULONG  size;

		pfnPrint(pvContext,FALSE,L"AttribID 0x%04x (%s)\n",usAttribId,GetAttribFromID(usAttribId));
	
		if (FAILED(pRecord->GetAttributeAsStream(usAttribId,&pStream,&size))) {
			if (pStream)
				CoTaskMemFree(pStream);

			// since this is almost certainly an OOM or an internal error, no point continuing processing.
			pfnPrint(pvContext,TRUE,L"Unable to parse attribute stream for attribute id %d.  Stopping processing.\n",usAttribId);
			goto done;
		}
	
		if (usAttribId > SDP_ATTRIB_ICON_URL) {
			SdpPrintUnknownAttribute(pStream,size,pfnPrint,pvContext,1);
		}
		else {
			g_PrintTable[usAttribId](pStream,size,pfnPrint,pvContext);
		}

		CoTaskMemFree(pStream);
	}

done:
	if (pAttributeList)
		CoTaskMemFree(pAttributeList);
}

// Error code -> string lookup
static const WCHAR *g_szErrorCodes[] = {
      L"Invalid/unsupported SDP version",
      L"Invalid Service Record Handle",
      L"Invalid request syntax",
      L"Invalid PDU size",
      L"Invalid Continuation State",
      L"Insufficient Resources to satisfy request"
};
static const WCHAR cszUnknownErr[] = L"Unknown Error Code";

const WCHAR *GetErrorFromId(USHORT usErrCode) {
	if ((usErrCode >= SDP_ERROR_INVALID_SDP_VERSION) && (usErrCode <= SDP_ERROR_INSUFFICIENT_RESOURCES))
		return g_szErrorCodes[usErrCode-1];

	return cszUnknownErr;
}

// Protocol packet type -> string lookup
static const WCHAR *g_szPDUTypes[] = {
     L"Error PDU",
     L"Service Search Request PDU",
     L"Service Search Response PDU",
     L"Attribute Request PDU",
     L"Attribute Response PDU",
     L"Service Attribute Search Request PDU",
     L"Service Attribute Search Response PDU"
};
static const WCHAR cszUnknownPDU[] = L"Unknown PDU packet";

const WCHAR *GetPduNameFromId(UCHAR id) {
	if ((id >= 1) && (id <= SVSUTIL_ARRLEN(g_szPDUTypes))) // PDU Error to PDU Service Attribute Response
		return g_szPDUTypes[id-1];

	return cszUnknownPDU;
}

ISdpStream * AllocateSdpStream(void) {
	ISdpStream *pIStream = NULL;

	if (FAILED(CoCreateInstance(__uuidof(SdpStream),NULL,CLSCTX_INPROC_SERVER,
	                        __uuidof(ISdpStream),(LPVOID *) &pIStream))) {
		return NULL;
	}
	return pIStream;
}

void FreeSdpStream(ISdpStream *pStream) {
	pStream->Release();
}

⌨️ 快捷键说明

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