⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obexdevice.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    if (*szRemotePath == L'\\') 
    {
        //fill in cPacket independent fields
        fields.flags = (char)dwFlags;
        fields.constants = 0;

        if(uiConnectionId != OBEX_INVALID_CONNECTION)
           pHeaders->AddConnectionId(uiConnectionId);

        pHeaders->AddName(L"");

        //move beyond the '\'
        ++szRemotePath;
        ASSERT(*szRemotePath != '\\');

        UCHAR *pNewPacket = NULL;
        ULONG uiNewPackSize;
        
        //send off the packet
        hResult = ObexSendRecvWithAuth(pConnection, uiMaxPacket, wcPassword, cOpCode, (char *)&fields, sizeof(PUTFields), pHeaders, &pNewPacket, &uiNewPackSize);        
        
        if (FAILED(hResult) || pNewPacket[0] != (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
        {
            pHeaders->Release();          
            return E_FAIL;
        }

        pHeaders->Release();
        pHeaders = new CHeaderCollection();
      
        delete [] pNewPacket;
        
        if(!pHeaders)
            return E_OUTOFMEMORY;
    }

    char fError = FALSE;
    while ((! fError) && (*szRemotePath != '\0')) 
    {
        pHeaders->Release();
        pHeaders = new CHeaderCollection();
        
        if(!pHeaders)
            return E_OUTOFMEMORY;

        WCHAR *p = (WCHAR*)wcschr (szRemotePath, L'\\');

        //clear fields
        memset(&fields, 0, sizeof(PUTFields));

        if (p) {
            *p = '\0';
            ASSERT(*(p+1) != '\\');
       }     

        if (wcscmp (szRemotePath, L"..") == 0) 
        {
            fields.flags = 3;
            fields.constants = 0;
            if(uiConnectionId != OBEX_INVALID_CONNECTION)
                pHeaders->AddConnectionId(uiConnectionId);            
        }         
        else if (wcscmp (szRemotePath, L".") == 0) 
        {
            if (p) 
            {
                *p = '\\';
                szRemotePath = p + 1;
                 continue;
            } 
            else
                break;
        } 
        else 
        {
            //fill in cPacket independent fields            
            fields.flags = (char)dwFlags;            
            fields.constants = 0;

            if(uiConnectionId != OBEX_INVALID_CONNECTION)
                pHeaders->AddConnectionId(uiConnectionId);    

            pHeaders->AddName(szRemotePath);    
        }

        //send off the packet
        UCHAR *pNewPacket;
        ULONG uiNewPackSize;
        hResult = ObexSendRecvWithAuth(pConnection, uiMaxPacket, wcPassword, cOpCode, (char *)&fields, sizeof(PUTFields), pHeaders, &pNewPacket, &uiNewPackSize);
 
        if(FAILED(hResult))
            return E_FAIL;

        if (pNewPacket[0] != (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
        {
            SetLastError (ERROR_INVALID_NAME);
            fError = TRUE;
        }
        
        delete [] pNewPacket;

        if (p) 
        {
            *p = '\\';
            szRemotePath = p + 1;
        } 
        else
            break;
    }

    pHeaders->Release();
     
    if(fError) 
        return E_FAIL;

    return S_OK;
}


HRESULT STDMETHODCALLTYPE
CObexDevice::EnumProperties(REFIID riid, void **ppv)
{   
    SVSUTIL_ASSERT(pPropBag);
    if (!ppv)
        return E_INVALIDARG;
    return pPropBag->QueryInterface(riid, ppv);
}

HRESULT STDMETHODCALLTYPE
CObexDevice::SetPassword(LPCWSTR _pszPassToUse)
{
    if(wcslen(_pszPassToUse) >= MAX_PASS_SIZE)
    {
        return E_FAIL;
    }
    

    //
    //  Set the password
    //    
    wcscpy(wcPassword, _pszPassToUse);

    //
    //  return...
    //
    return S_OK;
}

HRESULT STDMETHODCALLTYPE
CObexDevice::BindToStorage(DWORD dwCapability, IStorage **ppStorage)
{
    return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE 
CObexDevice::QueryInterface(REFIID riid, void** ppv) 
{
  DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::QueryInterface()\n"));
  if(!ppv) 
        return E_POINTER;
    if(riid == IID_IObexDevice) 
        *ppv = this;
    else if(riid == IID_IObexDevice) 
        *ppv = static_cast<IObexDevice*>(this);
    else 
        return *ppv = 0, E_NOINTERFACE;

    return AddRef(), S_OK;    
}      


ULONG STDMETHODCALLTYPE 
CObexDevice::AddRef() 
{
    ULONG ret = InterlockedIncrement((LONG *)&_refCount);
    DEBUGMSG(OBEX_ADDREFREL_ZONE,(L"CObexDevice::AddRef(%d) -- 0x%x\n",ret, (int)this));
    return ret;
}

ULONG STDMETHODCALLTYPE 
CObexDevice::Release() 
{
    SVSUTIL_ASSERT(_refCount != 0xFFFFFFFF);
    ULONG ret = InterlockedDecrement((LONG *)&_refCount);
    DEBUGMSG(OBEX_ADDREFREL_ZONE,(L"CObexDevice::Release(%d) -- 0x%x\n",ret, (int)this));
    if(!ret) 
        delete this; 
    return ret;
}



HRESULT
CObexDevice::CompleteDiscovery()
{
    //first make sure that we have figured out all fields required for connection
    //  (the user might have clicked on a BT device before the discovery had
    //    completed)    
    if(GetUpdateStatus() != 0xFFFFFFFF)
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- dont have full device property list... querying for it now\n"));       
        IObexTransport *pTransport = NULL;        
        
        HRESULT hr = CoCreateInstance(clsidTransport, NULL, CLSCTX_INPROC_SERVER, IID_IObexTransport,  
            (void **)&pTransport);

        if(SUCCEEDED(hr) && pTransport)
        {
            IObexAbortTransportEnumeration *pAbortEnum = NULL;
            if(SUCCEEDED(pTransport->QueryInterface(IID_IObexAbortTransportEnumeration, (LPVOID *)&pAbortEnum))) {                    
                    pAbortEnum->Resume();                    
                    pAbortEnum->Release();
            } 
        
            UINT uiUpdateStatus;
            hr = pTransport->UpdateDeviceProperties(pPropBag, NULL, TRUE, &uiUpdateStatus);            

                
            if (FAILED(hr) || 0 == (uiUpdateStatus & CAN_CONNECT))
            {
                DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- updated device to level 0x%x -- NOT GOOD ENOUGH TO CONNECT\n", uiUpdateStatus));
                hr = E_FAIL;
            }
            else
            {
                DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- updated device to level 0x%x -- ready to GO!\n", uiUpdateStatus));
            }
            
            pTransport->Release();            
            pTransport = NULL;            
            return hr;            
        }
        else
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- ERROR couldnt get a transport!\n"));
            return E_FAIL;
        }
    }
    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- SUCCESS -- no need to query, its already been done\n"));
    return S_OK;
}


HRESULT
CObexDevice::ConnectSocket()
{
    HRESULT hRes = S_OK;

    //
    //  complete the discovery phase... if it fails we have to quit
    //
    if(FAILED((hRes=CompleteDiscovery())))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ConnectSocket() --- Failure completing discovery!\n"));
        return hRes;
    }
    else
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ConnectSocket() --- SUCCEEDED completing discovery!\n"));
        

    //
    //  if we are not connected, get connected
    //
    if(!pConnection)
    {
        
        if(FAILED((hRes = ConnectToTransportSocket())))
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ConnectSocket() -- cannot ConnectToTransportSocket\n"));
            return hRes;
        }
        else
             DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ConnectSocket() --- SUCCEEDED with ConnectToTransportSocket!\n"));
    }
    else
       DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ConnectSocket() --- already have connection!\n"));
    

    return hRes;
}

HRESULT
CObexDevice::Connect(LPCWSTR _pszPassToUse, DWORD dwCapability, LPHEADERCOLLECTION pHeaderCollection)
{
    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::Connect()\n"));
    HRESULT hRes;
    BYTE bMyNonce[16];
    BOOL fOkayToContinueWithoutAuthentication = TRUE;
    BOOL fHaveAuthentication = FALSE;

    //verify password size
    if(_pszPassToUse && wcslen(_pszPassToUse) >= MAX_PASS_SIZE)
        return E_FAIL;

    //if we have an obex device but dont have a connection, they have not
    //  used a connection point (and thus have not 'BoundToDevice'...
    //  do the transport connection for them
    if(!pConnection && FAILED(ConnectSocket()))
        return E_FAIL;

    //
    //  if there is no global password, set the one passed in as global
    //
    if(wcPassword[0] == '\0' && _pszPassToUse)
    {
        wcscpy(wcPassword , _pszPassToUse);
    }    
    //
    //  As per spec: use the Connect() password first, if it does not 
    //     exist, use the cached one from SetPassword
    //
    else if(!_pszPassToUse)
    {
        _pszPassToUse = wcPassword;
    }


    //
    //  if a password was sent down, its not okay to continue without authentication
    //      so build up a nonce and put it in along with the headers
    //
    if(_pszPassToUse && wcPassword[0] != '\0')
    {
        fOkayToContinueWithoutAuthentication = FALSE;

        hRes = MakeNonce (_pszPassToUse, bMyNonce);
        if (hRes != ERROR_SUCCESS)
            return hRes;

        BYTE bChallenge[18];
        memcpy(bChallenge+2, bMyNonce, 16);
        bChallenge[0] = 0x00;
        bChallenge[1] = 0x10;
        
        pHeaderCollection->AddByteArray(OBEX_HID_AUTH_CHALLENGE, 18, bChallenge);
    }

    

    //
    //  Build the CONNECT headers
    //
    char packet[4]; 
    WORD wMaxSizeNBO = htons(g_uiMaxFileChunk);
    packet[0] = OBEX_VERSION;                  //version
    packet[1] = 0x00;                          //flags
    packet[2] = ((char *)(&wMaxSizeNBO))[0]; //max PACKET size (in nbo)
    packet[3] = ((char *)(&wMaxSizeNBO))[1];


    //
    //  Send out the CONNECT packet, and recieve a response
    //
    UCHAR *pPacket = 0;
    ULONG uiPackSize;
    hRes = ObexSendRecv(        
        pConnection, 
        uiMaxPacket,
        (char)OBEX_OP_CONNECT, 
        packet, 
        4,        
        pHeaderCollection, 
        &pPacket, 
        &uiPackSize);
    
    if(FAILED(hRes))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::Connect() -- error with ObexSendRecv!\n")); 
        return hRes;
    }

    //
    //  Parse the return packet for its fields
    //
    ObexParser *p = new ObexParser(pPacket, uiPackSize);

    if(!p) {
        return E_OUTOFMEMORY;
    }

    //
    //  if the opcode on the return packet is 0xA0 (OK, Success)
    //      fill out the max packet size and prepare the data
    //        for parsing below.  If it was UNAUTHORIZED (0xC1) then
    //        we need to complete the authorization part
    //    
    if (p->Op() == (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
    {
        WORD wMaxLen;
        ((char *)(&wMaxLen))[0] = pPacket[5];
        ((char *)(&wMaxLen))[1] = pPacket[6];
        uiMaxPacket = htons(wMaxLen) - OBEX_AUTH_HEADER_SIZE; 
 
        if(uiMaxPacket > g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE)
            uiMaxPacket = g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE;

        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexConnect() -- setting max packet size to : %d\n",uiMaxPacket));        
        

        //
        //  Fix up the ObexPacketData by pointing at the start of headers
        //     huh you ask? :)  the CONNECT response is like this
        //        byte0: response code
        //       byte1: connect response packet length
        //       byte2: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        //        byte3: OBEX version #
        //       byte4: flags
        //       byte5: max OBEX packet length
        //     byte6: ^^^^^^^^^^^^^^^^^^^^^^
        //  so we advance the packet by 7 bytes to account for this header stuff
        p->ppkt = pPacket;
        p->start = p->current = (pPacket + 7);
        p->length = uiPackSize - 7;    
    }
    else if(p->Op() == (OBEX_STAT_UNAUTHORIZED | OBEX_OP_ISFINAL)) 
    {    
        BYTE bServerChallenge[16];
        BOOL fChallengeFound = FALSE;

        WORD wMaxLen;
        ((char *)(&wMaxLen))[0] = pPacket[5];
        ((char *)(&wMaxLen))[1] = pPacket[6];
        uiMaxPacket = htons(wMaxLen) - OBEX_AUTH_HEADER_SIZE; 
 
        if(uiMaxPacket > g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE)
            uiMaxPacket = g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE;

        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexConnect() -- DENIED access, but setting max packet size to : %d -- retrying connection with password\n",uiMaxPacket));        
        
        //

⌨️ 快捷键说明

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