📄 obexdevice.cpp
字号:
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 + -