obexbthtransport.cpp
来自「Windows CE 6.0 Server 源码」· C++ 代码 · 共 1,341 行 · 第 1/4 页
CPP
1,341 行
//
while(pUUIDList)
{
BT_UUID16_LIST *pDel = pUUIDList;
pUUIDList = pUUIDList->pNext;
delete pDel;
}
}
done:
pIStream->Release();
for (i = 0; i < ulRecords; i++)
pRecordArg[i]->Release();
CoTaskMemFree(pRecordArg);
*pBTCList = pChannList;
return hres;
}
static void InitWSAQuerySet(WSAQUERYSET *pw, BT_ADDR *pba=NULL, CSADDR_INFO *pcsaBuffer=NULL, SOCKADDR_BTH *psockBT=NULL, LPBLOB pBlob=NULL) {
memset(pw,0,sizeof(WSAQUERYSET));
pw->dwSize = sizeof(WSAQUERYSET);
pw->dwNameSpace = NS_BTH;
pw->lpBlob = pBlob;
if (pba) {
pw->lpcsaBuffer = pcsaBuffer;
memset(pcsaBuffer,0,sizeof(CSADDR_INFO));
memset(psockBT,0,sizeof(SOCKADDR_BTH));
memcpy(&psockBT->btAddr,pba,sizeof(BT_ADDR));
pcsaBuffer->RemoteAddr.lpSockaddr = (LPSOCKADDR) psockBT;
pcsaBuffer->RemoteAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
}
}
static HRESULT QueryForChannel(BT_ADDR bt, BT_CHANNEL_LIST **pBTCList)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::QueryForChannel()\n"));
SVSUTIL_ASSERT(pBTCList);
SdpQueryUuid uuidObex;
uuidObex.u.uuid16 = OBEX_PROTOCOL_UUID16;
uuidObex.uuidType = SDP_ST_UUID16;
HRESULT hr = E_FAIL;
SdpAttributeRange attribRange[2];
attribRange[0].minAttribute = attribRange[0].maxAttribute = SDP_ATTRIB_CLASS_ID_LIST;
attribRange[1].minAttribute = attribRange[1].maxAttribute = SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST;
WSAQUERYSET wsaQuery;
PBTHNS_RESTRICTIONBLOB prBlob;
BLOB blob;
unsigned long ulBlobLen = sizeof(BTHNS_RESTRICTIONBLOB) + sizeof(SdpAttributeRange);
CHAR BTHNSStruct[sizeof(BTHNS_RESTRICTIONBLOB) + sizeof(SdpAttributeRange)];
if(NULL == BTHNSStruct)
return E_OUTOFMEMORY;
prBlob = (PBTHNS_RESTRICTIONBLOB) BTHNSStruct;
memset(BTHNSStruct,0,ulBlobLen); //required to have all UUID's following last
// valid UUID of prBlob->uuids be 0!
prBlob->type = SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST;
prBlob->numRange = 2; //tells that there are 2 attribRange's
//PREFAST NOTE: this should be okay - note prBlob points to BTHNSStruct and thats large
PREFAST_SUPPRESS(203, "PREfast error - the following line is valid");
memcpy(prBlob->pRange, attribRange, sizeof(SdpAttributeRange) * 2);
memcpy(prBlob->uuids, &uuidObex, sizeof(SdpQueryUuid));
blob.cbSize = ulBlobLen;
blob.pBlobData = (BYTE*)prBlob;
CSADDR_INFO csAddr;
SOCKADDR_BTH sockBT;
HINSTANCE hLib = LoadLibrary(L"btdrt.dll");
if (!hLib) {
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE, (L"CObexBTHTransport::QueryForChannel(): Failed to load btdrt.dll. GetLastError()=0x%08x\n", GetLastError()));
return hr;
}
typedef int (*BTHNSLOOKUPSERVICEBEGIN)(LPWSAQUERYSET, DWORD, LPHANDLE );
typedef int (*BTHNSLOOKUPSERVICENEXT)(HANDLE, DWORD, LPDWORD, LPWSAQUERYSET );
typedef int (*BTHNSLOOKUPSERVICEEND)(HANDLE);
BTHNSLOOKUPSERVICEBEGIN pfnBthNsLookupServiceBegin = (BTHNSLOOKUPSERVICEBEGIN )GetProcAddress(hLib, L"BthNsLookupServiceBegin");
BTHNSLOOKUPSERVICENEXT pfnBthNsLookupServiceNext = (BTHNSLOOKUPSERVICENEXT )GetProcAddress(hLib, L"BthNsLookupServiceNext");
BTHNSLOOKUPSERVICEEND pfnBthNsLookupServiceEnd = (BTHNSLOOKUPSERVICEEND )GetProcAddress(hLib, L"BthNsLookupServiceEnd");
if ((!pfnBthNsLookupServiceBegin) || (!pfnBthNsLookupServiceNext) || (!pfnBthNsLookupServiceEnd))
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE, (L"CObexBTHTransport::QueryForChannel(): BthNsLookupServiceXXX functions not found in btdrt.dll\n"));
FreeLibrary(hLib);
return hr;
}
InitWSAQuerySet(&wsaQuery,&bt,&csAddr,&sockBT,&blob);
DWORD dwFlags = 0;
ULONG lChannel = 0;
long lRet;
HANDLE hLookup;
lRet = pfnBthNsLookupServiceBegin(&wsaQuery,dwFlags,&hLookup);
if (ERROR_SUCCESS == lRet)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::QueryForChannel() BthNsLookupServiceBegin returned 0x%08x\r\n",lRet));
// Get Results
DWORD dwSize = 5000;
CHAR *pQueryResults = new char[dwSize];
if(!pQueryResults)
hr = E_OUTOFMEMORY;
else
{
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) pQueryResults;
dwFlags = LUP_RETURN_ALL;
lRet = pfnBthNsLookupServiceNext(hLookup,dwFlags,&dwSize,pwsaResults);
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::QueryForChannel() BthNsLookupServiceNext returned 0x%08x \r\n",lRet));
pfnBthNsLookupServiceEnd(hLookup);
if (lRet == ERROR_SUCCESS || lRet == ERROR_NO_MORE_ITEMS && pwsaResults->lpBlob)
{
hr = GetRFCOMMChannel(pwsaResults->lpBlob->pBlobData, pwsaResults->lpBlob->cbSize, pBTCList);
if(FAILED(hr))
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::QueryForChannel -- GetRFCOMMChannel failed\n"));
}
}
}
if(pQueryResults)
delete [] pQueryResults;
}
FreeLibrary(hLib);
return hr;
}
CObexBTHTransport::CObexBTHTransport() : _refCount(1), pNameCache(NULL), fIsAborting(FALSE)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::CObexBTHTransport()\n"));
//initilize the socket libs
WSADATA wsd;
WSAStartup (MAKEWORD(2,2), &wsd);
}
CObexBTHTransport::~CObexBTHTransport()
{
//
// clean out name cache
//
while(pNameCache)
{
NAME_CACHE_NODE *pDel = pNameCache;
VariantClear(&pDel->var);
pNameCache = pNameCache->pNext;
delete pDel;
}
//clean up winsock
WSACleanup();
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::~CObexBTHTransport()\n"));
}
HRESULT STDMETHODCALLTYPE
CObexBTHTransport::Init(void)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::Init()\n"));
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CObexBTHTransport::Shutdown(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
//singleton that holds a socket object
CObexBTHTransport::CreateSocket(LPPROPERTYBAG2 pPropertyBag,
LPSOCKET *ppSocket)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::CreateSocket()\n"));
*ppSocket = new CBTHTransportSocket();
if( !(*ppSocket) )
{
return E_OUTOFMEMORY;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CObexBTHTransport::CreateSocketBlob(unsigned long ulSize,
byte __RPC_FAR *pbData,
LPSOCKET __RPC_FAR *ppSocket)
{
return E_NOTIMPL;
}
typedef int (*TBthPerformInquiry) (unsigned int LAP, unsigned char length, unsigned char num_responses, unsigned int cBuffer, unsigned int *pcRequired, BthInquiryResult *pir);
HRESULT STDMETHODCALLTYPE
CObexBTHTransport::EnumDevices(LPPROPERTYBAGENUM *ppDevices)
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices()\n"));
HRESULT hRet = E_FAIL;
HINSTANCE hLib = NULL;
TBthPerformInquiry pBthPerformInquiry = NULL;
BthInquiryResult *pIR = NULL;
int iNumDevices = 0;
int i;
CPropertyBagEnum *pPropEnum = NULL;
CPropertyBag *pPropBag = NULL;
VARIANT var;
VariantInit(&var);
//
// verify input params
if (!ppDevices)
{
hRet = E_POINTER;
goto Cleanup;
}
//
// initialize input param
*ppDevices = 0;
//
// load the btdrt dll, and get the BthPerformInquiry function
if (NULL == (hLib = LoadLibrary (L"btdrt.dll")))
{
hRet = E_FAIL;
goto Cleanup;
}
if (NULL == (pBthPerformInquiry = (TBthPerformInquiry)GetProcAddress (hLib, L"BthPerformInquiry")))
{
hRet = E_FAIL;
goto Cleanup;
}
if(NULL == (pIR = new BthInquiryResult[BTH_INQUIRY_SIZE]))
{
hRet = E_OUTOFMEMORY;
goto Cleanup;
}
if (ERROR_SUCCESS != pBthPerformInquiry(BT_ADDR_GIAC, BTH_INQUIRY_LEN, 0, BTH_INQUIRY_SIZE, (unsigned int *)&iNumDevices, pIR))
{
hRet = E_FAIL;
goto Cleanup;
}
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices - Inquiry returned following devices...:\n"));
#if defined (DEBUG) || defined (_DEBUG)
for (i = 0 ; i < iNumDevices ; ++i)
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices - (%04x%08x)\n", GET_NAP(pIR[i].ba), GET_SAP(pIR[i].ba)));
#endif
if (NULL == (pPropEnum = new CPropertyBagEnum()))
{
hRet = E_OUTOFMEMORY;
goto Cleanup;
}
for(i=0; i < iNumDevices; ++i)
{
if (NULL == (pPropBag = new CPropertyBag()))
{
hRet = E_OUTOFMEMORY;
goto Cleanup;
}
//
// The name and the port will be the same (VB style BSTR here)
//
USHORT name[30];
swprintf(name, L"%04x%08x", GET_NAP(pIR[i].ba), GET_SAP(pIR[i].ba));
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(name);
// set the name and the address (again, they are the same)
hRet = pPropBag->Write(c_szDevicePropAddress, &var);
SVSUTIL_ASSERT(SUCCEEDED(hRet));
hRet = pPropBag->Write(c_szDevicePropName, &var);
SVSUTIL_ASSERT(SUCCEEDED(hRet));
//
// Put a marker in saying that the name has NOT been completed
//
VariantClear(&var);
var.vt = VT_I4;
var.lVal = 0;
hRet = pPropBag->Write(c_szDevicePropNameCompleted, &var);
// add the transport ID
LPOLESTR pszClsid = NULL;
hRet = StringFromCLSID((REFCLSID) CLSID_BthTransport, &pszClsid);
SVSUTIL_ASSERT(SUCCEEDED(hRet));
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(pszClsid);
CoTaskMemFree(pszClsid);
hRet = pPropBag->Write(c_szDevicePropTransport, &var);
SVSUTIL_ASSERT(SUCCEEDED(hRet));
VariantClear (&var);
// add to the enumeration
pPropEnum->Insert(pPropBag);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?