0

msdnからコードをコピーして変更しました。

その漏れているメモリ。助けてください。

#include "querysink.h"


int main(int argc, char **argv)
{
HRESULT hres;
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.
}



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.
}



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.
}


IWbemServices *pSvc = NULL;


hres = pLoc->ConnectServer(
    _bstr_t(L"ROOT\\CIMV2"), 
    NULL,
    NULL,
    0,
    NULL,
    0,
    0, 
    &pSvc
    );

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;




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;
}


QuerySink* pResponseSink = new QuerySink();
hres = pSvc->ExecQueryAsync(
    bstr_t("WQL"), 
    bstr_t("SELECT * FROM Win32_NTLogEvent"),
    WBEM_FLAG_BIDIRECTIONAL, 
    NULL,
    pResponseSink);

if (FAILED(hres))
{
    cout << "Query for log collection failed."
        << " Error code = 0x" 
        << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    pResponseSink->Release();
    CoUninitialize();
    return 1;
}


while(pResponseSink->IsDone()==false){
        Sleep(100);
        }


pSvc->Release();
pLoc->Release();
CoUninitialize();
while(1)
{
 //do other job here
}


return 0;   // Program successfully completed.

}//end of file

//querysink.cpp

#include "querysink.h"

ULONG QuerySink::AddRef()
{
return InterlockedIncrement(&m_lRef);
}

ULONG QuerySink::Release()
{
LONG lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
    delete this;
return lRef;
}

HRESULT QuerySink::QueryInterface(REFIID riid, void** ppv)
{
if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
{
    *ppv = (IWbemObjectSink *) this;
    AddRef();
    return WBEM_S_NO_ERROR;
}
else return E_NOINTERFACE;
}


HRESULT QuerySink::Indicate(long lObjectCount,
IWbemClassObject **apObjArray)
{
HRESULT hres = S_OK;
VARIANT writtenTime,genTime,logFile,eventCode,eventId,eventType,category;

for (int i = 0; i < lObjectCount; i++)
{
            hres = apObjArray[i]->Get(L"TimeWritten", 0, &writtenTime, 0, 0);
            hres = apObjArray[i]->Get(L"TimeGenerated", 0, &genTime, 0, 0);
            hres = apObjArray[i]->Get(L"Logfile", 0, &logFile, 0, 0);
            hres = apObjArray[i]->Get(L"Category", 0, &category, 0, 0);
            hres = apObjArray[i]->Get(L"EventCode", 0, &eventCode, 0, 0);
            hres = apObjArray[i]->Get(L"EventIdentifier", 0, &eventId, 0, 0);
            hres = apObjArray[i]->Get(L"EventType", 0, &eventType, 0, 0);

//7行以上を削除すると、メモリ消費は問題ありません。

    if (FAILED(hres))
    {
        cout << "Failed to get the data from the query"
            << " Error code = 0x"
            << hex << hres << endl;
        return WBEM_E_FAILED;       // Program has failed.
    }


}
VariantClear(&writtenTime);
VariantClear(&genTime);
VariantClear(&category);
VariantClear(&eventCode);
VariantClear(&eventId);
VariantClear(&eventType);
VariantClear(&logFile);

return WBEM_S_NO_ERROR;
}

HRESULT QuerySink::SetStatus(
        /* [in] */ LONG lFlags,
        /* [in] */ HRESULT hResult,
        /* [in] */ BSTR strParam,
        /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
    )
{
if(lFlags == WBEM_STATUS_COMPLETE)
{
    printf("Call complete.\n");

    EnterCriticalSection(&threadLock);
    bDone = true;
    LeaveCriticalSection(&threadLock);
}
else if(lFlags == WBEM_STATUS_PROGRESS)
{
    printf("Call in progress.\n");
}

return WBEM_S_NO_ERROR;
}


bool QuerySink::IsDone()
{
bool done = true;

//  EnterCriticalSection(&threadLock);
done = bDone;
//  LeaveCriticalSection(&threadLock);

return done;
}    // end of querysink.cpp

//querysink.h

#ifndef QUERYSINK_H
#define QUERYSINK_H

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib")

class QuerySink : public IWbemObjectSink
{
LONG m_lRef;
bool bDone;
CRITICAL_SECTION threadLock; // for thread safety

public:
QuerySink() { m_lRef = 0; bDone = false; 
    InitializeCriticalSection(&threadLock); }
~QuerySink() { bDone = true;
    DeleteCriticalSection(&threadLock); }

virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();        
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
    void** ppv);

virtual HRESULT STDMETHODCALLTYPE Indicate( 
        LONG lObjectCount,
        IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray
        );

virtual HRESULT STDMETHODCALLTYPE SetStatus( 
        /* [in] */ LONG lFlags,
        /* [in] */ HRESULT hResult,
        /* [in] */ BSTR strParam,
        /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
        );

bool IsDone();
};

#endif    // end of querysink.h
4

1 に答える 1

0

IWebmServices::Getのドキュメントを確認してください。また、バリアントのクリアランスが間違っています。基本的にその使用法を悪用しています。宣言を移動し、for ループ内でバリアントを解放することを検討してください。参照によってバリアントを取得しています。それぞれの処理が完了したらapObjArray、別のオブジェクトを取得するため、次のオブジェクトのプロパティを取得する前にバリアントをクリアする必要があります。コードが行うことは、各バリアントの最後にフェッチされた参照のみを解放することです。また、すべての呼び出しに同じHRESULTオブジェクトを使用しているためGet、呼び出しが失敗するとプロパティが解放されず、リークが発生することになります。

コードを次のように置き換えることを検討してください。

for (int i = 0; i < lObjectCount; i++)
{

         VARIANT writtenTime,genTime,logFile,eventCode,eventId,eventType,category;  
         BSTR strTimeWrittenProp = SysAllocString(L"TimeWritten");   
         hres = apObjArray[i]->Get(strTimeWrittenProp, 0, &writtenTime, 0, 0);   
         SysFreeString(strTimeWrittenProp); 

         //... Get other properties

         VariantClear( &writtenTime );
         //..clear variants before moving to next object in array
    enter code here
    if (FAILED(hres))
    {
        cout << "Failed to get the data from the query"
            << " Error code = 0x"
            << hex << hres << endl;
        return WBEM_E_FAILED;       // Program has failed.
    }


}

すべての get 呼び出しをこれに置き換えることを検討してください

于 2013-03-07T13:38:59.590 に答える