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:35:00 -0700,    group: microsoft.public.win32.programmer.wmi        back       


WMI server process leak querying performance data   
Hi,

  We found a memory leak problem in WMI while querying some performance 
classes in remote systems with Windows Vista or Windows Server 2008 without 
using refreshers, only executing simple queries. This not happens on a 
Windows XP remote system.

  We made a test program to show the memory use of the WMI remote service., 
the code of that application is incuded below on this post. The application 
just connects to a remote system, establishes the security options and do a 
simple query, releasing inmediately the answer and not processing it. Then we 
release all the components. The code is prepared to loop only the query 
section or the full connect-query-release process or both.

  If we only query "Select * from Win32_PerfRawData_PerfProc_Process" a 
number of times, the remote WMI server processes begin to consume memory 
(Commit Size) until a 0x800706ba error (The RPC server is unavailable) is 
raised, which stops the test application. A while after, all the WMI server 
processes created for the application dissappear. This happens only in 
Windows Server 2008, in Vista we were unable to reproduce this bahaviour.

  If we try to loop the full process instead of doing a lot of performance 
queries in the inner loop, the server process Commit Size grows, and when the 
memory reaches some level, the process restarts and no error is raised on the 
test application. 

  When we repeat all those tests with the query "Select * from 
Win32_OperatingSystem" then no increase in the Commit Size is shown. This is 
also true if we run the same tests targetting a Windows XP system with both 
those queries.

Regards,
Tango

To make the code work, change the user, password and remote namespace to the 
proper values:

#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"
#define QUERY_TYPE				L"WQL"
#define QUERY					L"Select * from Win32_PerfRawData_PerfProc_Process"
//#define QUERY					L"Select * from Win32_OperatingSystem"

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;
	IEnumWbemClassObject		*pEnumerator = NULL;
    BSTR						bstrNameSpace = NULL;
    BSTR						bstrUserName = NULL;
    BSTR						bstrPassword = NULL;
	BSTR						userbstr = NULL;
	BSTR						domainbstr = NULL;
	BSTR						bstrQueryType = NULL;
	BSTR						bstrQuery = 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;
		pEnumerator = NULL;
		bstrNameSpace = NULL;
		bstrUserName = NULL;
		bstrPassword = NULL;
		userbstr = NULL;
		domainbstr = NULL;
		bstrQueryType = NULL;
		bstrQuery = NULL;
		lID = 0;
		lVirtualBytesHandle = 0;
		lIDProcessHandle = 0;
		dwVirtualBytes = 0;
		dwProcessId = 0;
		dwNumObjects = 0;
		dwNumReturned = 0;
		dwIDProcess = 0;
		i=0;
		x=0;
		y=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;
		}

		bstrQueryType = SysAllocString(QUERY_TYPE);
		bstrQuery = SysAllocString(QUERY);

		for(x = 0; x < NUMBER_OF_REFRESHES; x++)
		{
			if (FAILED (hr = pNameSpace->ExecQuery(
								bstrQueryType, 
								bstrQuery,
								WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
								NULL,
								&pEnumerator)))
			{
				goto CLEANUP;
			}
			if (NULL != pEnumerator)
			{
				pEnumerator->Release();
				pEnumerator = NULL;
			}

		}
		// exit loop here
		CLEANUP:

		if (NULL != bstrNameSpace)
		{
			SysFreeString(bstrNameSpace);
		}
		if (NULL != bstrUserName)
		{
			SysFreeString(bstrUserName);
		}
		if (NULL != userbstr)
		{
			SysFreeString(userbstr);
		}
		if (NULL != domainbstr)
		{
			SysFreeString(domainbstr);
		}
		if (NULL != bstrPassword)
		{
			SysFreeString(bstrPassword);
		}
		if (NULL != bstrQueryType)
		{
			SysFreeString(bstrQueryType);
		}
		if (NULL != bstrQuery)
		{
			SysFreeString(bstrQuery);
		}

		if (NULL != pEnumerator)
		{
			pEnumerator->Release();
		}
		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:35:00 -0700   author:   Tango am

Google
 
Web ureader.com


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