📄 btsdp.cpp
字号:
}
SdpPrint(SDP_DBG_CONFIG_INFO,
("completing piggy back connect 0x%x\n", status));
return status;
}
if (pConnect->requestTimeout == SDP_REQUEST_TO_DEFAULT) {
pCon->maxTimeout = SDP_DEFAULT_TIMEOUT;
}
else {
pCon->maxTimeout = pConnect->requestTimeout;
}
PBRB pBrb;
PIRP irp;
status = STATUS_INSUFFICIENT_RESOURCES;
irp = NULL;
pBrb = NULL;
irp = IoAllocateIrp(pCon->pDevice->m_Struct.FunctionalDeviceObject->StackSize,
FALSE);
if (irp != NULL) {
pBrb = new (NonPagedPool, SDPI_TAG) BRB;
if (pBrb != NULL) {
pBrb->BrbHeader.Length = sizeof (_BRB_L2CA_CONNECT_REQ);
pBrb->BrbHeader.Type = BRB_L2CA_CONNECT_REQ;
pBrb->BrbHeader.Status = STATUS_SUCCESS;
pBrb->BrbL2caConnectReq.ContextCxn = (PVOID) pCon;
pBrb->BrbL2caConnectReq.btAddress = pCon->btAddress;
pBrb->BrbL2caConnectReq.PSM = PSM_SDP;
SdpPrint(SDP_DBG_CONFIG_INFO, ("Connect to %04x%08x\n",
GET_NAP(pBrb->BrbL2caConnectReq.btAddress),
GET_SAP(pBrb->BrbL2caConnectReq.btAddress)));
IoMarkIrpPending(pIrp);
pCon->Acquire(pIrp);
pCon->LockState(&irql);
pCon->connectList.AddTail(pIrp);
pCon->UnlockState(irql);
SdpPrint(SDP_DBG_CONFIG_INFO,
("pending connect request %p\n", irp));
SendBrbAsync(irp,
pBrb,
ConnectRequestComplete,
pCon,
this,
pBrb);
status = STATUS_PENDING;
}
else {
IoFreeIrp(irp);
irp = NULL;
}
}
return status;
}
#endif // UNDER_CE
// !UNDER_CE NTSTATUS SdpInterface::ServiceSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::ServiceSearch(SdpConnection *pCon, SdpServiceSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
NTSTATUS status;
pSearch->cUUIDs = 0;
status = VerifyServiceSearch(pSearch->uuids, (UCHAR*) &pSearch->cUUIDs);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Check to see if this is a local search
//
if (fLocal) {
ULONG *pResponse;
USHORT total = 0;
status = pSdpDB->ServiceSearchRequestResponseLocal(
pSearch->uuids,
(UCHAR) pSearch->cUUIDs,
pSearch->cMaxHandles,
&pResponse,
&total);
if (NT_SUCCESS(status) && pResponse != NULL) {
ASSERT(total != 0);
pCon->pClientBuf = (unsigned char*) pResponse;
pCon->u.Client.ServiceSearch.totalRecordCount = total;
}
#if defined (DEBUG) || defined (_DEBUG)
else {
ASSERT(pCon->u.Client.ServiceSearch.totalRecordCount == 0);
}
#endif
return status;
}
return pCon->SendServiceSearchRequest(NULL,pSearch);
#else // UNDER_CE
SdpConnection *pCon;
BthSdpServiceSearchRequest *pSearch;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
NTSTATUS status;
ULONG outlen;
info = 0;
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {
return STATUS_BUFFER_TOO_SMALL;
}
pSearch = (BthSdpServiceSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;
outlen = stack->Parameters.DeviceIoControl.OutputBufferLength;
if (outlen == 0 || (outlen % sizeof(ULONG) != 0)) {
return STATUS_INVALID_BUFFER_SIZE;
}
UCHAR maxUuids = 0;
status = VerifyServiceSearch(pSearch->uuids, &maxUuids);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Check to see if this is a local search
//
if (pSearch->hConnection == HANDLE_SDP_LOCAL) {
ULONG *pResponse;
USHORT total = 0, maxHandles;
maxHandles = (USHORT)
(stack->Parameters.DeviceIoControl.OutputBufferLength / sizeof(ULONG));
status = Globals.pSdpDB->ServiceSearchRequestResponseLocal(
pSearch->uuids,
maxUuids,
maxHandles,
&pResponse,
&total);
if (NT_SUCCESS(status) && pResponse != NULL) {
ASSERT(total != 0);
info = total * sizeof(ULONG);
RtlCopyMemory((PULONG) pIrp->AssociatedIrp.SystemBuffer, pResponse, info);
ExFreePool(pResponse);
}
return status;
}
pCon = NULL;
status = AcquireConnection(pSearch->hConnection, &pCon, pIrp);
if (!NT_SUCCESS(status)) {
return status;
}
ASSERT(pCon != NULL);
//
// Set the max uuids before we enqueue the request because the send function
// assumes it is set (even for a queud irp processed at a later time)
//
SetMaxUuidsInIrp(pIrp, maxUuids);
BOOLEAN added = pCon->clientQueue.AddIfBusy(pIrp, &status);
if (added) {
//
// The queue is busy and the request has been queued. Don't touch the
// irp anymore
//
return STATUS_PENDING;
}
else if (!NT_SUCCESS(status)) {
//
// The request was cancelled or something went wrong. The irp was not
// enqueued. Return the error status
//
pCon->ReleaseAndProcessNextRequest(pIrp);
return status;
}
else {
//
// This is the current request on the connection, see if it matches the
// previous request
//
//
// While we do not cache ServiceSearch responses, this will clean up
// any cached responsed from previous queries
//
status = pCon->IsPreviousRequest(pIrp,
SdpPDU_ServiceSearchRequest,
pSearch->uuids,
NULL,
0,
&info);
if (NT_SUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL) {
pCon->ReleaseAndProcessNextRequest(pIrp);
return STATUS_SUCCESS;
}
}
return pCon->SendServiceSearchRequest(pIrp);
#endif // UNDER_CE
}
// NTSTATUS SdpInterface::AttributeSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::AttributeSearch(SdpConnection *pCon, SdpAttributeSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
NTSTATUS status;
status =
VerifyAttributeSearch(pSearch->range,
&pSearch->numAttributes,
0);
if (!NT_SUCCESS(status)) {
return status;
}
if (fLocal) {
PVOID pOrig;
UCHAR *pResult;
ULONG size;
status = pSdpDB->ServiceAttributeRequestResponseLocal(
pSearch->recordHandle,
pSearch->range,
pSearch->numAttributes,
&pResult,
&size,
&pOrig);
if (NT_SUCCESS(status)) {
ASSERT(size != 0);
// pOrig is the base of allocated memory, pResult is what we need to pass
// to caller, is a few bytes past pOrig. Rather than have this info propogate up all
// the layers just alloc the data here.
if (NULL == (pCon->pClientBuf = (PUCHAR) SdpAllocatePool(size)))
return STATUS_INSUFFICIENT_RESOURCES;
memcpy(pCon->pClientBuf,pResult,size);
pCon->cClientBuf = size;
SdpFreePool(pOrig);
}
return status;
}
return pCon->SendAttributeSearchRequest(NULL,pSearch);
#else
SdpConnection *pCon;
BthSdpAttributeSearchRequest *pSearch;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
ULONG maxRange;
NTSTATUS status;
info = 0;
maxRange = 0;
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {
return STATUS_INVALID_BUFFER_SIZE;
}
if (stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BthSdpStreamResponse)) {
return STATUS_INVALID_BUFFER_SIZE;
}
pSearch = (BthSdpAttributeSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;
status =
VerifyAttributeSearch(pSearch->range,
&maxRange,
stack->Parameters.DeviceIoControl.InputBufferLength -
(sizeof(*pSearch) - sizeof(pSearch->range))
);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Check to see if it is a local search
//
if (pSearch->hConnection == HANDLE_SDP_LOCAL) {
PVOID pOrig;
UCHAR *pResult;
ULONG size;
status = Globals.pSdpDB->ServiceAttributeRequestResponseLocal(
pSearch->recordHandle,
pSearch->range,
maxRange,
&pResult,
&size,
&pOrig);
if (NT_SUCCESS(status)) {
//
// Even if there is no match, you still get an empty sequence
//
BthSdpStreamResponse *pResponse = (BthSdpStreamResponse *)
pIrp->AssociatedIrp.SystemBuffer;
ULONG responseSize;
responseSize =
stack->Parameters.DeviceIoControl.OutputBufferLength -
(sizeof(*pResponse) - sizeof(pResponse->response));
pResponse->requiredSize = size;
if (responseSize < size) {
info = responseSize;
}
else {
info = size;
}
pResponse->responseSize = info;
RtlCopyMemory(pResponse->response, pResult, info);
info += (sizeof(*pResponse) - sizeof(pResponse->response));
ExFreePool(pOrig);
}
return status;
}
pCon = NULL;
status = AcquireConnection(pSearch->hConnection, &pCon, pIrp);
if (!NT_SUCCESS(status)) {
return status;
}
ASSERT(pCon != NULL);
//
// Set the max range before we enqueue the request because the send function
// assumes it is set (even for a queud irp processed at a later time)
//
SetMaxRangeInIrp(pIrp, maxRange);
BOOLEAN added = pCon->clientQueue.AddIfBusy(pIrp, &status);
if (added) {
//
// The queue is busy and the request has been queued. Don't touch the
// irp anymore
//
return STATUS_PENDING;
}
else if (!NT_SUCCESS(status)) {
//
// The request was cancelled or something went wrong. The irp was not
// enqueued. Return the error status
//
pCon->ReleaseAndProcessNextRequest(pIrp);
return status;
}
else {
//
// This is the current request on the connection, see if it matches the
// previous request
//
//
// While we do not cache ServiceSearch responses, this will clean up
// any cached responsed from previous queries
//
status = pCon->IsPreviousRequest(pIrp,
SdpPDU_ServiceAttributeRequest,
NULL,
pSearch->range,
maxRange,
&info);
if (NT_SUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL) {
pCon->ReleaseAndProcessNextRequest(pIrp);
return STATUS_SUCCESS;
}
}
return pCon->SendAttributeSearchRequest(pIrp);
#endif // UNDER_CE
}
// NTSTATUS SdpInterface::ServiceAndAttributeSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::ServiceAndAttributeSearch(SdpConnection *pCon, SdpServiceAttributeSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
NTSTATUS status;
pSearch->cUUIDs = 0;
status = VerifyServiceSearch(pSearch->uuids, (UCHAR*) &pSearch->cUUIDs);
if (!NT_SUCCESS(status)) {
return status;
}
status =
VerifyAttributeSearch(pSearch->range,
&pSearch->numAttributes,
0);
if (!NT_SUCCESS(status)) {
return status;
}
if (fLocal) {
ULONG size;
UCHAR *pResult;
status = pSdpDB->ServiceSearchAttributeResponseLocal(
pSearch->uuids,
(UCHAR) pSearch->cUUIDs,
pSearch->range,
pSearch->numAttributes,
&pResult,
&size);
if (NT_SUCCESS(status)) {
ASSERT(size != 0);
pCon->pClientBuf = (PUCHAR) pResult;
pCon->cClientBuf = size;
}
return status;
}
return pCon->SendServiceSearchAttributeRequest(NULL,pSearch);
#else // UNDER_CE
SdpConnection *pCon;
BthSdpServiceAttributeSearchRequest *pSearch;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
NTSTATUS status;
ULONG maxRange = 0;
UCHAR maxUuids = 0;
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -