2010-05-07 3 views
0

Je suis en train d'utiliser les WscRegisterForChanges avec fonction C++ dans Windows 7.Accident utilisant WscRegisterForChanges

Documentation situé ici:

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

Mon problème est que même si le rappel exécute correctement, le le code tombe en panne quand il arrive à la fin de l'exécution du rappel.

Voici le code en question. Il est très simple, donc je ne sais pas pourquoi il s'écraser:

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

Ma pile d'appel ressemble à ceci lorsque l'accident se produit:

 
> 00faf6e8() 
    [email protected]() + 0x1293 bytes 
    [email protected]@12() + 0x12 bytes 
    [email protected]() + 0x27 bytes 
    [email protected]() + 0x1b bytes 

Si j'ajoute ExitThread (0); à la fin de SecurityCenterChangeOccurred, je reçois une erreur et la trace suivante (donc je ne pense pas que je devrais utiliser 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. 

    [email protected]() + 0x3ca2f bytes 
    [email protected]() + 0x30 bytes 
> WscRegisterForChangesCrash.exe!SecurityCenterChangeOccurred(void * param=0x00000000) Line 8 + 0xa bytes C++ 
    wscapi.dll!WorkItemWrapper() + 0x19 bytes 
    [email protected]() + 0xdf bytes 
    [email protected]() + 0x1293 bytes 
    [email protected]@12() + 0x12 bytes 
    [email protected]() + 0x27 bytes 
    [email protected]() + 0x1b bytes 

Est-ce que quelqu'un a des idées pour lesquelles cela pourrait se produire?

Pour déclencher l'arrêt, exécutez le programme et activez ou désactivez le pare-feu.

Répondre

0

Il semble que l'ajout de WINAPI au rappel corrige cela.

Le nouvel appel ressemble à ceci:

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

quelqu'un peut me dire pourquoi cela est nécessaire?

1

cela est dû aux conventions d'appel. Définitions des fonctions WinApi32 | callbacks doivent être précédés de la macro WINAPI, ou CALLBACK, qui indique au compilateur l'appel de la convention - l'ordre des paramètres à empiler, où doit être écrite la valeur de retour, la restauration de pile après retour à l'appelant. Pour résumer, les relations CC définies entre l'appelant et l'appelé