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; }
// 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; }
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; }
// 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; }
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; }
// 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; }
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; }
// 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; }
// 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; }
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; }
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; }
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; }
// 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; }
// 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; }
// 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; }
// 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; }
// 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; }
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; }
// 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; }
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; }
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)); }
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)); }
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; }
// 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; }
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; }
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; }
// 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; }
// 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); }
/******************************************************************************** //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); }
// 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; }