📄 btsdp.cpp
字号:
//
// max attrib byte count = 2
// attrib elem seq = 5 (see above)
// cont state = 1
// = 8
//
*ppServiceSearchSequence = pStream;
status =
CrackSequenceParameter(pStream, streamSize, 8, pServiceSearchSequenceSize);
if (!NT_SUCCESS(status)) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
RtlRetrieveUshort(pMaxAttributeByteCount, pStream);
*pMaxAttributeByteCount = RtlUshortByteSwap(*pMaxAttributeByteCount);
pStream += sizeof(USHORT);
streamSize -= sizeof(USHORT);
//
// cont state = 1
//
*ppAttributeIdSequence = pStream;
status =
CrackSequenceParameter(pStream, streamSize, 1, pAttributeIdSequenceSize);
if (!NT_SUCCESS(status)) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
return CrackContState(pStream, streamSize, pContState, pSdpError);
}
NTSTATUS
SdpInterface::CrackServerServiceSearchResponse(
IN UCHAR *pResponseStream,
IN ULONG streamSize,
OUT USHORT *pTotalCount,
OUT USHORT *pCurrentCount,
OUT ULONG **ppHandleList,
OUT ContinuationState *pContState,
OUT PSDP_ERROR pSdpError
)
{
//
// sizeof(total count) = 2
// sizeof(current count) = 2
// sizeof(0+ handles) = 0
// sizeof(cont state) >= 1
//
if (streamSize < 5) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
USHORT tmp;
RtlRetrieveUshort(&tmp, pResponseStream);
*pTotalCount = RtlUshortByteSwap(tmp);
pResponseStream += sizeof(tmp);
streamSize -= sizeof(tmp);
RtlRetrieveUshort(&tmp, pResponseStream);
*pCurrentCount = RtlUshortByteSwap(tmp);
pResponseStream += sizeof(tmp);
streamSize -= sizeof(tmp);
//
// see if the described number of records plus a finishing cont state is
// greater than what was sent OR if the current count is greater than the
// reported max count (incositent results)
//
if ((*pCurrentCount * sizeof(ULONG) + 1 > streamSize) ||
(*pCurrentCount > *pTotalCount)) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
*ppHandleList = (ULONG *) pResponseStream;
pResponseStream += sizeof(ULONG) * (*pCurrentCount);
streamSize -= sizeof(ULONG) * (*pCurrentCount);
return CrackContState(pResponseStream, streamSize, pContState, pSdpError);
}
NTSTATUS
SdpInterface::CrackServerServiceAttributeResponse(
IN UCHAR *pResponseStream,
IN ULONG streamSize,
OUT USHORT *pByteCount,
OUT UCHAR **ppAttributeList,
OUT ContinuationState *pContState,
OUT PSDP_ERROR pSdpError
)
{
//
// sizeof(list byte count) = 2
// sizeof(+1 byte attrib list) = 1
// sizeof(cont state) >= 1
//
if (streamSize < 4) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
USHORT tmp;
RtlRetrieveUshort(&tmp, pResponseStream);
*pByteCount = RtlUshortByteSwap(tmp);
pResponseStream += sizeof(tmp);
streamSize -= sizeof(tmp);
*ppAttributeList = (UCHAR *) pResponseStream;
ULONG count = *pByteCount;
if (count + 1 > streamSize) {
*pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
pResponseStream += count;
streamSize -= count;
return CrackContState(pResponseStream, streamSize, pContState, pSdpError);
}
NTSTATUS
SdpInterface::CreateServiceAttributePDU(
IN UCHAR *pResult,
IN ULONG resultSize,
IN ContinuationState *pContState,
IN USHORT maxAttribByteCount,
IN ULONG mtu,
OUT UCHAR **ppResponse,
OUT ULONG *pResponseSize,
OUT UCHAR **ppNextResult,
OUT ULONG *pNextResultSize,
OUT PSDP_ERROR pSdpError
)
{
NTSTATUS status;
ULONG fixedSize, adjustedResponseSize = 0;
USHORT byteCount = 0;
UCHAR *pStream;
//
// PDU header + byte count + cont state header
//
fixedSize = sizeof(SdpPDU) + sizeof(byteCount) + sizeof(UCHAR);
SdpPrint(SDP_DBG_PDU_TRACE, ("CreateServiceAttributePDU called\n"));
SdpPrint(SDP_DBG_PDU_INFO, ("fixed %d, result %d, mtu %d\n",
fixedSize, resultSize, mtu));
if (fixedSize + resultSize <= mtu) {
//
// We can fit the entire response in a single PDU...let's see if
// maxAttribByteCount allows us to do this
//
if (resultSize > maxAttribByteCount) {
//
// compute whatever amount of space is leftover
//
adjustedResponseSize = mtu - (fixedSize + pContState->size);
SdpPrint(SDP_DBG_PDU_INFO,
("could fit, res size > mtu, adjusted size %d\n",
adjustedResponseSize));
//
// still too big, just go smaller
//
if (adjustedResponseSize > maxAttribByteCount) {
SdpPrint(SDP_DBG_PDU_INFO,
("adjusted size (%d) bigger than max byte count (%d), fixing\n",
adjustedResponseSize, maxAttribByteCount));
adjustedResponseSize = maxAttribByteCount;
}
}
else {
//
// everything fits, set the cont state to reflect this
//
SdpPrint(SDP_DBG_PDU_INFO, ("everything fits\n"));
pContState->size = 0;
}
}
else {
//
// the entire response doesn't fit into the mtu, must trim it down
//
adjustedResponseSize = mtu - (fixedSize + pContState->size);
SdpPrint(SDP_DBG_PDU_INFO,
("total bigger than mtu, adjusted size %d\n",
adjustedResponseSize));
if (adjustedResponseSize > maxAttribByteCount) {
SdpPrint(SDP_DBG_PDU_INFO,
("still too big, setting to max attrib byte count %d\n",
adjustedResponseSize));
adjustedResponseSize = maxAttribByteCount;
}
}
if (adjustedResponseSize > 0) {
SdpPrint(SDP_DBG_PDU_INFO,
("adjustedResponseSize is %d\n", (ULONG) adjustedResponseSize));
ASSERT(pContState->size != 0);
*ppNextResult = pResult + adjustedResponseSize;
*pNextResultSize = resultSize - adjustedResponseSize;
resultSize = adjustedResponseSize;
SdpPrint(SDP_DBG_PDU_INFO,
("remaining result size %d\n", *pNextResultSize));
}
else {
SdpPrint(SDP_DBG_PDU_INFO, ("done...zeroing out continuation stuff\n"));
*ppNextResult = NULL;
*pNextResultSize = 0;
}
*pResponseSize = fixedSize + resultSize + pContState->size;
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
*ppResponse = new (PagedPool, SDPI_TAG) UCHAR[*pResponseSize];
#else
if (NULL != (*ppResponse = (PUCHAR) ExAllocatePoolWithTag(0,sizeof(UCHAR)*(*pResponseSize),0)))
memset(*ppResponse,0,*pResponseSize);
#endif
if (*ppResponse == NULL) {
SdpPrint(SDP_DBG_PDU_ERROR,
("could not allocate stream response for response\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
*pSdpError = MapNtStatusToSdpError(status);
return status;
}
//
// Write out the response except for the PDU
//
pStream = *ppResponse;
pStream += sizeof(SdpPDU);
ASSERT(resultSize <= 0xFFFF);
//
// Easy, just one (or the last) PDU
//
byteCount = (USHORT) resultSize;
byteCount = RtlUshortByteSwap(byteCount);
RtlCopyMemory(pStream, &byteCount, sizeof(byteCount));
pStream += sizeof(byteCount);
RtlCopyMemory(pStream, pResult, resultSize);
pStream += resultSize;
pContState->Write(pStream);
//
// Make sure we wrote out all the byte we thought we did
//
#if DBG
pStream += pContState->GetTotalSize();
ASSERT(((ULONG) (pStream - *ppResponse)) == *pResponseSize);
#endif
return STATUS_SUCCESS;
}
NTSTATUS
SdpInterface::CreateServiceSearchAttributePDU(
IN UCHAR *pResult,
IN ULONG resultSize,
IN ContinuationState *pContState,
IN USHORT maxAttribByteCount,
IN USHORT mtu,
OUT UCHAR **ppResponse,
OUT ULONG *pResponseSize,
OUT UCHAR **ppNextResult,
OUT ULONG *pNextResultSize,
OUT PSDP_ERROR pSdpError
)
{
return CreateServiceAttributePDU(pResult,
resultSize,
pContState,
maxAttribByteCount,
mtu,
ppResponse,
pResponseSize,
ppNextResult,
pNextResultSize,
pSdpError);
}
NTSTATUS
SdpInterface::CreateServiceSearchResponsePDU(
ULONG *pRecordHandles,
USHORT recordCount,
USHORT totalRecordCount,
IN ContinuationState *pContState,
IN USHORT mtu,
OUT UCHAR **ppResponse,
OUT ULONG *pResponseSize,
OUT ULONG **ppNextRecordHandles,
OUT USHORT *pNextRecordCount,
OUT PSDP_ERROR pSdpError
)
{
NTSTATUS status;
ULONG fixedSize;
USHORT count;
fixedSize =
sizeof(SdpPDU) +
sizeof(USHORT) + // TotalServiceRecordCount
sizeof(USHORT) + // CurrentServiceRecordCount
sizeof(UCHAR); // continuation state of 0
*ppNextRecordHandles = NULL;
*pNextRecordCount = 0;
SdpPrint(SDP_DBG_PDU_TRACE, ("CreateServiceSearchResponsePDU called\n"));
SdpPrint(SDP_DBG_PDU_TRACE, ("mtu is %d, response size is %d\n",
(ULONG) mtu, fixedSize + (recordCount * sizeof(ULONG))));
if (fixedSize + (recordCount * sizeof(ULONG)) > ((ULONG) mtu)) {
//
// figure out how much space we have left for the record handles
//
count = (mtu - ((USHORT) (fixedSize + pContState->size))) / sizeof(ULONG);
if (count == 0) {
SdpPrint(SDP_DBG_PDU_WARNING,
("could not fit in a single handle!!!!\n"));
//
// can't fit any record handles, ergh!
//
return STATUS_INVALID_BUFFER_SIZE;
}
ASSERT(recordCount > count);
//
// total required size
//
*ppNextRecordHandles = pRecordHandles + count;
*pNextRecordCount = recordCount - count;
recordCount = count;
}
else {
pContState->size = 0;
}
*pResponseSize = fixedSize + recordCount * sizeof(ULONG) + pContState->size;
SdpPrint(SDP_DBG_PDU_INFO,
("returning %d records (%d total), resp sizse is %d\n",
recordCount, totalRecordCount, *pResponseSize));
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
*ppResponse = new(PagedPool, SDPI_TAG) UCHAR[*pResponseSize];
#else
if (NULL != (*ppResponse = (PUCHAR) ExAllocatePoolWithTag(0,*pResponseSize,0)))
memset(*ppResponse,0,*pResponseSize);
#endif
if (*ppResponse == NULL) {
SdpPrint(SDP_DBG_PDU_ERROR,
("could not allocate a stream for a response\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
*pSdpError = MapNtStatusToSdpError(status);
return status;
}
//
// Write out the response except for the PDU. Format is
//
// total record count (2 bytes)
// record count in this response (2 bytes)
// handles (record count * sizeof(ULONG))
// continuation state (1-17 bytes)
//
UCHAR *pStream = *ppResponse + sizeof(SdpPDU);
totalRecordCount = RtlUshortByteSwap(totalRecordCount);
RtlCopyMemory(pStream, &totalRecordCount, sizeof(totalRecordCount));
pStream += sizeof(totalRecordCount);
count = RtlUshortByteSwap(recordCount);
RtlCopyMemory(pStream, &count, sizeof(count));
pStream += sizeof(count);
if (recordCount) {
RtlCopyMemory(pStream, pRecordHandles, recordCount * sizeof(ULONG));
pStream +=(recordCount * sizeof(ULONG));
}
//
// Finally the cont state
//
pContState->Write(pStream);
//
// Make sure we wrote only the number bytes we said we did
//
#if DBG
pStream += pContState->GetTotalSize();
ASSERT(((ULONG) (pStream - *ppResponse)) == *pResponseSize);
#endif
return STATUS_SUCCESS;
}
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
NTSTATUS
SdpInterface::ConnectRequestComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
PIO_STACK_LOCATION stack;
SdpInterface *pSdpInterface;
SdpConnection *pCon;
PBRB pBrb;
stack = IoGetCurrentIrpStackLocation(Irp);
pSdpInterface = (SdpInterface *) stack->Parameters.Others.Argument1;
pBrb = (BRB *) stack->Parameters.Others.Argument2;
pCon = (SdpConnection *) Context;
SdpPrint(SDP_DBG_CONFIG_TRACE,
("+ConnectRequestComplete: status 0x%x, hCon %p, con %p\n",
Irp->IoStatus.Status, pBrb->BrbL2caConnectReq.hConnection, pCon));
if (NT_SUCCESS(Irp->IoStatus.Status)) {
//
// Assigned when enter the config state
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -