📄 setstubbat.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <stdio.h>
#include <windows.h>
#include <stubbattery.h>
#include <tchar.h>
#define MUTEX_TIMEOUT 5000
#define dim(x) (sizeof(x) / sizeof(x[0]))
#define CMDENTRY(name, structure, member) \
{ name, L#member, &##structure##.##member, sizeof(structure##.##member) }
HANDLE g_hBatteryFileMutex = NULL;
HANDLE g_hFileMap = NULL;
LPVOID g_lpMemBlock = NULL;
BOOL
OpenMemSegment(void)
{
ASSERT(g_hFileMap == NULL);
ASSERT(g_lpMemBlock == NULL);
g_hFileMap = CreateFileMapping((HANDLE)INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
sizeof(BATTERY_STATUS), BATTERY_STATUS_FILE);
if(g_hFileMap == NULL) {
RETAILMSG(1,(TEXT("Could not create file mapping for battery info file\r\n")));
return FALSE;
}
else if(ERROR_ALREADY_EXISTS != GetLastError()){
RETAILMSG(1,(TEXT("Battery driver not exporting memory mapped file\r\n")));
CloseHandle(g_hFileMap);
return FALSE;
}
g_lpMemBlock = MapViewOfFile(g_hFileMap, FILE_MAP_ALL_ACCESS,0, 0,sizeof(BATTERY_STATUS));
if(NULL == g_lpMemBlock){
RETAILMSG(1,(_T("Can't map view of memory mapped file\r\n")));
CloseHandle(g_hFileMap);
g_hFileMap = NULL;
return FALSE;
}
return TRUE;
}
void
CloseSegment(void)
{
if(g_lpMemBlock) {
UnmapViewOfFile(g_lpMemBlock);
g_lpMemBlock = NULL;
}
if(g_hFileMap){
CloseHandle(g_hFileMap);
g_hFileMap=NULL;
}
}
DWORD
AcqMutex(void)
{
ASSERT(g_hBatteryFileMutex != NULL);
DWORD dwWaitResult = WaitForSingleObject(g_hBatteryFileMutex,MUTEX_TIMEOUT);
if(WAIT_OBJECT_0!=dwWaitResult) {
RETAILMSG(1,(TEXT("Wait for single object did not return WAIT_OBJECT_0 returned %d, Get last error returns %d\n"),
dwWaitResult, GetLastError()));
}
return dwWaitResult;
}
DWORD
RelMutex(void)
{
DWORD retval=-1;
ASSERT(g_hBatteryFileMutex!=NULL);
retval=ReleaseMutex(g_hBatteryFileMutex);
if(!retval){
retval=GetLastError();
RETAILMSG(1,(TEXT("Release Mutex failed with error %d. \n"),retval));
}
return retval;
}
BOOL
SetBatStatus(PBATTERY_STATUS pstatus)
{
DWORD dwWaitResults=-1;
ASSERT(pstatus);
dwWaitResults=AcqMutex();
if (WAIT_OBJECT_0 != dwWaitResults)
{
RETAILMSG(1,(TEXT("Timeout on acquiring mutex for battery info file, battery state not updated\n")));
return FALSE;
}
else
{
memcpy( g_lpMemBlock, (VOID*)pstatus,sizeof(BATTERY_STATUS));
dwWaitResults=RelMutex();
}
return TRUE;
}
BOOL
GetBatStatus(PBATTERY_STATUS pstatus)
{
DWORD dwWaitResults=-1;
ASSERT(pstatus);
dwWaitResults=AcqMutex();
if (WAIT_OBJECT_0 != dwWaitResults)
{
RETAILMSG(1,(TEXT("Timeout on acquiring mutex for battery info file, battery state not updated\n")));
return FALSE;
}
else
{
memcpy( pstatus,(PBATTERY_STATUS)g_lpMemBlock,sizeof(BATTERY_STATUS));
dwWaitResults=RelMutex();
}
return TRUE;
}
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
BATTERY_STATUS bstat;
int nOptions = 0;
struct {
LPCTSTR pszName;
LPCTSTR pszComment;
LPVOID pAddr;
DWORD dwSize;
} statcmd[] = {
CMDENTRY(_T("ls"), bstat.sps, ACLineStatus),
CMDENTRY(_T("bf"), bstat.sps, BatteryFlag),
CMDENTRY(_T("blp"), bstat.sps, BatteryLifePercent),
CMDENTRY(_T("blt"), bstat.sps, BatteryLifeTime),
CMDENTRY(_T("bflt"), bstat.sps, BatteryFullLifeTime),
CMDENTRY(_T("bbf"), bstat.sps, BackupBatteryFlag),
CMDENTRY(_T("bblp"), bstat.sps, BackupBatteryLifePercent),
CMDENTRY(_T("bblt"), bstat.sps, BackupBatteryLifeTime),
CMDENTRY(_T("bbflt"), bstat.sps, BackupBatteryFullLifeTime),
CMDENTRY(_T("bc"), bstat.sps, BatteryChemistry),
CMDENTRY(_T("bv"), bstat.sps, BatteryVoltage),
CMDENTRY(_T("bma"), bstat.sps, BatteryCurrent),
CMDENTRY(_T("bac"), bstat.sps, BatteryAverageCurrent),
CMDENTRY(_T("mai"), bstat.sps, BatteryAverageInterval),
CMDENTRY(_T("bmahc"), bstat.sps, BatterymAHourConsumed),
CMDENTRY(_T("bt"), bstat.sps, BatteryTemperature),
CMDENTRY(_T("bbv"), bstat.sps, BackupBatteryVoltage),
CMDENTRY(_T("c"), bstat, fChanged),
CMDENTRY(_T("sc"), bstat, fSupportsChange),
CMDENTRY(_T("bl"), bstat, wBackupLevels),
CMDENTRY(_T("ml"), bstat, wMainLevels),
};
// set up to access memory-mapped file
g_hBatteryFileMutex = CreateMutex(NULL, FALSE, BATTERY_FILE_MUTEX);
if (NULL == g_hBatteryFileMutex){
RETAILMSG(1,(TEXT("Could not aquire battery info file mutex handle\n")));
goto cleanup;
}
// access memory-mapped file
if(OpenMemSegment()){
// obtain the current battery status for update
if(!GetBatStatus(&bstat)){
RETAILMSG(TRUE, (_T("Can't access memory-mapped file\r\n")));
} else {
// parse the command line and update our local structure copy
BOOL fOk = TRUE;
LPTSTR pszSeparators = _T(" \t\n\r");
LPTSTR pszCmd = lpCmdLine;
LPTSTR pszToken;
while(fOk && (pszToken = _tcstok(pszCmd, pszSeparators)) != NULL) {
// use cached command line
pszCmd = NULL;
// match parameter
if(pszToken[0] != _T('-') && pszToken[0] != _T('/')) {
RETAILMSG(TRUE, (_T("Invalid parameter '%s'\r\n"), pszToken));
fOk = FALSE;
} else {
// look for the parameter
for(int i = 0; i < dim(statcmd); i++) {
if(_tcsicmp(pszToken + 1, statcmd[i].pszName) == 0) {
// found it, now get the value
LPTSTR pszParameter = pszToken;
pszToken = _tcstok(pszCmd, pszSeparators);
if(pszToken != NULL) {
LPTSTR pszEnd;
DWORD dwValue = _tcstol(pszToken, &pszEnd, 0);
if(*pszEnd != 0) {
RETAILMSG(TRUE, (_T("'%s' value '%s' improperly formatted\r\n"),
pszParameter, pszToken));
} else {
nOptions++;
switch(statcmd[i].dwSize) {
case 1:
*((LPBYTE) statcmd[i].pAddr) = (BYTE) dwValue & 0xFF;
break;
case 2:
*((LPWORD) statcmd[i].pAddr) = (WORD) dwValue & 0xFFFF;
break;
case 4:
*((LPDWORD) statcmd[i].pAddr) = dwValue;
break;
default:
// bad size
ASSERT(FALSE);
break;
}
}
} else {
RETAILMSG(TRUE, (_T("Missing parameter for '%s'\r\n"), pszParameter));
}
break;
}
}
if(i == dim(statcmd)) {
RETAILMSG(TRUE, (_T("Unknown parameter '%s'\r\n"), pszToken));
fOk = FALSE;
}
}
}
// did the user specify any parameters?
if(nOptions == 0) {
RETAILMSG(TRUE, (_T("No parameters specified\r\n")));
fOk = FALSE;
}
// update the shared structure?
if(fOk) {
SetBatStatus(&bstat);
} else {
RETAILMSG(TRUE, (_T("Usage: setstubbat param value [param value ...]\r\n")));
RETAILMSG(TRUE, (_T(" Parameters include:\r\n")));
for(int i = 0; i < dim(statcmd); i++) {
RETAILMSG(TRUE, (_T(" /%-8s -- sets %s\r\n"), statcmd[i].pszName, statcmd[i].pszComment));
}
RETAILMSG(TRUE, (_T(" Values are numbers, specified as with strtol().\r\n")));
}
}
CloseSegment();
}
cleanup:
if(g_hBatteryFileMutex) CloseHandle(g_hBatteryFileMutex);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -