📄 sdpdbserver.cpp
字号:
}
SdpAttributeRange * pAttr =
pAttribSrch->pRange + pAttribSrch->currentAttribute;
if (DataSize == sizeof(USHORT)) {
USHORT uint16;
RtlRetrieveUshort(&uint16, Data);
pAttr->minAttribute = pAttr->maxAttribute = RtlUshortByteSwap(uint16);
}
else {
ULONG uint32;
RtlRetrieveUlong(&uint32, Data);
uint32 = RtlUlongByteSwap(uint32);
pAttr->minAttribute = (USHORT) ((uint32 & 0xFFFF0000) >> 16);
pAttr->maxAttribute = (USHORT) (uint32 & 0xFFFF);
}
pAttribSrch->currentAttribute++;
return STATUS_SUCCESS;
}
NTSTATUS
SdpDatabase::ServiceAttributeRequestResponseRemote(
IN ULONG serviceHandle,
IN UCHAR *pAttribIdListStream,
IN ULONG streamSize,
OUT UCHAR **ppAttributeListStream,
OUT ULONG *pAttributeListSize,
OUT PVOID * ppOriginalAlloc,
OUT PSDP_ERROR pSdpError
)
{
SdpAttribSearch attribSrch;
NTSTATUS status;
PAGED_CODE();
status = attribSrch.RetrieveAttributes(pAttribIdListStream, streamSize);
if (!NT_SUCCESS(status)) {
*pSdpError = MapNtStatusToSdpError(status);
return status;
}
return ServiceAttributeRequestResponse(serviceHandle,
&attribSrch,
ppAttributeListStream,
pAttributeListSize,
ppOriginalAlloc,
pSdpError);
}
NTSTATUS
SdpDatabase::ServiceAttributeRequestResponseLocal(
IN ULONG serviceHandle,
IN SdpAttributeRange *pRange,
IN ULONG numRange,
OUT UCHAR **ppAttributeListStream,
OUT ULONG *pAttributeListSize,
OUT PVOID * ppOriginalAlloc
)
{
SdpAttribSearch attribSrch;
SDP_ERROR sdpError;
attribSrch.SetAttributes(pRange, numRange);
return ServiceAttributeRequestResponse(serviceHandle,
&attribSrch,
ppAttributeListStream,
pAttributeListSize,
ppOriginalAlloc,
&sdpError);
}
NTSTATUS
SdpDatabase::ServiceAttributeRequestResponse(
IN ULONG serviceHandle,
SdpAttribSearch *pAttribSearch,
OUT UCHAR **ppAttributeListStream,
OUT ULONG *pAttributeListSize,
OUT PVOID * ppOriginalAlloc,
OUT PSDP_ERROR pSdpError
)
{
ServiceRecord *pRecord;
PSDP_STREAM_ENTRY pStreamEntry;
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN foundRecord = FALSE;
pStreamEntry = NULL;
m_ServiceRecordList.Lock();
status = STATUS_UNSUCCESSFUL;
for (pRecord = m_ServiceRecordList.GetHead();
pRecord != NULL;
pRecord = m_ServiceRecordList.GetNext(pRecord)) {
if (pRecord->recordHandle == serviceHandle) {
_DbgPrintF(DBG_SDP_INFO,
("AttributeRequest found record handle 0x%08x", serviceHandle));
foundRecord = TRUE;
status = pAttribSearch->FindElements(
pRecord->pStream,
pRecord->streamSize,
&pStreamEntry,
pSdpError);
//
// FindElements will return success even if there was no match. If
// it returns an error, than that means there was either an invalid
// search or there was a problem allocating pool
//
if (!NT_SUCCESS(status)) {
_DbgPrintF(DBG_SDP_WARNING, ("search was not successful, 0x%x", status));
*pSdpError = MapNtStatusToSdpError(status);
}
break;
}
}
m_ServiceRecordList.Unlock();
if (foundRecord == TRUE) {
if (!NT_SUCCESS(status)) {
_DbgPrintF(DBG_SDP_WARNING, ("search was successful, but an error occurred, 0x%x", status));
if (pStreamEntry) {
ExFreePool(pStreamEntry);
pStreamEntry = NULL;
}
*ppAttributeListStream = NULL;
*pAttributeListSize = 0x0;
}
else if (pStreamEntry != NULL){
//
// there are search results
//
_DbgPrintF(DBG_SDP_INFO,
("search was successful, result is %d long", pStreamEntry->streamSize));
*ppAttributeListStream = pStreamEntry->stream;
*pAttributeListSize = pStreamEntry->streamSize;
*ppOriginalAlloc = pStreamEntry;
}
else {
//
// We didn't find anything so we need to create an empty sequence
// and send it back
//
_DbgPrintF(DBG_SDP_INFO, ("search was successful, no match though"));
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
UCHAR *pStream = new (PagedPool, SDP_TAG) UCHAR[2];
#else
UCHAR *pStream = (UCHAR*) ExAllocatePoolWithTag(0,2*sizeof(UCHAR),0);
if (pStream)
memset(pStream,0,sizeof(UCHAR[2]));
#endif
if (*ppAttributeListStream) {
*ppOriginalAlloc = pStream;
*ppAttributeListStream = pStream;
*pAttributeListSize = 2;
WriteVariableSizeToStream(SDP_TYPE_SEQUENCE, 0, pStream);
ASSERT(NT_SUCCESS(status));
}
else {
status = STATUS_INSUFFICIENT_RESOURCES;
*pSdpError = MapNtStatusToSdpError(status);
}
}
}
else {
_DbgPrintF(DBG_SDP_INFO,
("did not find the specified record handle (0x%08x) in the DB",
serviceHandle));
*pSdpError = SDP_ERROR_INVALID_RECORD_HANDLE;
status = STATUS_UNSUCCESSFUL;
}
return status;
}
NTSTATUS
SdpDatabase::ServiceSearchAttributeResponseLocal(
IN SdpQueryUuid *pUuid,
IN UCHAR numUuid,
IN SdpAttributeRange *pRange,
IN ULONG numRange,
OUT UCHAR **ppAttributeLists,
OUT ULONG *pAttributeListsByteCount
)
{
SdpUuidSearch uuidSrch;
SdpAttribSearch attribSrch;
SDP_ERROR sdpError;
uuidSrch.SetUuids(pUuid, numUuid);
attribSrch.SetAttributes(pRange, numRange);
return ServiceSearchAttributeResponse(&uuidSrch,
&attribSrch,
ppAttributeLists,
pAttributeListsByteCount,
&sdpError,
TRUE);
}
NTSTATUS
SdpDatabase::ServiceSearchAttributeResponseRemote(
IN UCHAR *pServiceSearchStream,
IN ULONG serviceSearchStreamSize,
IN UCHAR *pAttributeIdStream,
IN ULONG attributeIdStreamSize,
OUT UCHAR **ppAttributeLists,
OUT ULONG *pAttributeListsByteCount,
OUT PSDP_ERROR pSdpError
)
{
SdpUuidSearch uuidSrch;
SdpAttribSearch attribSrch;
NTSTATUS status;
status = uuidSrch.RetrieveUuids(pServiceSearchStream, serviceSearchStreamSize);
if (!NT_SUCCESS(status)) {
*pSdpError = MapNtStatusToSdpError(status);
return status;
}
status = attribSrch.RetrieveAttributes(pAttributeIdStream, attributeIdStreamSize);
if (!NT_SUCCESS(status)) {
*pSdpError = MapNtStatusToSdpError(status);
return status;
}
return ServiceSearchAttributeResponse(&uuidSrch,
&attribSrch,
ppAttributeLists,
pAttributeListsByteCount,
pSdpError,
FALSE);
}
NTSTATUS
SdpDatabase::ServiceSearchAttributeResponse(
IN SdpUuidSearch *pUuidSearch,
IN SdpAttribSearch *pAttribSearch,
OUT UCHAR **ppAttributeLists, // must be freed when xmit is finished
OUT ULONG *pAttributeListsByteCount,
OUT PSDP_ERROR pSdpError,
IN BOOLEAN Local
)
{
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
LIST_ENTRY head;
PLIST_ENTRY pListEntry;
PSDP_STREAM_ENTRY pStreamEntry;
*ppAttributeLists = NULL;
*pAttributeListsByteCount = 0;
InitializeListHead(&head);
ServiceRecord *pRecord;
ULONG streamSize = 0;
m_ServiceRecordList.Lock();
for (pRecord = m_ServiceRecordList.GetHead();
pRecord != NULL;
pRecord = m_ServiceRecordList.GetNext(pRecord)) {
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
if (Local == FALSE &&
pRecord->fOptions & SERVICE_OPTION_DO_NOT_PUBLISH) {
//
// Record sumbitter did not want this SDP record published to the
// world. Skip it.
//
continue;
}
#endif
if (pUuidSearch->SearchStream(pRecord->pStream, pRecord->streamSize)) {
pStreamEntry = NULL;
status = pAttribSearch->FindElements(
pRecord->pStream,
pRecord->streamSize,
&pStreamEntry,
pSdpError);
if (NT_SUCCESS(status)) {
if (pStreamEntry != NULL) {
//
// pStreamEntry will be freed when we exit this function
//
InsertTailList(&head, &pStreamEntry->link);
streamSize += pStreamEntry->streamSize;
}
else {
//
// success will be returned even if there is no match
//
;
}
}
else {
//
// if there was an error allocating pool or there was something
// incorrectly formatted, we will drop into here
//
break;
}
}
}
m_ServiceRecordList.Unlock();
if (NT_SUCCESS(status)) {
ULONG totalSize;
//
// compute the total amout of stream required
//
totalSize = streamSize + (USHORT) GetContainerHeaderSize(streamSize);
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
UCHAR *pStream = new(NonPagedPool, SDP_TAG) UCHAR[totalSize];
#else
UCHAR *pStream = (PUCHAR) ExAllocatePoolWithTag(0,sizeof(UCHAR)*totalSize,0);
if (pStream)
memset(pStream,0,sizeof(UCHAR)*totalSize);
#endif
if (pStream) {
*ppAttributeLists = pStream;
*pAttributeListsByteCount = totalSize;
pStream = WriteVariableSizeToStream(SDP_TYPE_SEQUENCE, streamSize, pStream);
ASSERT(streamSize == 0 || !IsListEmpty(&head));
for (pListEntry = head.Flink;
pListEntry != &head;
pListEntry = pListEntry->Flink) {
pStreamEntry =
CONTAINING_RECORD(pListEntry, SDP_STREAM_ENTRY, link);
RtlCopyMemory(pStream,
pStreamEntry->stream,
pStreamEntry->streamSize);
pStream += pStreamEntry->streamSize;
}
ASSERT((ULONG) (pStream - *ppAttributeLists) == totalSize);
}
else {
status = STATUS_INSUFFICIENT_RESOURCES;
*pSdpError = MapNtStatusToSdpError(status);
}
}
else {
*pSdpError = MapNtStatusToSdpError(status);
}
while (!IsListEmpty(&head)) {
pListEntry = RemoveHeadList(&head);
ExFreePool( CONTAINING_RECORD(pListEntry, SDP_STREAM_ENTRY, link) );
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -