⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obmain.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#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 + -