obexbthtransport.cpp
来自「Windows CE 6.0 Server 源码」· C++ 代码 · 共 1,341 行 · 第 1/4 页
CPP
1,341 行
pPropBag->Release();
pPropBag = NULL;
}
*ppDevices = pPropEnum;
pPropEnum = NULL; // <-- set it null so we dont release it
hRet = S_OK;
Cleanup:
if(hLib)
FreeLibrary(hLib);
if(pPropEnum)
pPropEnum->Release();
if(pPropBag)
pPropBag->Release();
if(pIR)
delete [] pIR;
VariantClear(&var);
return hRet;
}
/**********************************************************************************/
/* */
/* NameQueryHelper: */
/* */
/* Passed in is the VARIANT pointer NameVar */
/* it is just passed in (even though itsin the bag) because this is */
/* just a helper for UpdateDeviceProperties... */
/* */
/* Returned: */
/* HRESULT describing what happened... FAILURE only happens something bad */
/* happened */
/* */
/* uiUpdateStatus is in/out -- it returns the status after being run */
/**********************************************************************************/
HRESULT
CObexBTHTransport::NameQueryHelper(LPPROPERTYBAG2 pPropBag,
VARIANT *pNameVar,
BT_ADDR ba,
UINT *uiUpdateStatus)
{
HRESULT hRes = E_FAIL;
//
// First consult our name cache... if the BT name is there, dont SDP it!
//
NAME_CACHE_NODE *pNameCacheTemp = pNameCache;
while(pNameCacheTemp)
{
//oh yeah! the name is cached no SDP query needed!
if(GET_NAP(ba) == GET_NAP(pNameCacheTemp->ba) &&
GET_SAP(ba) == GET_SAP(pNameCacheTemp->ba))
{
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE, (L"[BT] -- UpdateDeviceProperties: Found name in cache! no need to SDP! yippie!\n"));
hRes = pPropBag->Write(c_szDevicePropName, &pNameCacheTemp->var);
SVSUTIL_ASSERT(SUCCEEDED(hRes));
VARIANT NameCompletedVar;
VariantInit(&NameCompletedVar);
NameCompletedVar.vt = VT_I4;
NameCompletedVar.lVal = 1;
hRes = pPropBag->Write(c_szDevicePropNameCompleted, &NameCompletedVar);
SVSUTIL_ASSERT(SUCCEEDED(hRes));
VariantClear(&NameCompletedVar);
*uiUpdateStatus = *uiUpdateStatus | FOUND_NAME;
return S_OK;
}
pNameCacheTemp = pNameCacheTemp->pNext;
}
//
// If the name couldnt be found in our cache, we need to do a query for it
//
WCHAR szName[_MAX_PATH];
unsigned int dwLength = 0;
szName[0] = '\0';
typedef int (*TBthRemoteNameQuery) (BT_ADDR *pba, unsigned int cBuffer, unsigned int *pcRequired, WCHAR *szString);
HINSTANCE hLib = LoadLibrary (L"btdrt.dll");
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE, (L"[BT] -- UpdateDeviceProperties: getting name\n"));
if (hLib)
{
TBthRemoteNameQuery pBthRemoteNameQuery = (TBthRemoteNameQuery)GetProcAddress (hLib, L"BthRemoteNameQuery");
if (pBthRemoteNameQuery)
{
int iErr = pBthRemoteNameQuery (&ba, _MAX_PATH, &dwLength, szName);
FreeLibrary(hLib);
if(ERROR_SUCCESS != iErr)
{
szName[0] = L'\0';
return (ERROR_TIMEOUT==iErr)?S_OK:E_FAIL;
}
else if ((dwLength <= 0) || (dwLength >= _MAX_PATH))
{
szName[0] = L'\0';
return S_OK;
}
}
else
{
FreeLibrary(hLib);
return E_FAIL;
}
}
else
return E_FAIL;
if (dwLength >= 1)
{
//if we have a name better than the one we had
if(dwLength > 1)
{
VariantClear(pNameVar);
pNameVar->vt = VT_BSTR;
pNameVar->bstrVal = SysAllocString(szName);
//put the newly found name into our name cache
NAME_CACHE_NODE *pNewCacheNode = new NAME_CACHE_NODE();
if(!pNewCacheNode) {
return E_OUTOFMEMORY;
}
memcpy(&pNewCacheNode->ba,&ba,sizeof(BT_ADDR));
VariantInit(&pNewCacheNode->var);
hRes = VariantCopy(&pNewCacheNode->var, pNameVar);
SVSUTIL_ASSERT(SUCCEEDED(hRes));
if(FAILED(hRes))
return hRes;
pNewCacheNode->pNext = pNameCache;
pNameCache = pNewCacheNode;
hRes = pPropBag->Write(c_szDevicePropName, pNameVar);
SVSUTIL_ASSERT(SUCCEEDED(hRes));
if(FAILED(hRes))
return hRes;
}
VARIANT NameCompletedVar;
VariantInit(&NameCompletedVar);
NameCompletedVar.vt = VT_I4;
NameCompletedVar.lVal = 1;
hRes= pPropBag->Write(c_szDevicePropNameCompleted, &NameCompletedVar);
SVSUTIL_ASSERT(SUCCEEDED(hRes));
VariantClear(&NameCompletedVar);
//update status on what we have found
*uiUpdateStatus = *uiUpdateStatus | FOUND_NAME;
return S_OK;
}
return E_FAIL;
}
/**********************************************************************************/
/*
/* ChannelQueryHelper:
/*
/* Passed in are the VARIANT pointers (NameVar, NameCompletedVar, and AddressVar
/* they are passed in (even though they are in the bag) because this is
/* just a helper for UpdateDeviceProperties...
/*
/* Returned:
/* HRESULT describing what happened... FAILURE only happens if the
/* device doesnt support OBEX or something bad happened
/*
/* _ppNewBagEnum will return a properybag enum describing all newly discovered
/* devices
/*
/* uiUpdateStatus is in/out -- it returns the status after being run
/**********************************************************************************/
HRESULT
CObexBTHTransport::ChannelQueryHelper(LPPROPERTYBAG2 pPropBag,
VARIANT *pNameVar,
VARIANT *pNameCompletedVar,
VARIANT *pAddressVar,
BT_ADDR ba,
IPropertyBagEnum **_ppNewBagEnum,
UINT *uiUpdateStatus,
BOOL fGetJustEnoughToConnect)
{
HRESULT hr;
BT_CHANNEL_LIST *pList = NULL;
CPropertyBagEnum *pNewBagEnum = NULL;
WCHAR *pRequestedService = NULL;
BOOL fHasDefaultService = FALSE;
BOOL fFoundEnoughToConnectOn = FALSE;
VARIANT varTransportVar;
VARIANT varUUID;
VARIANT varPort;
VARIANT varRequestedService;
VariantInit(&varUUID);
VariantInit(&varTransportVar);
VariantInit(&varPort);
VariantInit(&varRequestedService);
//
// If the query succeeded but no list was returned, the device doesnt support
// obex so we return with an error.
//
//Check if this device supports Obex services : (Obex UUID = UUID16 8)
hr = QueryForChannel(ba, &pList);
if(SUCCEEDED(hr) && (NULL == pList)) {
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices-Device (%04x%08x) does not support Obex.\n", GET_NAP(ba), GET_SAP(ba)));
hr = E_FAIL;
goto Done;
}
else if(FAILED(hr)) {
SVSUTIL_ASSERT(!pList);
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices-Device (%04x%08x) query failed, will retry\n", GET_NAP(ba), GET_SAP(ba)));
hr = S_OK;
goto Done;
}
//
// Loop through all the returned nodes adding them (and creating new
// devices if required)
//
hr = pPropBag->Read(c_szDevicePropTransport, &varTransportVar, 0);
if(pList && SUCCEEDED(hr)) {
*uiUpdateStatus = *uiUpdateStatus | FOUND_TRANSPORT;
}
hr = pPropBag->Read(c_szDeviceRequestedServiceUUID ,&varRequestedService, 0);
if(SUCCEEDED(hr) &&
VT_BSTR == varRequestedService.vt) {
pRequestedService = varRequestedService.bstrVal;
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices-Device (%04x%08x) trying to use default service %s\n", GET_NAP(ba), GET_SAP(ba),pRequestedService));
} else {
pRequestedService = L"{00001105-0000-1000-8000-00805f9b34fb}";
}
while(pList)
{
//
// Make sure everything is cleaned up
VariantClear(&varUUID);
VariantClear(&varPort);
//
// Count UUID's, and make a string of them... will be placed into
// property bag below
//
if(pList->pUUIDList)
{
UINT cUUID = 0;
BT_UUID16_LIST *pUUIDTemp = pList->pUUIDList;
WCHAR UUIDString[39 * 3];
WCHAR *pUUIDString = UUIDString;
WCHAR *pUUIDTempString = pUUIDString;
while(pUUIDTemp) {
cUUID++;
pUUIDTemp = pUUIDTemp->pNext;
}
//36 = size of GUID + 2 for {}'s and 1 for ; (or null on last)
if(sizeof(UUIDString) < (cUUID * 39 * sizeof(WCHAR))) {
pUUIDTempString = pUUIDString = new WCHAR[(cUUID * 39)];
if(NULL == pUUIDString) {
hr = E_OUTOFMEMORY;
goto Done;
}
}
pUUIDTemp = pList->pUUIDList;
while(pUUIDTemp) {
int len;
if(pUUIDTemp->pNext)
len = swprintf(pUUIDTempString, GUID_FORMAT_SEP, GUID_ELEMENTS(pUUIDTemp->uuid));
else
len = swprintf(pUUIDTempString, GUID_FORMAT, GUID_ELEMENTS(pUUIDTemp->uuid));
//
// see if this UUID is for the default inbox (do a wcsstr since a ; may bein the tempstring)
if(pUUIDTempString == wcsstr(pUUIDTempString, pRequestedService)) {
DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::ChannelQueryHelper- found requested service!\n"));
fHasDefaultService = TRUE;
}
pUUIDTempString += len;
BT_UUID16_LIST *pDelNode = pUUIDTemp;
pUUIDTemp = pUUIDTemp->pNext;
delete pDelNode;
}
pList->pUUIDList = NULL;
varUUID.vt = VT_BSTR;
varUUID.bstrVal = SysAllocString(pUUIDString);
if(pUUIDString != UUIDString) {
delete [] pUUIDString;
}
}
//if there are more nodes, clone this one and add it on
if(_ppNewBagEnum && pList->pNext)
{
CPropertyBag *pNewBag = NULL;
if(NULL == pNewBagEnum) {
pNewBagEnum = new CPropertyBagEnum();
if(NULL == pNewBagEnum) {
hr = E_OUTOFMEMORY;
goto Done;
}
*_ppNewBagEnum = pNewBagEnum;
}
if(NULL == (pNewBag = new CPropertyBag())) {
delete pNewBagEnum;
hr = E_OUTOFMEMORY;
goto Done;
}
//fill in fields that we care about
pNewBag->Write(c_szDevicePropAddress, pAddressVar);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?