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

📄 obex.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                hr = g_pObex->_pDevices->FindDevicesThatMatch (pBag, &pMatchedDeviceList);
                
                if(FAILED(hr))
                {
                    ReleaseLock();    
                    pBag->Release();
                    pBag = NULL;
                    pPropBagEnum->Release();
                    goto done;
                }

                //
                //  If there are no devices, this is a new one, so insert it
                //                
                if(NULL == pMatchedDeviceList)
                {                    
                    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumIndividualDevicesThread - New device found!\n"));
                        
                    //create a new device with our clsid and propertybag
                    // NOTE: creating the device effectivly calles SetModified
                    CObexDevice *pObexDevice = new CObexDevice(pBag, clsid);
                    
                    if (!pObexDevice)
                    {                        
                        ReleaseLock();
                        pBag->Release();
                        pBag = NULL;
                        pPropBagEnum->Release();
                        goto done;
                    }

                    //insert it into the device list
                    hr = g_pObex->_pDevices->Insert(pObexDevice);

                    //if all went okay, notify any connection points 
                    if ((g_dwObexCaps & SEND_DEVICE_UPDATES) && SUCCEEDED(hr))
                    {                    
                        if (!g_pObex->_bStopEnum)    
                            g_pObex->_pConnPt->Notify(OE_DEVICE_ARRIVAL, pBag, NULL);
                    }

                    pObexDevice->Release();    
                    pObexDevice = NULL;
                }

                //
                //  Otherwise, there are multiple devices, so update them individually
                //
                else
                {            
                    if(FAILED(g_pObex->UpdateDevices(pTransport, &clsid, pMatchedDeviceList)))
                    {
                        ReleaseLock();
                        pBag->Release();
                        pBag = NULL;
                        pPropBagEnum->Release();
                        goto done;
                    }
                    
                }//must leave this if locked!

                

                SVSUTIL_ASSERT(gpSynch->IsLocked());
                
                ulFetched = 0;
                ReleaseLock();                    
                
                pBag->Release();
                pBag = NULL;                
            } 
            SVSUTIL_ASSERT(!pBag);
            
            //end of while
            pPropBagEnum->Release();
            pPropBagEnum = NULL;
        }
        else 
        {            
            DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevicesThread - EnumDevices failed for transport %s...()\n", var.bstrVal));
            goto done;
        }
        SVSUTIL_ASSERT(!pPropBagEnum);
        

        if (!GetLock())
            goto done;

        //finish the enumeration run by building a list of all devices
        //  that have been removed (as determined by the Present flag)
        DEVICE_PROPBAG_LIST *pDevicesToRemove = NULL;
        hr = g_pObex->_pDevices->FinishEnumRun(&pDevicesToRemove, clsid);
        
        //now, iterate throuh the removed devices notifying the connection
        //  point of their departure.
        if (SUCCEEDED(hr) && pDevicesToRemove)
        {
            SVSUTIL_ASSERT(gpSynch->IsLocked());

            //loop through all devices to be removed and notify the connectionpts
            while(pDevicesToRemove)
            {
                SVSUTIL_ASSERT(pDevicesToRemove->pBag);
                g_pObex->_pConnPt->Notify(OE_DEVICE_DEPARTURE, pDevicesToRemove->pBag, NULL);

                //if an error occured, mark the device as a corpse in its bag
                VARIANT varCorpse;
                VariantInit(&varCorpse);
                
                hr = pDevicesToRemove->pBag->Read(L"Corpse", &varCorpse, NULL);                
                
                //if the device isnt a corpse, delete it & move on
                if(FAILED(hr) || VT_I4 != varCorpse.vt || 1 != varCorpse.lVal)
                {
                    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevicesThread - found device to remove (it walked off)... but not corpse\n"));
                    DEVICE_PROPBAG_LIST *pDel = pDevicesToRemove;
                    pDevicesToRemove->pBag->Release();
                    pDevicesToRemove = pDevicesToRemove->pNext;
                    delete pDel;
                }
                else
                {
                    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevicesThread - found device to remove (its a corpse)\n"));
                    DEVICE_PROPBAG_LIST *pPBTemp = pDevicesToRemove->pNext;
                    pDevicesToRemove->pNext = pDeviceCorpses;
                    pDeviceCorpses = pDevicesToRemove;
                    pDevicesToRemove = pPBTemp;
                }

                VariantClear(&varCorpse);                
            }
        }

        ReleaseLock();
    }

done:
    SVSUTIL_ASSERT(!gpSynch->IsLocked());

    //
    //  Clean our corpse list (devices that dont support obex but still get discovered
    //    but the transport enumerator)
    //
    while(pDeviceCorpses)
    {    
        DEVICE_PROPBAG_LIST *pDel = pDeviceCorpses;
        pDeviceCorpses = pDeviceCorpses->pNext;
        
        pDel->pBag->Release();
        delete pDel;
    }

    // remove this transport from the active list (there is no recovery for error)
    g_pObex->RemoveActiveTransport(pTransport);    
    
    if (pPropBag)
        pPropBag->Release();    
    if (pTransport)
        pTransport->Release();
    
    SVSUTIL_ASSERT(g_pObex && !pBag);
    
    //
    //  Because we are leaving the thread, the # of running threads
    //     must be decremented--- and because this has to be dec'ed
    //     we must call PauseEnumIfRequired

    gpSynch->Lock();
    //decrement the # of threads running
    g_pObex->_uiRunningENumThreadCnt --;
    gpSynch->Unlock();
    g_pObex->PauseEnumIfRequired();

    //close up shop
    if(g_pObex)
       g_pObex->Release();
    CoUninitialize();
    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevicesThread - FINISHED -- going away\n"));
    return 0;
}




DWORD 
//note: we are already under gpSynch->Lock()!
CObex::StartEnumeratingDevices()
{
    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevices()\n"));
    
    LPPROPERTYBAGENUM pTransportEnum = NULL;
    LPPROPERTYBAG2 pPropBag = NULL;    
    HKEY hk;
    HRESULT hr = E_FAIL;
    ULONG ulFetched;

    
    if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\obex", 0, KEY_READ, &hk))
    {
        DWORD dw = 0;
        DWORD dwType = REG_DWORD;
        DWORD dwSize = sizeof(dw);
        if (ERROR_SUCCESS == RegQueryValueEx (hk, L"clientcredits", NULL, &dwType, (LPBYTE)&dw, &dwSize))
        {
            if ((dwType == REG_DWORD) && (dwSize == sizeof(dw)) && (dw > 0) && (((int)dw) > 0))
                g_iCredits = (int)dw;
        }
        RegCloseKey (hk);
    }
    
    if ((!g_pObex) || (!g_pObex->IsInitialized()))
        goto done;
    
    //get a property bag of transports
    hr = g_pObex->EnumTransports(&pTransportEnum);

    if((FAILED(hr)) || (0 == pTransportEnum))
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::EnumDevicesThread - EnumTransports failed(err=0x%08x)()\n", hr));
        goto done;
    }
    
   
    //build a linked list of thread handles (and then copy them into an array)
    pTransportEnum->Reset();
    
    gpSynch->Lock();    
     _uiEnumThreadCnt = 0;
     while((SUCCEEDED(pTransportEnum->Next(1, &pPropBag, &ulFetched)) && ulFetched))
     {        //note: we are passing off ownership of the pPropBag!!!!!    
         SVSUTIL_ASSERT(g_pObex);
         g_pObex->AddRef();
        _hEnumThreadArray[_uiEnumThreadCnt] = CreateThread(NULL, 0, EnumIndividualDeviceThread, (void *)pPropBag, 0, 0);    
        _uiEnumThreadCnt++; 
        _uiRunningENumThreadCnt++;
     }
    gpSynch->Unlock();

 
done:    
    if (pTransportEnum)
        pTransportEnum->Release();
        
    SVSUTIL_ASSERT(gpSynch);
    return 0;
}


HRESULT STDMETHODCALLTYPE
CObex::PauseDeviceEnum(BOOL fPauseOn)
{
    HRESULT hr = S_OK;
    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::PauseDeviceEnum()\n"));
    if(fPauseOn)  {
        BOOL fBlock = FALSE;
        UINT uiPreviousThreadCnt; 
        gpSynch->Lock();
            uiPreviousThreadCnt = _uiRunningENumThreadCnt;
            if(FALSE == this->_fPause) {
                ResetEvent(_hEnumPauseEvent); 
                this->_fPause = TRUE; 
                AbortActiveTransports(TRUE);
                if(0 != _uiRunningENumThreadCnt) //dont block if no threads are running!
                    fBlock = TRUE;
            }
        gpSynch->Unlock();
        
        if(fBlock) {
            if(WAIT_OBJECT_0 != WaitForSingleObject(_hEnumPauseEvent_UnlockPauseFunction, INFINITE))
            {
                hr = E_FAIL;
            }
            gpSynch->Lock();
                _uiRunningENumThreadCnt = uiPreviousThreadCnt;
            gpSynch->Unlock();  
        }
        
        
    }    
    else  { 
        gpSynch->Lock();
            this->_fPause = FALSE;
        gpSynch->Unlock();    
        SetEvent(_hEnumPauseEvent);  
    }    
      
    gpSynch->Lock();
    AbortActiveTransports(FALSE);  
    gpSynch->Unlock(); 
    return hr;
}

HRESULT STDMETHODCALLTYPE 
CObex::StartDeviceEnum()
{
    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum()\n"));
    gpSynch->Lock();
    if (_stage != Initialized)
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum - Not yet initialized...()\n"));
        gpSynch->Unlock();
        return OBEX_E_NOT_INITIALIZED;
    }

    while (_bStopEnum)
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum - In the process of stopping previous enumeration...()\n"));

        SVSUTIL_ASSERT(_uiEnumThreadCnt);
    
        //wait for all threads to exit
        gpSynch->Unlock();

        //
        //wait for all threads to exit (they get the _bStopEnum flag and quit)
        //
        for(UINT i=0; i<_uiEnumThreadCnt; i++)
        {    
            DWORD waitRet = WaitForSingleObject(_hEnumThreadArray[i], INFINITE);
            CloseHandle(_hEnumThreadArray[i]);
            SVSUTIL_ASSERT(WAIT_FAILED != waitRet);

            if(WAIT_FAILED == waitRet)
            {
                DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::WaitForMultipleObject on thread failed: %x\n", GetLastError()));
                return E_FAIL;
            }
            else
            {
                DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::WaitForMultipleObject thread %d down\n", i));
            }
        }

        gpSynch->Lock();
        
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum - Previous enumeration stopped()\n"));

        if (_stage != Initialized)
        {
            DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum - Device shutdown in the meanwhile...()\n"));
            gpSynch->Unlock();
            return E_FAIL;
        }
    }

    if (_uiEnumThreadCnt)
    {           
        //inc the device ref count to the thread (to prevent removing it later)
        _uiDeviceEnumCnt ++;
        
        gpSynch->Unlock();
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StartDeviceEnum - Enum already running...()\n"));        
        return S_OK;
    }

    SVSUTIL_ASSERT(_uiEnumThreadCnt == 0);

    if (_pDevices)
    {
        _pDevices->Release();
        _pDevices = NULL;
    }

    _pDevices = new CDeviceEnum();
    if (!_pDevices)
    {
        gpSynch->Unlock();
        return E_OUTOFMEMORY;
    }
    _pDevices->Reset();
    
    //make sure we are not paused
    PauseDeviceEnum(FALSE);   

    //crank up the device enumeration threads
    StartEnumeratingDevices();    

    //inc the ref count to the thread (to prevent removing it later)
    _uiDeviceEnumCnt ++;
    
    gpSynch->Unlock();    
    return S_OK;
}

HRESULT STDMETHODCALLTYPE 
CObex::StopDeviceEnum()
{        
    DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StopDeviceEnum()\n"));
    gpSynch->Lock();
    if (_stage != Initialized || !_uiDeviceEnumCnt)
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::StopDeviceEnum - Not yet initialized...()\n"));
        gpSynch->Unlock();
        return OBEX_E_NOT_INITIALIZED;
    }

    //dec the ref count
    if(_uiDeviceEnumCnt)    
        _uiDeviceEnumCnt--;

    if (_bStopEnum || !_uiEnumThreadCnt || _uiDeviceEnumCnt)
    {
        gpSynch->Unlock();
        return S_OK;
    }
    
    //set the stop enum flag
    _bStopEnum = TRUE;

    gpSynch->Unlock();    
    
    //make sure we are not paused
    PauseDeviceEnum(FALSE);
    
    //abort any active connections
    gpSynch->Lock();
    AbortActiveTransports(TRUE);
    gpSynch->Unlock(); 
    
    //
    //wait for all threads to exit (they get the _bStopEnum flag and quit)
    //
    for(UINT i=0; i<_uiEnumThreadCnt; i++)
    {    
        DWORD waitRet = WaitForSingleObject(_hEnumThreadArray[i], INFINITE);
        CloseHandle(_hEnumThreadArray[i]);
        SVSUTIL_ASSERT(WAIT_FAILED != waitRet);

        if(WAIT_FAILED == waitRet)
        {
            DEBUGMSG(OBEX_COBEX_ZONE,(L"CObex::WaitForMultipleObject on thread failed: %x\n", GetLastError()));
            return E_FAIL;
        }
        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -