📄 parseutil.cpp
字号:
//
// 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.
//
#include "pch.h"
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
#include "bt_100.h"
#pragma code_seg("PAGE", "CODE")
#endif
void SdpByteSwapUuid128(GUID *uuid128From, GUID *uuid128To)
{
uuid128To->Data1 = RtlUlongByteSwap(uuid128From->Data1);
uuid128To->Data2 = RtlUshortByteSwap(uuid128From->Data2);
uuid128To->Data3 = RtlUshortByteSwap(uuid128From->Data3);
memcpy(uuid128To->Data4, uuid128From->Data4, sizeof(uuid128From->Data4));
}
void SdpByteSwapUint128(PSDP_ULARGE_INTEGER_16 pInUint128, PSDP_ULARGE_INTEGER_16 pOutUint128)
{
pOutUint128->HighPart = SdpUlonglongByteSwap(pInUint128->HighPart);
pOutUint128->LowPart = SdpUlonglongByteSwap(pInUint128->LowPart);
}
ULONGLONG SdpUlonglongByteSwap(IN ULONGLONG Source)
/*++
Routine Description:
The SdpUlonglongByteSwap function exchanges byte pairs 0:7, 1:6, 2:5, and
3:4 of Source and returns the resulting ULONGLONG.
We do not use RtlUlonglongByteSwap because on Windows 2000, only the first 4
bytes of the ULONGLONG are based in because of a linker issue
Arguments:
Source - 64-bit value to byteswap.
Return Value:
Swapped 64-bit value.
--*/
{
ULONGLONG swapped;
swapped = ((Source) << (8 * 7)) |
((Source & 0x000000000000FF00) << (8 * 5)) |
((Source & 0x0000000000FF0000) << (8 * 3)) |
((Source & 0x00000000FF000000) << (8 * 1)) |
((Source & 0x000000FF00000000) >> (8 * 1)) |
((Source & 0x0000FF0000000000) >> (8 * 3)) |
((Source & 0x00FF000000000000) >> (8 * 5)) |
((Source) >> (8 * 7));
return swapped;
}
ULONGLONG SdpByteSwapUint64(ULONGLONG uint64)
{
return SdpUlonglongByteSwap(uint64);
}
ULONG SdpByteSwapUint32(ULONG uint32)
{
return RtlUlongByteSwap(uint32);
}
USHORT SdpByteSwapUint16(USHORT uint16)
{
return RtlUshortByteSwap(uint16);
}
void SdpRetrieveUuid128(PUCHAR Stream, GUID *uuidVal)
{
PUCHAR tmpStream = Stream;
RtlRetrieveUlong(&uuidVal->Data1, tmpStream);
tmpStream = Stream + FIELD_OFFSET(GUID, Data2);
RtlRetrieveUshort(&uuidVal->Data2, tmpStream);
tmpStream = Stream + FIELD_OFFSET(GUID, Data3);
RtlRetrieveUshort(&uuidVal->Data3, tmpStream );
tmpStream = Stream + FIELD_OFFSET(GUID, Data4);
memcpy(uuidVal->Data4, tmpStream, sizeof(uuidVal->Data4));
}
void SdpRetrieveUint128(PUCHAR Stream, PSDP_ULARGE_INTEGER_16 pUint128)
{
PUCHAR tmpStream;
SdpRetrieveUlonglong(&pUint128->HighPart, Stream);
tmpStream = Stream + sizeof(pUint128->HighPart);
SdpRetrieveUlonglong(&pUint128->LowPart, tmpStream);
}
void SdpRetrieveUint64(PUCHAR Stream, PULONGLONG pUint64)
{
SdpRetrieveUlonglong(pUint64, Stream);
}
void SdpRetrieveUint32(PUCHAR Stream, PULONG pUint32)
{
RtlRetrieveUlong(pUint32, Stream);
}
void SdpRetrieveUint16(PUCHAR Stream, PUSHORT pUint16)
{
RtlRetrieveUshort(pUint16, Stream);
}
NTSTATUS ComputeNodeListSize(PSDP_NODE Node, PULONG Size)
{
SdpStack stack;
SD_STACK_ENTRY *stackEntry;
NTSTATUS status;
PLIST_ENTRY current;
PSDP_NODE node;
PSDP_NODE_HEADER header;
ULONG size = 0;
status = STATUS_SUCCESS;
current = &Node->hdr.Link;
while (1) {
node = CONTAINING_RECORD(current, SDP_NODE, hdr.Link);
// every node has a one byte header to describe it
size++;
switch (node->hdr.Type) {
case SDP_TYPE_NIL:
// nothing more to do, no storage required for nil
break;
case SDP_TYPE_BOOLEAN:
size++;
break;
case SDP_TYPE_UINT:
case SDP_TYPE_INT:
case SDP_TYPE_UUID:
// data immediately follows the header
size += node->DataSize;
break;
case SDP_TYPE_URL:
case SDP_TYPE_STRING:
// the length of the string (w/out a NULL)
size += node->DataSize;
// add on the storage for the length of the string
if (node->DataSize <= SIZE_8_BITS) {
size += sizeof(UCHAR);
}
else if (node->DataSize <= SIZE_16_BITS) {
size += sizeof(USHORT);
}
else {
size += sizeof(ULONG);
}
break;
case SDP_TYPE_SEQUENCE:
case SDP_TYPE_ALTERNATIVE:
// Assumes node->u.Sequence == node->u.Alternative
if (IsListEmpty(&node->u.sequence.Link)) {
// still need to store the length even if it is 0
size += sizeof(UCHAR);
node->DataSize = 0;
}
else {
status = stack.Push(node, size);
if (!NT_SUCCESS(status)) {
return status;
}
size = 0;
node = CONTAINING_RECORD(node->u.sequence.Link.Flink,
SDP_NODE,
hdr.Link);
current = &node->hdr.Link;
continue;
}
break;
case SDP_TYPE_CONTAINER:
//
// We let the container take care of everything, compensate for the
// header
//
size--;
break;
}
//
// Advance to the next link in the list
//
current = current->Flink;
header = CONTAINING_RECORD(current, SDP_NODE_HEADER, Link);
//
// Check to see if we are at the end of the list
//
while (header->Type == SDP_TYPE_LISTHEAD) {
//
// Check to see if we have pushed any items. If not, then we are
// done
//
if (stack.Depth() == 0) {
*Size = size;
return STATUS_SUCCESS;
}
stackEntry = stack.Pop();
node = stackEntry->Node;
node->DataSize = size;
//
// add storage for size of the sequence / alternative we just
// computed and add the amount of additional storage we need to
// store this value
//
if (size <= SIZE_8_BITS) {
size += sizeof(UCHAR);
}
else if (size <= SIZE_16_BITS) {
size += sizeof(USHORT);
}
else {
size += sizeof(ULONG);
}
//
// Add up the size and get the next item in the list
//
size = stackEntry->Size + size;
current = node->hdr.Link.Flink;
header = CONTAINING_RECORD(current, SDP_NODE_HEADER, Link);
}
}
*Size = size;
return STATUS_SUCCESS;
}
#define INC_STREAM(_inc) \
{ \
Stream += (_inc); \
Size -= (_inc); \
}
NTSTATUS ValidateStream(PUCHAR Stream, ULONG Size, PULONG NumEntries, PULONG ExtraPool, PULONG_PTR ErrorByte)
{
PUCHAR origStream;
ULONG ulVal, dataSize, elementSize;
USHORT usVal;
// UCHAR ucVal;
UCHAR type, sizeIndex;
origStream = Stream;
while (Size) {
SdpRetrieveHeader(Stream, type, sizeIndex);
INC_STREAM(1);
if (ARGUMENT_PRESENT(NumEntries)) {
(*NumEntries)++;
}
if (type == SDP_TYPE_NIL) {
//
// no storage necessary for nil, just continue
//
continue;
}
if (Size == 0) {
//
// Error! A type value, but no storage?
//
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
switch (type) {
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;
default:
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
if (dataSize > Size) {
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
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;
default:
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
}
return STATUS_INVALID_PARAMETER;
}
if (dataSize > Size) {
if (ARGUMENT_PRESENT(ErrorByte)) {
*ErrorByte = Stream - origStream;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -