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

📄 obexdevice.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    pPacket = NULL;
    p = NULL;

    hRes = ObexSendRecv(pConnection, 
                                uiMaxPacket,
                                cOpCode,                                 
                                additionalDta, 
                                cAddnlDta, 
                                pHeaderCollection, 
                                pNewPacket, 
                                pSize);
    if(FAILED(hRes))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- error with ObexSendRecv!\n")); 
        return hRes;
    }


    //
    //  create a new parser, and double check the opcode
    //    
    pPacket = *pNewPacket;
    uiPacketSize = *pSize;
    p = new ObexParser(pPacket, uiPacketSize);

    if (!p || p->Op() == (OBEX_STAT_UNAUTHORIZED | OBEX_OP_ISFINAL)) 
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- we were *NOT* verified... wrong password?!\n")); 
        if(p) 
            delete p;
        return OBEX_E_CONNECTION_NOT_ACCEPTED;
    }    
    else
        hr = S_OK;

    delete p;
    return hr;
}
    



HRESULT  
ObexSendRecv(IObexTransportConnection *pConnection,
                 UINT uiMaxPacket, 
                 char opCode, 
                 char *additionalDta,
                 UINT cAddnlDta, 
                 IHeaderCollection *pHeaders, 
                 unsigned char **pNewPacket, 
                 ULONG *pSize)
{
    SVSUTIL_ASSERT(pHeaders && pConnection); 
    
    *pNewPacket = 0;
    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend()\n"));

    if(!pConnection)
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- pConnection not there!\n"));
        return E_FAIL;
    }
    
    //send off the packet
    HRESULT hRet = S_OK;
    UINT uiHeaderSize = 0; 
    char *pHeader = 0;
   
    //if there are headers, make up the data
    if(pHeaders && (uiHeaderSize = SizeOfHeader(pHeaders)) > 0)
    {
        IHeaderEnum *pHeaderEnum;
        if(FAILED(pHeaders->EnumHeaders(&pHeaderEnum)))
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- cant enum headers!\n"));
            return E_FAIL;
        }
        
        OBEX_HEADER *myHeader = 0;
        ULONG ulFetched;
        UINT uiPacketSize;

        //see how big the headers are 
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"  ObexSend::Seeing how big the headers are\n"));
      
        //so here's the scoop here... I've allocated 21 special bytes that 
        //   are used for authentication.  At this point they MIGHT not have 
        //   been used by the authentication (maybe the server doesnt care who we are)
        //   so dotn check for it        
        //if(1 + 2 + cAddnlDta + uiHeaderSize > uiMaxPacket + OBEX_AUTH_HEADER_SIZE)
        uiPacketSize = 1 + 2;
        if(FAILED(UIntAdd(cAddnlDta, uiPacketSize, &uiPacketSize)) ||
           FAILED(UIntAdd(uiHeaderSize, uiPacketSize, &uiPacketSize))) {
            SVSUTIL_ASSERT(FALSE); //dont remove this ASSERT... if we got here
                                   //  there is a bug in the client
            pHeaderEnum->Release();
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- packet too large! internal error\n"));  
            return E_FAIL;
        }
        
        if(uiPacketSize > uiMaxPacket + OBEX_AUTH_HEADER_SIZE)
        {
            SVSUTIL_ASSERT(FALSE); //dont remove this ASSERT... if we got here
                                   //  there is a bug in the client
            pHeaderEnum->Release();
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- packet too large! internal error\n"));  
            return E_FAIL;
        }
        
        //allocate enough memory to hold them
        UINT uiRemaining = uiHeaderSize;
        pHeader = new char[uiHeaderSize];
        if(!pHeader)
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"Couldnt allocate: %d bytes\n", uiHeaderSize));
            return E_OUTOFMEMORY;
        }
        char *pHeaderTemp = pHeader;

        //copy in the data
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"  ObexSend::Copying in headers\n"));
        pHeaderEnum->Reset();
        while(SUCCEEDED(pHeaderEnum->Next(1, &myHeader, &ulFetched)))
        {
            if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_DWORD)  
            {
                *pHeaderTemp = myHeader->bId;
                DWORD valNBO = htonl(myHeader->value.dwData);
                if(uiRemaining < 4)
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- cant fit everything into buffer\n"));  
                    ASSERT(FALSE);
                    return E_FAIL;
                }
                uiRemaining -= 5;
                
                memcpy(pHeaderTemp+1, (char *)&valNBO, 4);
                pHeaderTemp += (4 + 1);
            }
            else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_BYTE)
            {
                if(uiRemaining < 2)
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- cant fit everything into buffer\n"));  
                    ASSERT(FALSE);
                    return E_FAIL;
                }
                uiRemaining -= 2;
                
                *pHeaderTemp = myHeader->bId;
                *(pHeaderTemp + 1) = myHeader->value.bData;
                pHeaderTemp+=2;                
            }
            else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_BYTESEQ)
            {
                SVSUTIL_ASSERT(myHeader->value.ba.dwSize + 3 <= 0xFFFF);
                WORD dwSize = (WORD)(myHeader->value.ba.dwSize + 3);
                WORD dwSizeNBO = htons(dwSize);
                
                //
                // Make sure everything fits and look for overflow on value.ba.dwSize
                if(myHeader->value.ba.dwSize > OBEX_MAX_PACKET_SIZE-3 || uiRemaining < dwSize)
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- cant fit everything into buffer\n")); 
                    ASSERT(FALSE);
                    return E_FAIL;
                }
                uiRemaining -= dwSize;
                
                *pHeaderTemp = myHeader->bId;
                pHeaderTemp[1] = ((char *)&dwSizeNBO)[0];
                pHeaderTemp[2] = ((char *)&dwSizeNBO)[1];
                PREFAST_SUPPRESS(508, "overflow is checked about 10 lines up");
                memcpy(pHeaderTemp+3, myHeader->value.ba.pbaData, myHeader->value.ba.dwSize);
                pHeaderTemp += dwSize;
            }
            else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_UNICODE)
            {
                WORD dwStrLen = wcslen(myHeader->value.pszData);
                WORD dwSize = (dwStrLen ? ((dwStrLen + 1) * sizeof(WCHAR)) : 0) + 3;

                if(uiRemaining < dwSize)
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- cant fit everything into buffer\n"));
                    ASSERT(FALSE);
                    return E_FAIL;
                }
                uiRemaining -= 3; // account for the header below

                *pHeaderTemp = myHeader->bId;
                pHeaderTemp[1] = (dwSize >> 8) & 0xff;
                pHeaderTemp[2] = dwSize & 0xff;;

                if (dwStrLen)
                {
                    unsigned char *pbuf = (unsigned char *)(pHeaderTemp+3);
                    WCHAR *psz = myHeader->value.pszData;
                    
                    //copy in the data, making it into NBO                    
                    while (*psz && uiRemaining>=2)
                    {
                        *pbuf++ = (*psz >> 8) & 0xff;
                        *pbuf++ = (*psz) & 0xff;
                        uiRemaining-=2;
                        ++psz;
                    }

                    *pbuf++ = 0;
                    *pbuf++ = 0;
                    uiRemaining-=2;
                }
                pHeaderTemp += dwSize;
            }           
        }
        ASSERT(uiRemaining == 0);
        pHeaderEnum->Release();
    }

    //build up a packet 
    WORD wPacketSize = 0;   
    WORD wAddnlDta = cAddnlDta;
    DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"  SendPacket::Building packet\n"));
    
    if(cAddnlDta > 0xFFFF || 
       FAILED(WordAdd(1, 2, &wPacketSize)) ||
       FAILED(WordAdd(wAddnlDta, wPacketSize, &wPacketSize)) ||
       FAILED(WordAdd(uiHeaderSize, wPacketSize, &wPacketSize))) {
            delete [] pHeader;
            pHeader = 0;        
            return E_OUTOFMEMORY;
    }
    
    WORD wPacketSizeNBO = htons(wPacketSize);
    char *pPacket = new char[wPacketSize];
   
    if(!pPacket)
    {     
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"SendPacket:: Couldnt allocate: %d bytes\n", wPacketSize));
        delete [] pHeader;
        pHeader = 0;        
        return E_OUTOFMEMORY;
    }

    pPacket[0] = opCode;
    memcpy(pPacket+1, (char *)&wPacketSizeNBO, 2);
    memcpy(pPacket+3, additionalDta, wAddnlDta);
    if(pHeader)
    {       
        memcpy(pPacket+3+wAddnlDta, pHeader, uiHeaderSize);       
        delete [] pHeader;
        pHeader = 0;
    }

#if defined(DEBUG) || defined(_DEBUG)
    DEBUGMSG(OBEX_DUMP_PACKETS_ZONE, (L"Sending -------------------------------"));
    DumpBuff ((UCHAR *)&pPacket[0], wPacketSize);
#endif


    //send out pPacket with size wPacketSize and recieve an ACK
    *pNewPacket = new UCHAR[g_uiMaxFileChunk];
    if( !(*pNewPacket) )
    {
        delete [] pPacket;
        return E_OUTOFMEMORY;
    }
    SVSUTIL_ASSERT(wPacketSize <= uiMaxPacket + OBEX_AUTH_HEADER_SIZE);
    hRet = pConnection->SendRecv(wPacketSize, (UCHAR *)pPacket, g_uiMaxFileChunk, *pNewPacket, pSize,0);
    delete [] pPacket;
    if (FAILED(hRet))
    {
        delete[] *pNewPacket;
        *pNewPacket = 0;
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecv -- SendRecv Failed!\n"));              
    }
    return hRet;
}


HRESULT
CObexDevice::ConnectToTransportSocket()
{
    PREFAST_ASSERT(pPropBag);
    DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket"));        
       

    HRESULT hr;

    //if we are alreay connected, release the connection
    if(pConnection)
    {
        pConnection->Release();
        pConnection = NULL;
    }
    if(pSocket)
    {
        pSocket->Release();
        pSocket = NULL;
    }

    //get the transport guid from the propterybag
    VARIANT var;
    VariantInit(&var);
    hr = pPropBag->Read(c_szDevicePropTransport, &var, 0);

    if(FAILED(hr)){
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket -- cannot read from transport!"));        
        return E_FAIL;
    }

    CLSID clsid;
    hr = CLSIDFromString(var.bstrVal, &clsid);  
    VariantClear(&var);

    if(FAILED(hr))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket -- cannot get CLSID from string!"));            
        return hr;
    }
   
    //seek out a transport
    IObexTransport *pTransport;
    hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IObexTransport,  
        (void **)&pTransport);
    
    if(FAILED(hr))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket -- cannot CoCreate an !"));              
        return E_FAIL;
    }

    IObexAbortTransportEnumeration *pAbortEnum = NULL;
    if(SUCCEEDED(pTransport->QueryInterface(IID_IObexAbortTransportEnumeration, (LPVOID *)&pAbortEnum))) {                    
            pAbortEnum->Resume();                    
            pAbortEnum->Release();
    } 
    
    if(SUCCEEDED(pTransport->CreateSocket(pPropBag, &pSocket)))
    {
        hr = pSocket->Connect(pPropBag, 0, &pConnection);
        if(FAILED(hr))
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket -- cannot Connect!"));              
            pSocket->Release();
            pSocket = 0;
        }       
    }
    else
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE, (L"CObexDevice::ConnectToTransportSocket -- cannot CreateSocket()!"));                     
    }

    pTransport->Release();

    if(SUCCEEDED(hr))
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::CompleteDiscovery() -- SUCCEEDED\n"));        
    return hr;
}

HRESULT
CObexDevice::GetDeviceName(VARIANT *pvarName)
{
    return pPropBag->Read(c_szDevicePropName, pvarName, NULL);
}

HRESULT
CObexDevice::GetDeviceAddress(VARIANT *pvarAddr)
{    
    return pPropBag->Read(c_szDevicePropAddress, pvarAddr, NULL);
}

HRESULT
CObexDevice::GetDevicePort(VARIANT *pvarAddr)
{    
    return pPropBag->Read(c_szPort, pvarAddr, NULL);
}

HRESULT 
CObexDevice::GetDeviceTransport(VARIANT *pvarAddr)
{
    return pPropBag->Read(c_szDevicePropTransport, pvarAddr, NULL);
}

HRESULT
CObexDevice::GetPropertyBag(LPPROPERTYBAG2 *ppBag)
{
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexDevice::GetPropertyBag()\n"));
    PREFAST_ASSERT(ppBag);
    PREFAST_ASSERT(pPropBag);

    pPropBag->AddRef();
    *ppBag = pPropBag;
    return S_OK;    
}


UINT 
SizeOfHeader(IHeaderCollection *pHeader)
{   
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexDevice::SizeOfHeader()\n"));
    UINT uiHSize = 0;
    OBEX_HEADER *myHeader;
    ULONG ulFetched;
    LPHEADERENUM pHeaderEnum;

    pHeader->EnumHeaders(&pHeaderEnum);

    //see how big the headers are 
    while(SUCCEEDED(pHeaderEnum->Next(1, &myHeader, &ulFetched)))
    {
        //determine the lenght of the data
        if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_DWORD)             
            uiHSize += (4 + 1);
        else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_BYTESEQ)
            uiHSize += (myHeader->value.ba.dwSize + 3);
        else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_UNICODE)
        {
            DWORD dwCsLen = wcslen(myHeader->value.pszData);
            uiHSize += dwCsLen ? (((dwCsLen+1) * sizeof(WCHAR)) + 3) : 3;
        }
        else if((myHeader->bId & OBEX_TYPE_MASK) == OBEX_TYPE_BYTE)
            uiHSize += (1 + 1);
    }

    pHeaderEnum->Release();

    return uiHSize;
}

⌨️ 快捷键说明

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