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 + -
显示快捷键?