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

📄 obex.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if(!pFactory)
            return E_OUTOFMEMORY;
            
        HRESULT hr = pFactory->QueryInterface(riid, ppv);
        pFactory->Release();            
        return hr;        
    }

private:
    LONG m_cRef;
};



template<typename T> ULONG STDMETHODCALLTYPE CFactory<T>::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}


template<typename T> ULONG STDMETHODCALLTYPE CFactory<T>::Release()
{
    SVSUTIL_ASSERT(m_cRef != 0xFFFFFFFF);
    unsigned cRef = InterlockedDecrement(&m_cRef);
    if(cRef != 0)
        return cRef;
    delete this;
    return 0;
}


template<typename T> HRESULT STDMETHODCALLTYPE CFactory<T>::QueryInterface(REFIID riid, void** ppv)
{
    if(riid == IID_IUnknown || riid == IID_IClassFactory)
    {
        *ppv = (IClassFactory *)this;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}


HRESULT STDMETHODCALLTYPE 
CFactory<CObex>::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
{
    if(pUnknownOuter != NULL)
        return CLASS_E_NOAGGREGATION;    

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    
    HRESULT hr;
    PREFAST_ASSERT(gpSynch);
    gpSynch->Lock();

    if (!g_pObex)
    {
        SVSUTIL_ASSERT(!g_pIRDATransport && !g_pBTHTransport); //their lifetimes depend on g_pObex

        g_pIRDATransport = new CObexIRDATransport();
        g_pBTHTransport = new CObexBTHTransport();
        g_pObex = new CObex;

        if (!g_pIRDATransport || !g_pBTHTransport || !g_pObex)
            goto done;

    }
    else
        g_pObex->AddRef();

    hr = g_pObex->QueryInterface(riid, ppv);
    g_pObex->Release();
    gpSynch->Unlock();
    return hr;

done:
    if (g_pObex)
    {
        g_pObex->Release();
        g_pObex = NULL;
    }
    if (g_pBTHTransport)
    {
        g_pBTHTransport->Release();
        g_pBTHTransport = NULL;
    }
    if (g_pIRDATransport)
    {
        g_pIRDATransport->Release();
        g_pIRDATransport = NULL;
    }
    gpSynch->Unlock();
    return E_OUTOFMEMORY;;
}

HRESULT STDMETHODCALLTYPE 
CFactory<CObexIRDATransport>::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
{
    if(pUnknownOuter != NULL)
        return CLASS_E_NOAGGREGATION;    
   
    gpSynch->Lock(); 
    SVSUTIL_ASSERT(g_pObex && g_pIRDATransport);
    HRESULT hr = g_pIRDATransport->QueryInterface(riid, ppv);
    gpSynch->Unlock(); 
    return hr;
    
}


HRESULT STDMETHODCALLTYPE 
CFactory<CObexBTHTransport>::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
{
    if(pUnknownOuter != NULL)
        return CLASS_E_NOAGGREGATION;    
   
    gpSynch->Lock(); 
    SVSUTIL_ASSERT(g_pObex && g_pBTHTransport);
    HRESULT hr = g_pBTHTransport->QueryInterface(riid, ppv);
    gpSynch->Unlock();
    return hr;
    
}


template<typename T> HRESULT STDMETHODCALLTYPE 
CFactory<T>::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
{
    if(pUnknownOuter != NULL)
        return CLASS_E_NOAGGREGATION;
    
    T* t = new T;
    
    if(!t)
        return E_OUTOFMEMORY;
        
    HRESULT hr = t->QueryInterface(riid, ppv);
    t->Release();
    return hr;
    
}




template<typename T> HRESULT STDMETHODCALLTYPE CFactory<T>::LockServer(BOOL bLock)
{
    if(bLock)
        g_cServerLocks++;
    else
        g_cServerLocks--;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE DllCanUnloadNow()
{
    if(g_cServerLocks == 0 && g_cComponents == 0)
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"DllCanUnloadNow -- unloading\n"));
        return S_OK;
    }
    else
    {
        DEBUGMSG(OBEX_COBEX_ZONE,(L"DllCanUnloadNow -- CANT UNLOAD\n"));    
        return S_FALSE;
    }
}

HRESULT STDMETHODCALLTYPE DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
    if(!ppv) return E_POINTER;
    
    if(rclsid == CLSID_Obex) 
        return CFactory<CObex>::GetClassObject(riid, ppv);

    if(rclsid == CLSID_HeaderCollection)
        return CFactory<CHeaderCollection>::GetClassObject(riid, ppv);

    if(rclsid == CLSID_PropertyBag)
        return CFactory<CPropertyBag>::GetClassObject(riid, ppv);

    if(rclsid == CLSID_IrdaTransport)
        return CFactory<CObexIRDATransport>::GetClassObject(riid, ppv);

    if(rclsid == CLSID_BthTransport)
        return CFactory<CObexBTHTransport>::GetClassObject(riid, ppv);

    if(rclsid == CLSID_IpTransport)
        return CFactory<CObexTCPTransport>::GetClassObject(riid, ppv);


    // repeat if statements here
    
    return *ppv = 0, CLASS_E_CLASSNOTAVAILABLE;

    
}

HRESULT STDMETHODCALLTYPE DllRegisterServer()
{
    HRESULT hRes = RegisterServer(L"ObexAPI.dll", CLSID_Obex, L"ObexAPI", L"Sum.OBEXAPI", L"Obex.OBEXAPI.1", L"Free");

    if(SUCCEEDED(hRes))
        hRes = RegisterServer(L"ObexAPI.dll", CLSID_HeaderCollection, L"ObexHeaderCollection", L"Obex.OBEXHeaderCollection", L"Sum.OBEXHeaderCollection.1", L"Free");

    if(SUCCEEDED(hRes))
        hRes = RegisterServer(L"ObexAPI.dll",  CLSID_IrdaTransport, L"ObexIrdaTransport", L"Obex.ObexIrdaTransport", L"Sum.ObexIrdaTransport.1", L"Free");

    if(SUCCEEDED(hRes))
        hRes = RegisterServer(L"ObexAPI.dll",  CLSID_BthTransport, L"ObexBthTransport", L"Obex.ObexBthTransport", L"Sum.ObexBthTransport.1", L"Free");

    return hRes;
 }

HRESULT STDMETHODCALLTYPE DllUnregisterServer()
{
    return UnregisterServer(IID_IObex, L"Sum.OBEXAPI", L"Sum.OBEXAPI.1");
}

// Register the component in the registry.
HRESULT RegisterServer(const WCHAR * szModuleName,     // DLL module handle
                       REFCLSID clsid,                 // Class ID
                       const WCHAR * szFriendlyName,   // Friendly Name
                       const WCHAR * szVerIndProgID,   // Programmatic
                       const WCHAR * szProgID,         // IDs
                       const WCHAR * szThreadingModel) // ThreadingModel
{
    // Get server location.
    WCHAR szModule[512];
    HMODULE hModule = GetModuleHandle(szModuleName);
    DWORD dwResult = GetModuleFileName(hModule, szModule, sizeof(szModule)/sizeof(WCHAR));
    SVSUTIL_ASSERT(dwResult != 0);

    // Convert the CLSID into a char.
    WCHAR szCLSID[CLSID_STRING_SIZE];
    if(FAILED(CLSIDtochar(clsid, szCLSID, sizeof(szCLSID) / sizeof(WCHAR))))
        return E_FAIL;

    // Build the key CLSID\\{...}
    WCHAR szKey[64];
    wcscpy(szKey, L"CLSID\\");
    wcscat(szKey, szCLSID);
  
    // Add the CLSID to the registry.
    setKeyAndValue(szKey, NULL, szFriendlyName);

    // Add the server filename subkey under the CLSID key.
    if(wcsstr(szModuleName, L".exe") == NULL)
    {
        setKeyAndValue(szKey, L"InprocServer32", szModule);
        WCHAR szInproc[64];
        wcscpy(szInproc, szKey);
        wcscat(szInproc, L"\\InprocServer32");
        setValueInKey(szInproc, L"ThreadingModel", szThreadingModel);
    }
    else
        setKeyAndValue(szKey, L"LocalServer32", szModule);

    // Add the ProgID subkey under the CLSID key.
    setKeyAndValue(szKey, L"ProgID", szProgID);

    // Add the version-independent ProgID subkey under CLSID key.
    setKeyAndValue(szKey, L"VersionIndependentProgID", szVerIndProgID);

    // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
    setKeyAndValue(szVerIndProgID, NULL, szFriendlyName); 
    setKeyAndValue(szVerIndProgID, L"CLSID", szCLSID);
    setKeyAndValue(szVerIndProgID, L"CurVer", szProgID);

    // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
    setKeyAndValue(szProgID, NULL, szFriendlyName); 
    setKeyAndValue(szProgID, L"CLSID", szCLSID);

    return S_OK;
}


// Remove the component from the registry.
LONG UnregisterServer(REFCLSID clsid,             // Class ID
                      const WCHAR * szVerIndProgID, // Programmatic
                      const WCHAR * szProgID)       // IDs
{
    // Convert the CLSID into a char.
    WCHAR szCLSID[CLSID_STRING_SIZE];
    if(FAILED(CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(WCHAR))))
        return E_UNEXPECTED;

    // Build the key CLSID\\{...}
    WCHAR szKey[64];
    wcscpy(szKey, L"CLSID\\");
    wcscat(szKey, szCLSID);

    // Delete the CLSID Key - CLSID\{...}
    LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
    SVSUTIL_ASSERT((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.

    // Delete the version-independent ProgID Key.
    lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
    SVSUTIL_ASSERT((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.

    // Delete the ProgID key.
    lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
    SVSUTIL_ASSERT((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.

    return S_OK;
}

// Convert a CLSID to a char string.
HRESULT CLSIDtochar(REFCLSID clsid, WCHAR * szCLSID, unsigned int length)
{
    SVSUTIL_ASSERT(length >= CLSID_STRING_SIZE);
    // Get CLSID
    LPOLESTR wszCLSID = NULL;
    HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
        SVSUTIL_ASSERT(SUCCEEDED(hr));

    if(SUCCEEDED(hr))
    {
        // Covert from wide characters to non-wide.
        if(wcslen(wszCLSID) <= length) {
            wcsncpy (szCLSID, wszCLSID, length);
        }
        else {
            ASSERT(FALSE);
            return E_FAIL;
        }

        // Free memory.
        CoTaskMemFree(wszCLSID);
    } 
    
    return hr; 
}


// Delete a key and all of its descendents.
LONG recursiveDeleteKey(HKEY hKeyParent,           // Parent of key to delete
                        const WCHAR* lpszKeyChild)  // Key to delete
{
    // Open the child.
    HKEY hKeyChild;
    LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
    if(lRes != ERROR_SUCCESS)
        return lRes;

    // Enumerate all of the decendents of this child.
    FILETIME time;
    WCHAR szBuffer[256];
    DWORD dwSize = 256;
    while(RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK)
    {
        // Delete the decendents of this child.
        lRes = recursiveDeleteKey(hKeyChild, szBuffer);
        if(lRes != ERROR_SUCCESS)
        {
            // Cleanup before exiting.
            RegCloseKey(hKeyChild);
            return lRes;
        }
        dwSize = 256;
    }

    // Close the child.
    RegCloseKey(hKeyChild);

    // Delete this child.
    return RegDeleteKey(hKeyParent, lpszKeyChild);
}


// Create a key and set its value.
BOOL setKeyAndValue(const WCHAR* szKey, const WCHAR* szSubkey, const WCHAR* szValue)
{
    HKEY hKey;
    WCHAR szKeyBuf[1024];

    if(1024 <= wcslen(szKey))
        return FALSE;

    // Copy keyname into buffer.
    wcsncpy(szKeyBuf, szKey, 1024 - 1);
    szKeyBuf[1024 - 1] = 0;

    // Add subkey name to buffer.
    if(szSubkey != NULL)
    {
        wcscat(szKeyBuf, L"\\");
        wcscat(szKeyBuf, szSubkey );
    }

    // Create and open key and subkey.
    long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
    if(lResult != ERROR_SUCCESS)
        return FALSE;

    // Set the Value.
    if(szValue != NULL)
        RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szValue, (wcslen(szValue)+1) * sizeof(WCHAR));

    RegCloseKey(hKey);
    return TRUE;
}


// Open a key and set a value.
BOOL setValueInKey(const WCHAR* szKey, const WCHAR* szNamedValue, const WCHAR* szValue)
{
    HKEY hKey;
    WCHAR szKeyBuf[1024];

    if(1024 <= wcslen(szKey))
        return FALSE;

    // Copy keyname into buffer.
    wcsncpy(szKeyBuf, szKey, 1024 - 1);
    szKeyBuf[1024 - 1] = 0;

    // Create and open key and subkey.
    long lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyBuf, 0, KEY_SET_VALUE, &hKey);
    if(lResult != ERROR_SUCCESS)
        return FALSE;

    // Set the Value.
    if(szValue != NULL)
        RegSetValueEx(hK

⌨️ 快捷键说明

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