使用WscRegisterForChanges崩溃

时间:2010-05-07 06:18:00

标签: crash multithreading securitycenter

我正在尝试在Windows 7中使用带有C ++功能的WscRegisterForChanges。

位于此处的文档:

http://msdn.microsoft.com/en-us/library/bb432507(v=VS.85).aspx

我的问题是,即使回调正确执行,代码也会在回调执行结束时崩溃。

这是有问题的代码。这很简单,所以我不确定它为什么会崩溃:

#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;
}

崩溃发生时我的调用堆栈如下所示:

> 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 

如果我添加ExitThread(0);在SecurityCenterChangeOccurred结束时,我得到一个错误和以下跟踪(所以我不认为我应该使用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!SecurityCenterChangeOccurred(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 

有没有人有任何想法可能会发生这种情况?

要触发崩溃,请运行​​程序并打开或关闭防火墙。

2 个答案:

答案 0 :(得分:2)

这是由于调用约定。 WinApi32函数的定义|回调必须以宏WINAPI或CALLBACK开头,它基本上告诉编译器有关调用约定 - 要推送到堆栈的参数的顺序,应该写入返回值,返回调用者后的堆栈恢复。

总结一下,CC定义了来电者和被叫者之间的关系

答案 1 :(得分:0)

看起来将WINAPI添加到回调修复此问题。

新电话如下:

void WINAPI SecurityCenterChangeOccurred(void *param) {
    printf("Change occurred!\n");
}

有人可以告诉我为什么这是必要的吗?