VirtualBox

Changeset 27618 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
Mar 23, 2010 4:39:41 AM (15 years ago)
Author:
vboxsync
Message:

iprt: Enabled RTSystemQueryDmiString-win.cpp. Fixed the header from the DDK instead of the SDK issue, by dropping the C++ conveniences and just program COM the good old C way. Btw. TEXT doesn't work on variables.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp

    r27129 r27618  
    3333*   Header Files                                                               *
    3434*******************************************************************************/
     35#define _WIN32_DCOM
     36#include <Windows.h>
     37#include <WbemCli.h>
     38
    3539#include <iprt/system.h>
    3640#include "internal/iprt.h"
     
    4044#include <iprt/string.h>
    4145
    42 #define _WIN32_DCOM
    43 #include <comdef.h>
    44 #include <Wbemidl.h>
    45 
    46 
    47 HRESULT rtSystemInitializeDmiLookup()
    48 {
    49     HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
    50     if (SUCCEEDED(hr))
    51     {
    52         hr = CoInitializeSecurity(NULL,
    53                                   -1,                          /* COM authentication. */
    54                                   NULL,                        /* Which authentication services. */
    55                                   NULL,                        /* Reserved. */
    56                                   RPC_C_AUTHN_LEVEL_DEFAULT,   /* Default authentication. */
    57                                   RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */
    58                                   NULL,                        /* Authentication info. */
    59                                   EOAC_NONE,                   /* Additional capabilities. */
    60                                   NULL);                       /* Reserved. */
    61     }
    62     return hr;
    63 }
    64 
    65 
    66 void rtSystemShutdownDmiLookup()
     46
     47/**
     48 * Initialize COM.
     49 *
     50 * @returns COM status code.
     51 */
     52static HRESULT rtSystemDmiWinInitialize(void)
     53{
     54    HRESULT hrc = CoInitializeEx(0, COINIT_MULTITHREADED);
     55    if (SUCCEEDED(hrc))
     56    {
     57        hrc = CoInitializeSecurity(NULL,
     58                                   -1,                          /* COM authentication. */
     59                                   NULL,                        /* Which authentication services. */
     60                                   NULL,                        /* Reserved. */
     61                                   RPC_C_AUTHN_LEVEL_DEFAULT,   /* Default authentication. */
     62                                   RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */
     63                                   NULL,                        /* Authentication info. */
     64                                   EOAC_NONE,                   /* Additional capabilities. */
     65                                   NULL);                       /* Reserved. */
     66    }
     67    return hrc;
     68}
     69
     70
     71/**
     72 * Undo what rtSystemDmiWinInitialize did.
     73 */
     74static void rtSystemDmiWinTerminate(void)
    6775{
    6876    CoUninitialize();
     
    7078
    7179
    72 HRESULT rtSystemConnectToDmiServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices)
     80/**
     81 * Convert a UTF-8 string to a BSTR.
     82 *
     83 * @returns BSTR pointer.
     84 * @param   psz                 The UTF-8 string.
     85 */
     86static BSTR rtSystemWinBstrFromUtf8(const char *psz)
     87{
     88    PRTUTF16 pwsz = NULL;
     89    int rc = RTStrToUtf16(psz, &pwsz);
     90    if (RT_FAILURE(rc))
     91        return NULL;
     92    BSTR pBStr = SysAllocString((const OLECHAR *)pwsz);
     93    RTUtf16Free(pwsz);
     94    return pBStr;
     95}
     96
     97
     98/**
     99 * Connect to the DMI server.
     100 *
     101 * @returns COM status code.
     102 * @param   pLocator            The locator.
     103 * @param   pszServer           The server name.
     104 * @param   ppServices          Where to return the services interface.
     105 */
     106static HRESULT rtSystemDmiWinConnectToServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices)
    73107{
    74108    AssertPtr(pLocator);
     
    76110    AssertPtr(ppServices);
    77111
    78     HRESULT hr = pLocator->ConnectServer(_bstr_t(TEXT(pszServer)),
    79                                          NULL,
    80                                          NULL,
    81                                          0,
    82                                          NULL,
    83                                          0,
    84                                          0,
    85                                          ppServices);
    86     if (SUCCEEDED(hr))
    87     {
    88         hr = CoSetProxyBlanket(*ppServices,
    89                                RPC_C_AUTHN_WINNT,
    90                                RPC_C_AUTHZ_NONE,
    91                                NULL,
    92                                RPC_C_AUTHN_LEVEL_CALL,
    93                                RPC_C_IMP_LEVEL_IMPERSONATE,
    94                                NULL,
    95                                EOAC_NONE);
    96     }
    97     return hr;
     112    BSTR pBStrServer = rtSystemWinBstrFromUtf8(pszServer);
     113    if (!pBStrServer)
     114        return E_OUTOFMEMORY;
     115
     116    HRESULT hrc = pLocator->ConnectServer(pBStrServer,
     117                                          NULL,
     118                                          NULL,
     119                                          0,
     120                                          NULL,
     121                                          0,
     122                                          0,
     123                                          ppServices);
     124    if (SUCCEEDED(hrc))
     125    {
     126        hrc = CoSetProxyBlanket(*ppServices,
     127                                RPC_C_AUTHN_WINNT,
     128                                RPC_C_AUTHZ_NONE,
     129                                NULL,
     130                                RPC_C_AUTHN_LEVEL_CALL,
     131                                RPC_C_IMP_LEVEL_IMPERSONATE,
     132                                NULL,
     133                                EOAC_NONE);
     134        if (FAILED(hrc))
     135            (*ppServices)->Release();
     136    }
     137    SysFreeString(pBStrServer);
     138    return hrc;
    98139}
    99140
     
    106147    AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER);
    107148
    108     HRESULT hr = rtSystemInitializeDmiLookup();
    109     if (FAILED(hr))
     149    /*
     150     * Figure the property name before we start.
     151     */
     152    const char *pszPropName;
     153    switch (enmString)
     154    {
     155        case RTSYSDMISTR_PRODUCT_NAME:      pszPropName = "Name"; break;
     156        case RTSYSDMISTR_PRODUCT_VERSION:   pszPropName = "Version"; break;
     157        case RTSYSDMISTR_PRODUCT_UUID:      pszPropName = "UUID"; break;
     158        case RTSYSDMISTR_PRODUCT_SERIAL:    pszPropName = "IdentifyingNumber"; break;
     159        default:
     160            return VERR_NOT_SUPPORTED;
     161    }
     162
     163    /*
     164     * Before we do anything with COM, we have to initalize it.
     165     */
     166    HRESULT hrc = rtSystemDmiWinInitialize();
     167    if (FAILED(hrc))
    110168        return VERR_NOT_SUPPORTED;
    111169
    112     IWbemLocator *pLoc;
    113     hr = CoCreateInstance(CLSID_WbemLocator,
    114                           0,
    115                           CLSCTX_INPROC_SERVER,
    116                           IID_IWbemLocator, (LPVOID *)&pLoc);
    117     int rc = VINF_SUCCESS;
    118     if (SUCCEEDED(hr))
    119     {
    120         IWbemServices *pServices;
    121         hr = rtSystemConnectToDmiServer(pLoc, "ROOT\\CIMV2", &pServices);
    122         if (SUCCEEDED(hr))
     170    int rc = VERR_NOT_SUPPORTED;
     171    BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName);
     172    if (pBstrPropName)
     173    {
     174        /*
     175         * Instantiate the IWbemLocator, whatever that is and connect to the
     176         * DMI serve.
     177         */
     178        IWbemLocator *pLoc;
     179        hrc = CoCreateInstance(CLSID_WbemLocator,
     180                               0,
     181                               CLSCTX_INPROC_SERVER,
     182                               IID_IWbemLocator,
     183                               (LPVOID *)&pLoc);
     184        if (SUCCEEDED(hrc))
    123185        {
    124             IEnumWbemClassObject *pEnum;
    125             hr = pServices->CreateInstanceEnum(L"Win32_ComputerSystemProduct", 0, NULL, &pEnum);
    126             if (SUCCEEDED(hr))
     186            IWbemServices *pServices;
     187            hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices);
     188            if (SUCCEEDED(hrc))
    127189            {
    128                 IWbemClassObject *pObj;
    129                 ULONG uCount;
    130 
    131                 do
     190                /*
     191                 * Enumerate whatever it is we're looking at and try get
     192                 * the desired property.
     193                 */
     194                BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct");
     195                if (pBstrFilter)
    132196                {
    133                     hr = pEnum->Next(WBEM_INFINITE,
    134                                      1,
    135                                      &pObj,
    136                                      &uCount);
    137                     if (   SUCCEEDED(hr)
    138                         && uCount > 0)
     197                    IEnumWbemClassObject *pEnum;
     198                    hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum);
     199                    if (SUCCEEDED(hrc))
    139200                    {
    140                         const char *pszPropName;
    141                         switch (enmString)
     201                        do
    142202                        {
    143                             case RTSYSDMISTR_PRODUCT_NAME:      pszPropName = "Name"; break;
    144                             case RTSYSDMISTR_PRODUCT_VERSION:   pszPropName = "Version"; break;
    145                             case RTSYSDMISTR_PRODUCT_UUID:      pszPropName = "UUID"; break;
    146                             case RTSYSDMISTR_PRODUCT_SERIAL:    pszPropName = "IdentifyingNumber"; break;
    147                             default:
    148                                 rc = VERR_NOT_SUPPORTED;
    149                         }
    150 
    151                         if (RT_SUCCESS(rc))
    152                         {
    153                             _variant_t v;
    154                             hr = pObj->Get(_bstr_t(TEXT(pszPropName)), 0, &v, 0, 0);
    155                             if (   SUCCEEDED(hr)
    156                                 && V_VT(&v) == VT_BSTR)
     203                            IWbemClassObject *pObj;
     204                            ULONG cObjRet;
     205                            hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet);
     206                            if (   SUCCEEDED(hrc)
     207                                && cObjRet >= 1)
    157208                            {
    158                                 RTStrPrintf(pszBuf, cbBuf, "%s", (char*)_bstr_t(v.bstrVal));
    159                                 VariantClear(&v);
     209                                VARIANT Var;
     210                                VariantInit(&Var);
     211                                hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0);
     212                                if (   SUCCEEDED(hrc)
     213                                    && V_VT(&Var) == VT_BSTR)
     214                                {
     215                                    /*
     216                                     * Convert the BSTR to UTF-8 and copy it
     217                                     * into the return buffer.
     218                                     */
     219                                    char *pszValue;
     220                                    rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue);
     221                                    if (RT_SUCCESS(rc))
     222                                    {
     223                                        rc = RTStrCopy(pszBuf, cbBuf, pszValue);
     224                                        RTStrFree(pszValue);
     225                                        hrc = WBEM_S_FALSE;
     226                                    }
     227                                }
     228                                VariantClear(&Var);
     229                                pObj->Release();
    160230                            }
    161                         }
    162                         pObj->Release();
     231                        } while (hrc != WBEM_S_FALSE);
     232
     233                        pEnum->Release();
    163234                    }
    164                 } while(hr != WBEM_S_FALSE);
    165                 pEnum->Release();
     235                    SysFreeString(pBstrFilter);
     236                }
     237                else
     238                    hrc = E_OUTOFMEMORY;
     239                pServices->Release();
    166240            }
    167             pServices->Release();
     241            pLoc->Release();
    168242        }
    169         pLoc->Release();
    170     }
    171 
    172     rtSystemShutdownDmiLookup();
    173     if (FAILED(hr))
    174         rc = VERR_NOT_FOUND; /** @todo Find a better error, since neither of the RTErrConvert* can do the conversion here. */
     243        SysFreeString(pBstrPropName);
     244    }
     245    else
     246        hrc = E_OUTOFMEMORY;
     247    rtSystemDmiWinTerminate();
     248    if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED)
     249        rc = VERR_NOT_SUPPORTED;
    175250    return rc;
    176251}
    177 RT_EXPORT_SYMBOL(RTSystemQueryDmiString);
    178 
     252
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette