На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Зачем нужна функция SysAllocString ?
    Есть код для работы с WMI (получение тем-ры процессора):

    ExpandedWrap disabled
      HRESULT GetCpuTemperature(LPLONG pTemperature)
      {
          if (pTemperature == NULL)
              return E_INVALIDARG;
       
          *pTemperature = -1;
          HRESULT ci = CoInitialize(NULL); // needs comdef.h
          HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
          if (SUCCEEDED(hr))
          {
              IWbemLocator* pLocator; // needs Wbemidl.h & Wbemuuid.lib
              hr = CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)& pLocator);
              if (SUCCEEDED(hr))
              {
                  IWbemServices* pServices;
                  BSTR ns = SysAllocString(L"root\\WMI");
                  hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices);
                  pLocator->Release();
                  SysFreeString(ns);
                  if (SUCCEEDED(hr))
                  {
                      BSTR query = SysAllocString(L"SELECT * FROM MSAcpi_ThermalZoneTemperature");
                      BSTR wql = SysAllocString(L"WQL");
                      IEnumWbemClassObject* pEnum;
                      hr = pServices->ExecQuery(wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
                      SysFreeString(wql);
                      SysFreeString(query);
                      pServices->Release();
                      if (SUCCEEDED(hr))
                      {
                          IWbemClassObject* pObject;
                          ULONG returned;
                          hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &returned);
                          pEnum->Release();
                          if (SUCCEEDED(hr))
                          {
                              BSTR temp = SysAllocString(L"CurrentTemperature");
                              VARIANT v;
                              VariantInit(&v);
                              hr = pObject->Get(temp, 0, &v, NULL, NULL);
                              pObject->Release();
                              SysFreeString(temp);
                              if (SUCCEEDED(hr))
                              {
                                  *pTemperature = V_I4(&v);
                              }
                              VariantClear(&v);
                          }
                      }
                  }
                  if (ci == S_OK)
                  {
                      CoUninitialize();
                  }
              }
          }
          return hr;
      }

    Зачем здесь нужны SysAllocString и SysFreeString ?
    Код и без них же работает.
      Цитата Jin X @
      Зачем здесь нужны SysAllocString и SysFreeString ?
      Код и без них же работает.

      Если воспользоваться поиском:
      1
      2
        ЫукпШ, я искал, но нормального объяснения как-то не находил. Инфа про формат строки (что он предваряется размером) – интересная. Хотя не факт, что она используется, ибо вариант:
        ExpandedWrap disabled
          hr = pLocator->ConnectServer((BSTR)L"root\\WMI", NULL, NULL, NULL, 0, NULL, NULL, &pServices);
        тоже прекрасно работает.

        Добавлено
        Хотя есть много примеров (в основном на VB), где используются обычные строки.
        Там (в VB) они в том же формате что ли хранятся, интересно?
          Цитата Jin X @
          Хотя не факт, что она используется, ибо вариант:
          ExpandedWrap disabled
            hr = pLocator->ConnectServer((BSTR)L"root\\WMI", NULL, NULL, NULL, 0, NULL, NULL, &pServices);
          тоже прекрасно работает.

          У меня твой пример вообще никак не заработал.
          Но я не специалист по этому вопросу, первый раз про WMI слышу.
          ---
          Ошибка происходит тут:
          ExpandedWrap disabled
             hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &returned);

          ---
          WBEM_E_NOT_SUPPORTED.
          И на домашнем компе, и на работе.
          Сообщение отредактировано: ЫукпШ -
            Цитата Jin X @
            Инфа про формат строки (что он предваряется размером) – интересная. Хотя не факт, что она используется, ибо вариант:
            ExpandedWrap disabled
              hr = pLocator->ConnectServer((BSTR)L"root\\WMI", NULL, NULL, NULL, 0, NULL, NULL, &pServices);
            тоже прекрасно работает.
            Это потому, что сервер использует то же представление, что и твой клиент. Вот был сервер написан на VB или там Delphi, пример прекрасно бы не заработал. Да и не только, достаточно, чтоб сервер заюзал обобщённые интерфейсы для BSTR.

            Добавлено
            Цитата Jin X @
            Там (в VB) они в том же формате что ли хранятся, интересно?
            Нет. Там скорее Дельфёвый формат. У дельфи, кстати, форматов тоже не один-единственный.
              Цитата Jin X @
              Зачем здесь нужны SysAllocString и SysFreeString ?

              Действительно, есть ещё более удобный вариант.
              Возьмём отрезок:
              ExpandedWrap disabled
                            BSTR ns = SysAllocString(L"root\\WMI");
                            hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices);
                            SysFreeString(ns);

              и изменим его так:
              ExpandedWrap disabled
                            bstr_t ns ("root\\WMI");
                            hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices);

              Сильно полегчает. :)

              Если подсмотреть, что это такое:
              ExpandedWrap disabled
                ...
                #define bstr_t _bstr_t
                ...
                //////////////////////////////////////////////////////////////////////////////
                //
                // Wrapper class for BSTR
                //
                //////////////////////////////////////////////////////////////////////////////
                 
                class _bstr_t {
                public:
                    // Constructors
                    //
                    _bstr_t() throw();
                    _bstr_t(const _bstr_t& s) throw();
                 
                // с любыми строками будет работать правильно:
                    _bstr_t(const char* s) ;
                    _bstr_t(const wchar_t* s) ;
                ...
              Сообщение отредактировано: ЫукпШ -
                Цитата ЫукпШ @
                У меня твой пример вообще никак не заработал.
                Надо запускать из-под админа.
                Но эту канитель BIOS должен поддерживать, там через SMBIOS работа идёт вроде, как я понимаю.

                Цитата Qraizer @
                Нет. Там скорее Дельфёвый формат. У дельфи, кстати, форматов тоже не один-единственный.
                Если брать Delphi'овый WideString, то он, по сути, такой же, как и BSTR: 4-мя байтами ранее указателя – кол-во (DWORD) байт в строке (без учёта нуля), далее ASCIIZ-строка в Unicode. В UnicodeString (он же String в Unicode-версии Delphi, т.е. 2009+) всё то же самое, только размер не в байтах, а в символах.
                А в VB ?

                Добавлено
                Вот как даже в Delphi описано, я сейчас нашёл:
                ExpandedWrap disabled
                    TBStr = POleStr;
                    POleStr = PWideChar;


                Добавлено
                А там просто ASCIIZ-строка в Unicode, никаких размеров нет. Странно как-то это всё.
                Конечно, если строку выделить через SysAllocString, то она будет в нужном формате и её можно вставить в SysFreeString, а вот если вставить обычную PWideChar-строку в метод какого-нибудь интерфейса (без её создания через SysAllocString), то синтаксически Delphi будет видеть, что всё ок и скомпилит, но по факту это будет не BSTR. Почему же POleStr не WideString? Ведь при работе с WideString используются системные функции работы с памятью (SysAllocStringLen, SysReAllocStringLen, SysFreeString) :-?
                Сообщение отредактировано: Jin X -
                  Цитата ЫукпШ @
                  bstr_t ns ("root\\WMI");
                  hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices);
                  Ништяк!
                  Даже вот так лучше:
                  ExpandedWrap disabled
                    hr = pLocator->ConnectServer(bstr_t(L"root\\WMI"), NULL, NULL, NULL, 0, NULL, NULL, &pServices);
                  (L - чтобы не было лишних конвертаций) ;)
                    Цитата Jin X @
                    А там просто ASCIIZ-строка в Unicode, никаких размеров нет. Странно как-то это всё.
                    Размер может быть по отрицательному смещению. -2 или -4. А сам поинтер указывает на собственно строку. Библиотечные функции об этом в курсе, знают об отрицательных смещениях с длиной и эффективно используют. И меняют при необходимости, подразумевая, что там есть место под длину.
                    Формально тут дело даже не в языке. Если OLE-партнёр с той стороны не будет использовать это поле, то и простой ASCIIZ- или UNICODEZ-строки будет достаточно, но ты не можешь быть уверен, что прохляет.
                      Цитата Qraizer @
                      Цитата Jin X @
                      А там просто ASCIIZ-строка в Unicode, никаких размеров нет. Странно как-то это всё.
                      Размер может быть по отрицательному смещению.

                      Как это может быть - не понятно.
                      Возможно, всё просто.
                      BSTR - это структура. С полем для строки, а затем полем для размера.
                      Таким образом, размер фактически может быть за хвостом строки.
                      Если функции, использующие этот тип, достаточно интеллектуальны,
                      они программно могут разбираться с содержимым и даже форматом строки.
                      Т.е. отличать ASCII от UNICODE.

                      Добавлено
                      Цитата Jin X @
                      Даже вот так лучше:

                      Продолжим фантазировать. Возможно, таких программ придётся делать много.
                      Обернём классом переменные:
                      ExpandedWrap disabled
                                     IWbemLocator*         pILocator  ;
                                     IWbemServices*        pIServices ;
                                     IEnumWbemClassObject* pIEnumObject   ;
                                     IWbemClassObject*     pIClassObject  ;

                      А заодно и CoInitialize/CoUninitialize.
                      В результате молучим приблизительно это:
                      Скрытый текст

                      ExpandedWrap disabled
                        // .h - файл
                        //---------------------------------------------------------------------------
                        // file MWmiTool.h  2019.12.16
                        //---------------------------------------------------------------------------
                        #ifndef __MWmiTool_H__
                        #define __MWmiTool_H__
                        //---------------------------------------------------------------------------
                        #define _WIN32_DCOM
                        #include <comdef.h>
                        #include <Wbemidl.h>
                        #include <objbase.h>
                         
                        #include "TypeDebugString.h"
                        //---------------------------------------------------------------------------
                        #pragma comment (lib, "OLE32.LIB")
                        #pragma comment (lib, "Wbemuuid.lib")
                        //---------------------------------------------------------------------------
                        // DbgStr::TypeDebugString(const TCHAR* pFmt,...);
                        // DbgStr::TypeDebugString(_T("%s"), _T(__FUNCTION__));
                        //---------------------------------------------------------------------------
                        class MWmiTool
                        {
                         private:
                         
                         protected:
                         
                         public:
                         
                                     HRESULT               hr;
                         
                                     IWbemLocator*         pILocator  ;
                                     IWbemServices*        pIServices ;
                                     IEnumWbemClassObject* pIEnumObject   ;
                                     IWbemClassObject*     pIClassObject  ;
                         
                         
                         
                                          WINAPI MWmiTool      (void);
                          virtual         WINAPI ~MWmiTool     (void);  
                         
                                     BOOL WINAPI Free          (void);
                         
                         
                                  void    WINAPI operator=(IWbemLocator* p);
                                          WINAPI operator IWbemLocator* ();
                                          WINAPI operator IWbemLocator** ();
                                          WINAPI operator LPVOID* ();
                                     BOOL WINAPI FreeIWbemLocator(void);
                         
                                  void    WINAPI operator=(IWbemServices* p);
                                          WINAPI operator IWbemServices* ();
                                          WINAPI operator IWbemServices** ();
                                     BOOL WINAPI FreeIWbemServices(void);
                         
                                  void    WINAPI operator=(IEnumWbemClassObject* p);
                                          WINAPI operator IEnumWbemClassObject* ();
                                          WINAPI operator IEnumWbemClassObject** ();
                                     BOOL WINAPI FreeIEnumWbemClassObject(void);
                         
                                  void    WINAPI operator=(IWbemClassObject* p);
                                          WINAPI operator IWbemClassObject* ();
                                          WINAPI operator IWbemClassObject** ();
                                     BOOL WINAPI FreeIWbemClassObject(void);
                        };
                        //---------------------------------------------------------------------------
                        #endif
                         
                        // .cpp файл
                        // --------------------------------------------------------------------------
                        //   FILE MWmiTool.cpp 2019.12.16
                        // --------------------------------------------------------------------------
                        #define _WIN32_DCOM
                        #include "stdafx.h"
                        #include "MWmiTool.h"
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::MWmiTool (void) :
                         
                         pILocator      (NULL),
                         pIServices     (NULL),
                         pIEnumObject   (NULL),
                         pIClassObject  (NULL),
                         hr             (S_FALSE)
                                                    
                        {
                         hr = ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
                        }
                        // --------------------------------------------------------------------------
                        WINAPI MWmiTool::~MWmiTool (void)                                                    
                        {
                         Free();
                        }
                        //---------------------------------------------------------------------------
                        BOOL WINAPI MWmiTool::Free(void)
                        {
                         BOOL RetC=TRUE;
                         
                         RetC &= FreeIWbemLocator();
                         RetC &= FreeIWbemServices();
                         RetC &= FreeIEnumWbemClassObject();
                         RetC &= FreeIWbemClassObject();
                         
                         if(hr==S_OK) { ::CoUninitialize(); hr=S_FALSE;}
                         
                        // S_OK    The COM library was initialized successfully on this thread.
                        // S_FALSE The COM library is already initialized on this thread.
                         
                        // RPC_E_CHANGED_MODE
                        // A previous call to CoInitializeEx specified the concurrency model for
                        //this thread as multithread apartment (MTA).
                        //If running Windows 2000, this could also mean that
                        //a change from neutral-threaded apartment to single-threaded
                        //apartment occurred
                         return RetC;
                        }
                        //---------------------------------------------------------------------------
                        BOOL WINAPI MWmiTool::FreeIWbemLocator(void)
                        {
                         BOOL RetC=TRUE;
                         if(pILocator)
                         {
                          pILocator->Release();
                          pILocator=NULL;
                         }
                         return RetC;
                        }
                        //---------------------------------------------------------------------------
                        void WINAPI MWmiTool::operator=(IWbemLocator* p)
                        {
                         FreeIWbemLocator();
                         pILocator=p;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemLocator* ()
                        {
                         return pILocator;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemLocator** ()
                        {
                         return &pILocator;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator LPVOID* ()
                        {
                         return (LPVOID*) &pILocator;
                        }
                        //---------------------------------------------------------------------------
                         
                         
                         
                        //---------------------------------------------------------------------------
                        BOOL WINAPI MWmiTool::FreeIWbemServices(void)
                        {
                         BOOL RetC=TRUE;
                         if(pIServices)
                         {
                          pIServices->Release();
                          pIServices=NULL;
                         }
                         return RetC;
                        }
                        //---------------------------------------------------------------------------
                        void WINAPI MWmiTool::operator=(IWbemServices* p)
                        {
                         FreeIWbemServices();
                         pIServices=p;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemServices* ()
                        {
                         return pIServices;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemServices** ()
                        {
                         return &pIServices;
                        }
                        //---------------------------------------------------------------------------
                         
                         
                         
                        //---------------------------------------------------------------------------
                        BOOL WINAPI MWmiTool::FreeIEnumWbemClassObject(void)
                        {
                         BOOL RetC=TRUE;
                         if(pIEnumObject)
                         {
                          pIEnumObject->Release();
                          pIEnumObject=NULL;
                         }
                         return RetC;
                        }
                        //---------------------------------------------------------------------------
                        void WINAPI MWmiTool::operator=(IEnumWbemClassObject* p)
                        {
                         FreeIEnumWbemClassObject();
                         pIEnumObject=p;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IEnumWbemClassObject* ()
                        {
                         return pIEnumObject;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IEnumWbemClassObject** ()
                        {
                         return &pIEnumObject;
                        }
                        //---------------------------------------------------------------------------
                         
                         
                        //---------------------------------------------------------------------------
                        BOOL WINAPI MWmiTool::FreeIWbemClassObject(void)
                        {
                         BOOL RetC=TRUE;
                         if(pIClassObject)
                         {
                          pIClassObject->Release();
                          pIClassObject=NULL;
                         }
                         return RetC;
                        }
                        //---------------------------------------------------------------------------
                        void WINAPI MWmiTool::operator=(IWbemClassObject* p)
                        {
                         FreeIWbemClassObject();
                         pIClassObject=p;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemClassObject* ()
                        {
                         return pIClassObject;
                        }
                        //---------------------------------------------------------------------------
                        WINAPI MWmiTool::operator IWbemClassObject** ()
                        {
                         return &pIClassObject;
                        }
                        //---------------------------------------------------------------------------


                      Это позволит переписать твою процедуру приблизительно так:
                      Скрытый текст

                      ExpandedWrap disabled
                        // --------------------------------------------------------------------------
                        // если плохо - break
                        int  GetCpuTemperature(LPLONG pTemperature)
                        {
                         int RetC=-1;
                         
                         MWmiTool wT;
                         
                         for(int ii=0;ii==0;++ii,RetC=0)
                         {
                          if(pTemperature == NULL) break;
                          *pTemperature = -1;
                         
                          HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
                          if(FAILED(hr)) {RetC=-2;break;}
                         
                          hr = ::CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, wT); if(FAILED(hr)) {RetC=-3;break;}
                         
                          bstr_t ns (_T("root\\WMI"));
                          hr = wT.pILocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, wT);  if(FAILED(hr)) {RetC=-4;break;}
                         
                          bstr_t query (_T("Select * from MSAcpi_ThermalZoneTemperature"));
                          bstr_t wql (_T("WQL"));
                          hr = wT.pIServices->ExecQuery(wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, wT);  if(FAILED(hr)) {RetC=-5;break;}
                         
                          ULONG returned=0;
                          hr = wT.pIEnumObject->Next(WBEM_INFINITE, 1, wT, &returned);  if(FAILED(hr)) { RetC=-6; break; }
                            
                          bstr_t temp (_T("CurrentTemperature"));
                          VARIANT v;  VariantInit(&v);
                          hr = wT.pIClassObject->Get(temp, 0, &v, NULL, NULL);  if(FAILED(hr)) {RetC=-7;break;}
                         
                          *pTemperature = V_I4(&v);
                          VariantClear(&v);
                         }
                         
                         return RetC;
                        }

                      Сообщение отредактировано: ЫукпШ -
                        Цитата Qraizer @
                        Размер может быть по отрицательному смещению.
                        Нет. В WideString и UnicodeString есть, а PWideChar – это просто указатель.
                        Даже если написать var X: TBSTR; ... X := WideString('Hello'); всё равно будет просто Unicode-строка и Z в конце.

                        Цитата Qraizer @
                        но ты не можешь быть уверен, что прохляет.
                        Вот именно.

                        Цитата ЫукпШ @
                        Как это может быть - не понятно.
                        В BSTR (и WideString, UnicodeString) именно так, в -4. Только в UnicodeString кол-во символов, а не размер.
                        И там везде Unicode. Ты ж сам ссылку с поиска прислал (вторую) :)

                        Цитата ЫукпШ @
                        Продолжим фантазировать.
                        Наоборот усложнил код :)

                        Цитата ЫукпШ @
                        for(int ii=0;ii==0;++ii,RetC=0)
                        do { ... } while(false); ?
                          Цитата Jin X @
                          Цитата ЫукпШ @
                          Продолжим фантазировать.
                          Наоборот усложнил код :)

                          Как это ? Наоборот, убрал все и разнообразные Cleanup-ы
                          в разных точках выхода из процедуры.
                          Сделал их один раз и навсегда.
                          Вот пример из MSDN - понятно, что это только пример.
                          Но делать так в реальной программе очень не удобно:
                          Скрытый текст

                          ExpandedWrap disabled
                            #define _WIN32_DCOM
                            #include <iostream>
                            using namespace std;
                            #include <comdef.h>
                            #include <Wbemidl.h>
                             
                            # pragma comment(lib, "wbemuuid.lib")
                             
                            int main(int argc, char **argv)
                            {
                                HRESULT hres;
                             
                                // Step 1: --------------------------------------------------
                                // Initialize COM. ------------------------------------------
                             
                                hres =  CoInitializeEx(0, COINIT_MULTITHREADED);
                                if (FAILED(hres))
                                {
                                    cout << "Failed to initialize COM library. Error code = 0x"
                                        << hex << hres << endl;
                                    return 1;                  // Program has failed.
                                }
                             
                                // Step 2: --------------------------------------------------
                                // Set general COM security levels --------------------------
                                // Note: If you are using Windows 2000, you need to specify -
                                // the default authentication credentials for a user by using
                                // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
                                // parameter of CoInitializeSecurity ------------------------
                             
                                hres =  CoInitializeSecurity(
                                    NULL,
                                    -1,                          // COM authentication
                                    NULL,                        // Authentication services
                                    NULL,                        // Reserved
                                    RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
                                    RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
                                    NULL,                        // Authentication info
                                    EOAC_NONE,                   // Additional capabilities
                                    NULL                         // Reserved
                                    );
                             
                                                  
                                if (FAILED(hres))
                                {
                                    cout << "Failed to initialize security. Error code = 0x"
                                        << hex << hres << endl;
                                    CoUninitialize();
                                    return 1;                    // Program has failed.
                                }
                                
                                // Step 3: ---------------------------------------------------
                                // Obtain the initial locator to WMI -------------------------
                             
                                IWbemLocator *pLoc = NULL;
                             
                                hres = CoCreateInstance(
                                    CLSID_WbemLocator,            
                                    0,
                                    CLSCTX_INPROC_SERVER,
                                    IID_IWbemLocator, (LPVOID *) &pLoc);
                             
                                if (FAILED(hres))
                                {
                                    cout << "Failed to create IWbemLocator object."
                                        << " Err code = 0x"
                                        << hex << hres << endl;
                                    CoUninitialize();
                                    return 1;                 // Program has failed.
                                }
                             
                                // Step 4: -----------------------------------------------------
                                // Connect to WMI through the IWbemLocator::ConnectServer method
                             
                                IWbemServices *pSvc = NULL;
                                
                                // Connect to the root\cimv2 namespace with
                                // the current user and obtain pointer pSvc
                                // to make IWbemServices calls.
                                hres = pLoc->ConnectServer(
                                     _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
                                     NULL,                    // User name. NULL = current user
                                     NULL,                    // User password. NULL = current
                                     0,                       // Locale. NULL indicates current
                                     NULL,                    // Security flags.
                                     0,                       // Authority (e.g. Kerberos)
                                     0,                       // Context object
                                     &pSvc                    // pointer to IWbemServices proxy
                                     );
                                
                                if (FAILED(hres))
                                {
                                    cout << "Could not connect. Error code = 0x"
                                         << hex << hres << endl;
                                    pLoc->Release();    
                                    CoUninitialize();
                                    return 1;                // Program has failed.
                                }
                             
                                cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
                             
                             
                                // Step 5: --------------------------------------------------
                                // Set security levels on the proxy -------------------------
                             
                                hres = CoSetProxyBlanket(
                                   pSvc,                        // Indicates the proxy to set
                                   RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
                                   RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
                                   NULL,                        // Server principal name
                                   RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
                                   RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
                                   NULL,                        // client identity
                                   EOAC_NONE                    // proxy capabilities
                                );
                             
                                if (FAILED(hres))
                                {
                                    cout << "Could not set proxy blanket. Error code = 0x"
                                        << hex << hres << endl;
                                    pSvc->Release();
                                    pLoc->Release();    
                                    CoUninitialize();
                                    return 1;               // Program has failed.
                                }
                             
                                // Step 6: --------------------------------------------------
                                // Use the IWbemServices pointer to make requests of WMI ----
                             
                                // For example, get the name of the operating system
                                IEnumWbemClassObject* pEnumerator = NULL;
                                hres = pSvc->ExecQuery(
                                    bstr_t("WQL"),
                                    bstr_t("SELECT * FROM Win32_OperatingSystem"),
                                    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                                    NULL,
                                    &pEnumerator);
                                
                                if (FAILED(hres))
                                {
                                    cout << "Query for operating system name failed."
                                        << " Error code = 0x"
                                        << hex << hres << endl;
                                    pSvc->Release();
                                    pLoc->Release();
                                    CoUninitialize();
                                    return 1;               // Program has failed.
                                }
                             
                                // Step 7: -------------------------------------------------
                                // Get the data from the query in step 6 -------------------
                             
                                IWbemClassObject *pclsObj;
                                ULONG uReturn = 0;
                              
                                while (pEnumerator)
                                {
                                    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
                                        &pclsObj, &uReturn);
                             
                                    if(0 == uReturn)
                                    {
                                        break;
                                    }
                             
                                    VARIANT vtProp;
                             
                                    // Get the value of the Name property
                                    hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
                                    wcout << " OS Name : " << vtProp.bstrVal << endl;
                                    VariantClear(&vtProp);
                             
                                    pclsObj->Release();
                                }
                             
                                // Cleanup
                                // ========
                                
                                pSvc->Release();
                                pLoc->Release();
                                pEnumerator->Release();
                                pclsObj->Release();
                                CoUninitialize();
                             
                                return 0;   // Program successfully completed.
                                
                            }


                          Убираем "под капот" и забываем навсегда об этих мероприятиях.
                          -----
                          bstr_t делает нечто похожее со строками - только своё, специфичное.
                          Он тоже следит за правильностью получения/возвращения ресурсов, что удобно и надёжно.
                          Сообщение отредактировано: ЫукпШ -
                            Цитата ЫукпШ @
                            Наоборот, убрал все и разнообразные Cleanup-ы
                            Проще – это если не учитывать MWmiTool.h или если работу с WMI не разово нужно делать ;)
                              Цитата Jin X @
                              Цитата ЫукпШ @
                              Наоборот, убрал все и разнообразные Cleanup-ы
                              Проще – это если не учитывать MWmiTool.h или если работу с WMI не разово нужно делать ;)

                              Не совсем так.
                              Будущее вообще не известно, что потребуется не понятно.
                              ---
                              Нужда в подобных классах, сделанных по одному
                              образцу, в принципе много. Поскольку программирование для такой системы
                              как Виндус, содержит множество разнообразно потребляемых ресурсов.
                              Первое что приходит в голову: Handle, socket, hmodule, hobject.
                              SC_HANDLE, HWINSTA.
                              Много ещё, лень лазить по исходникам.
                              "Мало ли в Бразилии Педров - и не сосчитаешь !" (с)
                              А вот ещё:
                              HCRYPTHASH, HCRYPTKEY, HCRYPTPROV, HCERTSTORE.
                              ---
                              MWmiTool.h - Это не затраты, это практически copy/paste.
                              Сообщение отредактировано: ЫукпШ -
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0642 ]   [ 17 queries used ]   [ Generated: 19.04.24, 06:57 GMT ]