obexstream.cpp

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

CPP
1,418
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
// ObexStream.cpp: implementation of the CObexStream class.
//
//////////////////////////////////////////////////////////////////////
#include "common.h"
#include "ObexDevice.h"
#include "ObexParser.h"
#include "ObexStream.h"
#include "HeaderEnum.h"
#include "HeaderCollection.h"
#include "ObexPacketInfo.h"
#include <intsafe.h>

//the size of the opcode(1)+size(2)
#define MIN_PUT_PACKET_SIZE 3


UINT GetNewStreamID()
{
    static UINT uiID = 0;
    uiID++;
    if(uiID == 0xFFFFFFFF)
        uiID = 0;
        
    return uiID;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CObexStream::CObexStream(
       IObexTransportConnection *_pConnection, 
       CObexDevice *_pMyOBEXDevice,
       UINT _uiMaxPacket,
       UINT _uiConnectionId,
       WCHAR *_pwcPassword,
       LPHEADERCOLLECTION _pHeaders) : 
pMyOBEXDevice(_pMyOBEXDevice),
_refCount(1),
uiBodyLen(0),
myHeaderCollection(0),
fHeaderAccounted(FALSE),
uiStreamType(OBEX_PUT),
pcBodyPtr(NULL),
pcBodyChunk(NULL),
fFirstPacket(TRUE),
fReadFinished(FALSE),
fHaveSentData(FALSE),
uiMaxPacket(_uiMaxPacket),
pConnection(_pConnection),
uiConnectionId(_uiConnectionId),
pResponseHeaders(NULL),
uiResponseHeaderLen(0),
pResponseHeadEnum(NULL),
m_Inited(TRUE)
{
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::CObexStream()\n"));
    SVSUTIL_ASSERT(_pHeaders && pConnection && _pwcPassword);
    
    //get a new stream id 
    uiStreamID = GetNewStreamID();   
    
    if(pMyOBEXDevice)
        pMyOBEXDevice->AddRef();
        
    if(pConnection)
        pConnection->AddRef();
    if(_pwcPassword)
    {
        //make *SURE* this isnt a pointer
        ASSERT(sizeof(wcPassword) != sizeof(WCHAR *));
        wcsncpy(wcPassword, _pwcPassword, sizeof(wcPassword)/sizeof(wcPassword[0]));
    }
    else
        wcPassword[0] = NULL;
       
    if(!_pHeaders)
    {
        myHeaderCollection = new CHeaderCollection();
        if( !myHeaderCollection )
	     m_Inited = FALSE;
    }
    else
    {
        myHeaderCollection=_pHeaders;
        myHeaderCollection->AddRef();
    }
}

CObexStream::CObexStream(
       IObexTransportConnection *_pConnection, 
       CObexDevice *_pMyOBEXDevice,
       UINT _uiMaxPacket,
       UINT _uiConnectionId,
       WCHAR *_pwcPassword, 
       LPHEADERCOLLECTION *_pHeaders) :  
pMyOBEXDevice(_pMyOBEXDevice),      
_refCount(1),
uiBodyLen(0),
myHeaderCollection(0),
fHeaderAccounted(FALSE),
uiStreamType(OBEX_GET),
pcBodyPtr(NULL),
pcBodyChunk(NULL),
fFirstPacket(TRUE),
fReadFinished(FALSE),
fHaveSentData(FALSE),
uiMaxPacket(_uiMaxPacket),
pConnection(_pConnection),
uiConnectionId(_uiConnectionId),
pResponseHeaders(NULL),
uiResponseHeaderLen(0),
pResponseHeadEnum(NULL),
m_Inited(TRUE)
{        
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::CObexStream()\n"));
    PREFAST_ASSERT(_pHeaders && pConnection && _pwcPassword);
    
    //get a new stream id
    uiStreamID = GetNewStreamID();
    
    if(pMyOBEXDevice)
        pMyOBEXDevice->AddRef();
        
    if(pConnection)
        pConnection->AddRef();
    if(_pwcPassword)
    {
        //make *SURE* this isnt a pointer
        ASSERT(sizeof(wcPassword) != sizeof(WCHAR *));
        wcsncpy(wcPassword, _pwcPassword, sizeof(wcPassword)/sizeof(wcPassword[0]));
    }
        
        
    else
        wcPassword[0] = NULL;

    if( !(*_pHeaders) )
    {
        myHeaderCollection = new CHeaderCollection();
        if( !myHeaderCollection )
	     m_Inited = FALSE;
    }
    else
    {
	  myHeaderCollection = *_pHeaders;
	  (*_pHeaders)->AddRef(); 
    }
  
}


CObexStream::~CObexStream()
{
    DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::~CObexStream()\n"));
    
    //if this is a PUT and our stream is still valid
    if(uiStreamType == OBEX_PUT && !StreamDisabled())
    {        
        FlushSendBuffers(OBEX_OP_PUT);
    }
    //if this is a GET, we havent finished reading, have sent a packet, and our stream
    //  id is still valid -- we must abort this connection
    else if(uiStreamType == OBEX_GET && !fReadFinished && fHaveSentData && !StreamDisabled())
    {
        HRESULT hr;
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexStream::Abort() -- sending OBEX Abort packet\n"));
    
        //abort the connection   
        IHeaderCollection *pAbortHeaders = NULL;
        if(FAILED(hr = CoCreateInstance(__uuidof(HeaderCollection), 
                                 NULL, 
                                 CLSCTX_INPROC_SERVER, 
                                 __uuidof(IHeaderCollection),  
                                 (void **)&pAbortHeaders)))
            goto Done;
         
        if(uiConnectionId != OBEX_INVALID_CONNECTION)
            pAbortHeaders->AddConnectionId(uiConnectionId);

        UCHAR *pNewPacket = NULL;
        ULONG uiNewPackSize;

        //send off the packet
        hr = ObexSendRecvWithAuth(pConnection, uiMaxPacket, wcPassword, (char)OBEX_OP_ABORT, 0,0, pAbortHeaders, &pNewPacket, &uiNewPackSize);        
        
        if (FAILED(hr) || pNewPacket[0] != (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexStream::Abort() -- sending abort failed... nothing we can do\n"));    
        } 
       
        if(pAbortHeaders)
            pAbortHeaders->Release();
        delete [] pNewPacket;
    }

    
Done:

    if(pMyOBEXDevice)
        pMyOBEXDevice->Release();
    if(pConnection)
        pConnection->Release();
    if(pcBodyChunk)
        delete [] pcBodyChunk;
    if(myHeaderCollection)
        myHeaderCollection->Release();   
    if (pResponseHeaders)
        delete [] pResponseHeaders;

    if (pResponseHeadEnum) {
    	pResponseHeadEnum->RemoveAll();
        delete pResponseHeadEnum;
    }
}


HRESULT 
CObexStream::FlushSendBuffers(char _cOpCode)
{
    if(uiStreamType == OBEX_ERR || StreamDisabled())
    {
        if(pcBodyChunk)
            delete [] pcBodyChunk;

        pcBodyPtr = pcBodyChunk = NULL;
        uiBodyLen = 0;
            
        DEBUGMSG(OBEX_NETWORK_ZONE, (L" CObexStream::FlushSendBuffers -- ERROR FLAG MARKED\n"));                             
        return S_OK;
    }
        

    //send out the remaining packet
    char cOpCode = (char)(_cOpCode | OBEX_OP_ISFINAL);
    
    unsigned char *pNewPacket = NULL;
    ULONG uiPacketSize;


    //add the connection ID
    if(uiConnectionId != OBEX_INVALID_CONNECTION)
        myHeaderCollection->AddConnectionId(uiConnectionId);

    if (pcBodyChunk) {
        myHeaderCollection->AddEndOfBody(uiBodyLen, pcBodyChunk);
        delete [] pcBodyChunk;
        pcBodyPtr = pcBodyChunk = NULL;
        uiBodyLen = 0;
    }
    else if(fHaveSentData) 
    {
        ASSERT(0 == uiBodyLen);
        myHeaderCollection->AddEndOfBody(0, NULL);
    }

    //
    //  send off the packet if there is a body, grab it and put it in the chain of
    //    incoming data
    //
    HRESULT hr = ObexSendRecvWithAuthSaveHeaders(pConnection, uiMaxPacket, wcPassword, cOpCode, 0,0, myHeaderCollection, &pNewPacket, &uiPacketSize);
    if(SUCCEEDED(hr) && pNewPacket)
    {
        //
        //  parse out all interesting fields
        //
        ObexParser p (pNewPacket, uiPacketSize);
                
        if (((p.Op () & 0xF0) == (OBEX_STAT_CONTINUE | OBEX_OP_ISFINAL)) || 
            ((p.Op () & 0xF0) == (OBEX_STAT_OK | OBEX_OP_ISFINAL))) 
        {           
            while (! p.__EOF ()) 
            {
                if (p.IsA (OBEX_HID_BODY) || (p.IsA (OBEX_HID_BODY_END))) 
                {                    
                    int cLen = 0;
                    unsigned char *pBuf;
                    if (! p.GetBytes (&pBuf, &cLen))
                    {
                        SVSUTIL_ASSERT(FALSE);                        
                        break;
                    }  
                    
                    //copy in the data (we cant have more than
                    //  we can hold)
                    if (pcBodyChunk) {
                        BYTE *pcNewChunk = new BYTE [uiBodyLen + cLen];
                        if (pcNewChunk)
                            memcpy (pcNewChunk, pcBodyPtr, uiBodyLen);

                        delete [] pcBodyChunk;
                        pcBodyChunk = pcBodyPtr = pcNewChunk;
                    } else {
                        pcBodyChunk = new BYTE[cLen];
                        pcBodyPtr = pcBodyChunk;
                    }

                    if (! pcBodyChunk)
                        return E_OUTOFMEMORY;

                    memcpy(pcBodyChunk + uiBodyLen, pBuf, cLen); 
                    uiBodyLen += cLen;                   
                    myHeaderCollection->Release();
                    myHeaderCollection=new CHeaderCollection();
                    if( !myHeaderCollection )
		          return E_OUTOFMEMORY;
					
                    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 ();
            }
        } 
        else
        {
            if(pNewPacket)
                delete [] pNewPacket;   
            return E_FAIL;
        }

         //
         //  at this point we dont need the packet anymore so delete it
         //
         if(pNewPacket)
            delete [] pNewPacket;   
    }
    else
    {
        DEBUGMSG(OBEX_OBEXSTREAM_ZONE, (L"CObexStream::FlushSendBuffers -- Sending final packet failed\n"));
        return E_FAIL;
    }
    
    return S_OK;
}


HRESULT CObexStream::CopyResponseHeaders(unsigned char *pNewPacket, ULONG Size) {
    ASSERT(pResponseHeaders == NULL);
    ASSERT(uiResponseHeaderLen == 0);

    pResponseHeaders = new UCHAR[Size];

⌨️ 快捷键说明

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