Click here to Skip to main content
Licence CPOL
First Posted 29 Jun 2009
Views 8,456
Downloads 123
Bookmarked 17 times

Process Create Notification using EnumProcess

By | 2 Jul 2009 | Article
Poll using EnumProcess to get process create notification in user-mode

Introduction

Windows does not provide an event based mechanism in user-mode for process related notifications. As a result, any solution becomes inherently polling based. One such option is to use EnumProcess API. WMI can also be used. I have never used WMI so I can't say about the overhead of using a WMI based method. But one thing is for sure, using WMI does bring an additional dependency on WMI service. In this article, I will consider an EnumProcess based method. Please refer here for a WMI based method.

Using the Code

The sample class CProcessNotify wraps EnumProcess polling functionality. Polling with user supplied interval is done in a separate thread. Notifications are delivered in that thread. But if you need the calling thread to block, you may modify the class to suit your purpose. Here is the main code. Basically, compare the process id list returned from EnumProcess using STL set_compare. The difference in the current and the previous list gives the created and terminated ids. The current approach has one small drawback. If a process disappears and a new process appears with the same id within the polling interval, it would not know. The workaround for that would be to store process start time using GetProcessTimes API with the id.

typedef std::vector<dword> PIDLIST;
typedef std::vector<dword>::iterator PIDLISTITER;

const DWORD nSize = 1024;
PIDLIST vPidListPrev;

for (;;)
{
	DWORD nRet = WaitForSingleObject(
		m_hQuit,
		m_nEnumInterval);
	if (WAIT_TIMEOUT != nRet)
	{
		return nRet;
	}

	PIDLIST vPidListNext(nSize);

	DWORD nNeeded = 0;
	BOOL bRet = EnumProcesses(
		&vPidListNext[0],
		nSize*sizeof(DWORD),
		&nNeeded);
	if (!bRet)
	{
		return GetLastError();
	}

	vPidListNext.resize(nNeeded / sizeof(DWORD));
	sort(
		vPidListNext.begin(),
		vPidListNext.end());

	if (vPidListPrev.empty())
	{
		if (!m_bNotifyCurrent)
		{
			vPidListPrev = vPidListNext;
			continue;
		}
	}

	if (vPidListNext.size() == vPidListPrev.size())
	{
		int nRet = memcmp(
			&vPidListNext[0],
			&vPidListPrev[0],
			nNeeded);
		if (0 == nRet)
		{
			continue;
		}
	}

	PIDLIST vPidListAdded(nSize);
	PIDLISTITER itAdded = set_difference(
		vPidListNext.begin(),
		vPidListNext.end(),
		vPidListPrev.begin(),
		vPidListPrev.end(),
		vPidListAdded.begin());
	for (PIDLISTITER it1 = vPidListAdded.begin() ; it1 != itAdded ; it1++)
	{
		BOOL bRet = OnNotify(*it1, TRUE);
		if (!bRet)
		{
			return ERROR_CANCELLED;
		}
		DWORD nRet = WaitForSingleObject(
			m_hQuit,
			0);
		if (WAIT_TIMEOUT != nRet)
		{
			return nRet;
		}
	}

	PIDLIST vPidListRemoved(nSize);
	PIDLISTITER itRemoved = set_difference(
		vPidListPrev.begin(),
		vPidListPrev.end(),
		vPidListNext.begin(),
		vPidListNext.end(),
		vPidListRemoved.begin());
	for (PIDLISTITER it1 = vPidListRemoved.begin() ; it1 != itRemoved ; it1++)
	{
		BOOL bRet = OnNotify(*it1, FALSE);
		if (!bRet)
		{
			return ERROR_CANCELLED;
		}
		DWORD nRet = WaitForSingleObject(
			m_hQuit,
			0);
		if (WAIT_TIMEOUT != nRet)
		{
			return nRet;
		}
	}

	vPidListPrev = vPidListNext;
}

Comments are most welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

My2Cents

Software Developer

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalrunning sample Pinmembermarc ochsenmeier4:21 4 Feb '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 3 Jul 2009
Article Copyright 2009 by My2Cents
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid