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 + -
显示快捷键?