📄 sdpcommon.cpp
字号:
UINT16 uuid16;
pSdpStream->RetrieveUint16(uuidRecord,&uuid16);
ulGUID = RtlUshortByteSwap(uuid16);
}
break;
default:
assert(0);
}
// The GUIDs we know about fall into a well known ranges.
// First check if it's a Protocol UUID
if (((ulGUID >= MIN_PROTOCOL_UUID16) && (ulGUID <= MAX_PROTOCOL_UUID16)) || (ulGUID == L2CAP_PROTOCOL_UUID16))
return ulGUID;
// Otherwise check the service classes.
switch (ulGUID) {
case ServiceDiscoveryServerServiceClassID_UUID16:
case BrowseGroupDescriptorServiceClassID_UUID16:
case PublicBrowseGroupServiceClassID_UUID16:
case SerialPortServiceClassID_UUID16:
case LANAccessUsingPPPServiceClassID_UUID16:
case DialupNetworkingServiceClassID_UUID16:
case IrMCSyncServiceClassID_UUID16:
case OBEXObjectPushServiceClassID_UUID16:
case OBEXFileTransferServiceClassID_UUID16:
case IrMcSyncCommandServiceClassID_UUID16:
case HeadsetServiceClassID_UUID16:
case CordlessServiceClassID_UUID16:
case IntercomServiceClassID_UUID16:
case FaxServiceClassID_UUID16:
case HeadsetAudioGatewayServiceClassID_UUID16:
case PnPInformationServiceClassID_UUID16:
case GenericNetworkingServiceClassID_UUID16:
case GenericFileTransferServiceClassID_UUID16:
case GenericAudioServiceClassID_UUID16:
case GenericTelephonyServiceClassID_UUID16:
return ulGUID;
break;
default:
break;
}
return 0;
}
#define SDP_PRINT_FLAG_INDEX 0x00000001
#define SDP_PRINT_FLAG_INDENT 0x00000002
void SdpPrintUUID(SDP_SPECIFICTYPE specType, ISdpStream *pSdpStream, PUCHAR uuidRecord, int iIndex, PFN_SDPPRINT pfnPrint, PVOID pvContext, DWORD dwFlags=(SDP_PRINT_FLAG_INDEX|SDP_PRINT_FLAG_INDENT)) {
ULONG ulGUID = FindUUIDType(specType,pSdpStream,uuidRecord);
const WCHAR *szName = GetUUIDString(ulGUID);
WCHAR szBuf[MAX_PATH];
int iOffset = 0;
if (dwFlags & SDP_PRINT_FLAG_INDENT) {
wcscpy(szBuf,L" ");
iOffset += 2;
}
if (dwFlags & SDP_PRINT_FLAG_INDEX) {
iOffset += wsprintf(szBuf+iOffset,L"Entry(%d) ",iIndex);
}
switch (specType) {
case SDP_ST_UUID128:
{
GUID uuid;
pSdpStream->RetrieveUuid128(uuidRecord,&uuid);
SdpByteSwapUuid128(&uuid,&uuid);
iOffset += wsprintf(szBuf+iOffset,L"UUID128 = " SVSUTIL_GUID_FORMAT_W L" (%s)\n",SVSUTIL_RGUID_ELEMENTS(uuid),szName);
}
break;
case SDP_ST_UUID32:
{
ULONG uuid;
pSdpStream->RetrieveUint32(uuidRecord,&uuid);
uuid = RtlUlongByteSwap(uuid);
iOffset += wsprintf(szBuf+iOffset,L"UUID32 = 0x%08x (%s)\n",uuid,szName);
}
break;
case SDP_ST_UUID16:
{
UINT16 uuid;
pSdpStream->RetrieveUint16(uuidRecord,&uuid);
uuid = RtlUshortByteSwap(uuid);
iOffset += wsprintf(szBuf+iOffset,L"UUID16 = 0x%04x (%s)\n",uuid,szName);
}
break;
default:
assert(0);
}
pfnPrint(pvContext,FALSE,szBuf);
}
void SdpPrintString(PUCHAR pStream, ULONG recordSize, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
WCHAR *psz = NULL;
int iOutLen = MultiByteToWideChar(CP_ACP, 0, (PCSTR)pStream, recordSize, 0, 0);
if(!iOutLen) {
pfnPrint(pvContext,TRUE,L"Cannot convert string\n");
return;
}
if (NULL == (psz = (WCHAR*) LocalAlloc(LMEM_FIXED,(iOutLen+1)*sizeof(WCHAR)))) {
pfnPrint(pvContext,TRUE,L"Out of memory\n");
return;
}
MultiByteToWideChar(CP_ACP, 0, (PCSTR)pStream, recordSize, psz, iOutLen);
psz[iOutLen] = 0;
pfnPrint(pvContext,FALSE,L"%s\n",psz);
LocalFree(psz);
}
class SdpBufferWrite {
public:
WCHAR *szBuf;
int iOffset;
SdpBufferWrite(WCHAR *sz, int i) {
szBuf = sz;
iOffset = i;
}
};
void SdpPrintToBuf(PVOID pvContext, BOOL fError, WCHAR *wszFormat,...) {
SdpBufferWrite *pBuf = (SdpBufferWrite*) pvContext;
int iOffset = pBuf->iOffset;
WCHAR *szBuf = pBuf->szBuf;
if (fError)
iOffset += wsprintf(szBuf + iOffset,L"Error: ");
va_list ap;
va_start(ap,wszFormat);
iOffset += vswprintf(szBuf + iOffset,wszFormat,ap);
va_end (ap);
pBuf->iOffset = iOffset;
}
// We don't have knowledge of a attribute, so print it out in a somewhat nice format.
void SdpPrintUnknownAttribute(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext, int iIndent) {
ISdpStream *pSdpStream = NULL;
SDP_TYPE type;
SDP_SPECIFICTYPE specType;
ULONG storageSize;
if (! LoadAndValidate(&pSdpStream,&pStream,&size,FALSE)) {
pfnPrint(pvContext,TRUE,L"Attribute Object misformatted\n");
goto done;
}
// NOTE: Most applications should use SDP Records or ISdpWalk when parsing
// SDP records. However some of these routines require that the data be a data
// element sequence or alternative, whereas this is designed for a general purpose
// parser that will print out *anything*.
while (size) {
PUCHAR pSubElement = pStream;
ULONG recordSize = 0;
WCHAR szBuf[1000];
int iOffset = 0;
pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&pSubElement);
if (type == SDP_TYPE_SEQUENCE || type == SDP_TYPE_ALTERNATIVE) {
// go recursive to handle this.
for (int i = 0; i < iIndent; i++)
iOffset += wsprintf(szBuf+iOffset,L" ");
iOffset += wsprintf(szBuf+iOffset,L"%s\n",(type == SDP_TYPE_SEQUENCE) ? L"SEQUENCE" : L"ALTERNATIVE");
pfnPrint(pvContext,FALSE,szBuf);
SdpPrintUnknownAttribute(pSubElement,recordSize,pfnPrint,pvContext,iIndent+1);
iOffset = 0;
for (i = 0; i < iIndent; i++)
iOffset += wsprintf(szBuf+iOffset,L" ");
iOffset += wsprintf(szBuf+iOffset,L"END SEQUENCE\n");
}
else {
for (int i = 0; i < iIndent; i++)
iOffset += wsprintf(szBuf+iOffset,L" ");
switch (type) {
case SDP_TYPE_NIL:
iOffset += wsprintf(szBuf+iOffset,L"NIL\n");
break;
case SDP_TYPE_UINT:
iOffset += wsprintf(szBuf+iOffset,L"UINT");
if (specType == SDP_ST_UINT8) {
iOffset += wsprintf(szBuf+iOffset,L"8: 0x%02x\n",*pSubElement);
}
else if (specType == SDP_ST_UINT16) {
USHORT us;
pSdpStream->RetrieveUint16(pSubElement,&us);
iOffset += wsprintf(szBuf+iOffset,L"16: 0x%04x\n",RtlUshortByteSwap(us));
}
else if (specType == SDP_ST_UINT32) {
ULONG ul;
pSdpStream->RetrieveUint32(pSubElement,&ul);
iOffset += wsprintf(szBuf+iOffset,L"32: 0x%08x\n",RtlUlongByteSwap(ul));
}
else if (specType == SDP_ST_UINT64) {
ULONGLONG ull;
pSdpStream->RetrieveUint64(pSubElement,&ull);
ull = RtlByteSwap64(ull);
iOffset += wsprintf(szBuf+iOffset,L"64: 0x%I64x\n",ull);
}
else if (specType == SDP_ST_UINT128) {
SDP_ULARGE_INTEGER_16 ull;
pSdpStream->RetrieveUint128(pSubElement,&ull);
ull.LowPart = RtlByteSwap64(ull.LowPart);
ull.HighPart = RtlByteSwap64(ull.HighPart);
iOffset += wsprintf(szBuf+iOffset,L"128 0x%I64x,0x%I64x\n",ull.HighPart,ull.LowPart);
}
break;
case SDP_TYPE_INT:
iOffset += wsprintf(szBuf+iOffset,L"INT: ");
if (specType == SDP_ST_INT8) {
iOffset += wsprintf(szBuf+iOffset,L"8: 0x%02x\n",*pSubElement);
}
else if (specType == SDP_ST_INT16) {
SHORT s;
pSdpStream->RetrieveInt16(pSubElement,&s);
iOffset += wsprintf(szBuf+iOffset,L"16: 0x%04x\n",s);
}
else if (specType == SDP_ST_INT32) {
LONG l;
pSdpStream->RetrieveInt32(pSubElement,&l);
iOffset += wsprintf(szBuf+iOffset,L"32: 0x%08x\n",RtlUlongByteSwap(l));
}
else if (specType == SDP_ST_INT64) {
LONGLONG ll;
pSdpStream->RetrieveInt64(pSubElement,&ll);
ll = RtlByteSwap64(ll);
iOffset += wsprintf(szBuf+iOffset,L"64: 0x%I64x\n",ll);
}
else if (specType == SDP_ST_INT128) {
SDP_LARGE_INTEGER_16 ll;
pSdpStream->RetrieveInt128(pSubElement,&ll);
ll.LowPart = RtlByteSwap64(ll.LowPart);
ll.HighPart = RtlByteSwap64(ll.HighPart);
iOffset += wsprintf(szBuf+iOffset,L"128 0x%I64x,0x%I64x\n",ll.HighPart,ll.LowPart);
}
break;
case SDP_TYPE_UUID:
{
SdpBufferWrite bufW(szBuf,iOffset);
SdpPrintUUID(specType,pSdpStream,pSubElement,iIndent,SdpPrintToBuf,&bufW,0);
}
break;
case SDP_TYPE_BOOLEAN:
iOffset += wsprintf(szBuf+iOffset,L"BOOL: %s\n",(*pSubElement) ? L"TRUE" : L"FALSE");
break;
case SDP_TYPE_STRING:
{
iOffset += wsprintf(szBuf+iOffset,L"STRING: ");
SdpBufferWrite bufW(szBuf,iOffset);
SdpPrintString(pSubElement,recordSize,SdpPrintToBuf,&bufW);
}
break;
case SDP_TYPE_URL:
{
iOffset += wsprintf(szBuf+iOffset,L"URL: ");
SdpBufferWrite bufW(szBuf,iOffset);
SdpPrintString(pSubElement,recordSize,SdpPrintToBuf,&bufW);
}
break;
default:
assert(0); // Validating code should catch unknown elements.
break;
}
}
pfnPrint(pvContext,FALSE,szBuf);
recordSize += 1 + storageSize;
pStream += recordSize;
size -= recordSize;
}
done:
if (pSdpStream)
FreeSdpStream(pSdpStream);
}
// Stream is a data element sequence containing a list of UUIDs.
void SdpPrintAttribUUIDs(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
ISdpStream *pSdpStream = NULL;
int iIndex = 0;
SDP_TYPE type;
SDP_SPECIFICTYPE specType;
ULONG storageSize;
if (! LoadAndValidate(&pSdpStream,&pStream,&size,TRUE)) {
pfnPrint(pvContext,TRUE,L"Attribute Object misformatted\n");
goto done;
}
while (size) {
PUCHAR uuidRecord = pStream;
ULONG recordSize = 0;
pSdpStream->RetrieveElementInfo(pStream,&type,&specType,&recordSize,&storageSize,&uuidRecord);
if (type != SDP_TYPE_UUID) {
pfnPrint(pvContext,TRUE,L"UUID stream invalid, element (%d) is not a UUID\n",iIndex);
goto done;
}
SdpPrintUUID(specType,pSdpStream,uuidRecord,iIndex,pfnPrint,pvContext);
recordSize += 1 + storageSize;
pStream += recordSize;
size -= recordSize;
iIndex++;
}
done:
if (pSdpStream)
FreeSdpStream(pSdpStream);
}
void SdpPrintAttribRecordState(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
ISdpStream *pSdpStream = NULL;
int iIndex = 0;
ULONG recordState;
if (! LoadAndValidate(&pSdpStream,&pStream,&size,FALSE)) {
pfnPrint(pvContext,TRUE,L"Attribute Record misformatted\n");
goto done;
}
if ( ! GetIntFromStream(pSdpStream,pStream,size,&recordState)) {
pfnPrint(pvContext,TRUE,L" Element is not a UINT32\n");
goto done;
}
pfnPrint(pvContext,FALSE,L" Record State = 0x%08x\n",recordState);
done:
if (pSdpStream)
FreeSdpStream(pSdpStream);
}
void SdpPrintAttribServiceId(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 (type != SDP_TYPE_UUID) {
pfnPrint(pvContext,TRUE,L" Element is not a UUID\n");
goto done;
}
SdpPrintUUID(specType,pSdpStream,pStream,0,pfnPrint,pvContext,SDP_PRINT_FLAG_INDENT);
done:
if (pSdpStream)
FreeSdpStream(pSdpStream);
}
#define SDP_PROTOCOL_UNKNOWN 0
void SdpPrintAttribProtDescrList(UCHAR *pStream, ULONG size, PFN_SDPPRINT pfnPrint, PVOID pvContext) {
ISdpStream *pSdpStream = NULL;
SDP_TYPE type;
SDP_SPECIFICTYPE specType;
ULONG storageSize;
ULONG sdpProtocol;
if (! LoadAndValidate(&pSdpStream,&pStream,&size,TRUE)) {
pfnPrint(pvContext,TRUE,L"Attribute Object misformatted\n");
goto done;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -