Вопросы по технологии COM WMI (pure C,ASM)

Тема в разделе "WASM.WIN32", создана пользователем M0rg0t, 23 сен 2020.

  1. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Моргот, может быть, информация окажется полезной

    http://scriptcoding.ru/2013/11/27/wmi-classy/

    http://scriptcoding.ru/2013/11/27/wmi-providers-znakomstvo/

    http://scriptcoding.ru/2013/11/27/wmi-cim-studio-1/
    http://scriptcoding.ru/2013/11/27/wmi-cim-studio-2/
    http://scriptcoding.ru/2013/11/27/wmi-cim-studio-3/

    http://scriptcoding.ru/2013/11/27/wmi-event-registration-1/
    http://scriptcoding.ru/2013/11/27/wmi-event-registration-2/

    http://scriptcoding.ru/2013/11/27/wmi-event-viewer/

    http://scriptcoding.ru/2013/11/30/wmic-znakomstvo/
    http://scriptcoding.ru/2013/11/30/wmic-metody/
    http://scriptcoding.ru/2013/11/30/wmic-operatory/

    http://scriptcoding.ru/2013/12/02/win32_keyboard-informacija-o-klaviature/
    http://scriptcoding.ru/2013/12/02/win32_pointingdevice-informacija-pro-mysku/
    http://scriptcoding.ru/2013/12/03/win32_diskdrive-informacija-o-zestkom-diske/
    http://scriptcoding.ru/2013/12/04/win32_logicaldisk-logiceskije-diski/
    http://scriptcoding.ru/2013/12/04/win32_baseboard-materinskaya-plata/
    http://scriptcoding.ru/2013/12/05/win32_bios-informacija-o-bios/
    http://scriptcoding.ru/2013/12/06/win32_processor-informacija-o-processore/
    http://scriptcoding.ru/2013/12/09/win32_videocontroller-informacija-o-videokarte/
    http://scriptcoding.ru/2013/12/09/win32_desktopmonitor-informacija-o-monitore/
    http://scriptcoding.ru/2013/12/09/win32_networkadapter-parametry-setevoho-adaptera/
    http://scriptcoding.ru/2013/12/13/wmic-format-vyvoda-dannych/
    http://scriptcoding.ru/2013/12/13/wmi-bezopasnost/
     
    M0rg0t нравится это.
  2. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.574
    Да, если можно, и буду изучать тогда. Вот полный код:

    Код (C):
    1. // EventSink.h
    2. #ifndef EVENTSINK_H
    3. #define EVENTSINK_H
    4.  
    5. #define _WIN32_DCOM
    6. #include <stdio.h>
    7. #include <Wbemidl.h>
    8.  
    9. #pragma comment(lib, "wbemuuid.lib")
    10.  
    11. #define DEFINE_INTERFACE(iface, name, ...)    iface name = {.lpVtbl=&((iface##Vtbl){__VA_ARGS__})}
    12. #define GET_IFACE_CLASS(iface)    Class_##iface
    13. #define IFACE_GET_PRIVATE(obj, class, private_member)    (((class *)(obj))->private_member)
    14.  
    15. IWbemObjectSink STDMETHODCALLTYPE *CreateEventSink(void);
    16. void            STDMETHODCALLTYPE DestroyEventSink(IWbemObjectSink *p);
    17. ULONG   STDMETHODCALLTYPE EventSink_AddRef(IWbemObjectSink * This);
    18. ULONG   STDMETHODCALLTYPE EventSink_Release(IWbemObjectSink * This);
    19. HRESULT STDMETHODCALLTYPE EventSink_QueryInterface(IWbemObjectSink * This, REFIID riid, void** ppv);
    20. HRESULT STDMETHODCALLTYPE EventSink_Indicate(IWbemObjectSink * This, long lObjectCount, IWbemClassObject **apObjArray);
    21. HRESULT STDMETHODCALLTYPE EventSink_SetStatus(IWbemObjectSink * This, LONG lFlags,  HRESULT hResult,  BSTR strParam,  IWbemClassObject __RPC_FAR *pObjParam );
    22.  
    23. typedef struct
    24. {
    25.     IWbemObjectSink;
    26.     LONG m_lRef;
    27.     BOOL bDone;
    28. } Class_EventSink;
    29.  
    30. #endif    // end of EventSink.h
    Код (C):
    1. #include "eventsink.h"
    2.  
    3. DEFINE_INTERFACE(IWbemObjectSink,                //Interface type
    4.                  EventSink,                        //Local interface name
    5.                  EventSink_QueryInterface,        //Interface functions list ...
    6.                  EventSink_AddRef,
    7.                  EventSink_Release,
    8.                  EventSink_Indicate,
    9.                  EventSink_SetStatus);
    10.  
    11. IWbemObjectSink STDMETHODCALLTYPE *CreateEventSink(void)
    12. {
    13.     Class_EventSink *p = malloc(sizeof(Class_EventSink));
    14.     if (!p)
    15.         return NULL;    //Failure
    16.  
    17.     p->m_lRef = 0;
    18.     p->bDone  = FALSE;
    19.     p->lpVtbl = EventSink.lpVtbl;
    20.  
    21.     return (IWbemObjectSink *)p;
    22. }
    23.  
    24. void STDMETHODCALLTYPE DestroyEventSink(IWbemObjectSink *p)
    25. {
    26.     free(p);
    27. }
    28.  
    29. ULONG STDMETHODCALLTYPE EventSink_AddRef(IWbemObjectSink * this)
    30. {
    31.     return InterlockedIncrement(&(IFACE_GET_PRIVATE(this, Class_EventSink, m_lRef)));
    32. }
    33.  
    34. ULONG STDMETHODCALLTYPE EventSink_Release(IWbemObjectSink * this)
    35. {
    36.     LONG lRef = InterlockedDecrement(&(IFACE_GET_PRIVATE(this, Class_EventSink, m_lRef)));
    37.     if(lRef == 0)
    38.         DestroyEventSink(this);
    39.     return lRef;
    40. }
    41.  
    42. HRESULT STDMETHODCALLTYPE EventSink_QueryInterface(IWbemObjectSink * this, REFIID riid, void** ppv)
    43. {
    44.     if (IsEqualCLSID(riid, &IID_IUnknown) || IsEqualCLSID(riid, &IID_IWbemObjectSink))
    45.     {
    46.         *ppv = (IWbemObjectSink *) this;
    47.         EventSink_AddRef(this);
    48.         return WBEM_S_NO_ERROR;
    49.     }
    50.     else return E_NOINTERFACE;
    51. }
    52.  
    53.  
    54. HRESULT STDMETHODCALLTYPE EventSink_Indicate(IWbemObjectSink *this, long lObjectCount, IWbemClassObject **apObjArray)
    55. {
    56.     for (int i = 0; i < lObjectCount; i++)
    57.     {
    58.         printf("Event occurred %d/%d\n", i, lObjectCount);
    59.         IWbemClassObject *pIWbemClassObject = apObjArray[i];
    60.         //IWbemClassObject *pIWbemClassObject = *apObjArray;
    61.         VARIANT vcn;
    62.         HRESULT hr;
    63.         if (!(hr = pIWbemClassObject->lpVtbl->Get(pIWbemClassObject, L"__Class", 0, &vcn, NULL, NULL)))
    64.         {
    65.             if (vcn.vt == VT_BSTR)
    66.                 printf("%ls\n", vcn.bstrVal);
    67.             VariantClear(&vcn);
    68.         }
    69.         else
    70.             printf("error: 0x%Xh\n", hr);
    71.         if (!(hr = pIWbemClassObject->lpVtbl->Get(pIWbemClassObject, L"TargetInstance", 0, &vcn, NULL, NULL)))
    72.         {
    73.             IUnknown *pUnk = vcn.punkVal;
    74.             IWbemClassObject *pIWbemClassObject1;
    75.             if (!(hr = pUnk->lpVtbl->QueryInterface(pUnk, &IID_IWbemClassObject, (void **)&pIWbemClassObject1)))
    76.             {
    77.                 VARIANT vcn1;
    78.                 if (!(hr = pIWbemClassObject1->lpVtbl->Get(pIWbemClassObject1, L"Name", 0, &vcn1, NULL, NULL)))
    79.                 {
    80.                     printf("%ls\t", vcn1.bstrVal);
    81.                     VariantClear(&vcn1);
    82.                 }
    83.  
    84.             }
    85.             VariantClear(&vcn);
    86.         }
    87.         else
    88.             printf("error: 0x%Xh\n", hr);
    89.     }
    90.  
    91.     return WBEM_S_NO_ERROR;
    92. }
    93.  
    94. HRESULT STDMETHODCALLTYPE EventSink_SetStatus(IWbemObjectSink * this, LONG lFlags, HRESULT hResult, BSTR strParam, IWbemClassObject __RPC_FAR *pObjParam)
    95. {
    96.     if(lFlags == WBEM_STATUS_COMPLETE)
    97.     {
    98.         printf("Call complete. hResult = 0x%X\n", hResult);
    99.     }
    100.     else if(lFlags == WBEM_STATUS_PROGRESS)
    101.     {
    102.         printf("Call in progress.\n");
    103.     }
    104.  
    105.     return WBEM_S_NO_ERROR;
    106. }
    Код (C):
    1. /*
    2. *    connects to WMI on the local computer, receives an event notification, and then cleans up.
    3. *    The example notifies the user of an event when a new process is created. The events are received asynchronously.
    4. */
    5. #include "eventsink.h"
    6.  
    7. int main(int iArgCnt, char ** argv)
    8. {
    9.     HRESULT hres;
    10.  
    11.     /*
    12.      * ===================================================================
    13.      * Step 1:
    14.      *        Initialize COM.
    15.      * ===================================================================
    16.      */
    17.  
    18.     hres =    CoInitializeEx(0, COINIT_MULTITHREADED);
    19.     if (FAILED(hres))
    20.     {
    21.         printf("Failed to initialize COM library. Error code = 0x%08x\n", hres);
    22.         return 1;                   // Program has failed.
    23.     }
    24.  
    25.     /*
    26.      * ===================================================================
    27.      * Step 2:
    28.      *        Set general COM security levels
    29.      * ===================================================================
    30.      */
    31.  
    32.     hres =    CoInitializeSecurity(
    33.                                     NULL,
    34.                                     -1,                          // COM authentication
    35.                                     NULL,                         // Authentication services
    36.                                     NULL,                         // Reserved
    37.                                     RPC_C_AUTHN_LEVEL_DEFAULT,     // Default authentication
    38.                                     RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
    39.                                     NULL,                         // Authentication info
    40.                                     EOAC_NONE,                     // Additional capabilities
    41.                                     NULL                         // Reserved
    42.                                 );
    43.  
    44.                    
    45.     if (FAILED(hres))
    46.     {
    47.         printf("Failed to initialize security. Error code = 0x%08x\n", hres);
    48.         CoUninitialize();
    49.         return 1;                     // Program has failed.
    50.     }
    51.  
    52.     /*
    53.      * ===================================================================
    54.      * Step 3:
    55.      *        Obtain the initial locator to WMI
    56.      * ===================================================================
    57.      */
    58.  
    59.     IWbemLocator *pLoc = NULL;
    60.  
    61.     hres =  CoCreateInstance(
    62.                                 &CLSID_WbemLocator,          
    63.                                 0,
    64.                                 CLSCTX_INPROC_SERVER,
    65.                                 &IID_IWbemLocator,
    66.                                 (LPVOID *) &pLoc
    67.                             );
    68.     if (FAILED(hres))
    69.     {
    70.         printf("Failed to create IWbemLocator object.\n"
    71.                                        " Err code = 0x%08x\n", hres);
    72.         CoUninitialize();
    73.         return 1;                  // Program has failed.
    74.     }
    75.  
    76.  
    77.     /*
    78.      * ===================================================================
    79.      * Step 4:
    80.      *        Connect to WMI through the IWbemLocator::ConnectServer method
    81.      * ===================================================================
    82.      */
    83.  
    84.     IWbemServices *pSvc = NULL;
    85.     /*
    86.      * Connect to the root\cimv2 namespace with
    87.      * the current user and obtain pointer pSvc
    88.      * to make IWbemServices calls.
    89.      */
    90.     BSTR bstr = SysAllocString(L"ROOT\\CIMV2");
    91.     hres      = pLoc->lpVtbl->ConnectServer (
    92.                          pLoc,
    93.                          bstr,        // Object path of WMI namespace
    94.                          NULL,        // User name. NULL = current user
    95.                          NULL,        // User password. NULL = current
    96.                          0,            // Locale. NULL indicates current
    97.                          0,            // Security flags.
    98.                          0,            // Authority (for example, Kerberos)
    99.                          0,            // Context object
    100.                          &pSvc        // pointer to IWbemServices proxy
    101.                     );
    102.     SysFreeString(bstr);
    103.  
    104.     if (FAILED(hres))
    105.     {
    106.         printf("Could not connect. Error code = 0x%08x\n", hres);
    107.         pLoc->lpVtbl->Release(pLoc);  
    108.         CoUninitialize();
    109.         return 1;                 // Program has failed.
    110.     }
    111.  
    112.     printf("Connected to ROOT\\CIMV2 WMI namespace\n");
    113.  
    114.  
    115.     /*
    116.      * ===================================================================
    117.      * Step 5:
    118.      *        Set security levels on the proxy
    119.      * ===================================================================
    120.      */
    121.  
    122.     hres = CoSetProxyBlanket(
    123.        (LPUNKNOWN)pSvc,                // Indicates the proxy to set
    124.        RPC_C_AUTHN_WINNT,            // RPC_C_AUTHN_xxx
    125.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    126.        NULL,                        // Server principal name
    127.        RPC_C_AUTHN_LEVEL_CALL,        // RPC_C_AUTHN_LEVEL_xxx
    128.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    129.        NULL,                        // client identity
    130.        EOAC_NONE                    // proxy capabilities
    131.     );
    132.  
    133.     if (FAILED(hres))
    134.     {
    135.         printf("Could not set proxy blanket. Error code = 0x%08x\n", hres);
    136.         pSvc->lpVtbl->Release(pSvc);
    137.         pLoc->lpVtbl->Release(pLoc);  
    138.         CoUninitialize();
    139.         return 1;                // Program has failed.
    140.     }
    141.  
    142.     /*
    143.      * ===================================================================
    144.      * Step 5:
    145.      *        Receive event notifications
    146.      * ===================================================================
    147.      */
    148.  
    149.     // Use an unsecured apartment for security
    150.     IUnsecuredApartment* pUnsecApp = NULL;
    151.  
    152.     hres = CoCreateInstance(&CLSID_UnsecuredApartment, NULL,
    153.                                 CLSCTX_LOCAL_SERVER, &IID_IUnsecuredApartment, (void**)&pUnsecApp);
    154.     IWbemObjectSink *pSink = CreateEventSink();
    155.     if (!pSink)
    156.     {
    157.         printf("Could not create a sink\n", hres);
    158.         pSvc->lpVtbl->Release(pSvc);
    159.         pLoc->lpVtbl->Release(pLoc);  
    160.         CoUninitialize();
    161.         return 1;                // Program has failed.
    162.     }
    163.  
    164.     pSink->lpVtbl->AddRef(pSink);
    165.  
    166.     IUnknown* pStubUnk = NULL;
    167.     pUnsecApp->lpVtbl->CreateObjectStub(pUnsecApp, (LPUNKNOWN)pSink, &pStubUnk);
    168.  
    169.     IWbemObjectSink* pStubSink = NULL;
    170.     pStubUnk->lpVtbl->QueryInterface(pStubUnk, &IID_IWbemObjectSink, (void **) &pStubSink);
    171.  
    172.     // The ExecNotificationQueryAsync method will call
    173.     // The EventQuery::Indicate method when an event occurs
    174.     BSTR bstrLanguage = SysAllocString(L"WQL");
    175.     BSTR bstrQuery    = SysAllocString(L"SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'");
    176.     hres = pSvc->lpVtbl->ExecNotificationQueryAsync
    177.                         (
    178.                             pSvc,
    179.                             bstrLanguage,
    180.                             bstrQuery,
    181.                             WBEM_FLAG_SEND_STATUS,
    182.                             NULL,
    183.                             pStubSink
    184.                         );
    185.     SysFreeString(bstrLanguage);
    186.     SysFreeString(bstrQuery);
    187.  
    188.     // Check for errors.
    189.     if (FAILED(hres))
    190.     {
    191.         printf("ExecNotificationQueryAsync failed with = 0x%X\n", hres);
    192.         pSvc->lpVtbl->Release(pSvc);
    193.         pLoc->lpVtbl->Release(pLoc);
    194.         pUnsecApp->lpVtbl->Release(pUnsecApp);
    195.         pStubUnk->lpVtbl->Release(pStubUnk);
    196.         pSink->lpVtbl->Release(pSink);
    197.         pStubSink->lpVtbl->Release(pStubSink);
    198.         CoUninitialize();  
    199.         return 1;
    200.     }
    201.  
    202.     // Wait for the event
    203.     Sleep(INFINITE); //or  WaitForSingleObject(GetCurrentProcess(), INFINITE);
    204.  
    205.        
    206.     hres = pSvc->lpVtbl->CancelAsyncCall(pSvc, pStubSink);
    207.  
    208.     // Cleanup
    209.     // ========
    210.  
    211.     pSvc->lpVtbl->Release(pSvc);
    212.     pLoc->lpVtbl->Release(pLoc);
    213.     pUnsecApp->lpVtbl->Release(pUnsecApp);
    214.     pStubUnk->lpVtbl->Release(pStubUnk);
    215.     pSink->lpVtbl->Release(pSink);
    216.     pStubSink->lpVtbl->Release(pStubSink);
    217.     CoUninitialize();
    218.  
    219.     printf("Press any key ...");
    220.     getchar();
    221.  
    222.     return 0;   // Program successfully completed.
    223. }
     
  3. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    860
    Первое что нужно сделать - это добавить поле m_pSvc в структуру Class_EventSink. По типу:
    Код (C):
    1. typedef struct
    2. {
    3.     IWbemObjectSink;
    4.     LONG m_lRef;
    5.     BOOL bDone;
    6.     IWbemServices *m_pSvc;
    7. } Class_EventSink;
    В CreateEventSink добавить аргумент IWbemServices *m_pSvc, а в коде дописать:
    Код (C):
    1. p->m_pSvc = pSvc;
    2. pSvc->lpVtbl->AddRef(pSvc);
    В DestroyEventSink соответственно дописать:
    Код (C):
    1. ((Class_EventSink*)p)->m_pSvc->lpVtbl->Release(((Class_EventSink*)p)->m_pSvc);
    В main соответственно написать IWbemObjectSink *pSink = CreateEventSink(pSvc);
    Для мониторинга сервисов добавить в main сразу после первого запроса:
    Код (C):
    1.   SysFreeString(bstrQuery);
    2. BSTR bstrQuery    = SysAllocString(L"SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Service'");
    3.     hres = pSvc->lpVtbl->ExecNotificationQueryAsync
    4.                         (
    5.                             pSvc,
    6.                             bstrLanguage,
    7.                             bstrQuery,
    8.                             WBEM_FLAG_SEND_STATUS,
    9.                             NULL,
    10.                             pStubSink
    11.                         );
    В EventSink_Indicate соответственно будут приходить сразу 2 типа уведомлений.
    Код (C):
    1. HRESULT STDMETHODCALLTYPE EventSink_Indicate(IWbemObjectSink *pthis ,long lObjectCount,
    2.     IWbemClassObject **apObjArray)
    3. {
    4.     VARIANT vObj, vClass, vPath, vName, vUser, vDomain;
    5.     HRESULT hr;
    6.     BSTR pszMeth = NULL;
    7.  
    8.     VariantInit(&vObj); VariantInit(&vClass); VariantInit(&vPath); VariantInit(&vName);
    9.     VariantInit(&vUser); VariantInit(&vDomain);
    10.  
    11.     for (int i = 0; i < lObjectCount; i++)
    12.     {
    13.         IWbemClassObject *pIWbemClassObject = apObjArray[i];
    14.         IWbemClassObject *pInstance = NULL;
    15.         IWbemClassObject *pOutParams = NULL;
    16.  
    17.         if (FAILED(hr = pIWbemClassObject->lpVtbl->Get(pIWbemClassObject, L"TargetInstance", 0, &vObj, NULL, NULL))) {
    18.             printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    19.             goto CleanUp;
    20.         }
    21.  
    22.         if (vObj.vt != VT_DISPATCH && vObj.vt != VT_UNKNOWN) {
    23.             printf("unexpected type\n");
    24.             goto CleanUp;
    25.         }
    26.  
    27.         if (FAILED(hr = vObj.punkVal->lpVtbl->QueryInterface(vObj.punkVal, IID_IWbemClassObject, (void**)&pInstance))) {
    28.             printf("IUnknown::QueryInterface failed: 0x%Xh\n", hr);
    29.             goto CleanUp;
    30.  
    31.         }
    32.      
    33.         if (FAILED(hr = pInstance->lpVtbl->Get(pInstance, L"__CLASS", 0, &vClass, NULL, NULL))) {
    34.             printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    35.             goto CleanUp;
    36.         }
    37.  
    38.         if (vClass.vt != VT_BSTR) {
    39.             printf("unexpected type\n");
    40.             goto CleanUp;
    41.         }
    42.  
    43.         if (!lstrcmpi(vClass.bstrVal, L"Win32_Service")) {
    44.  
    45.             if (FAILED(hr = pInstance->lpVtbl->Get(pInstance, L"Name", 0, &vName, NULL, NULL))) {
    46.                 printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    47.                 goto CleanUp;
    48.             }
    49.  
    50.             if (vName.vt != VT_BSTR) {
    51.                 printf("unexpected type\n");
    52.                 goto CleanUp;
    53.             }
    54.  
    55.             printf("Win32_Service with name %S\n", vName.bstrVal);
    56.  
    57.         } else if (!lstrcmpi(vClass.bstrVal, L"Win32_Process")) {
    58.  
    59.             if (FAILED(hr = pInstance->lpVtbl->Get(pInstance, L"__PATH", 0, &vPath, NULL, NULL))) {
    60.                 printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    61.                 goto CleanUp;
    62.             }
    63.  
    64.             if (vPath.vt != VT_BSTR) {
    65.                 printf("unexpected type\n");
    66.                 goto CleanUp;
    67.             }
    68.  
    69.             if (!pszMeth)
    70.                 pszMeth = SysAllocString(L"GetOwner");
    71.  
    72.             if (FAILED(hr = ((EventSink*)pthis)->m_pSvc->lpVtbl->ExecMethod(((EventSink*)pthis)->m_pSvc,
    73.                                                                                     vPath.bstrVal, pszMeth, 0, NULL,
    74.                                                                                     NULL, &pOutParams, NULL))) {
    75.                 printf("ExecMethod failed 0x%Xh\n", hr);
    76.                 goto CleanUp;
    77.             }
    78.                                                                  
    79.             if (FAILED(hr = pOutParams->lpVtbl->Get(pOutParams, L"User", 0, &vUser, NULL, NULL))) {
    80.                 printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    81.                 goto CleanUp;
    82.             }
    83.  
    84.             if (FAILED(hr = pOutParams->lpVtbl->Get(pOutParams, L"Domain", 0, &vDomain, NULL, NULL))) {
    85.                 printf("IWbemClassObject::Get failed: 0x%Xh\n", hr);
    86.                 goto CleanUp;
    87.             }
    88.  
    89.             printf("Win32_Process. User: %S ; Domain: %S;\n", vUser.bstrVal, vDomain.bstrVal);
    90.  
    91.         } else {
    92.             printf("unknown class %S\n", vClass.bstrVal);
    93.         }
    94.  
    95. CleanUp:
    96.  
    97.         VariantClear(&vObj); VariantClear(&vClass); VariantClear(&vPath); VariantClear(&vName);
    98.         VariantClear(&vUser); VariantClear(&vDomain);
    99.  
    100.         if (pInstance)
    101.             pInstance->lpVtbl->Release(pInstance);
    102.  
    103.         if (pOutParams)
    104.             pOutParams->lpVtbl->Release(pOutParams);
    105.  
    106.         pOutParams = NULL;
    107.         pInstance = NULL;
    108.  
    109.     }
    110.  
    111.     if (pszMeth)
    112.         SysFreeString(pszMeth);
    113.  
    114.     return WBEM_S_NO_ERROR;
    115. }
    116.  
    Здесь как пример показан вызов метода. Также я бы в main сделал отдельную секцию CleanUp и использовал goto (тот случай когда использование goto улучшает читаемость кода).
     
    M0rg0t нравится это.
  4. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    лучше тогда уж try{}catch{} блоки
     
  5. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    860
    В C же вроде нет их.
     
  6. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    все там есть
     
  7. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.574
    Thetrik, все работает, спасибо; буду теперь разбираться со всей этой матчастью.

    TermoSINteZ, разве что SEH или какие-то неофициальные вещи? В стандарте же вроде нет таки.
     
  8. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    M0rg0t, естественно SEH. вы же под винду пишете. )
    Но не обязательно прямо на сех все реализовывать. Есть уже готовые либы для этого.
    Ну и например раз под винду то компилятор видновый вроде в режиме Си позволял портабельно юзать __try()
     
  9. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    860
    Я про стандарт говорил.
    goto в любом случае более эффективней в данной ситуации.