📄 obmain.cxx
字号:
#endif
gpState->CloseConnection (pConn);
gpState->Unlock ();
continue;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Contents of recv'ed buffer: "));
IFDBG(svslog_DumpBuff (VERBOSE_OUTPUT_PACKETS, pConn->ucPeekBuff+pConn->cPeekFilled, ires));
pConn->cPeekFilled += ires;
SVSUTIL_ASSERT (pConn->cPeekFilled <= sizeof(pConn->ucPeekBuff));
if (pConn->cPeekFilled < sizeof(pConn->ucPeekBuff)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: insufficient data for a packet (%d out of 3), waiting for more\n", pConn->cPeekFilled));
gpState->Unlock ();
continue;
}
int iLen = (pConn->ucPeekBuff[1] << 8) | pConn->ucPeekBuff[2];
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: got full packet header, packet length is %d\n", iLen));
if (iLen < sizeof(pConn->ucPeekBuff)) { // close me...
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: connection %d closed because of incorrect packet size (%d bytes)\n", pConn->s, iLen));
gpState->CloseConnection (pConn);
gpState->Unlock ();
continue;
}
pConn->pBuffer = (unsigned char *)obex_Alloc (iLen);
if (! pConn->pBuffer) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Listen: failed to allocate %d bytes for incoming packet\n", iLen));
gpState->CloseConnection (pConn);
gpState->Unlock ();
continue;
}
memcpy (pConn->pBuffer + pConn->cFilled, pConn->ucPeekBuff, sizeof(pConn->ucPeekBuff));
pConn->cPeekFilled = 0;
pConn->cFilled = sizeof(pConn->ucPeekBuff);
pConn->cBufSize = iLen;
} else { // receive the rest of the data into the buffer...
ires = recv (pConn->s, (char *)(pConn->pBuffer + pConn->cFilled), pConn->cBufSize - pConn->cFilled, 0);
if (ires <= 0) {
#if defined (DEBUG) || defined (_DEBUG)
if (ires == 0)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: connection %d closed at the request of the client\n", pConn->s));
else if (ires < 0)
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: connection %d closed because of socket error %d (RECV returns %d)\n", pConn->s, WSAGetLastError (), ires));
#endif
gpState->CloseConnection (pConn);
gpState->Unlock ();
continue;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Contents of recv'ed buffer: "));
IFDBG(svslog_DumpBuff (VERBOSE_OUTPUT_PACKETS, pConn->pBuffer+pConn->cFilled, ires));
pConn->cFilled += ires;
SVSUTIL_ASSERT (pConn->cFilled <= pConn->cBufSize);
}
if (pConn->cFilled != pConn->cBufSize) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: insufficient data for a packet (%d out of %d), waiting for more\n", pConn->cFilled, pConn->cBufSize));
gpState->Unlock ();
continue;
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Listen: got a packet, will service it now\n"));
pConn->uiCurrentTransaction = ++gpState->uiTransactionId;
if (! pConn->uiCurrentTransaction)
pConn->uiCurrentTransaction = ++gpState->uiTransactionId;
SVSUTIL_ASSERT(0 != pConn->uiCurrentTransaction);
gpState->ServiceRequest(pConn);
}
}
if (fExit)
break;
}
SVSUTIL_ASSERT (! gpState->IsLocked ());
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] AddressFamily::Listen exited\n"));
}
//
// Server
//
int Server::CanUseConnection (Connection *pConn) {
if (cProtSeq == 0)
return TRUE;
int af = pConn->addFam;
for (int i = 0 ; i < cProtSeq ; ++i) {
if (af == aProtSeq[i])
return TRUE;
}
return FALSE;
}
int Server::Load (int iLen, unsigned char *pserviceid) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load -- attempting to load request handler\n"));
SVSUTIL_ASSERT (iLen <= OBEX_SERVICEID_LEN);
fServerStatus = NOT_INITED;
int fFoundKey = FALSE;
HKEY hk;
//
// Try GUID
//
if (iLen == sizeof(GUID)) {
GUID guid = *(GUID *)pserviceid;
ReverseByteOrder (&guid.Data1, sizeof(guid.Data1));
ReverseByteOrder (&guid.Data2, sizeof(guid.Data2));
ReverseByteOrder (&guid.Data3, sizeof(guid.Data3));
WCHAR szKeyName[SVSUTIL_ARRLEN(OBEX_KEY_SERVERS) + SVSUTIL_GUID_STR_LENGTH + 3];
if (FAILED(StringCchPrintfW(szKeyName, SVSUTIL_ARRLEN(szKeyName),
OBEX_KEY_SERVERS L"\\{" SVSUTIL_GUID_FORMAT L"}",
SVSUTIL_PGUID_ELEMENTS ((&guid)))))
{
SVSUTIL_ASSERT(0); // Buffer should always be large enough.
return FALSE;
}
SVSUTIL_ASSERT (wcslen(szKeyName) < SVSUTIL_ARRLEN(szKeyName));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load - trying %s\n", szKeyName));
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hk))
fFoundKey = TRUE;
}
//
// Can this be ASCII string?
//
if (! fFoundKey) {
WCHAR szKeyName[SVSUTIL_ARRLEN(OBEX_KEY_SERVERS) + OBEX_SERVICEID_LEN + 3];
int fCanBeASCII = TRUE;
for (int i = 0 ; i < iLen ; ++i) {
if ((pserviceid[i] < ' ') || (pserviceid[i] > 126)) {
fCanBeASCII = FALSE;
break;
}
}
if (fCanBeASCII) {
int iChars = MultiByteToWideChar (CP_ACP, 0, (char *)pserviceid, iLen, &szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS) + 2], OBEX_SERVICEID_LEN);
if (iChars > 0) {
memcpy (szKeyName, OBEX_KEY_SERVERS, sizeof(OBEX_KEY_SERVERS));
szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS)] = '\\';
szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS) + 1] = '{';
szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS) + 2 + iChars] = '}';
szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS) + 2 + iChars + 1] = '\0';
SVSUTIL_ASSERT (wcslen(szKeyName) < SVSUTIL_ARRLEN(szKeyName));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load - trying %s\n", szKeyName));
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hk))
fFoundKey = TRUE;
}
}
}
//
// As a last resort, try stringized id
//
if (! fFoundKey) {
WCHAR szKeyName[SVSUTIL_ARRLEN(OBEX_KEY_SERVERS) + 2 * OBEX_SERVICEID_LEN + 1];
memcpy (szKeyName, OBEX_KEY_SERVERS, sizeof(OBEX_KEY_SERVERS));
szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS)] = '\\';
WCHAR *p = &szKeyName[SVSUTIL_CONSTSTRLEN(OBEX_KEY_SERVERS) + 1];
for (int i = 0 ; i < iLen ; ++i) {
int c = pserviceid[i];
c = (c >> 4) & 0xf;
*p++ = (c > 9) ? c + 'a' - 10 : c + '0';
c = pserviceid[i];
c = c & 0xf;
*p++ = (c > 9) ? c + 'a' - 10 : c + '0';
}
*p++ = '\0';
SVSUTIL_ASSERT (p - szKeyName < SVSUTIL_ARRLEN(szKeyName));
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load - trying %s\n", szKeyName));
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hk))
fFoundKey = TRUE;
}
//
// If still not there, fail
//
if (! fFoundKey) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load failed - no such server\n"));
return FALSE;
}
memcpy (ucServerId, pserviceid, iLen);
cServerId = iLen;
//
// Now, read the values. We need: DLL name, protocol sequence
//
DWORD dwType;
DWORD dwSize;
dwSize = sizeof(aProtSeq);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"ProtSeq", 0, &dwType, (LPBYTE) aProtSeq, &dwSize)) &&
(dwSize <= sizeof(aProtSeq)) && (dwType == REG_BINARY))
cProtSeq = dwSize;
else
SVSUTIL_ASSERT (cProtSeq == 0);
dwSize = sizeof(szName);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"Server", 0, &dwType, (LPBYTE) szName, &dwSize)) ||
(dwSize > sizeof(szName)) || (dwType != REG_SZ)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load failed - no dll name\n"));
RegCloseKey (hk);
return FALSE;
}
RegCloseKey (hk);
hDll = LoadLibrary (szName);
if (! hDll) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load failed - no such dll %s\n", szName));
return FALSE;
}
if (! (pServiceCallback = (ServiceCallback)GetProcAddress (hDll, GPAARG("ServiceCallback"))))
return FALSE;
SVSUTIL_ASSERT (! iCallRef);
tickLastActive = GetTickCount ();
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Load - succeeded, loaded %s\n", szName));
return TRUE;
}
int Server::Unload (void) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::Unload : unloading %s\n", szName));
SVSUTIL_ASSERT (! pNext);
SVSUTIL_ASSERT (! iCallRef);
if (fServerStatus == OPERATING) {
PREFAST_ASSERT (pServiceCallback);
ObexTransaction o;
memset (&o, 0, sizeof(o));
o.uiOp = OBEX_REQ_UNLOAD;
o.ObexAlloc = obex_Alloc;
o.ObexFree = obex_Free;
// no ObexExecute!
++iCallRef;
__try {
if(pServiceCallback) {
pServiceCallback (&o);
}
} __except (1) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_WARNINGS, L"[OBEX] Server::Unload - server %s excepted on unload\n", szName));
}
--iCallRef;
}
if (hDll) {
if(0 == FreeLibrary (hDll)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_WARNINGS, L"[OBEX] Server::Unloading module DLL failed!"));
}
else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_WARNINGS, L"[OBEX] Server::Unloading module DLL succeeded."));
}
pServiceCallback = NULL;
fServerStatus = FAILED;
}
memset (this, 0, sizeof(*this));
return TRUE;
}
int Server::DispatchCall (unsigned int uiCId, Connection *pConn, ObexParser *pParser) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : Server %s CId 0x%08x\n", szName, uiCId));
//
// if uiCId != OBEX_INVALID_CID and pConn & pParser == 0, then we need to signal closing the connection
// if uiCId == OBEX_INVALID_CID and pConn & pParser != 0, then we need to allocate new association.
// if pConn != OBEX_INVALID_CID then pParser != 0 and we need to parse and supply data in ObexTransaction
// when client returns, if pConn != NULL and pConn->uiTransactionId != 0, we need to
// reject the call - server screwed up.
//
if (! pConn) {
SVSUTIL_ASSERT (! pParser);
}
else {
SVSUTIL_ASSERT (pParser);
}
ObexTransaction o;
memset (&o, 0, sizeof(0));
o.ObexAlloc = obex_Alloc;
o.ObexFree = obex_Free;
if ((uiCId != OBEX_INVALID_CID) && (! pConn)) { // Association is already removed, we need to just signal.
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : Server %s CId 0x%08x : OBEX_REQ_CLOSE\n", szName, uiCId));
int iRet = FALSE;
if (fServerStatus == OPERATING) {
o.uiOp = OBEX_REQ_CLOSE;
o.uiConnectionId = uiCId;
// no ObexExecute!
++iCallRef;
__try {
if(pServiceCallback) {
iRet = pServiceCallback (&o);
}
} __except (1) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_WARNINGS, L"Server::DispatchCall - server %s excepted (close connection)\n", szName));
}
--iCallRef;
} else
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : Skipping failed server %s CId 0x%08x : OBEX_REQ_CLOSE\n", szName, uiCId));
gpState->Unlock ();
return iRet;
}
if ((uiCId != OBEX_INVALID_CID) && (fServerStatus != OPERATING)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : Server %s CId 0x%08x : has never initialized; skipping the call\n", szName, uiCId));
gpState->SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
return FALSE;
}
if (fServerStatus == FAILED) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : Server %s CId 0x%08x : server has failed in the past, skipping call\n", szName, uiCId));
gpState->SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
return FALSE;
}
//see if we have a default connection for the packet
// if so, we set uiCId to the stored connection ID and continue
if (uiCId == OBEX_INVALID_CID) {
Association *pA = gpState->passocList;
while (pA) {
if ((pA->pConn == pConn) && (pA->pServer == this) && pA->fDefaultConnection)
break;
pA = pA->pNext;
}
if (pA && pParser->Op() == OBEX_OP_CONNECT)
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] Server::DispatchCall : would like to reassociated id but this is the second CONNECT... must reject\n"));
gpState->SendTrivial
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -