Search code examples
callbackwindows-8handlepower-managementpower-state

PowerRegisterSuspendResumeNotification - provided callback function doesn't work as expected


I register my application to receive notification when the system is suspended or resumed. MSDN documentation

Function I'd like to be executed after application receives notification (I tried both void and void CALLBACK and both work same way):

void isConnectedStandby()
{
    printf( "ConnectedStandby Request");
}

1st case - I provide pointer to the isConnectedStandby function, but system treats as a double pointer to the function - it calls an address which is under this callback pointer.

HPOWERNOTIFY RegistrationHandle;

PowerRegisterSuspendResumeNotification(
      DEVICE_NOTIFY_CALLBACK,
      &isConnectedStandby,
      &RegistrationHandle
);

2nd case - here I provide as follows (this way my function code is executed):

typedef void (*StatusFunction_t)(); 
StatusFunction_t StatusFunction = isConnectedStandby;
HPOWERNOTIFY RegistrationHandle;

    PowerRegisterSuspendResumeNotification(
      DEVICE_NOTIFY_CALLBACK,
      &isConnectedStandby,
      &RegistrationHandle
);

System calls not only mine function, but all addresses after the first one (if I provide an array of functions, it executes one after another to crash when there is no valid code available)

What is the correct way to use this function?


Solution

  • Function declaration (must be static ULONG with 3 parameters as you can see below):

    static ULONG isConnectedStandby(PVOID Context, ULONG Type, PVOID Setting);
    
    ULONG isConnectedStandby(PVOID Context, ULONG Type, PVOID Setting)
    {
        printf( "ConnectedStandby Request");
        return 0;
    }
    

    Istead of providing callback function directly to PowerRegisterSuspendResumeNotification we have to provide struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS filled with our functions address :

    static _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS testCallback = {
        isConnectedStandby,
        nullptr
        };
    HPOWERNOTIFY RegistrationHandle;
    
    PowerRegisterSuspendResumeNotification(
      DEVICE_NOTIFY_CALLBACK,
      &testCallback,
      &RegistrationHandle
    );
    

    MSDN documentation did not mention any of those information.