Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Fri, 11 Apr 2008 04:21:00 -0700,    group: microsoft.public.win32.programmer.wmi        back       


WMI server process leak using refreshers   
Hi,

  We found a memory leak problem in WMI while refreshing some high 
performance data in remote systems with Windows Vista or Windows Server 2008 
from a Windows XP system.

  We made a test program based on your example in Accessing Performance Data 
in C++ http://msdn2.microsoft.com/en-us/library/aa384724(VS.85).aspx to show 
the memory use of the WMI remote service, the code of that program is 
included below on this post. 

  The main difference with the official example is related about the 
security used to connect to a remote system, because the example didn't work 
for us while trying to monitor a remote machine. Other difference is that we 
do not get the objects refreshed, we only call the Refresh() method. The last 
difference is that we have two loops, one only for refreshes and one for the 
full process to emulate some different scenarios

  When we try to do only refreshes, the Commit Size value of the remote WMI 
server process starts to grow slowly until all the refreshes are done, then 
the server process dissapears abruptly after a while.

  When we try to loop the full process, then the Commit Size of the server 
process grows very fast, reaching hundredths of MB in seconds and then, when 
the process in near 512 MB, the test application starts to receive the error 
0x80004005 (Unspecified error) for each single operation. Some time later, 
the error changes to 0x8007046a (Not enough server storage is available to 
process this command.), 0x80041006 (There was not enough memory for the 
operation) or 0x800700a4 (No more threads can be created in the system) for 
every operation until the application ends.

  If I run the same tests targetting a Windows XP system, the WMI server 
process doesn't show any increase in the Commit Size.

Regards,
Tango

The test code is the following, need to replace the values of the user, 
password and remote namespace in order to work

#define _WIN32_DCOM

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

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

#define NUMBER_OF_REFRESHES 1
#define NUMBER_OF_FULL_LOOPS 1
#define NAME_SPACE L"\\\\Remote_System\\root\\cimv2"
#define DOMAIN L"Domain"
#define USER L"User"
#define FULL_USER L"Domain\\User"
#define PASSWORD L"Password"


int __cdecl wmain(int argc, wchar_t* argv[])
{
    HRESULT						hr = S_OK;
    IWbemRefresher				*pRefresher = NULL;
    IWbemConfigureRefresher		*pConfig = NULL;
    IWbemHiPerfEnum				*pEnum = NULL;
    IWbemServices				*pNameSpace = NULL;
    IWbemLocator				*pWbemLocator = NULL;
	IUnknown					*pUnkServ = NULL;
	SEC_WINNT_AUTH_IDENTITY_W	*pAuthIdentity = NULL;
    BSTR						bstrNameSpace = NULL;
    BSTR						bstrUserName = NULL;
	BSTR						userbstr = NULL;
	BSTR						domainbstr = NULL;
    BSTR						bstrPassword = NULL;
    long						lID = 0;
    long						lVirtualBytesHandle = 0;
    long						lIDProcessHandle = 0;
    DWORD						dwVirtualBytes = 0;
    DWORD						dwProcessId = 0;
    DWORD						dwNumObjects = 0;
    DWORD						dwNumReturned = 0;
    DWORD						dwIDProcess = 0;
    DWORD						i=0;
    int							x=0;
    int							y=0;

	for(y = 0; y < NUMBER_OF_FULL_LOOPS; y++) 
	{
		hr = S_OK;
		pRefresher = NULL;
		pConfig = NULL;
		pEnum = NULL;
		pNameSpace = NULL;
		pWbemLocator = NULL;
		pUnkServ = NULL;
		pAuthIdentity = NULL;
		bstrNameSpace = NULL;
		bstrUserName = NULL;
		userbstr = NULL;
		domainbstr = NULL;
		bstrPassword = NULL;
		lID = 0;
		lVirtualBytesHandle = 0;
		lIDProcessHandle = 0;
		dwVirtualBytes = 0;
		dwProcessId = 0;
		dwNumObjects = 0;
		dwNumReturned = 0;
		dwIDProcess = 0;
		i=0;

		if (FAILED (hr = CoInitializeEx(NULL,COINIT_MULTITHREADED)))
		{
			goto CLEANUP;
		}

		if (FAILED (hr = CoCreateInstance(
			CLSID_WbemLocator, 
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_IWbemLocator,
			(void**) &pWbemLocator)))
		{
			goto CLEANUP;
		}

		// Connect to the desired namespace.
		bstrNameSpace = SysAllocString(NAME_SPACE);
		if (NULL == bstrNameSpace)
		{
			hr = E_OUTOFMEMORY;
			goto CLEANUP;
		}
		userbstr = SysAllocString(USER);
		if (NULL == userbstr)
		{
			hr = E_OUTOFMEMORY;
			goto CLEANUP;
		}
		domainbstr = SysAllocString(DOMAIN);
		if (NULL == domainbstr)
		{
			hr = E_OUTOFMEMORY;
			goto CLEANUP;
		}
		bstrUserName = SysAllocString(FULL_USER);
		if (NULL == bstrUserName)
		{
			hr = E_OUTOFMEMORY;
			goto CLEANUP;
		}
		bstrPassword = SysAllocString(PASSWORD);
		if (NULL == bstrPassword)
		{
			hr = E_OUTOFMEMORY;
			goto CLEANUP;
		}
		if (FAILED (hr = pWbemLocator->ConnectServer(
			bstrNameSpace,
			bstrUserName, // User name
			bstrPassword, // Password
			NULL, // Locale
			0L,   // Security flags
			NULL, // Authority
			NULL, // Wbem context
			&pNameSpace)))
		{
			goto CLEANUP;
		}
		pWbemLocator->Release();
		pWbemLocator=NULL;

		SysFreeString(bstrNameSpace);
		bstrNameSpace = NULL;
		SysFreeString(bstrUserName);
		bstrUserName = NULL;
		
		pAuthIdentity = new SEC_WINNT_AUTH_IDENTITY_W;
		SecureZeroMemory(pAuthIdentity, sizeof(*pAuthIdentity));

		pAuthIdentity->User = new WCHAR[100];
		wcscpy (pAuthIdentity->User , userbstr);
		pAuthIdentity->UserLength = wcslen(pAuthIdentity->User);
		SysFreeString(userbstr);
		userbstr = NULL;

		pAuthIdentity->Domain = new WCHAR[100];
		wcscpy(pAuthIdentity->Domain, domainbstr);
		pAuthIdentity->DomainLength = wcslen(pAuthIdentity->Domain);
		SysFreeString(domainbstr);
		domainbstr = NULL;
		
		pAuthIdentity->Password = new WCHAR[wcslen(bstrPassword)+1];;
		wcscpy(pAuthIdentity->Password, bstrPassword);
		pAuthIdentity->PasswordLength = wcslen(pAuthIdentity->Password);
		SysFreeString(bstrPassword);
		bstrPassword = NULL;

		pAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;


		if (FAILED (hr = CoSetProxyBlanket(pNameSpace, 
					RPC_C_AUTHN_WINNT, 
					RPC_C_AUTHZ_NONE, 
					NULL, 
					RPC_C_AUTHN_LEVEL_PKT, 
					RPC_C_IMP_LEVEL_IMPERSONATE, 
					pAuthIdentity, 
					EOAC_NONE)))
		{
			goto CLEANUP;
		}

		if (FAILED (hr = pNameSpace->QueryInterface(IID_IUnknown, (void**) 
&pUnkServ)))
		{
			goto CLEANUP;
		}

		if (FAILED (hr = CoSetProxyBlanket(pUnkServ, 
					RPC_C_AUTHN_WINNT, 
					RPC_C_AUTHZ_NONE, 
					NULL, 
					RPC_C_AUTHN_LEVEL_PKT, 
					RPC_C_IMP_LEVEL_IMPERSONATE, 
					pAuthIdentity, 
					EOAC_NONE)))
		{
			goto CLEANUP;
		}

		if (FAILED (hr = CoCreateInstance(
			CLSID_WbemRefresher,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_IWbemRefresher, 
			(void**) &pRefresher)))
		{
			goto CLEANUP;
		}

		if (FAILED (hr = pRefresher->QueryInterface(
			IID_IWbemConfigureRefresher,
			(void **)&pConfig)))
		{
			goto CLEANUP;
		}

		// Add an enumerator to the refresher.
		if (FAILED (hr = pConfig->AddEnum(
			pNameSpace, 
			L"Win32_PerfRawData_PerfProc_Process", 
			0,
			NULL, 
			&pEnum, 
			&lID)))
		{
			goto CLEANUP;
		}
		pConfig->Release();
		pConfig = NULL;


		//Refresher loop
		for(x = 0; x < NUMBER_OF_REFRESHES; x++)
		{

			if (FAILED (hr =pRefresher->Refresh(0L)))
			{
				goto CLEANUP;
			}

		}
		// exit loop here
		CLEANUP:

		if (NULL != bstrNameSpace)
		{
			SysFreeString(bstrNameSpace);
			bstrNameSpace = NULL;
		}
		if (NULL != bstrUserName)
		{
			SysFreeString(bstrUserName);
			bstrUserName = NULL;
		}
		if (NULL != userbstr)
		{
			SysFreeString(userbstr);
			userbstr = NULL;
		}
		if (NULL != domainbstr)
		{
			SysFreeString(domainbstr);
			domainbstr = NULL;
		}
		if (NULL != bstrPassword)
		{
			SysFreeString(bstrPassword);
			bstrPassword = NULL;
		}
		if (NULL != pWbemLocator)
		{
			pWbemLocator->Release();
		}
		if (NULL != pNameSpace)
		{
			pNameSpace->Release();
		}
		if (NULL != pUnkServ)
		{
			pUnkServ->Release();
		}
		if (NULL != pAuthIdentity)
		{
			if (NULL != pAuthIdentity->User)
				delete [] pAuthIdentity->User;
			pAuthIdentity->User = NULL;
			
			if (NULL != pAuthIdentity->Domain)
				delete [] pAuthIdentity->Domain;
			pAuthIdentity->Domain = NULL;

			if (NULL != pAuthIdentity->Password)
				delete [] pAuthIdentity->Password;
			pAuthIdentity->Password = NULL;
		}
		if (NULL != pEnum)
		{
			pEnum->Release();
		}
		if (NULL != pConfig)
		{
			pConfig->Release();
		}
		if (NULL != pRefresher)
		{
			pRefresher->Release();
		}

		CoUninitialize();

		if (FAILED (hr))
		{
			wprintf (L"Error status=%08x\n",hr);
		}
	}
	wprintf (L"End");
	Sleep(600000);
	return 1;
}
date: Fri, 11 Apr 2008 04:21:00 -0700   author:   Tango am

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us