obexstream.cpp

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

CPP
1,418
字号
                    if(cLen)
                    {
                        memcpy(pcBodyChunk + uiBodyLen, pBuf, cLen); 
                        uiBodyLen += cLen; 
                    }

                    if (p.IsA (OBEX_HID_BODY_END) || p.Op() == (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
                    {
                      DEBUGMSG(OBEX_NETWORK_ZONE, (L"OBEX_HID_BODY_END reached...\n"));                   
                      fReadFinished = TRUE;
                    }
                }
                p.Next ();
            } 

            //at this point we dont need the packet anymore so delete it
            if(ucIncomingPacket)
                delete [] ucIncomingPacket;   
        } 
        else
        {
            if(ucIncomingPacket)
                delete [] ucIncomingPacket;   
            return E_FAIL;
        }
    }
    else
        return E_FAIL;


CallReadAgain:
   
    *pcbRead = cbRead;
    return S_OK;
}


//CObexStream::Write -- just do a sanity check for OBEX_PUT
//  and setup the opCode to be OBEX_OP_PUT (this is done because
//  the WriteAll function is used by Get's where the opcode
//  is different
HRESULT STDMETHODCALLTYPE
CObexStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
{  
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::Write() -- %d bytes\n", cb));
    HRESULT hr = E_FAIL;
    
     if(uiStreamType != OBEX_PUT || StreamDisabled()) 
     {
        return E_FAIL;
     }

     hr = WriteAll(OBEX_OP_PUT, pv, cb, pcbWritten);  
     
     if(FAILED(hr))
     {
         DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::Write() -- failed.  cutting off stream!\n"));
         uiStreamType = OBEX_ERR;
     }
     else
     {
        ASSERT(*pcbWritten == cb);
     }             
     return hr;
}


//WriteAllHeaders is a utility used by WriteAll for transmitting a set of 
//  user passed in headers that are bigger than one packet.  It returns when the 
//  headers in myHeaderCollection are smaller in size than one OBEX packet
HRESULT 
CObexStream::WriteAllHeaders(char cOpCode, UINT uiMINPackSize)
{
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- cant fit all headers into one packet -- breaking into multiple parts!"));                
        
    //
    //  While the packet is too large to contain
    //     BODY's send off as many of the headers
    //       as will fit in a packet
    //                
    HRESULT hr = E_FAIL;
    BYTE cOp;
    CHeaderCollection *pNewHeaderCollection = new CHeaderCollection();
    if( !pNewHeaderCollection )
        return E_OUTOFMEMORY;
	
    IHeaderEnum *pHeaderEnum = NULL;
    OBEX_HEADER *myHeader = NULL;
    ULONG ulFetched;
    UINT uiHeaderCount = 0;
        
    myHeaderCollection->EnumHeaders(&pHeaderEnum);
    while(SUCCEEDED((hr = pHeaderEnum->Next(1, &myHeader, &ulFetched))) && ulFetched)
    {    
        SVSUTIL_ASSERT(pHeaderEnum && pNewHeaderCollection);
    
        cOp = myHeader->bId;

        //copy the header and insert it into the new list (note: the collection
        //  takes ownership
        OBEX_HEADER *pNewHeader = new OBEX_HEADER();
        if( !pNewHeader )
        {
              hr = E_OUTOFMEMORY;
             goto Done;
        }

        CHeaderCollection::CopyHeader(myHeader,pNewHeader);
        DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- Adding 0x%x to temp pNewHeaderCollectoin!", pNewHeader->bId));                            
        if(FAILED(hr = pNewHeaderCollection->InsertHeader(pNewHeader)))
        {    
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- Error inserting new header into list!"));                
            goto Done;
        }

        uiHeaderCount ++;
        //
        //  If this header throws us over the edge in size, remove it
        //        and send off the header, otherwise, move (ie transfer) it from
        //        'myHeaderCollection' to 'pNewHeaderCollection'
        //
        if(uiMINPackSize + SizeOfHeader(pNewHeaderCollection) >= uiMaxPacket)
        {                        
            //remove the older header (note: this just removes it from the
            //  newheader collection and *NOT* the old one!)    
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- Removing 0x%x from temp pNewHeaderCollectoin!", cOp));                                       
            pNewHeaderCollection->Remove(cOp);
            uiHeaderCount --;
            
            //if there are NO headers, that means the one we just added is too
            //  big for one packet, so we are forced to quit... :(
            if(!uiHeaderCount)
            {            
                DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- one of our headers is too large -- cant send packet!"));                
                hr = E_FAIL;
                goto Done;
            }

            //add a connectionID (if required)
            if(uiConnectionId != OBEX_INVALID_CONNECTION)
                pNewHeaderCollection->AddConnectionId(uiConnectionId);
            
            //send out the packet, and grab the response
            unsigned char *pNewPacket;  
            ULONG uiIPackSize; 
            if(SUCCEEDED(hr = ObexSendRecvWithAuthSaveHeaders(pConnection, uiMaxPacket, wcPassword, cOpCode, 0,0, pNewHeaderCollection, &pNewPacket, &uiIPackSize)))
            {            
                //parse out all interesting fields
                ObexParser p (pNewPacket, uiIPackSize);
                
                //get the command data 
                if (p.Op() != 0x90)
                {
                    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- recieved an invalid return code! : op -- %d\n", p.Op()));
                    hr = E_FAIL;    
                }
                else
                    hr = S_OK;            

                //cleanup & init everything to be ready for a new packet
                delete [] pNewPacket;
                pNewHeaderCollection->Release();                
                pNewHeaderCollection = new CHeaderCollection();
                if( !pNewHeaderCollection )
                {
                     hr = E_OUTOFMEMORY;
                     goto Done;
                }
                uiHeaderCount = 0;

                //reset the enumerator (so we can start where we left off)
                pHeaderEnum->Release();
                pHeaderEnum = 0;
                myHeaderCollection->EnumHeaders(&pHeaderEnum);
                

                if(FAILED(hr))
                    goto Done;
               
            }    
            else
            {
                DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() --- ObexSendRecvWithAuth() failed!\n"));         
                goto Done;
            }
        }
        else
        {
            //
            //we have moved the header to our new location... so remove it from
            //  the origin (thereby transfering the bag)
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- Removing 0x%x from temp pHeaderCollection!", cOp));                                                       
            myHeaderCollection->Remove(cOp);
        }


        // 
        //    Recompute size of main header collection, if its too big loop again
        //    if it fits in one packet, break out of the loop
        UINT uiPacketSize = uiMINPackSize + SizeOfHeader(myHeaderCollection);    


        if(!uiHeaderCount && 3 + uiPacketSize <= uiMaxPacket)
           break;           
        //
        //  Flush the buffer
        //
        else if(uiHeaderCount && 3 + uiPacketSize <= uiMaxPacket)
        {
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- down to a managable header size, flushing temp buffer and going on as usual\n"));            
        
            //add a connectionID (if required)
            if(uiConnectionId != OBEX_INVALID_CONNECTION)
                pNewHeaderCollection->AddConnectionId(uiConnectionId);
            
            //send out the packet, and grab the response
            unsigned char *pNewPacket; 
            ULONG uiIPackSize; 
            if(SUCCEEDED(hr = ObexSendRecvWithAuthSaveHeaders(pConnection, uiMaxPacket, wcPassword, cOpCode, 0,0, pNewHeaderCollection, &pNewPacket, &uiIPackSize)))
            {            
                //parse out all interesting fields
                ObexParser p (pNewPacket, uiIPackSize);
                
                //get the command data 
                if (p.Op() != 0x90)
                {
                    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- recieved an invalid return code! : op -- %d\n", p.Op()));
                    hr = E_FAIL;    
                }
                else
                    hr = S_OK;            

                //cleanup & init everything to be ready for a new packet
                delete [] pNewPacket;
                pNewHeaderCollection->Release();
                pNewHeaderCollection = NULL;
                uiHeaderCount = 0;

                if(FAILED(hr))
                    goto Done;
               
            }    
            else
            {
                DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() --- ObexSendRecvWithAuth() failed!\n"));         
                hr = E_FAIL;
                goto Done;
            }

            break;
        }
    }

Done:
    if(pHeaderEnum)
        pHeaderEnum->Release();
    if(pNewHeaderCollection)
        pNewHeaderCollection->Release();

    return hr;    
}

HRESULT STDMETHODCALLTYPE
CObexStream::WriteAll(char cOpCode, const void *pv, ULONG cb, ULONG *pcbWritten)
{
    HRESULT hr = S_OK;
    UINT cbTotalWritten = 0;
    if(!cb) {
	ULONG cbJustWritten = 0;
        if(FAILED(hr = WriteAllHelper(cOpCode, pv, cb, &cbJustWritten)))
           goto Done;
	ASSERT(0 == cbJustWritten);
    }
    else {
        while(cb)
        {
            ULONG cbJustWritten = 0;
            if(FAILED(hr = WriteAllHelper(cOpCode, pv, cb, &cbJustWritten)))
                goto Done;
           
            cbTotalWritten += cbJustWritten;
            pv = (char *)pv + (UINT) cbJustWritten;
            cb -= cbJustWritten;
        }
    }
Done:
    if(SUCCEEDED(hr))
    {        
        *pcbWritten = cbTotalWritten;
    }    
    
        
    return hr;
}

HRESULT 
CObexStream::WriteAllHelper(char cOpCode, const void *pv, ULONG cb, ULONG *pcbWritten)
{  
    PREFAST_ASSERT(myHeaderCollection);
    PREFAST_ASSERT(pcbWritten);
    
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- %d bytes\n", cb));
    
    UINT uiPacketSize = 0;
    UINT toWrite = cb;  // <-- make the first attempt the entire buffer
    UINT uiMINPackSize = MIN_PUT_PACKET_SIZE;
    UINT uiTemp; //holder for temp comparisons
    HRESULT hr = S_OK;
   
    *pcbWritten = 0;
   
     //determine the minimum packet we can transmit 
     //   (5 bytes to transfer a connection ID)
     //   also remove a previous connection ID (if one exists)
     if(OBEX_INVALID_CONNECTION != uiConnectionId)
        uiMINPackSize += 5;
     myHeaderCollection->Remove(OBEX_HID_CONNECTIONID);  
       
     //figure out the size of the packet (as it currently is...)
     if(FAILED(UIntAdd(uiMINPackSize, SizeOfHeader(myHeaderCollection), &uiPacketSize))||
        FAILED(UIntAdd(uiPacketSize, 3, &uiTemp))) {
        DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- WriteAllHeaders overflow of uiPacketSize!"));                        
        goto Done;
     }
     
     //if the packet is too large without any BODY send off a few packets
     //  before attaching a body
     if(uiTemp >= uiMaxPacket)
     {         
         DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- cant fit all headers into one packet -- breaking into multiple parts!"));                        
         if(FAILED(hr = WriteAllHeaders(cOpCode, uiMINPackSize)))
         {
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- WriteAllHeaders failed!"));                        
            goto Done;
         }
         SVSUTIL_ASSERT(uiMaxPacket >= uiMINPackSize + SizeOfHeader(myHeaderCollection));
         
         //recompute the packet size after sending as many headers as possible        
         if(FAILED(UIntAdd(uiMINPackSize, SizeOfHeader(myHeaderCollection), &uiPacketSize))) {
            DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- WriteAllHeaders overflow of uiPacketSize!"));                        
            goto Done;
         }
    }
     
    //
    //  figure out how much non header data we can put into one packet
    //
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- toWrite(%d) uiBodyLen(%d) uiPacketSize(%d) maxPacket(%d)\n", toWrite, uiBodyLen, uiPacketSize, uiMaxPacket));
    UINT uiTotalSize = 0;
    
    if(FAILED(UIntAdd(3, toWrite, &uiTotalSize)) ||
       FAILED(UIntAdd(uiBodyLen, uiTotalSize, &uiTotalSize)) ||
       FAILED(UIntAdd(uiPacketSize, uiTotalSize, &uiTotalSize))) {
            ASSERT(FALSE);
            hr = E_INVALIDARG;

⌨️ 快捷键说明

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