Click here to Skip to main content
Click here to Skip to main content

Detecting Windows NT/2K process execution

By , 25 Mar 2002
 

Sample Image

Abstract

Intercepting and tracing process execution is a very useful mechanism for implementing NT Task Manager-like applications and systems that require manipulations of external processes. Notifying interested parties upon starting of a new processes is a classic problem of developing process monitoring systems and system-wide hooks. Win32 API provides set of great libraries (PSAPI and ToolHelp [1]) that allow you to enumerate processes currently running in the system. Although these APIs are extremely powerful they don't permit you to get notifications when a new process starts or ends up. This article provides an efficient and robust technique based on a documented interface for achieving this goal.

Solution

Luckily, NT/2K provides a set of APIs, known as "Process Structure Routines" [2] exported by NTOSKRNL. One of these APIs PsSetCreateProcessNotifyRoutine() offers the ability to register system-wide callback function which is called by OS each time when a new process starts, exits or is terminated. The mentioned API can be employed as an easy to implement method for tracking down processes simply by implementing a NT kernel-mode driver and a user mode Win32 control application. The role of the driver is to detect process execution and notifiy the control program about these events.

Requirements

  • Provide a simple, efficient, reliable and thread-safe mechanism for monitoring process execution
  • Resolve synchronization issues between the driver and the user mode application
  • Build an easy to use and extend OOP user-mode framework
  • Allow registering and un-registering of the callback as well as ability to dynamically load and unload the kernel driver

How it works

The control application register the kernel mode driver under HKLM\SYSTEM\CurrentControlSet\Services and dynamically loads it. The kernel driver then creates a named event object that is used to signal the user-mode application when new event has been fired (i.e. process starts or ends up). The control application opens the same event object and creates a listening thread that waits on this event. Next, the user mode application sends a request to the driver to start monitoring. The driver invokes PsSetCreateProcessNotifyRoutine(), which accepts two parameters. One of them specifies the entry point of a caller-supplied callback routine, responsible for receiving all notifications from Windows. Upon a notification, that takes place in the callback, the driver signals that event in order to inform the user-mode application that something has happened. The control application then gets the data for that particular event from the driver and stores it in a special queue container for further processing. If there is no need for detecting process execution anymore the user mode application sends a request to the driver to stop monitoring. The driver then deactivates the observing mechanism. Later the control mode application can unload the driver and un-register it.

Design and implementation

NT Kernel mode driver (ProcObsrv)

The entry point DriverEntry() (ProcObsrv.c) performs the driver's initialization only. The I/O manager calls this function when the driver is loaded. Since PsSetCreateProcessNotifyRoutine() allows to un-register the callback I implemented the actual process of registration and un-registration in the driver's dispatch routine. This allows me dynamically to start and stop the monitoring activities by using a single IOCTL (control code IOCTL_PROCOBSRV_ACTIVATE_MONITORING). Once the callback is registered each time when a process starts or terminates the OS calls user supplied ProcessCallback(). This function populates a buffer that will be picked up by the user mode application. Next the driver signals the named event object, thus the user-mode application that waits on it will be informed that there is available information to be retrieved.

Control application (ConsCtl)

For the sake of simplicity I decided to provide a simple console application, leaving the implementation of the fancy GUI stuff to you. Designing of an application to be multithreaded allows that application to scale and be more responsive. On the other hand, it is very important to take into account several considerations related to synchronizing the access to information provided by the publisher (i.e. kernel driver) and retrieved by the subscriber (i.e. control application). The other important key point is that a detecting system must be reliable, and makes sure that no events are missed out. To simplify the design process, first I needed to assign the responsibilities between different entities in the user mode application, responsible for handling the driver. However it isn't difficult to do it by answering these questions [5]:

  1. What are the processes in the system
  2. What are the roles in the framework
  3. Who does what and how do they collaborate

Follows UML class diagram, that illustrates the relations between classes:

CApplicationScope implements a singleton and wraps up the main interface to the framework. It exposes two public methods that start and stop the monitoring process.

class CApplicationScope  
{
    .. Other Other details ignored for the sake of simplicity  ....
public:
    // Initiates process of monitoring process 
    BOOL StartMonitoring(PVOID pvParam);
    // Ends up the whole process of monitoring
    void StopMonitoring();
};

CProcessThreadMonitor is the thread that waits on the created by the driver event to be signaled. As soon as a process has been created or ended up, the driver signals this event object and CProcessThreadMonitor's thread wakes up. Then the user mode application retrieves the data from the driver. Next, the data is appended to queue container (CQueueContainer) using its method Append().

CQueueContainer is a thread-safe queue controller that offers an implementation of the Monitor/Condition variable pattern. The main purpose of this class is to provide a thread-safe semaphore realization of a queue container. This is how the method Append() works:

  1. Lock access to the aggregated STL deque object
  2. Add the data item
  3. Signal m_evtElementAvailable event object
  4. Unlock the deque

And here is its actual implementation:

// Insert data into the queue
BOOL CQueueContainer::Append(const QUEUED_ITEM& element)
{
    BOOL bResult = FALSE;
    DWORD dw = ::WaitForSingleObject(m_mtxMonitor, INFINITE);
    bResult = (WAIT_OBJECT_0 == dw);
    if (bResult)
    {
        // Add it to the STL queue
        m_Queue.push_back(element);
        // Notify the waiting thread that there is 
        // available element in the queue for processing
        ::SetEvent(m_evtElementAvailable);
    }//
    ::ReleaseMutex(m_mtxMonitor);
    return bResult;
}

Since it is designed to notify when there is an element available in the queue, it aggregates an instance of CRetreivalThread, which waits until an element becomes available in the local storage. This is its pseudo implementation:

  1. Wait on m_evtElementAvailable event object
  2. Lock access to the STL deque object
  3. Extract the data item
  4. Unlock the deque
  5. Process the data that has been retrieved from the queue

Here is the method invoked when something has been added to the queue:

// Implement specific behavior when kernel mode driver notifies 
// the user-mode app void
CQueueContainer::DoOnProcessCreatedTerminated() {
    QUEUED_ITEM element; // Initially we have at least one element for processing 
    BOOL    bRemoveFromQueue = TRUE; 
    while    (bRemoveFromQueue) {
        DWORD dwResult = ::WaitForSingleObject( m_mtxMonitor, INFINITE );
        if (WAIT_OBJECT_0 == dwResult) {

            // Is there anything in the queue 
            bRemoveFromQueue = (m_Queue.size() > 0); 
            if (bRemoveFromQueue) {
                // Get the element from the queue 
                element    = m_Queue.front(); m_Queue.pop_front();    
            } // if 
            else
                // Let's make sure that the event hasn't been 
                // left in signaled state if there are no items 
                // in the queue 
                ::ResetEvent(m_evtElementAvailable);
            }
            // if ::ReleaseMutex(m_mtxMonitor);
            // Process it only if there is an element that has 
            // been picked up
            if (bRemoveFromQueue)    
                m_pHandler->OnProcessEvent( &element, m_pvParam );
        else
            break;
    } // while
}

CCustomThread - To help manage the complexity of maintaining raw threads I encapsulated all thread's related activities in an abstract class. It provides a pure virtual method Run(), that must be implemented by any specific thread class (e.g. CRetrievalThread and CProcessThreadMonitor). CCustomThread is designed to ensure that thread function returns when you want the thread to terminate as the only way to make sure that all thread's resources are cleaned up properly. It offers a means to shut any of its instances down by signaling a named event m_hShutdownEvent.

CCallbackHandler is an abstract class that has been designed to provide interface for performing user-supplied actions when process is created or terminated. It exposes a pure virtual method OnProcessEvent(), which must be implemented according to the specific requirements of the system. In the sample code you will see a class CMyCallbackHandler, that inherits from CCallbackHandler and implements OnProcessEvent() method. One of the parameters pvParam of OnProcessEvent() method allows you to pass any kind of data, that's why it is declared as PVOID. In the sample code a pointer to an instance of CWhatheverYouWantToHold is passed to the OnProcessEvent(). You might want to use this parameter to pass just a handle to a window, that could be used for sending a message to it within OnProcessEvent() implementation.

class CCallbackHandler  
{
public:
    CCallbackHandler();
    virtual ~CCallbackHandler();
    // Define an abstract interface for receiving notifications
    virtual void OnProcessEvent(
        PQUEUED_ITEM pQueuedItem, 
        PVOID        pvParam
        ) = 0;
};

Compiling the sample code

You need to have installed MS Platform SDK on your machine. Provided sample code of the user-mode application can be compiled for ANSI or UNICODE. In case you would like to compile the driver you have to install Windows DDK as well.

Running the sample

However, it is not a problem if you don't have Windows DDK installed, since the sample code contains a compiled debug version of ProcObsrv.sys kernel driver as well as it source code. Just place control program along with the driver in single directory and let it run.

For demonstration purposes, the user mode application dynamically installs the driver and initiates process of monitoring. Next, you will see 10 instances of notepad.exe launched and later on closed. Meanwhile you can peek at the console window and see how the process monitor works. If you want you can start some program and see how the console will display its process ID along with its name.

Conclusion

This article demonstrated how you can employ a documented interface for detecting NT/2K process execution. However it is by far not the only one solution to this issue and certainly might miss some details, but I hope you would find it helpful for some real scenarios.

References:

  1. Single interface for enumerating processes and modules under NT and Win9x/2K, Ivo Ivanov
  2. Windows DDK Documentation, Process Structure Routines
  3. Nerditorium, Jim Finnegan, MSJ January 1999
  4. Windows NT Device Driver Development, Peter G. Viscarola and W. Anthony Mason
  5. Applying UML and Patterns, Craig Larman
  6. Using predicate waits with Win32 threads, D. Howard, C/C++ Users Journal, May 2000

License

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

About the Author

Ivo Ivanov
Chief Technology Officer
Australia Australia
Member
I'm a Security Researcher with over 20 years of experience. I specialise in Windows Internals and Malware Analysis. I'm the owner of InfoProcess and also a co-founder and Chief Security Architect of Vinsula.

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.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat abt 64 bit Os ( vista onwards) Pinmembermannujam2927 Jul '11 - 18:57 
Hi
This is a very clean piece of code and run perectly well on 32 bit OS (XP/vista /Win7).
It also works for 32 bit process running on 64 bit OS.
But it is not working out for 64 bit process.
 
Any update for the component.
 
Thanks in advance
 

Mannujam
AnswerRe: What abt 64 bit Os ( vista onwards) PinmemberIvo Ivanov29 Jul '11 - 22:50 
GeneralHow about Win 7. Is it usable ? Pinmember14400027 Apr '11 - 3:05 
It's nice code.
 
But It didn't work in Windows 7. How to use ?
GeneralRe: How about Win 7. Is it usable ? PinmemberIvo Ivanov29 Jul '11 - 22:50 
GeneralQuestion.. PinmemberNehaMishra286845 Oct '10 - 21:18 
The article is great I am new to this programming and have a question..
When a process is created, we get notification in the callback.Similarly when a process is terminated we get it in the callback function here.
 
What i want to do is, as soon as user closes the notepad.exe, i want to be notified and take a decision if i want it to be terminated or not...
GeneralRe: Question.. PinmemberIvo Ivanov29 Jul '11 - 22:54 
Generalunable to run the exe Pinmembersrshilpa10 Aug '09 - 22:03 
I do not have Windows DDK installed...
i compliled the ConsCtl in visual studio 2005 and placed ProcObsrv.sys in the same folder.
10 notepads are opening up but the process information is not getting displayed.
GeneralVista Compatible PinmemberIdentity Undisclosed3 Jun '09 - 20:02 
Hello,
 
Is the solution compatible with Vista ? I have tried to run the ConsCtl.exe and I didnt get any sort of message in the window. Any help ?
 
Where can I get DDK downloaded ? and do I need a different DDK for XP and different for Vista ?
 
Thanks.
 
Top 10, Top ten, Top 10 lists, Top ten lists
Top 10 about everything

QuestionIs it applicable on Windows 9x,XP??? PinmemberKrazzze's14 May '09 - 9:46 
Can you please tell me about some method of detecting process execution on Windows 98, XP????
I really need to know. Thanks...
 
Satyajit
AnswerRe: Is it applicable on Windows 9x,XP??? PinmemberIvo Ivanov14 May '09 - 21:46 
Questiondon't it proper for WIN2003 with sp2...?? Pinmemberryancs18 Sep '08 - 23:54 
when i compiled at winxp ,ddk and vs2005 , it completed.
 
but don't work at win2003.
 
m_hKernelEvent always NULL.
 
what wrong with it...?
 

-----------
m_hKernelEvent = ::OpenEvent(
SYNCHRONIZE, FALSE, TEXT("ProcObsrvProcessEvent") );
 
if(m_hKernelEvent == NULL)
printf(" m_hKernelEvent is NULL \n");
 
-----------
AnswerRe: don't it proper for WIN2003 with sp2...?? PinmemberIvo Ivanov21 Sep '08 - 16:45 
QuestionUsing this method as non-administrator account PinmemberGaro1 Jun '08 - 21:20 
Ever since the driver (ProcObsrv.sys) is using IoCreateNotificationEvent DDK API, I don't think (n I've tried) that it'd be able to run in non-administrator privilege, as stated in http://msdn.microsoft.com/en-us/library/aa490498.aspx
 
The driver creates a named event object in the \\BaseNamedObjects object directory. You can open a kernel-mode event named \\BaseNamedObjects\Xxx in user mode under the name Xxx. Note that security settings can prevent an application from opening the event. For more information, see the OpenEvent Fails in a Non-Administrator Account KB article. The \\BaseNamedObjects object directory is not created until the Microsoft Win32 subsystem initializes, so drivers that are loaded at boot time cannot create event objects in the \\BaseNamedObjects directory in their DriverEntry routines
 
even tho' in that article, also stated that it might be solved by using workaround here, http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q228785 , is there anybody around can implement this?
 
thank you for all
AnswerRe: Using this method as non-administrator account PinmemberIvo Ivanov1 Jun '08 - 21:35 
QuestionHow to build this Project as DLL? PinmemberMarvin Ferber20 Apr '08 - 7:56 
Hi,
 
I am trying to use this process detection mechanism in a python script. To get this work I need a shared library(DLL) form this project.
 
I managed to rewrite the code in order to start an stop the monitoring-process(CApplicationScope is a global structure in my code). To do this I use the DLLMain-Function . I can compile the projcet and the driver. No problem so far.
 
Any time I load the DLL I end up in the following loop:
CustomThread.cpp:
while (!GetIsActive()){}
 
It seems the thread will not be activated. But why? The untouched Project works fine on my Windows XP Professional machines. I am using Visual Studio 2008 Express Edition.
 
Is it not possible to build a shared library with this driver? Can anyone give me a hint how to make this work?
 
Thanks
AnswerRe: How to build this Project as DLL? PinmemberBlake Miller29 Jul '11 - 10:30 
GeneralRe: How to build this Project as DLL? PinmemberIvo Ivanov29 Jul '11 - 22:46 
GeneralThere is a much easier way of doing this PinmemberJan Stetka14 Jan '08 - 8:50 
See http://myweb.tiscali.co.uk/janstetka/
GeneralRe: There is a much easier way of doing this PinmemberIvo Ivanov14 Jan '08 - 12:28 
GeneralRe: There is a much easier way of doing this PinmemberJan Stetka10 Apr '08 - 23:22 
GeneralOpenEvent() on xp return NULL Pinmemberliy7716120 Dec '07 - 22:50 
m_hKernelEvent = ::OpenEvent(
SYNCHRONIZE, FALSE, TEXT("ProcObsrvProcessEvent") );
return (NULL != m_hKernelEvent);
 
result is NULL.
 

win2003 is very good!
GeneralOpenEvent() on xp return NULL Pinmemberliy7716120 Dec '07 - 22:48 
m_hKernelEvent = ::OpenEvent(
SYNCHRONIZE, FALSE, L"ProcObsrvProcessEvent" );
 
return (NULL != m_hKernelEvent);
 
result is NULL.
 

2003 is very good!
QuestionOpenEvent() on vista return NULL Pinmemberflyonok16 Oct '07 - 0:45 
m_hKernelEvent = ::OpenEvent(
SYNCHRONIZE, FALSE, L"ProcObsrvProcessEvent" );
 
return (NULL != m_hKernelEvent);
 
result is NULL.
 
Linux is very good!

AnswerRe: OpenEvent() on vista return NULL PinmemberByeBye12330 Oct '07 - 20:14 
General.NET Version PinmemberReMuZe3 Oct '07 - 5:40 
Not sure if it is a good way to do it, but i have recently been using a FileSystemWatcher class to monitor a directory. Configure it to watch for last access time and when a process gets run it triggers your event.
 
This only works if you know the directory and filename though obviously Smile | :)
 
ReM
QuestionThread exception Pinmembersatish_abiram19 Aug '07 - 23:24 
Hello
Its a nice article. I've changed the code and made it as DLL. I removed ConsCtl.cpp and wrote the same in DLL constructor. Till now its fine, but pQueuedItem in CMyCallbackHandler class, OnProcessEvent method after GetProcessName is NULL. I dont know why pQueuedItem is pointing to NULL. After that the Thread is aborted. Did you experience this any time before?
Confused | :confused:
Thanks in Advance

GeneralCPU utilizing Pinmembersatish_abiram13 Aug '07 - 0:54 
Hello
When I run this process, this process is using 60 to 70% of CPU. Can you suggest how can I reduce that?
thanks in advance
GeneralRe: CPU utilizing PinmemberIvo Ivanov14 Aug '07 - 11:36 
Generalexe compile errors fixing [modified] PinmemberAlex_I25 Jun '07 - 23:45 
"ApplicationScope.cpp" and "ThreadMonitor.cpp" lacks of :
#include <winioctl.h>
 
It causes those :
error C2065: 'CTL_CODE' : undeclared identifier
error C2065: 'METHOD_BUFFERED' : undeclared identifier
error C2065: 'FILE_READ_ACCESS' : undeclared identifier
error C2065: 'FILE_WRITE_ACCESS' : undeclared identifier
Already reported and fixed by Dave Midgley.
 
To author :   remove this message, when this "big problem" will be fixed Smile | :)
 

 
-- modified at 5:50 Tuesday 26th June, 2007
GeneralI'm able to run Consctl.c but it is using 100% cpu PinmemberChandrashekhar.M31 Jan '07 - 23:59 
Hi!
 
I'm using Win 2000 System with VC++ 6.0.
Able to run Consctl.c but when executing it I observed that it
is consuming 100% of the cpu.
 
Actually I'm developing the Client/Server API and want to monitor the programs executed by the client, therefore I want to deploy this code at
the client side. As it is taking 100% of the cpu, client wont be able to do his daily work.
 
So pls provide me the way to optimize the code to take less cpu cycles or
any other source code for the same purpose.
 
Any help is appreciated.
 
Waiting for reply.
 

 
Chandu
GeneralRe: I'm able to run Consctl.c but it is using 100% cpu PinmemberLepon2k23 Apr '07 - 20:51 
Generalunable to compile ProcObsrv.c PinmemberChandrashekhar.M31 Jan '07 - 22:20 

When I tried to build the ProcObsrv.c, it is ending with error
"fatal error C1083: Cannot open include file: 'ntddk.h': No such file or directory"
 
M.Chandrashekhar
GeneralRe: unable to compile ProcObsrv.c PinmemberIvo Ivanov14 Aug '07 - 11:37 
GeneralConsCtl does not compile PinmemberDave Midgley18 Sep '06 - 23:42 
Like BBBCA I cannot compile ConsCtl because CTL_CODE, METHOD_BUFFERED, FILE_READ_ACCESS and FILE_WRITE_ACCESS are not defined. I am using Microsoft Visual Studio 6 under Windows XP, and I have not installed the DDK. Please can you clarify this. Thanks.
 

 
Dave

GeneralRe: ConsCtl does not compile PinmemberDave Midgley20 Sep '06 - 4:39 
Generalhelp please Pinmemberrabah170720 Apr '06 - 8:13 
what I should be do for use this in c++ builder app.
thanks
Generalproblem with driver Pinmembereuacela27 Mar '06 - 2:37 
I compile your driver with the Win Xp checked build environment from my winddk. The thing is that is compiled OK but it only has 3 kb not like yours which has 7kb. and mine does not work, I mean if I send IOCTL requests with DeviceIoControl it only enters the CreateClose routine and I only get the "Dispatch CreateClose" message.
I am noew to drivers can you please tell me what your makefile looked like and what did the sources file looked like.
I compiled it using the command
 
build -cZ
my makefile lokked like this:
 
!IFDEF WIN95_BUILD
 
ROOT = ..\..\..\..
IS_32 = TRUE
IS_OEM = TRUE
WANT_LATEST = TRUE
DEVICEDIR = 1394VDEV
COMMONMKFILE = $(DEVICEDIR).mk
DEPENDTARGETS = debug retail
 
!include $(ROOT)\dev\master.mk
 
!ELSE
 
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
 
!INCLUDE $(NTMAKEENV)\makefile.def
 
!ENDIF
 

and the sources file contained:
 
TARGETNAME=DeviceDriver
TARGETPATH=.
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
 
USE_MAPSYM=1
 
SOURCES= Gabby.c \


Please Help me.
Thank you.

 

 
gabby
GeneralRe: problem with driver Pinmemberbbcca27 Mar '06 - 12:53 
GeneralRe: problem with driver Pinmemberlijf97116 Apr '07 - 0:00 
GeneralRe: problem with driver Pinmembercoremsg17 Oct '07 - 20:42 
GeneralComplie Errors in ConsCtl,But build successful the ProcObsrv.c ,Why,Please help me,thank you! Pinmemberbbcca26 Mar '06 - 14:27 
Thank you for you codes first,But when I try to compile the file,I found the following errors:
================================================ --------------------Configuration: ConsCtl - Win32 Debug-------------------- Compiling... ApplicationScope.cpp d:\code\consctl\applicationscope.cpp(214) : error C2065: 'CTL_CODE' : undeclared identifier d:\code\consctl\applicationscope.cpp(214) : error C2065: 'METHOD_BUFFERED' : undeclared identifier d:\code\consctl\applicationscope.cpp(214) : error C2065: 'FILE_READ_ACCESS' : undeclared identifier d:\code\consctl\applicationscope.cpp(214) : error C2065: 'FILE_WRITE_ACCESS' : undeclared identifier ThreadMonitor.cpp d:\code\consctl\threadmonitor.cpp(169) : error C2065: 'CTL_CODE' : undeclared identifier d:\code\consctl\threadmonitor.cpp(169) : error C2065: 'METHOD_BUFFERED' : undeclared identifier d:\code\consctl\threadmonitor.cpp(169) : error C2065: 'FILE_READ_ACCESS' : undeclared identifier d:\code\consctl\threadmonitor.cpp(169) : error C2065: 'FILE_WRITE_ACCESS' : undeclared identifier Error executing cl.exe. ConsCtl.exe - 8 error(s), 0 warning(s)
=================================================
I already install the WIN2000 DDK.
I know that the CTL_CODE is defined in ntddk.h,also ,I build the ProcObsrv.c successful under the win2000 DDK,but I can't find the way to handle the ConsCtl's compile errors.Plz help me ,thank you !Frown | :(
GeneralRe: Complie Errors in ConsCtl,But build successful the ProcObsrv.c ,Why,Please help me,thank you! PinmemberDave Midgley20 Sep '06 - 4:39 
GeneralDetect process attempt to start PinmemberJuliano27 Feb '06 - 0:19 
How can I detect a process attempt to start and block it before it runs?
GeneralRe: Detect process attempt to start PinmemberIvo Ivanov27 Feb '06 - 10:14 
GeneralCPU overload: CCustomThread Pinmemberpphilippot30 Jan '06 - 23:21 
Hi,
 
I have a service based on this code and from time to time, the service starts to consume 100% of the CPU time. I just found out why. CCustomThread appears to be the culprit.
 
When a call is made to SetActive(TRUE), the method calls _beginthreadex and then enters the following loop
 
while (!GetIsActive()) {}
 
GetIsActive returns true only if the thread has been dispatched because it's CCustomThread::ThreadFunc that sets the "active" flag. When the CPU overloading problem occurs, I can attach my debugger to the process and see that SetActive is stuck in the above loop. This is a very dangerous approach. If for some reason the thread is never dispatched, we are in an endless loop. Actually, the loop is itself overloading the CPU giving less chance to the thread to be dispatched. At least on some systems, this situation actually occurs. Moreover, I'm wondering about the purpose of this waiting loop. Why wait for the thread to be actually dispatched before leaving the SetActive method?
 
Likewise, the call to SetActive(FALSE) triggers a call to the same kind of loop which is also dangerous:
 
while (GetIsActive())
 
The method is waiting for the thread to terminate. If the thread never terminates for some reason, we have another endless loop.
 
I have replaced this call with
 
WaitForSingleObject(sm_hThread, MAX_WAIT_CUSTOM_THREAD);
 
Cheers.
 
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
GeneralRe: CPU overload: CCustomThread Pinmemberpphilippot31 Jan '06 - 0:11 
GeneralRe: CPU overload: CCustomThread Pinmemberpphilippot6 Feb '06 - 1:34 
GeneralRe: CPU overload: CCustomThread Pinmembereaster_200720 Feb '06 - 17:38 
GeneralRe: CPU overload: CCustomThread Pinmemberpphilippot20 Feb '06 - 21:01 
GeneralRe: CPU overload: CCustomThread Pinmembereaster_200721 Feb '06 - 12:51 

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 26 Mar 2002
Article Copyright 2002 by Ivo Ivanov
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid