📄 parseutil.cpp
字号:
}
return STATUS_INVALID_PARAMETER;
}
INC_STREAM(dataSize);
break;
case SDP_TYPE_URL:
case SDP_TYPE_STRING:
case SDP_TYPE_SEQUENCE:
case SDP_TYPE_ALTERNATIVE:
//
// valid indecies are 5, 6 ,7
//
// Retrieve the size, convert it to little endian, and then compute
// the total size for this element (amount of storage for the size
// + the size itself).
//
// Furthermore, make sure we have enough storage for the stored size.
//
switch (sizeIndex) {
case 5:
elementSize = ((ULONG) *Stream);
dataSize = 1 + elementSize;
break;
case 6:
if (Size < 2) {
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
RtlRetrieveUshort(&usVal, Stream);
elementSize = (ULONG) RtlUshortByteSwap(usVal);
dataSize = 2 + elementSize;
break;
case 7:
if (Size < 4) {
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
RtlRetrieveUlong(&ulVal, Stream);
elementSize = RtlUlongByteSwap(ulVal);
dataSize = 4 + elementSize;
break;
default:
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
//
// Finally, check to see if there is enough storage for the storage
// for the size + the actual amount of data.
//
if (dataSize > Size) {
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL) {
//
// Increment past the string / URL data
//
if (ARGUMENT_PRESENT(ExtraPool)) {
(*ExtraPool) += ROUND_SIZE(elementSize);
}
INC_STREAM(dataSize);
}
else {
//
// Validate the sequence / alternative list, increment only past
// the storage that holds the size
//
INC_STREAM((dataSize - elementSize));
}
break;
default:
// there is an error in the stream
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
}
return STATUS_SUCCESS;
}
ULONG ComputeNumberOfEntries(PUCHAR Stream, ULONG Size, UCHAR FullParse)
{
ULONG dataSize, elementSize, ulVal, numEntries = 0;
USHORT usVal;
UCHAR type, sizeIndex;
while (Size) {
SdpRetrieveHeader(Stream, type, sizeIndex);
INC_STREAM(1);
numEntries++;
switch (type) {
case SDP_TYPE_NIL:
break;
case SDP_TYPE_BOOLEAN:
INC_STREAM(1);
break;
case SDP_TYPE_UINT:
case SDP_TYPE_INT:
//
// valid size indicides are 0 - 4.
//
switch (sizeIndex) {
case 0: dataSize = 1; break;
case 1: dataSize = 2; break;
case 2: dataSize = 4; break;
case 3: dataSize = 8; break;
case 4: dataSize = 16; break;
}
INC_STREAM(dataSize);
break;
case SDP_TYPE_UUID:
//
// valid indecies are 1,2,4
//
switch (sizeIndex) {
case 1: dataSize = 2; break;
case 2: dataSize = 4; break;
case 4: dataSize = 16; break;
}
INC_STREAM(dataSize);
break;
case SDP_TYPE_URL:
case SDP_TYPE_STRING:
case SDP_TYPE_SEQUENCE:
case SDP_TYPE_ALTERNATIVE:
//
// valid indecies are 5, 6 ,7
//
// Retrieve the size, convert it to little endian, and then compute
// the total size for this element (amount of storage for the size
// + the size itself).
//
switch (sizeIndex) {
case 5:
elementSize = (ULONG) *Stream;
dataSize = 1 + elementSize;
break;
case 6:
RtlRetrieveUshort(&usVal, Stream);
elementSize = (ULONG) RtlUshortByteSwap(usVal);
dataSize = 2 + elementSize;
break;
case 7:
RtlRetrieveUlong(&ulVal, Stream);
elementSize = RtlUlongByteSwap(ulVal);
dataSize = 4 + elementSize;
}
if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL || !FullParse) {
//
// Increment past the string / URL data / container
// (if we are not fully parsing)
//
INC_STREAM(dataSize);
}
else {
//
// Validate the sequence / alternative list, increment only past
// the storage that holds the size
//
INC_STREAM((dataSize - elementSize));
}
break;
}
}
return numEntries;
}
SDP_ERROR MapNtStatusToSdpError(NTSTATUS Status)
{
switch (Status) {
case STATUS_INVALID_PARAMETER:
return SDP_ERROR_INVALID_REQUEST_SYNTAX;
case STATUS_INSUFFICIENT_RESOURCES:
return SDP_ERROR_INSUFFICIENT_RESOURCES;
default:
ASSERT(FALSE);
return SDP_ERROR_INVALID_REQUEST_SYNTAX;
}
}
VOID Sdp_InitializeListHead(PLIST_ENTRY ListHead)
{
InitializeListHead(ListHead);
}
UCHAR Sdp_IsListEmpty(PLIST_ENTRY ListHead)
{
return IsListEmpty(ListHead);
}
VOID Sdp_InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
{
InsertHeadList(ListHead, Entry);
}
VOID Sdp_InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
{
InsertTailList(ListHead, Entry);
}
VOID Sdp_InsertEntryList(PLIST_ENTRY Previous, PLIST_ENTRY Entry)
{
InsertEntryList(Previous, Entry);
}
PLIST_ENTRY Sdp_RemoveHeadList(PLIST_ENTRY ListHead)
{
return RemoveHeadList(ListHead);
}
VOID Sdp_RemoveEntryList(PLIST_ENTRY Entry)
{
RemoveEntryList(Entry);
}
struct VerifyRecord {
VerifyRecord() {
isAttribId = TRUE;
done = FALSE;
seenFirstElem = FALSE;
}
UCHAR seenFirstElem;
UCHAR isAttribId;
UCHAR done;
};
NTSTATUS
VerifyIsRecordWalk(
VerifyRecord *verify,
UCHAR DataType,
ULONG DataSize,
PVOID Data,
ULONG DataStorageSize
)
{
NTSTATUS status = STATUS_SUCCESS;
if (verify->done) {
//
// if we encounter any stream elements after we are done, than this is
// an invalid stream
//
return STATUS_INVALID_PARAMETER;
}
else if (verify->seenFirstElem == FALSE) {
if (DataType == SDP_TYPE_SEQUENCE) {
verify->seenFirstElem = TRUE;
}
else {
//
// first item in the list must be a sequence
//
status = STATUS_INVALID_PARAMETER;
}
}
else {
if (verify->isAttribId) {
if (DataType == SDP_TYPE_SEQUENCE && Data == NULL) {
//
// end of the sequence
//
verify->done = TRUE;
return STATUS_SUCCESS;
}
else if (DataType != SDP_TYPE_UINT && DataSize != sizeof(USHORT)) {
//
// not a attrib ID where we expect it, bad stream!
//
return STATUS_INVALID_PARAMETER;
}
}
else {
if (DataType == SDP_TYPE_SEQUENCE ||
DataType == SDP_TYPE_ALTERNATIVE) {
status = STATUS_REPARSE_POINT_NOT_RESOLVED;
}
}
verify->isAttribId = !verify->isAttribId;
}
return status;
}
NTSTATUS SdpIsStreamRecord(PUCHAR Stream, ULONG Size)
{
NTSTATUS status;
status = ValidateStream(Stream, Size, NULL, NULL, NULL);
if (!NT_SUCCESS(status)) {
return status;
}
VerifyRecord vr;
return SdpWalkStream(Stream,
Size,
(PSDP_STREAM_WALK_FUNC) VerifyIsRecordWalk,
&vr);
}
void SdpNormalizeUuid(PSDP_NODE pUuid, GUID* uuid)
{
if (pUuid->hdr.SpecificType == SDP_ST_UUID128) {
RtlCopyMemory(uuid, &pUuid->u.uuid128, sizeof(GUID));
}
else if (pUuid->hdr.SpecificType == SDP_ST_UUID32) {
RtlCopyMemory(uuid, &Bluetooth_Base_UUID, sizeof(GUID));
uuid->Data1 += pUuid->u.uuid32;
}
else {
RtlCopyMemory(uuid, &Bluetooth_Base_UUID, sizeof(GUID));
uuid->Data1 += pUuid->u.uuid16;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -