Exemplo n.º 1
0
DWORD
CSDHCBase::DetermineSlotCount(
                              )
{
    SETFNAME(_T("DetermineSlotCount"));

    DWORD cSlots = 0;

    // Read window information
    DDKWINDOWINFO wini = { sizeof(wini) };
    DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini);
    if (dwStatus != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"),
            pszFname));
        goto EXIT;
    }

    cSlots = wini.dwNumMemWindows;

    if (cSlots == 0) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s There were not any reported slots.\r\n"),
            pszFname));
        goto EXIT;
    }

EXIT:
    return cSlots;
}
Exemplo n.º 2
0
// This routine opens a handle to a given device, or to the parent device
// that is its proxy.  The return value is the device's handle, or 
// INVALID_HANDLE_VALUE if there's an error.
static HANDLE 
OpenStreamDevice(PDEVICE_STATE pds)
{
    PDEVICE_STATE pdsReal = pds;

#ifndef SHIP_BUILD
    SETFNAME(_T("OpenStreamDevice"));
#endif

    // determine what device to actually open
    if(pds->pParent != NULL) {
        pdsReal = pds->pParent;
    }

    // get a handle to the client
    HANDLE hRet = CreateFile(pdsReal->pszName, 0, 
        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if(hRet == INVALID_HANDLE_VALUE) {
        PMLOGMSG(ZONE_WARN || ZONE_IOCTL, (_T("%s: OpenFile('%s') failed %d (0x%08x)\r\n"), pszFname,
            pdsReal->pszName, GetLastError(), GetLastError()));
    }
    PMLOGMSG(ZONE_DEVICE || ZONE_IOCTL, (_T("%s: handle to '%s' on behalf of '%s' is 0x%08x\r\n"), \
        pszFname, pdsReal->pszName, pds->pszName, hRet));

    return hRet;
}
Exemplo n.º 3
0
BOOL
PowerState::Init ()
{
	SETFNAME (_T ("PowerState::Init"));
	if (m_pPwrStateMgr && m_hUnsignaledHandle)
	{
		for (DWORD dwIndex = 0; dwIndex < m_dwNumOfEvent; dwIndex++)
			if (m_dwEventArray[dwIndex] == NULL)
			{
				ASSERT (FALSE);
				return FALSE;
			}
		m_LastNewState = GetState ();	// Point to itself
		DWORD dwReturn = StateValidateRegistry ();

		if (dwReturn != ERROR_SUCCESS)
		{
			PMLOGMSG (ZONE_PLATFORM,
					  (_T ("%s: StateValidateRegistry return (0x%08x) fails\r\n"), pszFname,
					   dwReturn));
			ASSERT (FALSE);
			return FALSE;
		}
		return TRUE;
	}
	return FALSE;
}
Exemplo n.º 4
0
// This routine issues a request to a device.  It returns TRUE if successful,
// FALSE if there's a problem.
static BOOL
RequestStreamDevice(HANDLE hDevice, DWORD dwRequest, LPVOID pInBuf, DWORD dwInSize, 
              LPVOID pOutBuf, DWORD dwOutSize, LPDWORD pdwBytesRet)
{
    BOOL fOk;

#ifndef SHIP_BUILD
    SETFNAME(_T("RequestStreamDevice"));
#endif

    DEBUGCHK(hDevice != INVALID_HANDLE_VALUE);

    __try {
        PMLOGMSG(ZONE_IOCTL, (_T("%s: calling DeviceIoControl(0x%08x) w/ request %d ('%s')\r\n"),
            pszFname, hDevice, dwRequest, 
            dwRequest == IOCTL_POWER_CAPABILITIES ? _T("IOCTL_POWER_CAPABILITIES") 
            : dwRequest == IOCTL_POWER_GET ? _T("IOCTL_POWER_GET") 
            : dwRequest == IOCTL_POWER_SET ? _T("IOCTL_POWER_SET") 
            : dwRequest == IOCTL_POWER_QUERY ? _T("IOCTL_POWER_QUERY") 
            : dwRequest == IOCTL_REGISTER_POWER_RELATIONSHIP ? _T("IOCTL_REGISTER_POWER_RELATIONSHIP")
            : _T("<UNKNOWN>")));
        fOk = DeviceIoControl(hDevice, dwRequest, pInBuf, dwInSize, 
            pOutBuf, dwOutSize, pdwBytesRet, NULL);
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        PMLOGMSG(ZONE_WARN || ZONE_IOCTL, (_T("%s: exception in DeviceIoControl(%d)\r\n"), pszFname,
            dwRequest));
        fOk = FALSE;
    }

    PMLOGMSG(!fOk && (ZONE_WARN || ZONE_IOCTL), 
        (_T("%s: DeviceIoControl(%d) to 0x%08x failed %d (0x%08x)\r\n"), pszFname,
        dwRequest, hDevice, GetLastError(), GetLastError()));
    return fOk;
}
Exemplo n.º 5
0
static
void 
WINAPI
Matrix_ToggleLights(
    UINT uiPddId,
    KEY_STATE_FLAGS KeyStateFlags
    )
{
	static const KEY_STATE_FLAGS ksfLightMask = KeyShiftCapitalFlag | 
		KeyShiftNumLockFlag | KeyShiftScrollLockFlag; 
	static KEY_STATE_FLAGS ksfCurr;

    SETFNAME(_T("Matrix_ToggleLights"));

	KEY_STATE_FLAGS ksfNewState = (ksfLightMask & KeyStateFlags);

	if (ksfNewState != ksfCurr) 
    {
        DEBUGMSG(ZONE_PDD, (_T("%s: PDD %u: Changing light state\r\n"), 
            pszFname, uiPddId));
		KeybdPdd_ToggleKeyNotification(ksfNewState);
		ksfCurr = ksfNewState;
	}

    return;
}
Exemplo n.º 6
0
// this routine takes the battery mutex
DWORD
LockBattery(void)
{
    DWORD dwStatus;
    SETFNAME(_T("LockBattery"));
	DPSTR("+LockBattery");

    DEBUGCHK(ghMutex != NULL);

    dwStatus = WaitForSingleObject(ghMutex, MUTEX_TIMEOUT);
    if(dwStatus == WAIT_OBJECT_0) {
        dwStatus = ERROR_SUCCESS;
    } else {
        dwStatus = GetLastError();
        DEBUGCHK(dwStatus != ERROR_SUCCESS);
    }
    
    DEBUGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
        (_T("%s: WaitForSingleObject() failed %d\r\n"), TEXT(__FUNCTION__), 
        GetLastError()));
    DEBUGCHK(dwStatus == ERROR_SUCCESS);

	DPSTR("-LockBattery");
    return dwStatus;
}
Exemplo n.º 7
0
BOOL
Matrix(
    PDEVICE_LAYOUT pDeviceLayout
    )
{
    SETFNAME(_T("Matrix"));

    BOOL fRet = FALSE;

    if (pDeviceLayout == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: pDeviceLayout error!\r\n"), pszFname));
        return FALSE;
    }

    if (pDeviceLayout->dwSize != sizeof(DEVICE_LAYOUT))
    {
        DEBUGMSG(ZONE_ERROR, (_T("Matrix: data structure size mismatch\r\n")));
        goto leave;
    }

    // Make sure that the Sc->Vk tables are the sizes that we expect
    if (dim(ScanCodeToVKeyTable) != (1 + ScanCodeTableLast - ScanCodeTableFirst))
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: ScanCodeToVKeyTable error!\r\n"), pszFname));
    }

    *pDeviceLayout = dlMatrixEngUs;

    fRet = TRUE;

leave:
    return fRet;
}
Exemplo n.º 8
0
// This routine releases a power relationship that was created with 
// PmRegisterPowerRelationship().  It returns
//      ERROR_SUCCESS - relationship removed
//      ERROR_INVALID_PARAMETER - bad handle
// Deregistering a power relationship has the side effect of deregistering
// the child device with the PM.  Note that if the child exits while
// the relationship is outstanding, the caller will get ERROR_INVALID_PARAMETER
// when they attempt to release the relationship handle.
EXTERN_C DWORD WINAPI 
PmReleasePowerRelationship(HANDLE h)
{
    PDEVICE_STATE pds = (PDEVICE_STATE) h;
    DWORD dwStatus = ERROR_INVALID_PARAMETER;

#ifndef SHIP_BUILD
    SETFNAME(_T("PmReleasePowerRelationship"));
#endif

    PMLOGMSG(ZONE_API, (_T("%s: releasing 0x%08x\r\n"), pszFname, h));

    // make sure that this pointer is a child node with a parent
    if(pds != NULL) {
        BOOL fExists = CheckDevicePointer(pds); // increments refcnt if TRUE
        if(fExists) {
            // delete the device
            PREFAST_DEBUGCHK(pds->pListHead != NULL);
            RemoveDevice(pds->pListHead->pGuid, pds->pszName);

            // done with the pointer
            DeviceStateDecRef(pds);

            // return a good status
            dwStatus = ERROR_SUCCESS;
        }
    }

    PMLOGMSG(ZONE_API || (dwStatus != ERROR_SUCCESS && ZONE_WARN), (_T("%s: returning %d\r\n"), 
        pszFname, dwStatus));
    return dwStatus;
}
Exemplo n.º 9
0
// This routine closes a handle opened with OpenStreamDevice().  It returns TRUE
// if successful, FALSE if there's a problem.
static BOOL
CloseStreamDevice(HANDLE hDevice)
{
#ifndef SHIP_BUILD
    SETFNAME(_T("CloseStreamDevice"));
#endif

    PMLOGMSG(ZONE_DEVICE || ZONE_IOCTL, (_T("%s: closing 0x%08x\r\n"), pszFname, hDevice));
    BOOL fOk = CloseHandle(hDevice);
    PMLOGMSG(!fOk && (ZONE_WARN || ZONE_IOCTL), (_T("%s: CloseHandle(0x%08x) failed %d (0x%08x)\r\n"), pszFname,
        hDevice, GetLastError(), GetLastError()));
    return fOk;
}
Exemplo n.º 10
0
DWORD
PowerState::StateValidateRegistry (DWORD dwDState, DWORD dwFlag)
{
	HKEY hkPM = NULL, hkSubkey;
	TCHAR pszSubKey[MAX_PATH];
	DWORD dwDisposition;

	SETFNAME (_T ("PowerState::StateValidateRegistry"));

	// Open the Power Manager registry key:
	DWORD dwStatus =
		RegCreateKeyEx (HKEY_LOCAL_MACHINE, PWRMGR_REG_KEY, 0, NULL, 0, 0, NULL, &hkPM, &dwDisposition);

	if (dwStatus != ERROR_SUCCESS)
	{
		PMLOGMSG (ZONE_ERROR,
				  (_T ("%s: can't open '%s', error is %d\r\n"), pszFname, PWRMGR_REG_KEY, dwStatus));
	}

	// Verify the system state:
	if (dwStatus == ERROR_SUCCESS)
	{
		StringCchPrintf (pszSubKey, MAX_PATH, _T ("State\\%s"), GetStateString ());
		dwStatus = RegCreateKeyEx (hkPM, pszSubKey, 0, NULL, 0, 0, NULL, &hkSubkey, &dwDisposition);
		if (dwStatus == ERROR_SUCCESS)
		{
			if (dwDisposition == REG_CREATED_NEW_KEY)
			{
				// Allow devices to go to any passed-in power level:
				DWORD dwValue = dwDState;	// D State
				dwStatus = RegSetValueEx (hkSubkey, NULL, 0, REG_DWORD, (LPBYTE) & dwValue, sizeof (dwValue));

				// Write the passed flags value:
				if (dwStatus == ERROR_SUCCESS)
				{
					dwValue = dwFlag;
					dwStatus = RegSetValueEx (hkSubkey, _T ("Flags"), 0, REG_DWORD, (LPBYTE) & dwValue, sizeof (dwValue));
				}
			}
			RegCloseKey (hkSubkey);
		}
		PMLOGMSG (dwStatus != ERROR_SUCCESS && ZONE_ERROR,
				  (_T ("%s: error %d while creating or writing values in '%s\\%s'\r\n"), pszFname,
				   dwStatus, PWRMGR_REG_KEY, pszSubKey));
	}

	// Release resources:
	if (hkPM != NULL)
		RegCloseKey (hkPM);
	return dwStatus;
}
Exemplo n.º 11
0
BOOL
WINAPI
Matrix_Entry(
    UINT uiPddId,
    PFN_KEYBD_EVENT pfnKeybdEvent,
    PKEYBD_PDD *ppKeybdPdd
    )
{
    SETFNAME(_T("PS2_8042_Entry"));

	BOOL fRet = FALSE;

    v_uiPddId = uiPddId;
    v_pfnKeybdEvent = pfnKeybdEvent;

    DEBUGMSG(ZONE_INIT, (_T("%s: Initialize Matrix ID %u\r\n"), pszFname, 
        uiPddId));
    DEBUGCHK(ppKeybdPdd != NULL);

    *ppKeybdPdd = &MatrixPdd;
	
    if (v_pp2k) {
        fRet = TRUE;
        goto leave;
    }
    //	We always assume that there is a keyboard.
    v_pp2k = new Ps2Keybd;
    if (v_pp2k->Initialize()) {
        v_pp2k ->IsrThreadStart();
    } 
    else {
        ERRORMSG(1,(TEXT("Could not initialize ps2 keyboard.\r\n")));
        delete v_pp2k;
        v_pp2k = NULL;
    }

	if (!KeybdDriverInitializeAddresses()) {
		goto leave;
	}

    if (v_pp2k)
    {
	    v_pp2k->KeybdPowerOn();
    }

	fRet = TRUE;
		
leave:
    DEBUGMSG(ZONE_INIT, (_T("%s: Initialization complete\r\n"), pszFname));
	return fRet;
}
Exemplo n.º 12
0
PLATFORM_ACTIVITY_EVENT
PowerState::MsgQueueEvent ()
{
	SETFNAME (_T ("PowerState::MsgQueueEvent"));
	PLATFORM_ACTIVITY_EVENT activeEvent = NoActivity;
	POWERPOLICYMESSAGE ppm;
	DWORD dwStatus =
		PmPolicyReadNotificationQueue (m_dwEventArray[PM_MSGQUEUE_EVENT], &ppm, sizeof (ppm));

	if (dwStatus == ERROR_SUCCESS)
	{
		PMLOGMSG (ZONE_PLATFORM,
				  (_T ("%s: got request 0x%04x (data 0x%08x) from process 0x%08x\r\n"), pszFname,
				   ppm.dwMessage, ppm.dwData, ppm.hOwnerProcess));
		switch (ppm.dwMessage)
		{
		  case PPN_POWERCHANGE:
			  if (PmUpdatePowerStatus ())
			  {
				  activeEvent = PowerSourceChange;
			  }
			  break;
		  case PPN_SUSPENDKEYPRESSED:
			  activeEvent = PowerButtonPressed;
			  break;
		  case PPN_APPBUTTONPRESSED:
			  activeEvent = AppButtonPressed;
			  break;
		  case PPN_UNATTENDEDMODE:
			  // Somebody wants to enter or leave unattended mode:
			  if (ppm.dwData != FALSE)
			  {
				  activeEvent = EnterUnattendedModeRequest;
			  }
			  else
			  {
				  activeEvent = LeaveUnattendedModeRequest;
			  }
			  break;
		  default:
			  // Unhandled notification type, so ignore it:
			  PMLOGMSG (ZONE_WARN,
						(_T ("%s: unhandled policy notification 0x%04x (data 0x%08x)\r\n"),
						 pszFname, ppm.dwMessage, ppm.dwData));
			  break;
		}
	}
	PMLOGMSG (ZONE_PLATFORM, (_T ("%s: return ActiveEvent = 0x%08x\r\n"), pszFname, activeEvent));
	return activeEvent;
}
Exemplo n.º 13
0
// this routine reads device notifications from a message queue and updates
// the PM's internal tables appropriately.
BOOL
ProcessPnPMsgQueue(HANDLE hMsgQ)
{
    BOOL fOk = FALSE;
    UCHAR deviceBuf[PNP_QUEUE_SIZE];
    DWORD iBytesInQueue = 0;
    DWORD dwFlags = 0;
    SETFNAME(_T("ProcessPnPMsgQueue"));

    // read a message from the message queue -- it should be a device advertisement
    memset(deviceBuf, 0, PNP_QUEUE_SIZE);
    if ( !ReadMsgQueue(hMsgQ, deviceBuf, PNP_QUEUE_SIZE, &iBytesInQueue, 0, &dwFlags)) {
        // nothing in the queue
        PMLOGMSG(ZONE_WARN, (_T("%s: ReadMsgQueue() failed %d\r\n"), pszFname,
            GetLastError()));
    } else if(iBytesInQueue >= sizeof(DEVDETAIL)) {
        // process the message
        PDEVDETAIL pDevDetail = (PDEVDETAIL) deviceBuf;
        DWORD dwMessageSize = sizeof(DEVDETAIL) + pDevDetail->cbName;
        
        // check for overlarge names
        if(pDevDetail->cbName > ((PNP_MAX_NAMELEN - 1) * sizeof(pDevDetail->szName[0]))) {
            PMLOGMSG(ZONE_WARN, (_T("%s: device name longer than %d characters\r\n"), 
                pszFname, PNP_MAX_NAMELEN - 1));
        } else {
            // convert the device name to lower case
            int i;
            for(i = 0; i < (PNP_MAX_NAMELEN - 1) && pDevDetail->szName[i] != 0; i++) {
                pDevDetail->szName[i] = _totlower(pDevDetail->szName[i]);
            }
            pDevDetail->szName[i] = 0;
            
            // add or remove the device -- note that a particular interface may be
            // advertised more than once, so these routines must handle that possibility.
            if(pDevDetail->fAttached) {
                AddDevice(&pDevDetail->guidDevClass, pDevDetail->szName, NULL, NULL);
            } else {
                RemoveDevice(&pDevDetail->guidDevClass, pDevDetail->szName);
            }
            fOk = TRUE;
        }
    } else {
        // not enough bytes for a message
        PMLOGMSG(ZONE_WARN, (_T("%s: got runt message (%d bytes)\r\n"), pszFname, 
            iBytesInQueue));
    }

    return fOk;
}
Exemplo n.º 14
0
// This routine returns TRUE to indicate that the pfBatteriesChangedSinceLastCall
// value filled in by BatteryPDDGetStatus() is valid.  If there is no way to
// tell that the platform's batteries have been changed this routine should
// return FALSE.
//Not support
BOOL
BatteryPDDSupportsChangeNotification(void)
{
    BOOL fSupportsChange;
    SETFNAME(_T("BatteryPDDPowerHandler"));
    RETAILMSG(ZONE_REG_PRINT, (TEXT("+BatteryPDDSupportsChangeNotification...  \r\n"))); 

    PREFAST_DEBUGCHK(gpStatus != NULL);

    LockBattery();
    fSupportsChange = gpStatus->fSupportsChange;
		DPNOK(fSupportsChange);
    UnlockBattery();

    return fSupportsChange;

}
Exemplo n.º 15
0
// this thread is signaled when the system wakes from a suspend state
DWORD WINAPI
ResumeThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[2];
    BOOL fDone = FALSE;
    INT iPriority;
    SETFNAME(_T("ResumeThreadProc"));

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

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

    // we're up and running
    SetEvent(hevReady);

    // wait for new devices to arrive
    hEvents[0] = ghevResume;
    hEvents[1] = ghevPmShutdown;
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dim(hEvents), hEvents, FALSE, INFINITE);
        switch(dwStatus) {
        case (WAIT_OBJECT_0 + 0):
            PMLOGMSG(ZONE_RESUME, (_T("%s: resume event signaled\r\n"), pszFname));
            PlatformResumeSystem();
            break;
        case (WAIT_OBJECT_0 + 1):
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
            break;
        default:
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                                 pszFname, dwStatus, GetLastError()));
            fDone = TRUE;
            break;
        }
    }

    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
Exemplo n.º 16
0
// This routine indicates how many battery levels will be reported
// in the BatteryFlag and BackupBatteryFlag fields of the PSYSTEM_POWER_STATUS_EX2
// filed in by BatteryPDDGetStatus().  This number ranges from 0 through 3 --
// see the Platform Builder documentation for details.  The main battery
// level count is reported in the low word of the return value; the count 
// for the backup battery is in the high word.
//have not used currently
LONG
BatteryPDDGetLevels(void)
{
    LONG lLevels;
    SETFNAME(_T("BatteryPDDPowerHandler"));

    RETAILMSG(ZONE_REG_PRINT, (TEXT("+BatteryPDDGetLevels...  \r\n"))); 

    PREFAST_DEBUGCHK(gpStatus != NULL);

    LockBattery();
    lLevels = MAKELONG (gpStatus->wMainLevels, gpStatus->wBackupLevels);
	DPNOK(lLevels);
    UnlockBattery();

    DEBUGMSG(ZONE_PDD, (_T("%s: returning %u (%d main levels, %d backup levels)\r\n"),
        TEXT(__FUNCTION__), lLevels, LOWORD(lLevels), HIWORD(lLevels)));

    return lLevels;
}
Exemplo n.º 17
0
// this routine releases the battery mutex
DWORD
UnlockBattery(void)
{
    DWORD dwStatus = ERROR_SUCCESS;
    BOOL fOk;
    SETFNAME(_T("UnlockBattery"));
	DPSTR("+UnlockBattery");	

    DEBUGCHK(ghMutex != NULL);

    fOk = ReleaseMutex(ghMutex);
    if(!fOk) {
        dwStatus = GetLastError();
        DEBUGCHK(dwStatus != ERROR_SUCCESS);
    }
    
    DEBUGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
        (_T("%s: ReleaseMutex() failed %d\r\n"), TEXT(__FUNCTION__), GetLastError()));
    DEBUGCHK(dwStatus == ERROR_SUCCESS);
	DPSTR("-UnlockBattery");
    return dwStatus;
}
Exemplo n.º 18
0
DWORD
CSDHCBase::IST()
{
    SETFNAME(_T("IST"));
    
    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Starting\n"), pszFname));

    if (!CeSetThreadPriority(GetCurrentThread(), m_dwPriority)) {
        DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Failed to set CEThreadPriority\n"),
            pszFname));
    }

    while (TRUE) {
        DEBUGCHK(m_hevInterrupt);
        DWORD dwWaitStatus = WaitForSingleObject(m_hevInterrupt, INFINITE);
        Validate();
        //InterruptDone(m_dwSysIntr);
        RETAILMSG(0,(TEXT("CSDHCBase::IST() Event is signaled [SYSINT = %x].\n"),m_dwSysIntr));
        if (WAIT_OBJECT_0 != dwWaitStatus) {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Wait Failed! 0x%08X\n"), 
                pszFname, dwWaitStatus));
            // bail out
            break;
        }
        else if (m_fDriverShutdown) {
            break;
        }
        else {
		  RETAILMSG(0,(TEXT("CSDHCBase::IST()\n")));			
            HandleInterrupt();
        }
    }

    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Exiting\n"), pszFname));

    return 0;
}
Exemplo n.º 19
0
// This routine initializes the list of activity timers.  It returns ERROR_SUCCESS 
// if successful or a Win32 error code otherwise.
DWORD
ActivityTimerInitList(VOID)
{
    DWORD dwStatus;
    HKEY hk = NULL;
    TCHAR szSources[1024];
    DWORD dwNumTimers = 0;
    PPACTIVITY_TIMER ppatList = NULL;

#ifndef SHIP_BUILD
    SETFNAME(_T("ActivityTimerInitList"));
#endif

    wsprintf(szSources, _T("%s\\ActivityTimers"), PWRMGR_REG_KEY);
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSources, 0, 0, &hk);
    if(dwStatus == ERROR_SUCCESS) {
        // figure out how many values are associated with the key
        dwStatus = RegQueryInfoKey(hk, NULL, NULL, NULL, &dwNumTimers, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL);
    } else {
        // no timers configured in the registry
        dwNumTimers = 0;
        dwStatus = ERROR_SUCCESS;
    }

    // if there are any values, allocate an array to hold them
    if(dwStatus == ERROR_SUCCESS) {
        ppatList = (PPACTIVITY_TIMER) PmAlloc((dwNumTimers + 1) * sizeof(PACTIVITY_TIMER));
        if(ppatList == NULL) {
            PMLOGMSG(ZONE_WARN, (_T("%s: couldn't allocate %d timers\r\n"), pszFname,
                dwNumTimers));
            dwStatus = ERROR_NOT_ENOUGH_MEMORY;
        } else {
            memset(ppatList, 0, (dwNumTimers + 1) * sizeof(PACTIVITY_TIMER));
            ppatList[dwNumTimers] = NULL;
        }
    }

    // read list of timers
    if(dwStatus == ERROR_SUCCESS && dwNumTimers != 0) {
        DWORD dwIndex = 0;
        do {
            TCHAR szName[256];
            DWORD cbValueName = dim(szName);
            
            dwStatus = RegEnumKeyEx(hk, dwIndex, szName, &cbValueName, NULL,
                NULL, NULL, NULL);
            if(dwStatus == ERROR_SUCCESS) {
                HKEY hkSubKey = NULL;
                
                // open the subkey
                dwStatus = RegOpenKeyEx(hk, szName, 0, 0, &hkSubKey);
                if(dwStatus == ERROR_SUCCESS) {
                    DWORD dwSize, dwType, dwTimeout;
                    LPTSTR pszValueName;

                    // read the timeout, expressed in seconds
                    dwSize = sizeof(dwTimeout);
                    pszValueName = _T("Timeout");
                    dwStatus = RegQueryValueEx(hkSubKey, pszValueName, NULL, &dwType, (LPBYTE) &dwTimeout, 
                        &dwSize);
                    if(dwStatus == ERROR_SUCCESS) {
                        if(dwType != REG_DWORD || dwTimeout > MAXTIMERINTERVAL) {
                            PMLOGMSG(ZONE_WARN, 
                                (_T("%s: RegQueryValueEx('%s'\'%s') or returned invalid type %d or invalid value %d\r\n"),
                                pszFname, szName, pszValueName, dwType, dwTimeout));
                            dwStatus = ERROR_INVALID_DATA;
                        }

                        // convert timeout to milliseconds
                        dwTimeout *= 1000;
                    } else {
                        // no timeout in seconds, try milliseconds
                        dwSize = sizeof(dwTimeout);
                        pszValueName = _T("TimeoutMs");
                        dwStatus = RegQueryValueEx(hkSubKey, pszValueName, NULL, &dwType, (LPBYTE) &dwTimeout, 
                            &dwSize);
                        if(dwStatus != ERROR_SUCCESS || dwType != REG_DWORD || dwTimeout > (MAXTIMERINTERVAL * 1000)) {
                            PMLOGMSG(ZONE_WARN, 
                                (_T("%s: RegQueryValueEx('%s'\'%s') failed %d (or returned invalid type %d or invalid value %d)\r\n"),
                                pszFname, szName, pszValueName, dwStatus, dwType, dwTimeout));
                            dwStatus = ERROR_INVALID_DATA;
                        }
                    }

                    if(dwStatus == ERROR_SUCCESS) {
                        // get wake sources
                        dwSize = sizeof(szSources);
                        pszValueName = _T("WakeSources");
                        dwStatus = RegQueryValueEx(hkSubKey, pszValueName, NULL, &dwType, (LPBYTE) szSources, 
                            &dwSize);
                        if(dwStatus != ERROR_SUCCESS) {
                            // no wake sources
                            szSources[0] = 0;
                            szSources[1] = 0;
                            dwStatus = ERROR_SUCCESS;
                        } else if(dwType != REG_MULTI_SZ) {
                            PMLOGMSG(ZONE_WARN, (_T("%s: invalid type %d for '%s'\'%s'\r\n"), pszFname, dwType,
                                szName, pszValueName));
                            dwStatus = ERROR_INVALID_DATATYPE;
                        } else {
                            szSources[dim(szSources) -1] = szSources[dim(szSources) -2] = 0; // Terminate MultiSZ
                        }
                    }
                    
                    // did we get the parameters?
                    if(dwStatus == ERROR_SUCCESS) {
                        ppatList[dwIndex] = ActivityTimerCreate(szName, dwTimeout, szSources);
                        if(ppatList[dwIndex] == NULL) {
                            dwStatus = ERROR_NOT_ENOUGH_MEMORY;
                        }
                    }
                }
                
                // release the registry key
                RegCloseKey(hkSubKey);
            }
            
            // update the index
            dwIndex++;
        } while(dwStatus == ERROR_SUCCESS && dwIndex < dwNumTimers);

        // did we read all items ok?
        if(dwStatus == ERROR_NO_MORE_ITEMS) {
            dwStatus = ERROR_SUCCESS;
        }

        // terminate the list with a NULL
        ppatList[dwIndex] = NULL;
    }

    // did we succeed?
    if(dwStatus == ERROR_SUCCESS) {
        PMLOCK();
        gppActivityTimers = ppatList;
        PMUNLOCK();
    } else {
        DWORD dwIndex;
        if(ppatList != NULL) {
            for(dwIndex = 0; dwIndex < dwNumTimers; dwIndex++) {
                if(ppatList[dwIndex] != NULL) {
                    ActivityTimerDestroy(ppatList[dwIndex]);
                }
            }
            PmFree(ppatList);
        }
    }

    // release resources
    if(hk != NULL) RegCloseKey(hk);

    PMLOGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
        (_T("%s: returning %d\r\n"), pszFname, dwStatus));
    return dwStatus;
}
Exemplo n.º 20
0
BOOL WINAPI 
BatteryPDDInitialize(LPCTSTR pszRegistryContext)
{
    BOOL fOk = TRUE;
    SYSTEM_POWER_STATUS_EX2 sps;
    WORD wMainLevels = 3, wBackupLevels = 0;
    BOOL fSupportsChange = FALSE;
    SETFNAME(_T("BatteryPDDInitialize"));

    DEBUGCHK(ghMutex == NULL);
    DEBUGCHK(ghFileMap == NULL);
    DEBUGCHK(gpStatus == NULL);
    DEBUGCHK(pszRegistryContext != NULL);
    
    RETAILMSG(ZONE_REG_PRINT, (TEXT("+++BatteryPDDInitialize... +++ \r\n"))); 

 //[david.modify] 2008-05-31 14:38
    RegInfo_Init();


    //Check Hardware status and system interface first
    if(!BspBattAllocResource()) goto _ERR_BATT;



    // intialize the battery status structure -- assume AC power, no battery info

    sps.ACLineStatus               = AC_LINE_ONLINE;
    sps.BatteryFlag                = BATTERY_FLAG_HIGH;
    sps.BatteryLifePercent         = BATTERY_PERCENTAGE_UNKNOWN;
    sps.Reserved1                  = 0;
    sps.BatteryLifeTime            = BATTERY_LIFE_UNKNOWN;
    sps.BatteryFullLifeTime        = BATTERY_LIFE_UNKNOWN;
    sps.Reserved2                  = 0;
    sps.BackupBatteryFlag          = BATTERY_FLAG_UNKNOWN;
    sps.BackupBatteryLifePercent   = BATTERY_PERCENTAGE_UNKNOWN;
    sps.Reserved3                  = 0;
    sps.BackupBatteryLifeTime      = BATTERY_LIFE_UNKNOWN;
    sps.BackupBatteryFullLifeTime  = BATTERY_LIFE_UNKNOWN;
    sps.BatteryChemistry           = BATTERY_CHEMISTRY_UNKNOWN;
    sps.BatteryVoltage             = 0;
    sps.BatteryCurrent             = 0;
    sps.BatteryAverageCurrent      = 0;
    sps.BatteryAverageInterval     = 0;
    sps.BatterymAHourConsumed      = 0;
    sps.BatteryTemperature         = 0;
    sps.BackupBatteryVoltage       = 0;

    // allocate resources
    if((ghMutex = CreateMutex(NULL, FALSE, BATTERY_FILE_MUTEX)) == NULL) {
        DEBUGMSG(ZONE_ERROR || ZONE_PDD || ZONE_INIT,
            (_T("%s: Could not aquire battery info file mutex handle\n"), TEXT(__FUNCTION__)));
        fOk = FALSE;
    } else {
        HINSTANCE hiCoreDll = NULL; 
        BOOL fNewMapping = TRUE;
        
        // get pointers to file-mapping functions
        hiCoreDll = LoadLibrary(_T("coredll.dll"));
        if(hiCoreDll != NULL) {
            gpfnCreateFileMappingW = (PFN_CreateFileMappingW) GetProcAddress((HMODULE) hiCoreDll, _T("CreateFileMappingW"));
            gpfnMapViewOfFile = (PFN_MapViewOfFile) GetProcAddress((HMODULE) hiCoreDll, _T("MapViewOfFile"));
            gpfnUnmapViewOfFile = (PFN_UnmapViewOfFile) GetProcAddress((HMODULE) hiCoreDll, _T("UnmapViewOfFile"));
        }
        FreeLibrary(hiCoreDll);		// we're already linked to coredll
        
        // serialize access to the mapping file
        LockBattery();
        
        // create the mapping
        if(gpfnCreateFileMappingW == NULL ) {
            // no file mapping, use a global variable
            static BATTERY_STATUS sBatteryStatus;
            gpStatus = &sBatteryStatus;
        } else if((ghFileMap = gpfnCreateFileMappingW((HANDLE)INVALID_HANDLE_VALUE, NULL, 
            PAGE_READWRITE, 0, sizeof(BATTERY_STATUS), BATTERY_STATUS_FILE)) == NULL) {
            DEBUGMSG(ZONE_ERROR || ZONE_PDD || ZONE_INIT,
                (_T("%s: Could not create file mapping for battery info file\n"), TEXT(__FUNCTION__)));
            fOk = FALSE;
        } else {
            // is this a new mapping?
            if(GetLastError() == ERROR_ALREADY_EXISTS) {
                fNewMapping = FALSE;
            }
            
            // map the object into our address space
            if(gpfnMapViewOfFile == NULL 
            || (gpStatus = (PBATTERY_STATUS) gpfnMapViewOfFile(ghFileMap, FILE_MAP_ALL_ACCESS, 
                0, 0, sizeof(BATTERY_STATUS))) == NULL) {
                DEBUGMSG(ZONE_ERROR || ZONE_PDD || ZONE_INIT,
                    (_T("Could not map view of battery info file into process address space\n"), TEXT(__FUNCTION__)));
                fOk = FALSE;
            } 
        }
        
        // should we initialize our structure?
        if(fOk && fNewMapping) {
            // initialize the memory mapped object
            memcpy(&gpStatus->sps, &sps, sizeof(gpStatus->sps));
            gpStatus->fSupportsChange = fSupportsChange;
            gpStatus->fChanged = FALSE;
            gpStatus->wMainLevels = wMainLevels;
            gpStatus->wBackupLevels = wBackupLevels;
        }
        
        // allow access to the battery buffer
        UnlockBattery();
    }
    
    // clean up if necessary
    if(!fOk) {
        if(gpStatus != NULL && gpfnUnmapViewOfFile != NULL) gpfnUnmapViewOfFile(gpStatus);
        if(ghFileMap != NULL) CloseHandle(ghFileMap);
        if(ghMutex != NULL) CloseHandle(ghMutex);
        gpStatus = NULL;
        ghFileMap = NULL;
        ghMutex = NULL;
    }
    
    return fOk;

_ERR_BATT:
	
    RETAILMSG(ZONE_BATT_ERROR, (TEXT("+Battery ERROR OR UNKNOWN STATUS...  \r\n"))); 
    BspBattDeallocResource();	
    SetLastError(ERROR_NOT_SUPPORTED);	
    return  FALSE;		

}
Exemplo n.º 21
0
EXTERN_C VOID WINAPI
PlatformManageSystemPower (HANDLE hevReady)
{
	BOOL fDone = FALSE;
	HANDLE hqNotify = NULL;
	HMODULE hmCoreDll = NULL;

	SETFNAME (_T ("PlatformManageSystemPower"));

	PMLOGMSG (ZONE_INIT || ZONE_PLATFORM, (_T ("+%s\r\n"), pszFname));

	// Initialize globals:
	ghevReloadActivityTimeouts = NULL;
	ghevRestartTimers = NULL;

	// Determine thread priority settings while we're suspending (in case
	// of priority inversion):

	if (!GetPMThreadPriority (_T ("PreSuspendPriority256"), &giPreSuspendPriority))
	{
		giPreSuspendPriority = DEF_PRESUSPEND_THREAD_PRIORITY;
	}
	if (!GetPMThreadPriority (_T ("SuspendPriority256"), &giSuspendPriority))
	{
		giSuspendPriority = DEF_SUSPEND_THREAD_PRIORITY;
	}

	// Get pointers to GWES's suspend/routine APIs.  These require GWES, so the OEM may
	// not have them on this platform.  Also get battery level APIs, which require a
	// battery driver and may not be present.

	hmCoreDll = (HMODULE) LoadLibrary (_T ("coredll.dll"));
	gfGwesReady = FALSE;
	PmInitPowerStatus (hmCoreDll);
	if (hmCoreDll != NULL)
	{
		gpfnGwesPowerDown = (PFN_GwesPowerDown) GetProcAddress (hmCoreDll, _T ("GwesPowerDown"));
		gpfnGwesPowerUp = (PFN_GwesPowerUp) GetProcAddress (hmCoreDll, _T ("GwesPowerUp"));

		// Do we have both GWES suspend/resume APIs?
		if (gpfnGwesPowerDown == NULL || gpfnGwesPowerUp == NULL)
		{
			// No, ignore GWES.
			gpfnGwesPowerDown = NULL;
			gpfnGwesPowerUp = NULL;
		}
	}

	// Create events:
	ghevReloadActivityTimeouts =
		CreateEvent (NULL, FALSE, FALSE, _T ("PowerManager/ReloadActivityTimeouts"));
	ghevRestartTimers = CreateEvent (NULL, FALSE, FALSE, NULL);
	if (ghevReloadActivityTimeouts == NULL || ghevRestartTimers == NULL)
	{
		PMLOGMSG (ZONE_WARN, (_T ("%s: CreateEvent() failed for system event\r\n"), pszFname));
		goto done;
	}

	// Create our notification queue:
	hqNotify = PmPolicyCreateNotificationQueue ();
	if (hqNotify == NULL)
	{
		PMLOGMSG (ZONE_WARN, (_T ("%s: PmPolicyCreateNotificationQueue() failed\r\n"), pszFname));
		goto done;
	}

	if (!fDone)
	{
        // Instantiate the PowerStateManager object and call its Init method:

		PowerStateManager *pPowerStateManager = new PowerStateManager ();

		if (pPowerStateManager && pPowerStateManager->Init ())
		{
			g_pPowerStateManager = pPowerStateManager;

			// We're up and running:
			SetEvent (hevReady);
			g_pPowerStateManager->ThreadRun ();
		}
		else
		{
            // Power Manager initialization failed:
			ASSERT (FALSE);
			if (pPowerStateManager)
				delete pPowerStateManager;

			PMLOGMSG (ZONE_INIT || ZONE_ERROR,
					  (_T ("%s: PowerStateManager Intialization Failed!!!\r\n"), pszFname));
		}
		if (g_pPowerStateManager)
		{
			delete g_pPowerStateManager;
			g_pPowerStateManager = NULL;
		}
	}

  done:
	// Clean up before exiting:
	if (ghevReloadActivityTimeouts == NULL)
	{
		CloseHandle (ghevReloadActivityTimeouts);
		ghevReloadActivityTimeouts = NULL;
	}
	if (ghevRestartTimers != NULL)
	{
		CloseHandle (ghevRestartTimers);
		ghevRestartTimers = NULL;
	}
	if (hqNotify != NULL)
	{
		PmPolicyCloseNotificationQueue (hqNotify);
		hqNotify = NULL;
	}

	if (hmCoreDll != NULL)
		FreeLibrary (hmCoreDll);

	PMLOGMSG (ZONE_PLATFORM, (_T ("-%s: exiting\r\n"), pszFname));
}
Exemplo n.º 22
0
EXTERN_C VOID WINAPI
PlatformResumeSystem (void)
{
	SETFNAME (_T ("PlatformResumeSystem"));

	PMLOGMSG (ZONE_RESUME, (_T ("+%s: suspend flag is %d\r\n"), pszFname, gfSystemSuspended));

	// Was this an unexpected resume event?  If so, there may be a thread priority problem
	// or some piece of software suspended the system without calling SetSystemPowerState().

	DEBUGCHK (gfSystemSuspended);
	if (!gfSystemSuspended)
	{
		// Unexpected resume -- go to the resuming state.  This should not happen unless
		// somebody is illegally calling PowerOffSystem() directly.

		PMLOGMSG (ZONE_WARN || ZONE_RESUME, (_T ("%s: WARNING: unexpected resume!\r\n"), pszFname));

		// Go into the new state.  OEMs that choose to support unexpected resumes may want to
		// lock PM variables with PMLOCK(), then set the curDx and actualDx values for all
		// devices to PwrDeviceUnspecified before calling PmSetSystemPowerState_I().  This will
		// force an update IOCTL to all devices.

		DEBUGCHK (ghevRestartTimers != NULL);
		SetEvent (ghevRestartTimers);
	}
	else
	{
		DWORD dwWakeSource, dwBytesReturned;
		BOOL fOk;

		// Get the system wake source to help determine which power state we resume into:
		fOk = KernelIoControl (IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &dwWakeSource,
							   sizeof (dwWakeSource), &dwBytesReturned);
		if (fOk)
		{
			// IOCTL succeeded (not all platforms necessarily support it), but sanity check
			// the return value, just in case.

			if (dwBytesReturned != sizeof (dwWakeSource))
			{
				PMLOGMSG (ZONE_WARN, (_T ("%s: KernelIoControl() returned an invalid size %d\r\n"),
									  pszFname, dwBytesReturned));
			}
			else
			{
				// Look for an activity timer corresponding to this wake source.
				PACTIVITY_TIMER pat = ActivityTimerFindByWakeSource (dwWakeSource);

				if (pat != NULL)
				{
					PMLOGMSG (ZONE_RESUME, (_T ("%s: signaling '%s' activity at resume\r\n"),
											pszFname, pat->pszName));

					// Is there an activity timer we need to reset?
					if (pat->hevReset != NULL)
					{
						// Found a timer, elevate the timer management priority thread so that it
						// executes before the suspending thread.

						DWORD dwOldPriority = CeGetThreadPriority (ghtActivityTimers);
						DWORD dwNewPriority = (CeGetThreadPriority (GetCurrentThread ()) - 1);

						DEBUGCHK (dwNewPriority >= 0);
						SetEvent (pat->hevReset);
						CeSetThreadPriority (ghtActivityTimers, dwNewPriority);
						CeSetThreadPriority (ghtActivityTimers, dwOldPriority);
					}
				}
			}
		}
	}
	PMLOGMSG (ZONE_RESUME, (_T ("-%s\r\n"), pszFname));
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
// this thread handles activity timer events
DWORD WINAPI 
ActivityTimersThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus, dwNumEvents, dwWaitInterval;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
    BOOL fDone = FALSE;
    HANDLE hevDummy = NULL;
    INT iPriority;
    const DWORD cdwTimerBaseIndex = 2;

#ifndef SHIP_BUILD
    SETFNAME(_T("ActivityTimersThreadProc"));
#endif

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

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

    // initialize the list of activity timers
    if(ActivityTimerInitList() != ERROR_SUCCESS) {
        PMLOGMSG(ZONE_WARN, (_T("%s: ActivityTimerInitList() failed\r\n"), pszFname));
        goto done;
    }

    // create a dummy event that's never signaled
    hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);
    if(hevDummy == NULL) {
        PMLOGMSG(ZONE_WARN, (_T("%s: Couldn't create dummy event\r\n"), pszFname));
        goto done;
    }

    // set up the list of events
    dwNumEvents = 0;
    hEvents[dwNumEvents++] = ghevPmShutdown;
    hEvents[dwNumEvents++] = ghevTimerResume;
    PMLOCK();
    if(gppActivityTimers[0] == NULL) {
        // no activity timers defined
        PmFree(gppActivityTimers);
        gppActivityTimers = NULL;
    } else {
        // copy activity timer events into the event list
        while(dwNumEvents < dim(hEvents) && gppActivityTimers[dwNumEvents - cdwTimerBaseIndex] != NULL) {
            hEvents[dwNumEvents] = gppActivityTimers[dwNumEvents - cdwTimerBaseIndex]->hevReset;
            dwNumEvents++;
        }
    }
    PMUNLOCK();

    // we're up and running
    SetEvent(hevReady);

    // are there actually any timers to wait on?
    if(dwNumEvents <= cdwTimerBaseIndex) {
        // no timers defined, so we don't need this thread to wait on them.
        PMLOGMSG(ZONE_INIT || ZONE_WARN, (_T("%s: no activity timers defined, exiting\r\n"), pszFname));
        Sleep(1000);            // don't want PM initialization to fail when we exit
        goto done;
    }

    // wait for these events to get signaled
    PMLOGMSG(ZONE_TIMERS, (_T("%s: entering wait loop, %d timers total\r\n"),
        pszFname, dwNumEvents - cdwTimerBaseIndex));
    dwWaitInterval = 0;
    while(!fDone) {
        DWORD dwTimeout = GetNextInactivityTimeout(dwWaitInterval);
        DWORD dwWaitStart = GetTickCount();

        PMLOGMSG(ZONE_TIMERS, 
            (_T("%s: waiting %u (0x%08x) ms for next event, wait interval was %d\r\n"), pszFname,
            dwTimeout, dwTimeout, dwWaitInterval));
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, dwTimeout);
        dwWaitInterval = GetTickCount() - dwWaitStart;

        // figure out what caused the wakeup
        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 + 1)) {
            DWORD dwIndex;
            PACTIVITY_TIMER pat;

            // we've resumed, so re-enable all activity timers that can be reset
            PMLOGMSG(ZONE_TIMERS, (_T("%s: resume event set\r\n"), pszFname));
            PMLOCK();
            for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
                DWORD dwEventIndex = dwIndex + cdwTimerBaseIndex;
                if(hEvents[dwEventIndex] == hevDummy) {
                    hEvents[dwEventIndex] = pat->hevReset;
                }
                pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
            }
            PMUNLOCK();
        } else if(dwStatus == WAIT_TIMEOUT) {
            DWORD dwIndex;
            PACTIVITY_TIMER pat;

            // figure out which event(s) timed out
            PMLOCK();
            for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
                if(pat->dwTimeLeft <= dwWaitInterval  && pat->dwTimeLeft != INFINITE) {
                    // has the timer really expired?
                    if(WaitForSingleObject(pat->hevReset, 0) == WAIT_OBJECT_0) {
                        // The timer was reset while we weren't looking at it, so we'll look
                        // at it again later.  Calculate the new timeout, compensating for the update
                        // that will occur in GetNextInactivityTimeout().
                        PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset after timeout\r\n"), pszFname,
                            pat->pszName));
                        pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
                        pat->dwResetCount++;
                    } else {
                        // the timer has really expired, update events appropriately
                        PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' has expired\r\n"), pszFname,
                            pat->pszName));
                        ResetEvent(pat->hevActive);
                        SetEvent(pat->hevInactive);

                        // start looking at the reset event for this timer again
                        hEvents[dwIndex + cdwTimerBaseIndex] = pat->hevReset;

                        // update counts
                        pat->dwTimeLeft = INFINITE;
                        pat->dwExpiredCount++;
                    }
                }
            }
            PMUNLOCK();
        } else if(dwStatus > (WAIT_OBJECT_0 + 0) && dwStatus < (WAIT_OBJECT_0 + dwNumEvents)) {
            PACTIVITY_TIMER pat;
            DWORD dwEventIndex = dwStatus - WAIT_OBJECT_0;

            PMLOCK();
            
            // get a pointer to the timer
            pat = gppActivityTimers[dwEventIndex - cdwTimerBaseIndex];

            // handle its events
            DEBUGCHK(pat != NULL);
            if(pat->dwTimeout == 0) {
                // we're not using the event, so ignore it
                pat->dwTimeLeft = INFINITE;
            } else {
                PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset\r\n"), pszFname, pat->pszName));

                // set events appropriately
                ResetEvent(pat->hevInactive);
                SetEvent(pat->hevActive);

                // don't look at this event again until it's about ready to time out
                hEvents[dwEventIndex] = hevDummy;

                // update time left on the timer, compensating for the update
                // that will occur in GetNextInactivityTimeout().
                pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
            }
            pat->dwResetCount++;
            PMUNLOCK();
        } else {
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                pszFname, dwStatus, GetLastError())); 
            fDone = TRUE;
        }
    }

done:
    // release resources
    if(hevDummy != NULL) CloseHandle(hevDummy);
    PMLOCK();
    if(gppActivityTimers != NULL) {
        DWORD dwIndex = 0;
        while(gppActivityTimers[dwIndex] != NULL) {
            ActivityTimerDestroy(gppActivityTimers[dwIndex]);
            dwIndex++;
        }
        PmFree(gppActivityTimers);
        gppActivityTimers = NULL;
    }
    PMUNLOCK();

    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
Exemplo n.º 25
0
BOOL 
CSDHCBase::InitializeHardware(
                              )
{
    SETFNAME(_T("InitializeHardware"));

    DEBUGCHK(m_hBusAccess);
    DEBUGCHK(m_regDevice.IsOK());
    PREFAST_DEBUGCHK(m_pSlotInfos);
	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware\n")));
	ValidateSlotCount();

    BOOL fRet = FALSE;
    PHYSICAL_ADDRESS PortAddress;
    DWORD inIoSpace = 0;

    // Read window information
    DDKWINDOWINFO wini;
    wini.cbSize = sizeof(wini);
    DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini);
    if (dwStatus != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"),
            pszFname));
        goto EXIT;
    }

    // Read ISR information
    DDKISRINFO isri;
    isri.cbSize = sizeof(isri);
    dwStatus = DDKReg_GetIsrInfo(m_regDevice, &isri);
    if (dwStatus != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting ISR information\r\n"),
            pszFname));
        goto EXIT;
    }

#ifdef SET_TI_BOARD_PCI_REG
	{
		DDKPCIINFO dpi;
		dpi.cbSize = sizeof(dpi);
		DDKReg_GetPciInfo(m_regDevice, &dpi);

		DWORD RetVal;
		PCI_SLOT_NUMBER SlotNumber;
		SlotNumber.u.AsULONG = 0;
		SlotNumber.u.bits.DeviceNumber = dpi.dwDeviceNumber;
		SlotNumber.u.bits.FunctionNumber = 1;

		HalGetBusDataByOffset( PCIConfiguration,
							   wini.dwBusNumber,
							   SlotNumber.u.AsULONG,
							   &RetVal,
							   0x84,
							   sizeof( RetVal ) );

		if (!(RetVal & 0x00200000)) {
			RetVal |= 0x00200000;
			HalSetBusDataByOffset( PCIConfiguration,
								   wini.dwBusNumber,
								   SlotNumber.u.AsULONG,
								   &RetVal,
								   0x84,
								   sizeof( RetVal ) );
		}
	}
#endif

    // Sanity check ISR
    if (isri.dwSysintr == SYSINTR_NOP) {
		RETAILMSG(0,(TEXT("%s No sysintr specified in registry\r\n"),pszFname));
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s No sysintr specified in registry\r\n"),
            pszFname));
        goto EXIT;
    }

    if (isri.szIsrDll[0] != 0) {
        if ( (isri.szIsrHandler[0] == 0) || (isri.dwIrq == IRQ_UNSPECIFIED) ) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Invalid installable ISR information in registry\r\n"),
                pszFname));
            goto EXIT;
        }
    }

    m_interfaceType = (INTERFACE_TYPE) wini.dwInterfaceType;
    m_dwBusNumber = wini.dwBusNumber;

    DWORD dwSlotZeroWindow;
    dwSlotZeroWindow = DetermineFirstSlotWindow(&wini);

    DEBUGCHK(dwSlotZeroWindow < wini.dwNumMemWindows);
    DEBUGCHK( (dwSlotZeroWindow + m_cSlots) <= wini.dwNumMemWindows );

    // Use the slot zero window for the ISR
    PDEVICEWINDOW pWindowSlotZero = &wini.memWindows[dwSlotZeroWindow];
    PortAddress.LowPart = pWindowSlotZero->dwBase;
    PortAddress.HighPart = 0;

	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware go on...\n")));

    // Install an ISR, if present
    if (isri.szIsrDll[0] != 0) {
        m_hISRHandler = LoadIntChainHandler(isri.szIsrDll, isri.szIsrHandler, 
            (BYTE) isri.dwIrq);

        if (m_hISRHandler == NULL) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error installing ISR\r\n"), pszFname));
            goto EXIT;
        } 
        else {
            GIISR_INFO  Info;
            DWORD       dwPhysAddr;

            fRet = BusTransBusAddrToStatic(m_hBusAccess, 
                (INTERFACE_TYPE) wini.dwInterfaceType,
                wini.dwBusNumber, PortAddress, pWindowSlotZero->dwLen,
                &inIoSpace, (PVOID *) &dwPhysAddr);
            if (fRet == FALSE) {
                DEBUGMSG(SDCARD_ZONE_ERROR,
                    (_T("%s Error translating bus address to static address\r\n"), 
                    pszFname));
                goto EXIT;
            }

            // Initialize ISR
            Info.SysIntr = isri.dwSysintr;
            Info.CheckPort = TRUE;
            Info.PortIsIO = (inIoSpace != 0);
            Info.UseMaskReg = FALSE;
            Info.PortAddr = dwPhysAddr + SDHC_SLOT_INT_STATUS;
            Info.PortSize = sizeof(USHORT);
            Info.Mask = 0xFF;

            fRet = KernelLibIoControl(m_hISRHandler, IOCTL_GIISR_INFO, &Info, 
                sizeof(Info), NULL, 0, NULL);
            if (fRet == FALSE) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error setting up ISR\r\n"), pszFname));
                goto EXIT;
            }
        }
    }

    m_dwSysIntr = isri.dwSysintr;
    DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s IRQ 0x%X mapped to SYS_INTR 0x%X\r\n"), 
        pszFname, isri.dwIrq, m_dwSysIntr));

    const DWORD dwEndWindow = dwSlotZeroWindow + m_cSlots;

    for (DWORD dwWindow = dwSlotZeroWindow; dwWindow < dwEndWindow; ++dwWindow) {
        DEBUGCHK(dwWindow < wini.dwNumMemWindows);
        PDEVICEWINDOW pWindowSD = &wini.memWindows[dwWindow];

        DEBUGMSG(SDCARD_ZONE_INIT,
            (_T("%s Base address -> 0x%x; length -> 0x%x \r\n"),
            pszFname, pWindowSD->dwBase, pWindowSD->dwLen));

        PortAddress.LowPart = pWindowSD->dwBase;
        PortAddress.HighPart = 0;

        inIoSpace = 0;
        PVOID pvRegisters;
        DEBUGCHK(pWindowSlotZero->dwLen >= sizeof(SSDHC_REGISTERS));

	RETAILMSG(0,(TEXT("BusTransBusAddrToVirtual. 0x%X\n"),PortAddress));
        fRet = BusTransBusAddrToVirtual(m_hBusAccess, 
            (INTERFACE_TYPE) wini.dwInterfaceType,
            wini.dwBusNumber, PortAddress, pWindowSD->dwLen, &inIoSpace, 
            &pvRegisters);
        if (fRet == FALSE) {
				RETAILMSG(0,(TEXT("%s error translating SD address \r\n"),pszFname));
            DEBUGMSG(SDCARD_ZONE_ERROR,
                (_T("%s error translating SD address \r\n"),
                pszFname));
            goto EXIT;
        }

        DEBUGCHK(inIoSpace == 0); // Will not work for I/O mappings.

        DWORD dwSlot = dwWindow - dwSlotZeroWindow;
        DEBUGCHK(dwSlot < m_cSlots);
        m_pSlotInfos[dwSlot].pucRegisters = (volatile UCHAR*) pvRegisters;
        m_pSlotInfos[dwSlot].dwExtraInfo = pWindowSD->dwLen;
    }

    m_fHardwareInitialized = TRUE;
    fRet = TRUE;
	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware finished.\n")));
EXIT:
    return fRet;
}
Exemplo n.º 26
0
EXTERN_C DWORD WINAPI
PlatformSetSystemPowerState (LPCTSTR pszName, BOOL fForce, BOOL fInternal)
{
	DWORD dwStatus = ERROR_SUCCESS;
	PSYSTEM_POWER_STATE pNewSystemPowerState = NULL;
	PDEVICE_POWER_RESTRICTION pNewCeilingDx = NULL;
	BOOL fDoTransition = FALSE;
	INT iPreSuspendPriority = 0;
	static BOOL fFirstCall = TRUE;

	SETFNAME (_T ("PlatformSetSystemPowerState"));

	// Read system power state variables and construct new lists:

	if (gfFileSystemsAvailable)
		PmUpdateSystemPowerStatesIfChanged ();
	dwStatus = RegReadSystemPowerState (pszName, &pNewSystemPowerState, &pNewCeilingDx);

	// Did we get registry information about the new power state?

	if (dwStatus == ERROR_SUCCESS)
	{
		BOOL fSuspendSystem = FALSE;
		static BOOL fWantStartupScreen = FALSE;
		DWORD dwNewStateFlags = pNewSystemPowerState->dwFlags;

		// Assume we will update the system power state:
		fDoTransition = TRUE;

		// Are we going to suspend the system as a whole?
		if ((dwNewStateFlags &
			 (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL | POWER_STATE_RESET)) != 0)
		{
			fSuspendSystem = TRUE;
		}

		// A "critical" suspend might mean we have totally lost battery power and need
		// to suspend really quickly.  Depending on the platform, OEMs may be able
		// to bypass driver notification entirely and rely on xxx_PowerDown() notifications
		// to suspend gracefully.  Or they may be able to implement a critical suspend
		// kernel ioctl.  This sample implementation is very generic and simply sets the
		// POWER_FORCE flag, which is not used.

		if (dwNewStateFlags & (POWER_STATE_CRITICAL | POWER_STATE_OFF | POWER_STATE_RESET))
		{
			fForce = TRUE;
		}

		// If everything seems OK, do the set operation:

		if (fDoTransition)
		{
			POWER_BROADCAST_BUFFER pbb;
			PDEVICE_LIST pdl;
			BOOL fResumeSystem = FALSE;

			// Send out system power state change notifications:
			pbb.Message = PBT_TRANSITION;
			pbb.Flags = pNewSystemPowerState->dwFlags;
			pbb.Length = _tcslen (pNewSystemPowerState->pszName) + 1;	// Char count not byte count for now
			if (pbb.Length > MAX_PATH)
			{
				// Truncate the system power state name -- note, we actually have MAX_PATH + 1
				// characters available.
				pbb.Length = MAX_PATH;
			}
			_tcsncpy_s (pbb.SystemPowerState, _countof (pbb.SystemPowerState),
						pNewSystemPowerState->pszName, pbb.Length);
			pbb.Length *= sizeof (pbb.SystemPowerState[0]);	           // Convert to byte count
			GenerateNotifications ((PPOWER_BROADCAST) & pbb);

			// Is GWES ready?
			if (!gfGwesReady)
			{
				if (WaitForAPIReady (SH_GDI, 0) == WAIT_OBJECT_0)
				{
					gfGwesReady = TRUE;
				}
			}

			// Are we suspending?
			if (fSuspendSystem && gpfnGwesPowerDown != NULL)
			{
				// Start the process of suspending GWES:
				if (gfGwesReady)
				{
					fWantStartupScreen = gpfnGwesPowerDown ();
				}
			}

			// Update global system state variables:
			PMLOCK ();
			PSYSTEM_POWER_STATE pOldSystemPowerState = gpSystemPowerState;
			PDEVICE_POWER_RESTRICTION pOldCeilingDx = gpCeilingDx;

			if (gpSystemPowerState != NULL
				&& (gpSystemPowerState->
					dwFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) != 0)
			{
				// We are exiting a suspended state:
				fResumeSystem = TRUE;
			}
			gpSystemPowerState = pNewSystemPowerState;
			gpCeilingDx = pNewCeilingDx;
			PMUNLOCK ();

			// Are we suspending, resuming, or neither?
			if (fSuspendSystem)
			{
				INT iCurrentPriority;

				// We're suspending: update all devices other than block devices,
				// in case any of them need to access the registry or write files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying non-block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Notify the kernel that we are about to suspend.  This gives the
				// kernel an opportunity to clear wake source flags before we initiate
				// the suspend process.  If we don't do this and a wake source interrupt
				// occurs between the time we call PowerOffSystem() and the time
				// OEMPowerOff() is invoked, it is hard for the kernel to know whether or
				// not to suspend.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: calling KernelIoControl(IOCTL_HAL_PRESUSPEND)\r\n"), pszFname));
				KernelIoControl (IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL);
				iCurrentPriority = CeGetThreadPriority (GetCurrentThread ());
				DEBUGCHK (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN);
				if (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN)
				{
					CeSetThreadPriority (GetCurrentThread (), giPreSuspendPriority);
					Sleep (0);
					CeSetThreadPriority (GetCurrentThread (), iCurrentPriority);
				}

				// Notify file systems that their block drivers will soon go away.
				// After making this call, this thread is the only one that can access
				// the file system (including registry and device drivers) without
				// blocking.  Unfortunately, this API takes and holds the file system
				// critical section, so other threads attempting to access the registry
				// or files may cause priority inversions.  To avoid priority problem
				// that may starve the Power Manager, we may raise our own priority to a
				// high level.  Do this if giSuspendPriority is non-zero.

				if (giSuspendPriority != 0)
				{
					iPreSuspendPriority = CeGetThreadPriority (GetCurrentThread ());
					DEBUGCHK (iPreSuspendPriority != THREAD_PRIORITY_ERROR_RETURN);
					PMLOGMSG (ZONE_PLATFORM,
							  (_T
							   ("%s: suspending: raising thread priority for 0x%08x from %d to %d\r\n"),
							   pszFname, GetCurrentThreadId (), iPreSuspendPriority,
							   giSuspendPriority));
					CeSetThreadPriority (GetCurrentThread (), giSuspendPriority);
				}

                // Discard code pages from drivers.  This is a diagnostic tool to
                // forcibly expose paging-related bugs that could cause apparently
                // random system crashes or hangs.  Optionally, OEMs can disable this
                // for production systems to speed up resume times.  We have to call
                // PageOutMode before FileSys Shutdown. Otherwise, it cause dead lock
                // between filesystem and loader.

				if (gfPageOutAllModules)
				{
					ForcePageout ();
				}

				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->EnterLock ();
				gfFileSystemsAvailable = FALSE;

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Is this to be a cold boot?
					if (_tcscmp (pszName, _T ("coldreboot")) == 0)
					{
						SetCleanRebootFlag ();
					}
				}

				FileSystemPowerFunction (FSNOTIFY_POWER_OFF);

				// Update block device power states:
				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Handle resets and shutdowns here, after flushing files.  Since Windows CE does
				// not define a standard mechanism for handling shutdown (via POWER_STATE_OFF),
				// OEMs will need to fill in the appropriate code here.  Similarly, if an OEM does
				// not support IOCTL_HAL_REBOOT, they should not support POWER_STATE_RESET.

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Should not return from this call, but if we do just suspend the system:
					KernelLibIoControl ((HANDLE) KMOD_OAL, IOCTL_HAL_REBOOT, NULL, 0, NULL, 0,
										NULL);
					RETAILMSG (TRUE,
							   (_T
								("PM: PlatformSetSystemPowerState: KernelIoControl(IOCTL_HAL_REBOOT) returned!\r\n")));
					DEBUGCHK (FALSE);	// Break into the debugger.
				}
			}
			else if (fResumeSystem)
			{
				// We're waking up from a resume -- update block device power states
				// so we can access the registry and/or files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Notify file systems that their block drivers are back.

				FileSystemPowerFunction (FSNOTIFY_POWER_ON);
				gfFileSystemsAvailable = TRUE;
				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->LeaveLock ();

				// Update all devices other than block devices:

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Tell GWES to wake up:
				if (gpfnGwesPowerUp != NULL && gfGwesReady)
				{
					gpfnGwesPowerUp (fWantStartupScreen);
					fWantStartupScreen = FALSE;
				}

				// Send out resume notification:
				pbb.Message = PBT_RESUME;
				pbb.Flags = 0;
				pbb.Length = 0;
				pbb.SystemPowerState[0] = 0;
				GenerateNotifications ((PPOWER_BROADCAST) & pbb);
			}
			else
			{
				// Update all devices without any particular ordering:
				UpdateAllDeviceStates ();
			}

			// Release the old state information:
			SystemPowerStateDestroy (pOldSystemPowerState);
			while (pOldCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pOldCeilingDx->pNext;

				PowerRestrictionDestroy (pOldCeilingDx);
				pOldCeilingDx = pdpr;
			}

			// Are we suspending?
			if (fSuspendSystem)
			{
				// Set a flag to notify the resume thread that this was a controlled suspend.
				gfSystemSuspended = TRUE;

				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: calling PowerOffSystem()\r\n"), pszFname));
				PowerOffSystem ();	    // Sets a flag in the kernel for the scheduler.
				Sleep (0);	            // Force the scheduler to run.
				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: back from PowerOffSystem()\r\n"), pszFname));

				// Clear the suspend flag:
				gfSystemSuspended = FALSE;
			}
		}
		else
		{
			// Release the unused new state information:
			SystemPowerStateDestroy (pNewSystemPowerState);
			while (pNewCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pNewCeilingDx->pNext;

				PowerRestrictionDestroy (pNewCeilingDx);
				pNewCeilingDx = pdpr;
			}
		}
	}

	// Restore our priority if we updated it during a suspend transition:
	if (giSuspendPriority != 0 && iPreSuspendPriority != 0)
	{
		PMLOGMSG (ZONE_PLATFORM, (_T ("%s: restoring thread priority to %d\r\n"),
								  pszFname, iPreSuspendPriority));
		CeSetThreadPriority (GetCurrentThread (), iPreSuspendPriority);
	}

	return dwStatus;
}
Exemplo n.º 27
0
// Remapping function for the matrix keyboard
static
UINT
WINAPI
MatrixUsRemapVKey(
    const KEYBD_EVENT *pKbdEvents,
    UINT               cKbdEvents,
    KEYBD_EVENT       *pRmpKbdEvents,
    UINT               cMaxRmpKbdEvents
    )
{
    SETFNAME(_T("MatrixUsRemapVKey"));

    static BOOL fFnDown = FALSE;

    UINT cRmpKbdEvents = 0;
    UINT ui;

    if (pRmpKbdEvents == NULL)
    {
        // 1 to 1 mapping
        if (cMaxRmpKbdEvents != 0)
        {
            DEBUGMSG(ZONE_ERROR, (_T("%s: cMaxRmpKbdEvents error!\r\n"), pszFname));
        }
        return cKbdEvents;
    }

    if (pKbdEvents == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: pKbdEvents error!\r\n"), pszFname));
    }

    if (cMaxRmpKbdEvents < cKbdEvents)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Buffer is not large enough!\r\n"), pszFname));
        return 0;
    }

    for (ui = 0; ui < cKbdEvents; ++ui)
    {
        const KEYBD_EVENT *pKbdEventCurr = &pKbdEvents[ui];
        KEYBD_EVENT *pKbdEventRmpCurr = &pRmpKbdEvents[cRmpKbdEvents];

        // Copy the input key event to our remapped list
        pKbdEventRmpCurr->uiVk = pKbdEventCurr->uiVk;
        pKbdEventRmpCurr->uiSc = pKbdEventCurr->uiSc;
        pKbdEventRmpCurr->KeyStateFlags = pKbdEventCurr->KeyStateFlags;

        const VirtualKeyMapping *pvkMap = NULL;
        BOOL fKeyDown = (pKbdEventCurr->KeyStateFlags & KeyStateDownFlag) != 0;
        UINT32 uiVkCurr = pKbdEventCurr->uiVk;

        if (uiVkCurr == VK_MATRIX_FN)
        {
            fFnDown = fKeyDown;
            // Fn virtual key does not get sent to the system so
            // do not increment cRmpKbdEvents.
            DEBUGMSG(ZONE_DEVICELAYOUT, (_T("%s: Fn key is now %s\r\n"),
                pszFname, (fFnDown ? _T("DOWN") : _T("UP"))));
        }
        else
        {
            // We have one key event
            ++cRmpKbdEvents;

            if (fKeyDown)
            {
                // Handle key down
                if (fFnDown)
                {
                    // Fn key is on
                    if (IS_NUMLOCK_ON(pKbdEventCurr->KeyStateFlags))
                    {
                        pvkMap = FindRemappedKey(uiVkCurr, g_rgvkMapNumLock, dim(g_rgvkMapNumLock));
                    }

                    if (pvkMap == NULL)
                    {
                        // NumLock did not effect this key. See if the
                        // Fn key by itself does.                        
                        pvkMap = FindRemappedKey(uiVkCurr, g_rgvkMapFn, dim(g_rgvkMapFn));
                    }
                }
            }
            else
            {
                // Handle key up
                if (fFnDown)
                {
                    // Fn key is on
                    if (IS_NUMLOCK_ON(pKbdEventCurr->KeyStateFlags))
                    {
                        pvkMap = FindRemappedKey(uiVkCurr, g_rgvkMapNumLock, dim(g_rgvkMapNumLock));
                    }

                    if (pvkMap == NULL)
                    {
                        // NumLock did not effect this key. See if the
                        // Fn key by itself does.                        
                        pvkMap = FindRemappedKey(uiVkCurr, g_rgvkMapFn, dim(g_rgvkMapFn));
                    }
                }
            }

            if (pvkMap != NULL)
            {
                // This combination generates a different virtual key
                if (pvkMap->uiVkGenerated == NULL)
                {
                    DEBUGMSG(ZONE_ERROR, (_T("%s: pvkMap->uiVkGenerated error!\r\n"), pszFname));
                }
                pKbdEventRmpCurr->uiVk = pvkMap->uiVkGenerated;
            }
        }
    }

    return cRmpKbdEvents;    
}
Exemplo n.º 28
0
// This routine initializes the power manager and notifies the system that
// its api set is ready to be used.  It returns TRUE if successful and FALSE
// if there's a problem.
EXTERN_C BOOL WINAPI
PmInit(VOID)
{
    BOOL fOk = TRUE;
    HANDLE hevPnPReady = NULL, hevResumeReady = NULL, hevSystemReady = NULL;
    HANDLE hevActivityTimersReady = NULL, hevDummy = NULL;

#ifndef SHIP_BUILD
    SETFNAME(_T("PmInit"));
#endif

    PMLOGMSG(ZONE_INIT || ZONE_API, (_T("+%s\r\n"), pszFname));

    // set up globals
    InitializeCriticalSection(&gcsPowerManager);
    InitializeCriticalSection(&gcsDeviceUpdateAPIs);
    gpFloorDx = NULL;
    gpCeilingDx = NULL;
    gpPowerNotifications = NULL;
    gpSystemPowerState = NULL;
    ghPmHeap = GetProcessHeap();
    gpDeviceLists = NULL;
    gppActivityTimers = NULL;
    ghevPowerManagerReady = NULL;
    ghevResume = NULL;
    ghevTimerResume = NULL;
    ghtPnP = NULL;
    ghtResume = NULL;
    ghtActivityTimers = NULL;
    ghtSystem = NULL;

    // cleanup event (hopefully never used)
    ghevPmShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
    if(ghevPmShutdown == NULL) {
        PMLOGMSG(ZONE_ERROR, (_T("%s: CreateEvent() failed for shutdown event\r\n"), pszFname));
        fOk = FALSE;
    } 

    // validate the power management registry settings.  OEM code should use this
    // routine to make sure that registry settings are present for all the power
    // states they expect to support.  If the registry is not configured, the OEM
    // code can treat it as a fatal error or perform its own initialization.
    if(fOk) {
        DWORD dwStatus = PlatformValidatePMRegistry();
        if(dwStatus != ERROR_SUCCESS) {
            PMLOGMSG(ZONE_ERROR, (_T("%s: PlatformValidatePMRegistry() failed %d\r\n"), 
                pszFname, dwStatus));
            fOk = FALSE;
        } else {
            // read the list of interface types we will monitor
            fOk = DeviceListsInit();
        }
    }

    // create events
    if(fOk) {
        ghevPowerManagerReady = CreateEvent(NULL, TRUE, FALSE, _T("SYSTEM/PowerManagerReady"));
        ghevResume = CreateEvent(NULL, FALSE, FALSE, NULL);
        ghevTimerResume = CreateEvent(NULL, FALSE, FALSE, NULL);
        hevPnPReady = CreateEvent(NULL, FALSE, FALSE, NULL);
        hevResumeReady = CreateEvent(NULL, FALSE, FALSE, NULL);
        hevSystemReady = CreateEvent(NULL, FALSE, FALSE, NULL);
        hevActivityTimersReady = CreateEvent(NULL, FALSE, FALSE, NULL);
        hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);

        // check everything
        if(hevPnPReady == NULL
        || hevResumeReady == NULL 
        || hevSystemReady == NULL
        || hevActivityTimersReady == NULL
        || hevDummy == NULL
        || ghevPowerManagerReady == NULL
        || ghevTimerResume == NULL
        || ghevResume == NULL) {
            PMLOGMSG(ZONE_ERROR, (_T("%s: event creation failure\r\n"), pszFname));
            fOk = FALSE;
        }
    }

    // start threads
    if(fOk) {
        ghtPnP = CreateThread(NULL, 0, PnpThreadProc, (LPVOID) hevPnPReady, 0, NULL);
        ghtResume = CreateThread(NULL, 0, ResumeThreadProc, (LPVOID) hevResumeReady, 0, NULL);
        ghtActivityTimers = CreateThread(NULL, 0, ActivityTimersThreadProc, 
            (LPVOID) hevActivityTimersReady, 0, NULL);
        
        // check everything
        if(ghtPnP == NULL 
        || ghtResume == NULL 
        || ghtActivityTimers == NULL) {
            PMLOGMSG(ZONE_ERROR, (_T("%s: thread creation failure\r\n"), pszFname));
            fOk = FALSE;
        }
    }

    // wait for threads to initialize (or fail to initialize)
    #define NUM_OF_READY_EXIT_PAIR 3
    HANDLE hEvents[] = { hevPnPReady, hevResumeReady, hevActivityTimersReady, 
        ghtPnP, ghtResume, ghtActivityTimers };
    int iReady = 0;
    while( iReady < NUM_OF_READY_EXIT_PAIR  && fOk) {
        DWORD dwStatus = WaitForMultipleObjects(dim(hEvents), hEvents, FALSE, INFINITE);
        switch(dwStatus) {
        // thread ready events
        case (WAIT_OBJECT_0 + 0):   // pnp ready
        case (WAIT_OBJECT_0 + 1):   // resume ready
        case (WAIT_OBJECT_0 + 2):   // activity timers ready
            // don't watch for the thread exiting now -- some may do
            // so if they don't have work to do.
            hEvents[dwStatus - WAIT_OBJECT_0 + NUM_OF_READY_EXIT_PAIR] = hevDummy;
            iReady++;
            break;

        // thread exiting events
        case (WAIT_OBJECT_0 + 3):   // pnp exited
        case (WAIT_OBJECT_0 + 4):   // resume exited
        case (WAIT_OBJECT_0 + 5):   // activity timers exited
            PMLOGMSG(ZONE_ERROR, (_T("%s: thread initialization failure\r\n"), pszFname));
            fOk = FALSE;
            break;
        default:
            PMLOGMSG(ZONE_ERROR, (_T("%s: WaitForMultipleObjects() returnd %d, status is %d\r\n"),
                pszFname, GetLastError()));
            fOk = FALSE;
            break;
        }
    }

    // load PMExt DLL, call init
    if (fOk) {
        TCHAR DevDll[DEVDLL_LEN];
        DWORD cbData;
        DWORD Flags;
        HKEY hKey;

        gpPMExtInit = NULL;
        gpPMExtDeinit = NULL;;

        // Note: TEXT("\\Omap") is appended to the PMExt_Registry_Root because this is the only PMExt that we support
        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, PMExt_Registry_Root TEXT("\\Omap"), 0, 0, &hKey)) {
            cbData = sizeof(DevDll);
            if (ERROR_SUCCESS == RegQueryValueEx(hKey, DEVLOAD_DLLNAME_VALNAME, NULL, NULL, (LPBYTE) DevDll, &cbData)) {
                cbData = sizeof(Flags);
                if (ERROR_SUCCESS != RegQueryValueEx(hKey, DEVLOAD_FLAGS_VALNAME, NULL, NULL, (LPBYTE) &Flags, &cbData)) {
                    Flags = DEVFLAGS_NONE;
                }
                ghPMExtLib = (Flags & DEVFLAGS_LOADLIBRARY) ? LoadLibrary(DevDll) : LoadDriver(DevDll);
                if (!ghPMExtLib) {
                    PMLOGMSG(ZONE_ERROR, (_T("%s: couldn't load PMExt \"%s\" -- error %d\r\n"), pszFname, DevDll, GetLastError()));
                } 
                else {
                    gpPMExtInit = (PFN_PMExt_Init) GetProcAddress(ghPMExtLib, PMExt_Init_NAME);
                    if (!gpPMExtInit)
                        PMLOGMSG(ZONE_ERROR, (_T("%s: \"%s\" can't GetProcAddress\r\n"), pszFname, PMExt_Init_NAME));

                    gpPMExtDeinit = (PFN_PMExt_DeInit) GetProcAddress(ghPMExtLib, PMExt_DeInit_NAME);
                }
            }
            else {
                PMLOGMSG(ZONE_INIT, (_T("%s: can't get value \"%s\" in key \"%s\"\r\n"), pszFname, DEVLOAD_DLLNAME_VALNAME, PMExt_Registry_Root TEXT("\\Omap")));
            }
            if (gpPMExtInit && gpPMExtDeinit) {
#ifdef DEBUG
               gdwPMExtContext = gpPMExtInit(HKEY_LOCAL_MACHINE, PMExt_Registry_Root TEXT("\\Omap"));
#else
                __try {
                    gdwPMExtContext = gpPMExtInit(HKEY_LOCAL_MACHINE, PMExt_Registry_Root TEXT("\\Omap"));
                }
                __except(EXCEPTION_EXECUTE_HANDLER) {
                    gdwPMExtContext = 0;
                }
#endif
                if (!gdwPMExtContext)
                    PMLOGMSG(ZONE_ERROR, (_T("%s: \"%s\" failed\r\n"), pszFname, PMExt_Init_NAME));
                else
                    PMLOGMSG(ZONE_INIT, (_T("%s: \"%s\" success\r\n"), pszFname, PMExt_Init_NAME));
            }
            RegCloseKey(hKey);
        }
Exemplo n.º 29
0
/********************************************************************************
//ACLineStatus -- 0 Offline  1 Online  255 Unknown status 
//
//
//*******************************************************************************/
BOOL WINAPI
BatteryPDDGetStatus(
    PSYSTEM_POWER_STATUS_EX2 pstatus,  PBOOL pfBatteriesChangedSinceLastCall)
{
    BOOL fOk = TRUE;
    SYSTEM_POWER_STATUS_EX2 sps;
    BOOL ACStatus=FALSE;
    UCHAR ucBatteryPer = 0;
    UINT32 BATTERY_AUTOSLEEP_VOLTAGE_PERCENT ;
    UINT32 PERCENT_CRITICAL2LOW;

    BATTERY_AUTOSLEEP_VOLTAGE_PERCENT= 	( (g_stBattParam.u32AutoSleepVbat - BATTERY_MIN_VOLTAGE)* 100/(BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE)+1) ;
    PERCENT_CRITICAL2LOW	= BATTERY_AUTOSLEEP_VOLTAGE_PERCENT + 4;

    DPNOK(BATTERY_AUTOSLEEP_VOLTAGE_PERCENT);	
    DPNOK(PERCENT_CRITICAL2LOW);	
   
    SETFNAME(_T("BatteryPDDGetStatus"));

    RETAILMSG(ZONE_REG_PRINT, (TEXT("+BatteryPDDGetStatus...  \r\n")));
  
    DEBUGCHK(pstatus != NULL);
    DEBUGCHK(pfBatteriesChangedSinceLastCall != NULL);

    /* Fill 	ACLineStatus part */
    sps.ACLineStatus          = AC_LINE_UNKNOWN;	
    if(BspGetACStatus())
    {
        sps.ACLineStatus          = AC_LINE_ONLINE;
    }
    else
    {
        sps.ACLineStatus          = AC_LINE_OFFLINE;
    }

    /* Fill Battery status part */
    battery_status = BspGetBatteryFlag();

    if (PDD_NO_BATTERY == battery_status )
    {
        BspNotifyLed(FALSE);
        sps.BatteryFlag  = BATTERY_FLAG_NO_BATTERY;
        sps.BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
    }
    else if (PDD_BATTERY_CHARGING == battery_status )
    {
        RETAILMSG(ZONE_REG_PRINT, (TEXT("+Battery status PDD_BATTERY_CHARGING...  \r\n"))); 
        BspFuelGaugeResetBatStatusInPercent();	   
        BspNotifyLed(FALSE);
        sps.BatteryFlag  = BATTERY_FLAG_CHARGING;
        sps.BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
//  //[david.modify] 2008-05-31 14:49
// ڴ˴óʱҲʾٷֱ
//=======================================================
	   if(CHARGING_BIT&g_stBattParam.u32Debug) {
          ucBatteryPer = BspFuelGaugeGetBatStatusInPercent();

            if(ucBatteryPer >= PERCENT_CRITICAL2LOW)
            {
                sps.BatteryFlag  = BATTERY_FLAG_HIGH;
  	         BspNotifyLed(FALSE);
            }		 
            else if (( ucBatteryPer <PERCENT_CRITICAL2LOW) && (ucBatteryPer >=BATTERY_AUTOSLEEP_VOLTAGE_PERCENT))
            {
                 sps.BatteryFlag  = BATTERY_FLAG_LOW;
		   BspNotifyLed(TRUE);		 
            }		
            else if(ucBatteryPer<=BATTERY_AUTOSLEEP_VOLTAGE_PERCENT)
            {
                 sps.BatteryFlag  = BATTERY_FLAG_CRITICAL;
		   BspNotifyLed(TRUE);	
            }
            sps.BatteryLifePercent = 	ucBatteryPer;
	   }
//=======================================================		

		
    }
    else	
    {
        if(PDD_BATTERY_EOC == battery_status)
        {
            RETAILMSG(0, (TEXT("+Battery status PDD_BATTERY_EOC...  \r\n"))); 
            BspFuelGaugeResetBatStatusInPercent();	   
            BspNotifyLed(FALSE);
            sps.BatteryFlag  = BATTERY_FLAG_HIGH;
            sps.BatteryLifePercent =  100;
        } //end if PDD_BATTERY_EOC == battery_status
        else 
        {
            RETAILMSG(0, (TEXT("+Get Battery status PDD_BATTERY_ON...  \r\n"))); 
            ucBatteryPer = BspFuelGaugeGetBatStatusInPercent();

            if(ucBatteryPer >= PERCENT_CRITICAL2LOW)
            {
            ///// //Awisc.Chen add 2008-07-14 18:36 start
            #if 0//awisc add for test
            	  DPSTR("ucBatteryPer >= 20");
                 sps.BatteryFlag  = BATTERY_FLAG_CRITICAL;
		   BspNotifyLed(TRUE);	
		    //[david.modify] 2008-05-31 14:39
		   if(g_stBattParam.u32LowPowerSleep) {
		   	BspBattCriticalLow();}
		#endif
		///// //Awisc.Chen add 2008-07-14 18:35 end
                sps.BatteryFlag  = BATTERY_FLAG_HIGH; //Awisc.Chen delete 2008-07-14 18:36
  	         BspNotifyLed(FALSE); //Awisc.Chen delete 2008-07-14 18:36
            }		 
            else if (( ucBatteryPer <PERCENT_CRITICAL2LOW) && (ucBatteryPer >=BATTERY_AUTOSLEEP_VOLTAGE_PERCENT))
            {
                 sps.BatteryFlag  = BATTERY_FLAG_LOW;
		   BspNotifyLed(TRUE);		 
            }		
            else if(ucBatteryPer<=BATTERY_AUTOSLEEP_VOLTAGE_PERCENT) 
            {
            	  DPSTR("BATTERY_FLAG_CRITICAL");
                 sps.BatteryFlag  = BATTERY_FLAG_CRITICAL;
		   BspNotifyLed(TRUE);	
		    //[david.modify] 2008-05-31 14:39
		   if(g_stBattParam.u32LowPowerSleep) {
		   	BspBattCriticalLow();
		   }
            }
            sps.BatteryLifePercent = 	ucBatteryPer;
        }	//end else PDD_BATTERY_ONLY 	
    }//end else  PDD_BATTERY_CHARGING == battery_status

    sps.Reserved1                  = 0;
    sps.BatteryLifeTime            = BATTERY_LIFE_UNKNOWN;
    sps.BatteryFullLifeTime        = BATTERY_LIFE_UNKNOWN;
	
    sps.Reserved2                  = 0;
    sps.BackupBatteryFlag          = BATTERY_FLAG_UNKNOWN;
    sps.BackupBatteryLifePercent   = 0;
    sps.Reserved3                  = 0;
    sps.BackupBatteryLifeTime      = BATTERY_LIFE_UNKNOWN;
    sps.BackupBatteryFullLifeTime  = BATTERY_LIFE_UNKNOWN;
	
    sps.BatteryChemistry           = BATTERY_CHEMISTRY_LIPOLY;
//  sps.BatteryVoltage             = (unsigned long) (voltage_percent * 4.1); ;
    sps.BatteryCurrent             = 0;
    sps.BatteryAverageCurrent      = 0;
    sps.BatteryAverageInterval     = 0;
    sps.BatterymAHourConsumed      = 0;
    sps.BatteryTemperature         = 0;//temperature;
    sps.BackupBatteryVoltage       = 0;

    memcpy(&gpStatus->sps, &sps, sizeof(gpStatus->sps));
    
    // get battery status information from the shared structure
    LockBattery();
    memcpy(pstatus, &gpStatus->sps, sizeof(*pstatus));
    *pfBatteriesChangedSinceLastCall = gpStatus->fChanged;
    if(*pfBatteriesChangedSinceLastCall) {
        gpStatus->fChanged = FALSE;		// reset changed flag if it's set
    }
    UnlockBattery();
    
    DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), TEXT(__FUNCTION__), fOk));
    return (fOk);
}
Exemplo n.º 30
0
// This routine reads the registry to determine what type of device interfaces
// we will be monitoring.  The default PM GUID is ignored if present in the
// registry and is always added last (so it's first in the list).
BOOL
DeviceListsInit(VOID)
{
    BOOL fOk = TRUE;
    PDEVICE_LIST pdl;
    DWORD dwStatus;
    HKEY hk;
    TCHAR szBuf[MAX_PATH];

#ifndef SHIP_BUILD
    SETFNAME(_T("DeviceListsInit"));
#endif 

    // enumerate all the device classes
    StringCchPrintf(szBuf,_countof(szBuf), _T("%s\\Interfaces"), PWRMGR_REG_KEY);
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuf, 0, 0, &hk);
    if(dwStatus == ERROR_SUCCESS) {
        DWORD dwIndex = 0;
        do {
            DWORD cbValueName = dim(szBuf), dwType;
            GUID idInterface;

            dwStatus = RegEnumValue(hk, dwIndex, szBuf, &cbValueName, NULL,
                &dwType, NULL, NULL);
            if(dwStatus == ERROR_SUCCESS) {
                if(dwType != REG_SZ) {
                    PMLOGMSG(ZONE_WARN, (_T("%s: invalid type for value '%s'\r\n"),
                        pszFname, szBuf));
                } else if(!ConvertStringToGuid(szBuf, &idInterface)) {
                    PMLOGMSG(ZONE_WARN, (_T("%s: can't convert '%s' to GUID\r\n"),
                        pszFname, szBuf));
                } else if(idInterface == idGenericPMDeviceClass) {
                    PMLOGMSG(ZONE_INIT, (_T("%s: default GUID found in registry as expected\r\n"), 
                        pszFname));
                } else if((pdl = DeviceListCreate(&idInterface)) == NULL) {
                    PMLOGMSG(ZONE_WARN, (_T("%s: DeviceListCreate() failed\r\n"), 
                        pszFname));
                } else if(PlatformDeviceListInit(pdl) == FALSE) {
                    PMLOGMSG(ZONE_WARN, (_T("%s: PlatformDeviceListInit() failed\r\n"), 
                        pszFname));
                    DeviceListDestroy(pdl);
                } else {
                    // add the new entry to the list
                    pdl->pNext = gpDeviceLists;
                    gpDeviceLists = pdl;
                }

                // update the index
                dwIndex++;
            }
        } while(dwStatus == ERROR_SUCCESS);

        // check for abnormal termination of the loop
        if(dwStatus != ERROR_NO_MORE_ITEMS) {
            fOk = FALSE;
        }

        // close the registry handle
        RegCloseKey(hk);
    }

    // add the default list last
    if(fOk) {
        fOk = FALSE;
        pdl = DeviceListCreate(&idGenericPMDeviceClass);
        if(pdl != NULL) {
            if(PlatformDeviceListInit(pdl) == FALSE) {
                PMLOGMSG(ZONE_INIT || ZONE_WARN, 
                    (_T("%s: PlatformDeviceListInit() failed for default class\r\n"),
                    pszFname));
                DeviceListDestroy(pdl);
            } else {
                pdl->pNext = gpDeviceLists;
                gpDeviceLists = pdl;
                fOk = TRUE;
            }
        }
    }

    // clean up if necessary
    if(!fOk) {
        PMLOGMSG(ZONE_WARN, (_T("%s: error during list initialization\r\n"), 
            pszFname));
        while(gpDeviceLists != NULL) {
            pdl = gpDeviceLists;
            gpDeviceLists = pdl->pNext;
            pdl->pNext = NULL;
            DeviceListDestroy(pdl);
        }
    }

    return fOk;
}