Ejemplo n.º 1
0
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmShow)
{
    HANDLE hNotifications = NULL;
    HANDLE hDeviceNotifications[64];
    HANDLE ht;
    int i;
    LPTSTR pszFname = _T("PMMON:WinMain");

    MSGQUEUEOPTIONS msgOptions = {0};

    UNREFERENCED_PARAMETER(hInst);
    UNREFERENCED_PARAMETER(hPrevInst);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmShow);

    // clear globals
    memset(hDeviceNotifications, 0, sizeof(hDeviceNotifications));

    // create a termination event
    ghevTerminate = CreateEvent(NULL, FALSE, FALSE, _T("SOFTWARE/PMTestPrograms/PMMON/Terminate"));
    if(ghevTerminate == NULL) {
        RetailPrint  (_T("%s: CreateEvent() failed %d for termination event\r\n"),
                      pszFname, GetLastError());
        goto _Exit;
    }

    // did the event already exist?
    if(GetLastError() == ERROR_ALREADY_EXISTS) {
        // yes, kill the existing process
        RetailPrint  (_T("%s: Signaling termination event\r\n"), pszFname);
        SetEvent(ghevTerminate);
        goto _Exit;
    }

    // create a message queue for Power Manager notifications
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.dwMaxMessages = QUEUE_ENTRIES;
    msgOptions.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;
    msgOptions.bReadAccess = TRUE;

    ghPowerNotifications= CreateMsgQueue(NULL, &msgOptions);
    if (!ghPowerNotifications) {
        DWORD dwErr = GetLastError();
        RetailPrint  (TEXT("%s:CreateMessageQueue ERROR:%d\n"), pszFname, dwErr);
        goto _Exit;
    }

    // request Power notifications
    hNotifications = RequestPowerNotifications(ghPowerNotifications, POWER_NOTIFY_ALL); // Flags
    if (!hNotifications) {
        DWORD dwErr = GetLastError();
        RetailPrint  (TEXT("%s:RequestPowerNotifications ERROR:%d\n"), pszFname, dwErr);
        goto _Exit;
    }

    // create message queues
    memset(&msgOptions, 0, sizeof(msgOptions));
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.cbMaxMessage = PNP_QUEUE_SIZE;
    msgOptions.bReadAccess = TRUE;
    ghDeviceNotifications = CreateMsgQueue(NULL, &msgOptions);
    if(ghDeviceNotifications == NULL) {
        DWORD dwStatus = GetLastError();
        RetailPrint  (_T("%s:CreateMsgQueue() failed %d\r\n"), pszFname, dwStatus);
        goto _Exit;
    }

    // create the monitoring thread
    ht = CreateThread(NULL, 0, MonThreadProc, NULL, 0, NULL);
    if(ht) {
        // request device notifications (do this after the thread is
        // created so we don't drop any notifications)
        RequestPMDeviceNotifications(64, hDeviceNotifications);

        // wait for the thread to exit
        WaitForSingleObject(ht, INFINITE);
        CloseHandle(ht);
    }

_Exit:
    if(hNotifications) StopPowerNotifications(hNotifications);
    if(ghPowerNotifications) CloseMsgQueue(ghPowerNotifications);
    for(i = 0; i < 64 && hDeviceNotifications[i] != NULL; i++) {
        StopDeviceNotifications(hDeviceNotifications[i]);
    }
    if(ghDeviceNotifications) CloseMsgQueue(ghDeviceNotifications);
    if(ghevTerminate) CloseHandle(ghevTerminate);
    RetailPrint  (_T("%s: exiting\r\n"), pszFname);

    return 0;
}
Ejemplo n.º 2
0
static void destroyDeviceNotificationQueue(HANDLE& queue, HANDLE& notif)
{
    StopDeviceNotifications(notif);
    CloseMsgQueue(queue);
}
Ejemplo n.º 3
0
DWORD WINAPI 
PnpThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hnGeneric = NULL;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
    DWORD dwNumEvents = 0;
    BOOL fDone = FALSE;
    BOOL fOk;
    INT iPriority;
    PDEVICE_LIST pdl;
    SETFNAME(_T("PnpThreadProc"));

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("PnPPriority256"), &iPriority)) {
        iPriority = DEF_PNP_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // first list entry is the exit event
    hEvents[dwNumEvents++] = ghevPmShutdown;

    // set up device notifications
    for(pdl = gpDeviceLists; pdl != NULL && dwNumEvents < dim(hEvents); pdl = pdl->pNext) {
        hEvents[dwNumEvents++] = pdl->hMsgQ;
        pdl->hnClass = RequestDeviceNotifications(pdl->pGuid, pdl->hMsgQ, TRUE);
        if(pdl->hnClass == NULL) {
            PMLOGMSG(ZONE_WARN, (_T("%s: RequestDeviceNotifications() failed %d\r\n"),
                pszFname, GetLastError()));
        }
    }
    DEBUGCHK(dwNumEvents > 1);
    // we're up and running
    SetEvent(hevReady);
    
    // Wait for Initalization complete.
    HANDLE hInit[2] = {ghevPowerManagerReady, ghevPmShutdown};
    fDone = (WaitForMultipleObjects(_countof(hInit), hInit, FALSE, INFINITE)!= WAIT_OBJECT_0);

    // wait for new devices to arrive
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, INFINITE);
        if(dwStatus == (WAIT_OBJECT_0 + 0)) {
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
        } else if(dwStatus > WAIT_OBJECT_0 && dwStatus <= (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { 
            dwStatus -= WAIT_OBJECT_0;
            fOk = ProcessPnPMsgQueue(hEvents[dwStatus]);
            if(!fOk) {
                PMLOGMSG(ZONE_WARN, (_T("%s: ProcessPnPMsgQueue(0x%08x) failed\r\n"), pszFname,
                    hEvents[dwStatus]));
            }
        } else {
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                pszFname, dwStatus, GetLastError())); 
            fDone = TRUE;
            break;
        }
    }

    // release resources
    for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
        if(pdl->hnClass != NULL) StopDeviceNotifications(pdl->hnClass);
    }

    // all done
    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}