Сбой при использовании WscRegisterForChanges - PullRequest
0 голосов
/ 07 мая 2010

Я пытаюсь использовать WscRegisterForChanges с функцией C ++ в Windows 7.

Документация находится здесь:

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 ]

2 голосов
/ 14 декабря 2011

это связано с соглашениями о вызовах. Определениям функций WinApi32 | обратным вызовам должен предшествовать макрос WINAPI или CALLBACK, который в основном сообщает компилятору о соглашении о вызовах - порядок передачи параметров в стек, куда должно быть записано возвращаемое значение, восстановление стека после возврата к вызывающему.

Чтобы подвести итог, CC определил отношения между вызывающим абонентом и вызываемым абонентом

0 голосов
/ 07 мая 2010

Похоже, что добавление WINAPI к обратному вызову исправляет это.

Новый вызов выглядит так:

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

Может кто-нибудь сказать мне, почему это необходимо?

...