Crash using WscRegisterForChanges
I'm trying to use the WscRegisterForChanges with C++ function in Windows 7.
Documentation located here:
http://msdn.microsoft.com/en-us/library/bb432507(v=VS.85).aspx
My problem is that even though the callback properly executes, the code crashes when it gets to the end of the callback's execution.
Here's the code in question. It's very simple, so I'm not sure why it's crashing:
#include #include #include void SecurityCenterChangeOccurred(void *param) { printf("Change occurred!\n"); } int main() { HRESULT result = S_OK; HANDLE callbackRegistration = NULL; result = WscRegisterForChanges( NULL, &callbackRegistration, (LPTHREAD_START_ROUTINE)SecurityCenterChangeOccurred, NULL); while(1) { Sleep(100); } return 0; }
My call stack looks like this when the crash occurs:
> 00faf6e8() ntdll.dll!_TppWorkerThread@4() + 0x1293 bytes kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
If I add ExitThread(0); to the end of SecurityCenterChangeOccurred, I get an error and the following trace (So I don't think I should be using ExitThread):
Unhandled exception at 0x7799852b (ntdll.dll) in WscRegisterForChangesCrash.exe: 0xC000071C: An invalid thread, handle %p, is specified for this operation. Possibly, a threadpool worker thread was specified. ntdll.dll!_TpCheckTerminateWorker@4() + 0x3ca2f bytes ntdll.dll!_RtlExitUserThread@4() + 0x30 bytes > WscRegisterForChangesCrash.exe!Sec开发者_运维问答urityCenterChangeOccurred(void * param=0x00000000) Line 8 + 0xa bytes C++ wscapi.dll!WorkItemWrapper() + 0x19 bytes ntdll.dll!_RtlpTpWorkCallback@8() + 0xdf bytes ntdll.dll!_TppWorkerThread@4() + 0x1293 bytes kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Does anyone have any ideas why this might be happening?
To trigger the crash run the program and turn the firewall on or off.
this is due to calling conventions. Definitions of WinApi32 functions|callbacks must be preceded by macro WINAPI, or CALLBACK, which basically tells compiler about calling convention - order of parameters to be pushed to stack, where should be written return value, stack restoration after comeback to caller.
To sum it up, CC defined relations between caller and callee
It looks like adding WINAPI to the callback fixes this.
The new call looks like this:
void WINAPI SecurityCenterChangeOccurred(void *param) { printf("Change occurred!\n"); }
Can somebody tell me why this is necessary?
精彩评论