obexbthtransport.cpp

来自「Windows CE 6.0 Server 源码」· C++ 代码 · 共 1,341 行 · 第 1/4 页

CPP
1,341
字号

            //fill in fields that we care about        
            if(VT_EMPTY != varUUID.vt)
                pNewBag->Write(c_szDeviceServiceUUID, &varUUID);
                
            if(*uiUpdateStatus & FOUND_TRANSPORT)
                pNewBag->Write(c_szDevicePropTransport, &varTransportVar);
                
            if(*uiUpdateStatus & FOUND_NAME)
                pNewBag->Write(c_szDevicePropName, pNameVar);

            if(pNameCompletedVar)
                pNewBag->Write(c_szDevicePropNameCompleted, pNameCompletedVar);

            //
            // Add the port
            varPort.vt = VT_I4;                
            varPort.lVal = pList->ulChannel;
            hr = pNewBag->Write(c_szPort, &varPort);
            SVSUTIL_ASSERT(SUCCEEDED(hr));
           
            DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::ChannelQueryHelper-Device (%04x%08x) running Obex server on channel %d\n", GET_NAP(ba), GET_SAP(ba), pList->ulChannel));    
            
            //insert the new bag into the linked list
            pNewBagEnum->Insert(pNewBag);
            pNewBag->Release();
        }
        else if(FALSE == fGetJustEnoughToConnect ||
               ((TRUE == fGetJustEnoughToConnect) && (TRUE == fHasDefaultService))) {
                varPort.vt = VT_I4;
                varPort.lVal = pList->ulChannel;
                hr = pPropBag->Write(c_szPort, &varPort);
                SVSUTIL_ASSERT(SUCCEEDED(hr));

                //add the service UUID
                if(VT_EMPTY != varUUID.vt)
                    pPropBag->Write(c_szDeviceServiceUUID, &varUUID);
                            
                DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::ChannelQueryHelper-Device (%04x%08x) running Obex server on channel %d -- stopping here\n", GET_NAP(ba), GET_SAP(ba), pList->ulChannel));    

                if(TRUE == fGetJustEnoughToConnect) {
                    fFoundEnoughToConnectOn = TRUE;
                }
                break;          
        }       

        BT_CHANNEL_LIST *pDel = pList;
        pList = pList->pNext;
        DeleteBtChannelListNode(pDel);
    }

    if(TRUE == fGetJustEnoughToConnect && (FALSE == fFoundEnoughToConnectOn)) {
        DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::EnumDevices - Device (%04x%08x) didnt have enough to connect to! failing\n", GET_NAP(ba), GET_SAP(ba)));                           
        hr = E_FAIL;
        goto Done;
    }
    
    //
    // Success!
    *uiUpdateStatus = *uiUpdateStatus | FOUND_PORT;
    *uiUpdateStatus = *uiUpdateStatus | CAN_CONNECT;
    hr = S_OK;

    Done:
        while(pList) {
            BT_CHANNEL_LIST *pDel = pList;
            pList = pList->pNext;
            DeleteBtChannelListNode(pDel);            
        }
        
        VariantClear(&varUUID);   
        VariantClear(&varTransportVar);
        VariantClear(&varPort);
        VariantClear(&varRequestedService);
        return hr;
}



//NOTE:  passing NULL to _ppNewBagEnum results in just the existing bag being updated... no enum
//  will be returned
HRESULT STDMETHODCALLTYPE 
CObexBTHTransport::UpdateDeviceProperties(LPPROPERTYBAG2 pPropBag, 
                                          IPropertyBagEnum **_ppNewBagEnum, 
                                          BOOL fGetJustEnoughToConnect, 
                                          UINT *uiUpdateStatus)
{    
    DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties on bag: 0x%x\n", (int)pPropBag));

    SVSUTIL_ASSERT(pPropBag && uiUpdateStatus);
    BOOL fAbort;    
    HRESULT hRes = S_OK;
    
    // if we are told to abort, do so
    IsAborting(&fAbort);        
    if(TRUE == fAbort) {        
        return E_ABORT;  
    }    

    if(fGetJustEnoughToConnect)
    {
        SVSUTIL_ASSERT(!_ppNewBagEnum);
    }
    if(_ppNewBagEnum)
    {
        SVSUTIL_ASSERT(!fGetJustEnoughToConnect);
    }

    if (!pPropBag || !uiUpdateStatus)
    {
        DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties -- INVALID PARAM!\n"));
        return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WINDOWS, ERROR_INVALID_PARAMETER);
    }

    if(_ppNewBagEnum)
        *_ppNewBagEnum = NULL;

    //set the mask to have nothing
    *uiUpdateStatus = 0;

    //varaibles
    BT_ADDR ba;    
    
    //
    //  See how much information we already have
    //
    VARIANT AddressVar;
    VARIANT NameVar;
    VARIANT NameCompletedVar;
    VARIANT PortVar;

    BOOL fHaveNameCompleted = FALSE;
    
    VariantInit(&AddressVar);
    VariantInit(&NameVar);
    VariantInit(&NameCompletedVar);
    VariantInit(&PortVar);

    
    //grab the address and setup the BT_ADDR struct
    if ((FAILED(pPropBag->Read(c_szDevicePropAddress, &AddressVar, NULL))) || (AddressVar.vt != VT_BSTR))
    {
        DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateDeviceProperties-Cant get BTA from BSTR!\n"));
        VariantClear(&AddressVar);        
        return  E_FAIL;
    }
    // move in the device id for the selected device 
    else if(!CObexBTHTransport::GetBA(AddressVar.bstrVal, &ba))
    {
        DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties-Device addrress missing in property bag.\n"));
        VariantClear(&AddressVar);
        return E_FAIL;
    }
    
    //see how far we have progressed by reading from the property bag
    if(SUCCEEDED(pPropBag->Read(c_szDevicePropName, &NameVar, 0)))    
        *uiUpdateStatus = *uiUpdateStatus | FOUND_NAME;
    if(SUCCEEDED(pPropBag->Read(c_szDevicePropNameCompleted, &NameCompletedVar, 0)))
        fHaveNameCompleted = TRUE;
    if(SUCCEEDED(pPropBag->Read(c_szPort, &PortVar, 0)))    
        *uiUpdateStatus = *uiUpdateStatus | CAN_CONNECT | FOUND_PORT;

   
    if( !(g_dwObexCaps & SEND_DEVICE_UPDATES))
    {
        //lie about finding a port for PPC2002
        if(!fGetJustEnoughToConnect)
           *uiUpdateStatus |= FOUND_PORT;
        else
           *uiUpdateStatus &= ~(FOUND_PORT); 
    }        
   
    //
    //  If we have enough to connect, just return (w/o query) otherwise,
    //     we will go after the name/port.... UNLESS fGetJustEnoughToConnect is set
    //     then (assuming we can connect) just send back okay
    if(  (*uiUpdateStatus & FOUND_NAME) && 
         (*uiUpdateStatus & FOUND_PORT) &&                
         (fHaveNameCompleted && 1 == NameCompletedVar.lVal)
      )
    {
        DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties - got enough to connect\n"));
        *uiUpdateStatus = 0xFFFFFFFF;
        hRes = S_OK;
    }
    else if(fGetJustEnoughToConnect && (*uiUpdateStatus & FOUND_PORT))
    {            
        hRes = S_OK; 
    } 
    //if no name query for one
    else if(!fGetJustEnoughToConnect &&
            (0 == (*uiUpdateStatus & FOUND_NAME) || 
            !fHaveNameCompleted || 
            (fHaveNameCompleted &&  0 == NameCompletedVar.lVal)))
    {    
        hRes = NameQueryHelper(pPropBag, 
                               &NameVar, 
                               ba,
                               uiUpdateStatus); 
        if(FAILED(hRes))
            DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties - NameQueryHelper FAILED\n"));        

    }
    
    //if not port, query for one
    else if(0 == (*uiUpdateStatus & FOUND_PORT))
    {      
        //ChannelQueryHelper return E_ if no OBEX
        //  otherwise, S_ (we might need to ask again)
        hRes = ChannelQueryHelper(pPropBag, 
                                  &NameVar,
                                  &NameCompletedVar,
                                  &AddressVar,
                                  ba, 
                                  _ppNewBagEnum, 
                                  uiUpdateStatus,
                                  fGetJustEnoughToConnect);
        if(FAILED(hRes))
            DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::UpdateProperties - ChannelQueryHelper FAILED\n"));        
    }
  
   


    //clean out all variants (we have what we need)
    VariantClear(&AddressVar); 
    VariantClear(&NameVar); 
    VariantClear(&PortVar); 
    VariantClear(&NameCompletedVar);

     if(*uiUpdateStatus == 0xFFFFFFFF)
         return S_OK;
     else if(SUCCEEDED(hRes))
        return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_WINDOWS, ERROR_CONTINUE);
     else 
        return hRes;
}

HRESULT STDMETHODCALLTYPE 
CObexBTHTransport::EnumProperties(LPPROPERTYBAG2 __RPC_FAR *ppProps)
{
     return E_NOTIMPL;
}

ULONG STDMETHODCALLTYPE 
CObexBTHTransport::AddRef() 
{
    DEBUGMSG(OBEX_ADDREFREL_ZONE,(L"CObexDevicePropBag::AddRef()\n"));
    return InterlockedIncrement((LONG *)&_refCount);
}

ULONG STDMETHODCALLTYPE 
CObexBTHTransport::Release() 
{
    DEBUGMSG(OBEX_ADDREFREL_ZONE,(L"CObexDevicePropBag::Release()\n"));
    SVSUTIL_ASSERT(_refCount != 0xFFFFFFFF);
    ULONG ret = InterlockedDecrement((LONG *)&_refCount);    
    if(!ret) 
        delete this; 
    return ret;
}

HRESULT STDMETHODCALLTYPE 
CObexBTHTransport::QueryInterface(REFIID riid, void** ppv) 
{
    DEBUGMSG(OBEX_BTHTRANSPORT_ZONE,(L"CObexBTHTransport::QueryInterface()\n"));
       if(!ppv) 
        return E_POINTER;
    else if(riid == IID_IUnknown) 
        *ppv = this;
    else if(riid == IID_IObexTransport) 
        *ppv = static_cast<IObexTransport*>(this); 
      else if(riid == IID_IObexAbortTransportEnumeration)
        *ppv = static_cast<IObexAbortTransportEnumeration*>(this);
    else 
        return *ppv = 0, E_NOINTERFACE;

    return AddRef(), S_OK;    
}

HRESULT STDMETHODCALLTYPE
CObexBTHTransport::Abort()
{
    fIsAborting = TRUE;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE
CObexBTHTransport::Resume()
{
    fIsAborting = FALSE;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE
CObexBTHTransport::IsAborting(BOOL *_fIsAborting)
{
    *_fIsAborting = fIsAborting;
    return S_OK;
}


int 
CObexBTHTransport::GetBA (WCHAR *pp, BT_ADDR *pba) 
{
    while (*pp == ' ')
        ++pp;

    
    for (int i = 0 ; i < 12 ; ++i, ++pp) 
    {
        if (! iswxdigit (*pp))
            return FALSE;

        int c = *pp;
        if (c >= 'a')
            c = c - 'a' + 0xa;
        else if (c >= 'A')
            c = c - 'A' + 0xa;
        else c = c - '0';

        if ((c < 0) || (c > 16))
            return FALSE;

        *pba = (*pba << 4) + c;
    }

    if ((*pp != ' ') && (*pp != '\0'))
        return FALSE;

    return TRUE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?