📄 obmain.cxx
字号:
//
// 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.
//
//
// Windows CE OBEX implementation.
// (C) Microsoft 2000
//
// Notes:
// 1. Need to move timeout and other parameters (ports and services) to registry.
// 2. Implement server class
#include <windows.h>
#include <strsafe.h>
#include <stdio.h>
#include "obexp.hxx"
#include <ws2bth.h>
#include <Ws2tcpip.h>
#include <md5.h>
#include <intsafe.h>
#if defined(DEBUG) || defined(_DEBUG)
void *operator new(UINT size)
{
return g_funcAlloc(size, g_pvAllocData);
}
void operator delete(void *pVoid)
{
g_funcFree(pVoid, g_pvAllocData);
}
#endif
#define WSAGetLastError GetLastError
//
// Class definitions
//
class AddressFamily;
class Association;
class Connection;
class Server;
enum ServerState {
STARTING,
RUNNING,
DOWN
};
enum ServerStatus {
NOT_INITED,
OPERATING,
FAILED
};
static void ReverseByteOrder (void *pData, int size) {
unsigned char *puc = (unsigned char *)pData;
for (int i = 0 ; i < size / 2 ; ++i) {
unsigned char c = puc[i];
puc[i] = puc[size - 1 - i];
puc[size - 1 - i] = c;
}
}
class GlobalData : public SVSSynch {
public:
FixedMemDescr *pfmdServers;
FixedMemDescr *pfmdAssociations;
FixedMemDescr *pfmdConnections;
AddressFamily *pafList;
Association *passocList;
Connection *pconnList;
Server *pservList;
SVSThreadPool *pThreads;
ServerState fState;
unsigned int uiConnectionId;
unsigned int uiTransactionId;
int fMaintain;
unsigned int uiOBEX_MAINT_PERIOD;
unsigned int uiOBEX_SERVER_TIMEOUT;
unsigned int uiOBEX_CONNECTION_TIMEOUT;
GlobalData (void) {
pfmdServers =
pfmdAssociations =
pfmdConnections = NULL;
pafList = NULL;
passocList = NULL;
pconnList = NULL;
pservList = NULL;
pThreads = NULL;
fState = STARTING;
uiConnectionId = 1;
uiTransactionId = 1;
fMaintain = FALSE;
uiOBEX_CONNECTION_TIMEOUT = OBEX_CONNECTION_TIMEOUT;
uiOBEX_SERVER_TIMEOUT = OBEX_SERVER_TIMEOUT;
uiOBEX_MAINT_PERIOD = OBEX_MAINT_PERIOD;
}
~GlobalData (void);
int Start (void); // +
// this starts locked and returns unlocked.
int Stop (void); // +
// will unlock inside
HRESULT CloseConnection (Connection *pConn); // +
// this starts locked and returns unlocked.
int SendTrivialResponse (Connection *pConn, int iResponseCode); // +
void SetMaintain (void); // +
// this starts locked and returns unlocked.
void ServiceRequest (Connection *pConn); // +
static DWORD WINAPI Compact (LPVOID pThis); // +
};
class AddressFamily : public SVSAllocClass {
public:
AddressFamily *pNext;
SOCKET aSocket[OBEX_MAXPORTS];
//hold the address family for the socket
// (uses same index as aSocket)
int addFam[OBEX_MAXPORTS];
int cSockets;
HANDLE hThread;
AddressFamily () {
pNext = NULL;
cSockets = 0;
hThread = NULL;
uiSDPRecordHandleCnt = 0;
}
~AddressFamily (void) {
//
// Flush out the BTH
//
while(uiSDPRecordHandleCnt)
{
int ret = obutil_SdpDelRecord(SDPRecordHandle[uiSDPRecordHandleCnt-1]);
if(ERROR_SUCCESS != ret)
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] AddressFamily::~AddressFamily -- removing handle failed\n"));
}
uiSDPRecordHandleCnt --;
}
if (hThread)
CloseHandle (hThread);
}
UINT uiSDPRecordHandleCnt;
ULONG SDPRecordHandle[MAX_NUM_STP_RECS];
int Start (int af, int iPort); // +
int Start (int af, char *szServiceName); // +
int Start (int af);
int Stop (void); // +
int IsDown (void); // +
void Listen (void); // +
static DWORD WINAPI ThreadListen (LPVOID pThis) {
AddressFamily *pA = (AddressFamily *)pThis;
pA->Listen ();
return 0;
}
};
class Connection {
public:
Connection *pNext;
AddressFamily *paf;
SOCKET s;
int addFam;
int tickLastActive;
unsigned int uiCurrentTransaction;
unsigned int uiConnectionId;
unsigned char *pBuffer;
int cFilled;
int cBufSize;
unsigned char ucPeekBuff[3];
int cPeekFilled;
};
class Association {
public:
Association *pNext;
Connection *pConn;
Server *pServer;
unsigned int uiConnectionId;
unsigned int uiTransactionId;
bool fDefaultConnection;
};
class Server {
public:
Server *pNext;
int fServerStatus;
int iCallRef;
int tickLastActive;
int cProtSeq;
unsigned char aProtSeq[OBEX_PROTOCOLS];
unsigned int cServerId;
unsigned char ucServerId[OBEX_SERVICEID_LEN];
HINSTANCE hDll;
ServiceCallback pServiceCallback;
WCHAR szName[_MAX_PATH];
int CanUseConnection (Connection *pConn); // +
int Load (int iLen, unsigned char *pserviceid); // +
// will unlock - starts and returns locked
int Unload (void); // +
// This starts locked and returns unlocked
int DispatchCall (unsigned int uiConnectionId, Connection *pConn, ObexParser *pParser); // -
};
//
// Variable declarations
//
static GlobalData *gpState = NULL;
HRESULT obex_MD5_Helper(unsigned char *orig, unsigned int len, unsigned char *dest, unsigned int *pDestSize)
{
MD5_CTX context;
if(!orig || !dest || !pDestSize) {
return E_INVALIDARG;
}
MD5Init(&context);
MD5Update(&context, (UCHAR *)orig, len);
MD5Final(&context);
if(*pDestSize < 16) {
*pDestSize = 16;
return E_INVALIDARG;
} else {
*pDestSize = 16;
}
memcpy(dest, context.digest, 16);
return S_OK;
}
//
// GlobalData
//
GlobalData::~GlobalData()
{
SVSUTIL_ASSERT (fState != RUNNING);
//
//Lock to make CloseConnection happy
//
gpState->Lock();
//
// Shut down all active connections
//
while (pconnList)
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::~GlobalData: shutting down connection\n"));
if(FAILED(CloseConnection (pconnList))) {
ASSERT(0);
break;
}
}
//
// Unload any DLL's that we might have
//
Server *pServ = pservList;
while (pServ)
{
Server *pDel = pServ;
pServ = pServ->pNext;
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::~GlobalData: retiring server %s\n", pDel->szName));
pDel->pNext = NULL;
pDel->Unload ();
}
gpState->Unlock();
//
// do memory cleanup
//
if(pThreads)
delete pThreads;
if (pfmdServers)
svsutil_ReleaseFixedNonEmpty (pfmdServers);
if (pfmdAssociations)
svsutil_ReleaseFixedNonEmpty (pfmdAssociations);
if (pfmdConnections)
svsutil_ReleaseFixedNonEmpty (pfmdConnections);
SVSUTIL_ASSERT (! pafList);
}
int GlobalData::Start (void) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] +GlobalData::Start\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -