[Sorry if this post is a dup. For whatever reason, messages I send sometimes have attachments (even when sending “plain text”!), and the list software rightly stops these messages.]
That’s close, but there is one important detail missing. As someone else pointed out, CancelIo can only cancel the IRPs that were created by the calling thread. (CancelIo walks an IRP list whose list head is in the thread structure.) But unfortunately, you don’t have control over which thread runs the handler that you provide to SetConsoleCtrlHandler. The details are uninteresting, but in most cases, the thread that calls your handler function will NOT be the same as the thread that issued the async I/O. Consider this program:
BOOL CALLBACK ControlHandler(DWORD control) {
_tprintf(_T(“[tid %08x] ControlHandler: control = %d\r\n”), GetCurrentThreadId(), control);
switch (control) {
case CTRL_C_EVENT:
_tprintf(_T(“[tid %08x] ControlHandler: Received CTRL_C_EVENT\r\n”), GetCurrentThreadId());
return TRUE;
default:
_tprintf(_T(“[tid %08x] ControlHandler: Received unknown control, ignoring\r\n”), GetCurrentThreadId());
return FALSE;
}
}
int _tmain(int argc, _TCHAR* argv)
{
SetConsoleCtrlHandler(ControlHandler, TRUE);
for (;
{
_tprintf(_T(“[tid %08x] Waiting…\r\n”), GetCurrentThreadId());
SleepEx(INFINITE, TRUE);
}
return 0;
}
If you run this program, and then press control-C, you’ll see that the “Waiting” message is printed with a different thread ID than the “Received CTRL_C_EVENT” message. So you will need to take this into consideration.
On NT kernels that predate the Vista/Longhorn code base, the best solution is to send some sort of message to your main thread, telling it to cancel the async I/O requests. (Even for Vista/LH, this is a good approach.) You can use whatever mechanism you want to accomplish this: APCs, events, PostMessage, I/O completion ports, etc. If you go with events, then you will have some sort of “HANDLE ControlCPressedEvent”, which you create when your app starts. In your control-C handler, you’ll call SetEvent(ControlCPressedEvent), and in your main I/O loop, you’ll monitor that event sing WaitForMultipleObjects. When that event fires, call CancelIo on your file handle (which, as pointed out before, must be opened in async mode).
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, March 27, 2007 6:25 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SetConsoleCtrlHandler
Hi All,
Thanks for your inputs.
So, if i understand right, this is what i should be doing -
- Create the device handle with FILE_FLAG_OVERLAPPED flag set 2. Create an event event_from_ReadFile in the overlapped structure 2. Call ReadFile 3. WaitOnMultipleObjects(event_from_ReadFile, event_from_Ctrl_C) 4. If event_from_Ctrl_C is signalled, call CancelIo 5. If event_from_ReadFile is signalled, continue with whatever it is that i have to do
Quick questions, what are the IRP_MJ_CODE (on the driver side) corresponding dispatch_routines to the CancelIo win32 call? Is it DispatchCleanup or DispatchClose or something else? Oh yes, this is a USB driver that i am writing.
Thanks all.
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer