📄 obmain.cxx
字号:
SVSUTIL_ASSERT (IsLocked ());
int fUseIRDA = FALSE;
int fUseBTH = FALSE;
int fUseTCP = FALSE;
//
// Read registry parameters
//
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_KEY_BASE, 0, KEY_READ, &hk)) {
DWORD dw;
DWORD dwType;
DWORD dwSize;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"IsEnabled",0,&dwType,(LPBYTE)&dw,&dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && (dw == 0)) {
// Obex disabled via registry.
RegCloseKey(hk);
return FALSE;
}
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"ServerTimeout", 0, &dwType, (LPBYTE)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && (dw >= OBEX_SERVER_TIMEOUT_MIN))
uiOBEX_SERVER_TIMEOUT = dw;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"ConnectionTimeout", 0, &dwType, (LPBYTE)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && ((dw == 0) || (dw >= OBEX_CONNECTION_TIMEOUT_MIN)))
uiOBEX_CONNECTION_TIMEOUT = dw;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"MaintPeriod", 0, &dwType, (LPBYTE)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && (dw > OBEX_MAINT_PERIOD_MIN))
uiOBEX_MAINT_PERIOD = dw;
WCHAR szProtocols[OBEX_SMALLBUFFER];
dwSize = sizeof(szProtocols);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"protocols", 0, &dwType, (LPBYTE)szProtocols, &dwSize)) &&
(dwType == REG_SZ) && (dwSize < sizeof(szProtocols))) {
if (wcsstr (szProtocols, L"irda"))
fUseIRDA = TRUE;
if (wcsstr (szProtocols, L"bth"))
fUseBTH = TRUE;
if (wcsstr (szProtocols, L"tcp"))
fUseTCP = TRUE;
}
RegCloseKey (hk);
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : Supported protocols : %s %s %s\n", fUseTCP ? L"TCP/IP" : L"", fUseIRDA ? L"IRDA" : L"", fUseBTH ? L"Bluetooth" : L""));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : uiOBEX_SERVER_TIMEOUT = %d\n", uiOBEX_SERVER_TIMEOUT));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : uiOBEX_CONNECTION_TIMEOUT = %d\n", uiOBEX_CONNECTION_TIMEOUT));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : uiOBEX_MAINT_PERIOD = %d\n", uiOBEX_MAINT_PERIOD));
pfmdServers = svsutil_AllocFixedMemDescr (sizeof (Server), OBEX_MEM_SCALE);
pfmdAssociations = svsutil_AllocFixedMemDescr (sizeof(Association), OBEX_MEM_SCALE);
pfmdConnections = svsutil_AllocFixedMemDescr (sizeof(Connection), OBEX_MEM_SCALE);
pThreads = new SVSThreadPool();
if (! (pfmdServers && pfmdAssociations && pfmdConnections && pThreads)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start: out of memory\n"));
return FALSE;
}
//
// Initialize listeners
//
ASSERT(NULL == pafList);
pafList = NULL;
#ifndef SDK_BUILD
if (fUseTCP) {
AddressFamily *pNewAF = new AddressFamily ();
if(!pNewAF)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start: could not initialize TCP/IP : out of memory\n"));
else {
if (! pNewAF->Start (PF_UNSPEC, OBEX_TCP_PORT)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Error registering OBEX name with TCP\n"));
delete pNewAF;
} else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : Registered OBEX name with TCP\n"));
pNewAF->pNext = pafList;
pafList = pNewAF;
}
}
}
#endif
if (fUseIRDA) {
AddressFamily *pNewAF = new AddressFamily ();
if(!pNewAF)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start: could not initialize TCP/IP : out of memory\n"));
else {
BOOL fOBEXFailed = FALSE;
BOOL fOBEXIrXFerFailed = FALSE;
if (! pNewAF->Start (AF_IRDA, "OBEX")) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Error registering OBEX name with IrDA\n"));
fOBEXFailed = TRUE;
}
else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Registered OBEX name with IrDA\n"));
}
if (! pNewAF->Start (AF_IRDA, "OBEX:IrXfer")) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Error registering OBEX:IrXfer name with IrDA\n"));
fOBEXIrXFerFailed = TRUE;
}
else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Registered OBEX:IrXfer name with IrDA\n"));
}
//if both failed, we need to delete this address family
// otherwise chain our new AF onto the list
if(fOBEXFailed && fOBEXIrXFerFailed)
delete pNewAF;
else {
pNewAF->pNext = pafList;
pafList = pNewAF;
}
}
}
if (fUseBTH) {
AddressFamily *pNewAF = new AddressFamily ();
if(!pNewAF)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start: could not initialize TCP/IP : out of memory\n"));
else {
if (! pNewAF->Start (AF_BT)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] GlobalData::Start : Error registering OBEX name with Bluetooth\n"));
delete pNewAF;
} else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start : Registered OBEX name with Bluetooth\n"));
pNewAF->pNext = pafList;
pafList = pNewAF;
}
}
}
if (pafList) {
fState = RUNNING;
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start - successfully started OBEX server\n"));
return TRUE;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Start - started OBEX server has no protocols\n"));
return FALSE;
}
int GlobalData::Stop (void) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Stop - initiating unload\n"));
fState = DOWN;
AddressFamily *pAF = pafList;
while (pAF) {
pAF->Stop ();
pAF = pAF->pNext;
}
Unlock ();
SVSUTIL_ASSERT (! IsLocked ());
if (pThreads)
pThreads->Shutdown ();
for ( ; ; ) {
int fRepeat = FALSE;
pAF = pafList;
while (pAF) {
if (! pAF->IsDown())
fRepeat = TRUE;
pAF = pAF->pNext;
}
if (! fRepeat)
break;
Sleep (1000);
}
while (pafList) {
AddressFamily *pNext = pafList->pNext;
delete pafList;
pafList = pNext;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] GlobalData::Stop - successfully unloaded\n"));
return TRUE;
}
void GlobalData::ServiceRequest (Connection *pConn) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x\n", pConn->uiCurrentTransaction));
SVSUTIL_ASSERT (pConn->cBufSize >= 3);
SVSUTIL_ASSERT (pConn->cFilled == pConn->cBufSize);
SVSUTIL_ASSERT (pConn->pBuffer);
ObexParser p(pConn->pBuffer, pConn->cBufSize);
unsigned int uiCId = OBEX_INVALID_CID;
if ((p.Op () != OBEX_OP_CONNECT) &&
(p.Op () != OBEX_OP_DISCONNECT) &&
((p.Op () & OBEX_OP_OPMASK) != OBEX_OP_PUT) &&
((p.Op () & OBEX_OP_OPMASK) != OBEX_OP_GET) &&
(p.Op () != OBEX_OP_SETPATH) &&
(p.Op () != OBEX_OP_ABORT)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with bad opcode\n", pConn->uiCurrentTransaction));
// This unlocks internally
SendTrivialResponse (pConn, OBEX_STAT_NOTIMPLEMENTED | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
#if defined (DEBUG) || defined (_DEBUG)
if (p.Op () == OBEX_OP_CONNECT)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = CONNECT\n", pConn->uiCurrentTransaction));
if (p.Op () == OBEX_OP_DISCONNECT)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = DISCONNECT\n", pConn->uiCurrentTransaction));
if (p.Op () == OBEX_OP_SETPATH)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = SETPATH\n", pConn->uiCurrentTransaction));
if (p.Op () == OBEX_OP_ABORT)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = ABORT\n", pConn->uiCurrentTransaction));
if (p.Op () == (OBEX_OP_PUT | OBEX_OP_ISFINAL))
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = PUT, FINAL\n", pConn->uiCurrentTransaction));
if (p.Op () == OBEX_OP_PUT)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = PUT, CONTINUE\n", pConn->uiCurrentTransaction));
if (p.Op () == (OBEX_OP_GET | OBEX_OP_ISFINAL))
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = GET, FINAL\n", pConn->uiCurrentTransaction));
if (p.Op () == OBEX_OP_GET)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x OP = GET, CONTINUE\n", pConn->uiCurrentTransaction));
#endif
int fHaveConnectionId = FALSE;
//if the packet has a connection ID quickly dispatch it
if (p.IsA (OBEX_HID_CONNECTIONID)) {
//
// Have connection id
//
if (! p.GetDWORD((unsigned long *)&uiCId)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"GlobalData::ServiceRequest: packet 0x%08x fails with BADREQUEST\n", pConn->uiCurrentTransaction));
// This unlocks internally
SendTrivialResponse (pConn, OBEX_STAT_BADREQUEST | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x cid = 0x%08x\n", pConn->uiCurrentTransaction, uiCId));
fHaveConnectionId = TRUE;
if (! (p.Op() & OBEX_OP_ISFINAL))
pConn->uiConnectionId = uiCId;
} else if ((pConn->uiConnectionId != OBEX_INVALID_CID) &&
(((p.Op () & OBEX_OP_OPMASK) == OBEX_OP_PUT) || ((p.Op () & OBEX_OP_OPMASK) == OBEX_OP_GET))) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x cid = 0x%08x from pending connection\n", pConn->uiCurrentTransaction, uiCId));
uiCId = pConn->uiConnectionId;
fHaveConnectionId = TRUE;
}
if (p.Op() & OBEX_OP_ISFINAL)
pConn->uiConnectionId = OBEX_INVALID_CID;
if (fHaveConnectionId) {
Association *pA = passocList;
while (pA) {
if (pA->uiConnectionId == uiCId) {
// if the connectionID's match but the connections dont drop the request -- most likely being hacked
if(pA->pConn != pConn) {
break;
}
pA->uiTransactionId = pConn->uiCurrentTransaction;
pA->pServer->DispatchCall (pA->uiConnectionId, pConn, &p); // This unlocks internally
SVSUTIL_ASSERT (! IsLocked ());
return;
}
pA = pA->pNext;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x : connection id is not available. Searching by targetid...\n", pConn->uiCurrentTransaction));
char serviceid[OBEX_SERVICEID_LEN + 1];
int iLen = 0;
//check to see the opcode is for a TARGET id
if (p.IsA (OBEX_HID_TARGET)) {
//
// Have target
//
iLen = p.Length ();
if (iLen > OBEX_SERVICEID_LEN) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL (too big id)\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
//call GetBytes to fetch the service ID from the header
// on error, fail with a bad request
if (! p.GetBytes (serviceid, iLen)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with BADREQUEST (incorrect id)\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_BADREQUEST | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
}
//if the packet has no TARGET or CONNECTION ID
// go on and eventally try to figure out something to do with the packet (default mailbox perhaps)
else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x : no targetid... Assuming default inbox.\n", pConn->uiCurrentTransaction));
memset (serviceid, 0, sizeof(serviceid));
iLen = 16;
}
Server *pServ = pservList;
while (pServ) {
if (((int)pServ->cServerId == iLen) && (memcmp (pServ->ucServerId, serviceid, iLen) == 0))
break;
pServ = pServ->pNext;
}
if (! pServ) {
pServ = (Server *)svsutil_GetFixed (pfmdServers);
if (! pServ) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with INTERNALERROR\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_INTERNALERROR | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -