mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
607 lines
21 KiB
607 lines
21 KiB
/*
|
|
* title: HidBattIOCT.cpp
|
|
*
|
|
* purpose: Contains misc ioctl handlers for status and query info mainly
|
|
*
|
|
* Initial checkin for the hid to battery class driver. This should be
|
|
* the same for both Win 98 and NT 5. Alpha level source. Requires
|
|
* modified composite battery driver and modified battery class driver for
|
|
* Windows 98 support
|
|
*
|
|
*/
|
|
|
|
|
|
#include "hidbatt.h"
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
IOCTL handler. As this is an exclusive battery device, send the
|
|
Irp to the battery class driver to handle battery IOCTLs.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Battery for request
|
|
Irp - IO request
|
|
|
|
Return Value:
|
|
|
|
Status of request
|
|
|
|
--*/
|
|
NTSTATUS
|
|
HidBattIoControl(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;
|
|
CBatteryDevExt * pDevExt;
|
|
PIO_STACK_LOCATION irpSp;
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
|
|
irpSp = IoGetCurrentIrpStackLocation(pIrp);
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattIoctl = %x\n", irpSp->Parameters.DeviceIoControl.IoControlCode));
|
|
|
|
// PrintIoctl(irpSp->Parameters.DeviceIoControl.IoControlCode);
|
|
|
|
pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
|
|
|
|
if (NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)))
|
|
{
|
|
if (pDevExt->m_pBattery &&
|
|
pDevExt->m_pBattery->m_pBatteryClass) {
|
|
ntStatus = BatteryClassIoctl (pDevExt->m_pBattery->m_pBatteryClass, pIrp);
|
|
}
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
} else {
|
|
ntStatus = STATUS_DEVICE_REMOVED;
|
|
pIrp->IoStatus.Status = ntStatus;
|
|
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
|
|
}
|
|
|
|
if (ntStatus == STATUS_NOT_SUPPORTED)
|
|
{
|
|
HidBattCallLowerDriver(ntStatus, pDevExt->m_pLowerDeviceObject, pIrp);
|
|
}
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
VOID
|
|
HidBattNotifyHandler (
|
|
IN PVOID pContext,
|
|
IN CUsage * pUsage
|
|
)
|
|
{
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
NTSTATUS ntStatus;
|
|
ULONG ulCapacityLimit = BATTERY_UNKNOWN_CAPACITY;
|
|
BOOL bResult;
|
|
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattNotifyHandler\n"));
|
|
// called by input routine whenever a value change is noted to
|
|
// a notificable usage
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) pContext;
|
|
|
|
HidBattPrint (HIDBATT_DATA, ("HidBattNotifyHandler: Usage: %x\n", pUsage->m_pProperties->m_Usage));
|
|
switch (pUsage->m_pProperties->m_Usage)
|
|
{
|
|
case REMAINING_CAPACITY_ID:
|
|
|
|
bResult = pDevExt->m_pBattery->GetSetValue(REMAINING_CAPACITY_LIMIT_INDEX,&ulCapacityLimit,FALSE);
|
|
// Only send notification when capacity drops below notify level.
|
|
if ((bResult) && (ulCapacityLimit != BATTERY_UNKNOWN_CAPACITY) && (pUsage->m_Value != BATTERY_UNKNOWN_CAPACITY)
|
|
&& (pUsage->m_Value > ulCapacityLimit)) {
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattNotifyHandler:Suppressing notify\n"));
|
|
break;
|
|
}
|
|
|
|
case AC_PRESENT_ID: // check for battery off/on line
|
|
case DISCHARGING_ID:
|
|
case CHARGING_ID:
|
|
case BELOW_REMAINING_CAPACITY_ID:
|
|
case SHUTDOWN_IMMINENT_ID:
|
|
{
|
|
pDevExt->m_pBattery->m_bIsCacheValid=FALSE;
|
|
|
|
if (NT_SUCCESS (IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag))) {
|
|
ntStatus = BatteryClassStatusNotify(
|
|
pDevExt->m_pBattery->m_pBatteryClass);
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
}
|
|
break;
|
|
}
|
|
default: // nothing to notify
|
|
break;
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
NTSTATUS
|
|
HidBattQueryTag (
|
|
IN PVOID pContext,
|
|
OUT PULONG pulBatteryTag
|
|
)
|
|
{
|
|
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) pContext;
|
|
|
|
if (!NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)) )
|
|
{
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
*pulBatteryTag = pDevExt->m_pBattery->m_Tag;
|
|
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
HidBattSetStatusNotify (
|
|
IN PVOID pContext,
|
|
IN ULONG BatteryTag,
|
|
IN PBATTERY_NOTIFY pBatteryNotify
|
|
)
|
|
{
|
|
bool bResult;
|
|
ULONG CentiAmpSec;
|
|
ULONG ulValue;
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattSetStatusNotify \n"));
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) pContext;
|
|
CBattery * pBattery = pDevExt->m_pBattery;
|
|
|
|
|
|
HidBattPrint (HIDBATT_DEBUG, ("HidBattSetStatusNotify->PowerState = %x\n", pBatteryNotify->PowerState));
|
|
HidBattPrint (HIDBATT_DEBUG, ("HidBattSetStatusNotify->LowCapacity = %x\n", pBatteryNotify->LowCapacity));
|
|
HidBattPrint (HIDBATT_DEBUG, ("HidBattSetStatusNotify->HighCapacity = %x\n", pBatteryNotify->HighCapacity));
|
|
|
|
if (!NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)))
|
|
{
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
if (pBattery->m_Tag != BatteryTag) {
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
if ((pBatteryNotify->HighCapacity == BATTERY_UNKNOWN_CAPACITY) ||
|
|
(pBatteryNotify->LowCapacity == BATTERY_UNKNOWN_CAPACITY)) {
|
|
HidBattPrint (HIDBATT_DEBUG, ("HidBattSetStatusNotify failing because of BATTERY_UNKNOWN_CAPACITY.\n"));
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
return STATUS_NOT_SUPPORTED;
|
|
}
|
|
|
|
// first check for relative or absolute
|
|
if(pBattery->m_bRelative)
|
|
{
|
|
ulValue = pBatteryNotify->LowCapacity; // done
|
|
} else
|
|
{
|
|
// first check if setting to zero so that can skip below formula
|
|
if(pBatteryNotify->LowCapacity == 0)
|
|
{
|
|
ulValue = 0;
|
|
} else
|
|
{
|
|
// first must covert value to whatever is being used by this HID device.
|
|
// currently we assume either MilliVolts consistant with battery class or
|
|
// AmpSecs consistant with power spec
|
|
ULONG ulUnit = pBattery->GetUnit(REMAINING_CAPACITY_INDEX);
|
|
if(ulUnit)
|
|
{
|
|
short sExponent;
|
|
ULONG lMilliVolts;
|
|
long milliWattHours,CentiWattHours,CentiWattSecs;
|
|
|
|
sExponent = pBattery->GetExponent(REMAINING_CAPACITY_INDEX);
|
|
|
|
// conversion from millWattHours to AmpSecs
|
|
// formula = mWHs / 1000 / 3600 / volts ^ exponent correction
|
|
lMilliVolts = pBattery->m_BatteryStatus.Voltage; // stored as MilliVolts
|
|
|
|
if (lMilliVolts == 0) {
|
|
HidBattPrint (HIDBATT_ERROR,
|
|
("HidBattSetStatusNotify: Error: voltage = 0, fudging with 24V.\n"));
|
|
lMilliVolts = 24000;
|
|
}
|
|
milliWattHours = pBatteryNotify->LowCapacity;
|
|
CentiWattHours = milliWattHours /10;
|
|
CentiWattSecs = CentiWattHours / 3600;
|
|
CentiAmpSec = (CentiWattSecs *1000)/ lMilliVolts;
|
|
ulValue = CorrectExponent(CentiAmpSec,-2,sExponent);
|
|
} else
|
|
{
|
|
ulValue = pBatteryNotify->LowCapacity;
|
|
}
|
|
} // end if LowCapacity
|
|
} // end if relative
|
|
// now set low
|
|
bResult = pBattery->GetSetValue(REMAINING_CAPACITY_LIMIT_INDEX,&ulValue,TRUE);
|
|
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
|
|
return bResult ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
HidBattDisableStatusNotify (
|
|
IN PVOID pContext
|
|
)
|
|
{
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) pContext;
|
|
pDevExt->m_pBattery->m_pBatteryNotify = NULL; // remove notify procedure
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called by the class driver to retrieve the batteries current status
|
|
|
|
The battery class driver will serialize all requests it issues to
|
|
the miniport for a given battery.
|
|
|
|
Arguments:
|
|
|
|
Context - Miniport context value for battery
|
|
BatteryTag - Tag of current battery
|
|
BatteryStatus - Pointer to structure to return the current battery status
|
|
|
|
Return Value:
|
|
|
|
Success if there is a battery currently installed, else no such device.
|
|
|
|
--*/
|
|
|
|
NTSTATUS
|
|
HidBattQueryStatus (
|
|
IN PVOID pContext,
|
|
IN ULONG BatteryTag,
|
|
OUT PBATTERY_STATUS pBatteryStatus
|
|
)
|
|
{
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) pContext;
|
|
NTSTATUS ntStatus;
|
|
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryStatus - Tag (%d)\n",
|
|
BatteryTag));
|
|
|
|
if (!NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)) )
|
|
{
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
if ((BatteryTag == BATTERY_TAG_INVALID) || (pDevExt->m_pBattery->m_Tag == BATTERY_TAG_INVALID)) {
|
|
ntStatus = STATUS_NO_SUCH_DEVICE;
|
|
} else {
|
|
|
|
RtlZeroMemory (pBatteryStatus, sizeof(BATTERY_STATUS));
|
|
ntStatus = pDevExt->m_pBattery->RefreshStatus();
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
RtlCopyMemory (pBatteryStatus, &pDevExt->m_pBattery->m_BatteryStatus, sizeof(BATTERY_STATUS));
|
|
HidBattPrint (HIDBATT_DATA, ("HidBattQueryStatus - Data (%08x)(%08x)(%08x)(%08x)\n",
|
|
pBatteryStatus->PowerState,
|
|
pBatteryStatus->Capacity,
|
|
pBatteryStatus->Rate,
|
|
pBatteryStatus->Voltage ));
|
|
|
|
} else {
|
|
ntStatus = STATUS_NO_SUCH_DEVICE;
|
|
HidBattPrint (HIDBATT_DATA, ("HidBattQueryStatus - Error\n" ));
|
|
}
|
|
}
|
|
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
|
|
return ntStatus;
|
|
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called by the class driver to retrieve battery information
|
|
|
|
The battery class driver will serialize all requests it issues to
|
|
the miniport for a given battery.
|
|
|
|
We return invalid parameter when we can't handle a request for a
|
|
specific level of information. This is defined in the battery class spec.
|
|
|
|
Arguments:
|
|
|
|
Context - Miniport context value for battery
|
|
BatteryTag - Tag of current battery
|
|
Level - type of information required
|
|
AtRate - Optional Parameter
|
|
Buffer - Location for the information
|
|
BufferLength - Length in bytes of the buffer
|
|
ReturnedLength - Length in bytes of the returned data
|
|
|
|
Return Value:
|
|
|
|
Success if there is a battery currently installed, else no such device.
|
|
|
|
--*/
|
|
|
|
NTSTATUS
|
|
HidBattQueryInformation (
|
|
IN PVOID Context,
|
|
IN ULONG BatteryTag,
|
|
IN BATTERY_QUERY_INFORMATION_LEVEL Level,
|
|
IN LONG AtRate OPTIONAL,
|
|
OUT PVOID Buffer,
|
|
IN ULONG BufferLength,
|
|
OUT PULONG ReturnedLength
|
|
)
|
|
{
|
|
|
|
CBatteryDevExt * pDevExt = (CBatteryDevExt *) Context;
|
|
ULONG ulResult;
|
|
NTSTATUS ntStatus;
|
|
PVOID pReturnBuffer;
|
|
ULONG ulReturnBufferLength;
|
|
WCHAR scratchBuffer[MAX_BATTERY_STRING_SIZE];
|
|
WCHAR buffer2[MAX_BATTERY_STRING_SIZE];
|
|
UNICODE_STRING tmpUnicodeString;
|
|
UNICODE_STRING unicodeString;
|
|
ANSI_STRING ansiString;
|
|
bool bResult;
|
|
BATTERY_REMAINING_SCALE ScalePtr[2];
|
|
ULONG ulReturn,ulNewValue;
|
|
ULONG ulEstTimeStub = 5;
|
|
|
|
HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
|
|
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Tag (%d)\n",
|
|
BatteryTag));
|
|
|
|
|
|
if (!NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)) )
|
|
{
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
//
|
|
// If caller has the wrong ID give an error
|
|
//
|
|
|
|
if (BatteryTag == BATTERY_TAG_INVALID ||
|
|
pDevExt->m_pBattery->m_Tag == BATTERY_TAG_INVALID ||
|
|
BatteryTag != pDevExt->m_pBattery->m_Tag)
|
|
{
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
ulResult = 0;
|
|
pReturnBuffer = NULL;
|
|
ulReturnBufferLength = 0;
|
|
ntStatus = STATUS_SUCCESS;
|
|
CUString cUniqueID;
|
|
SHORT sExponent;
|
|
char * pTemp;
|
|
//
|
|
// Get the info requested
|
|
//
|
|
|
|
switch (Level) {
|
|
case BatteryInformation:
|
|
//
|
|
// This data structure is populated by CmBattVerifyStaticInfo
|
|
//
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Battery Info\n"));
|
|
pReturnBuffer = (PVOID) &pDevExt->m_pBattery->m_BatteryInfo;
|
|
ulReturnBufferLength = sizeof (pDevExt->m_pBattery->m_BatteryInfo);
|
|
break;
|
|
|
|
case BatteryGranularityInformation:
|
|
//
|
|
// Get the granularity from the static info structure
|
|
// This data structure is populated by CmBattVerifyStaticInfo
|
|
//
|
|
{
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Granularity\n"));
|
|
bResult = pDevExt->m_pBattery->GetSetValue(GRANULARITY1_INDEX, &ulReturn,FALSE);
|
|
if(!pDevExt->m_pBattery->m_bRelative)
|
|
{
|
|
// convert from amps to watts
|
|
sExponent = pDevExt->m_pBattery->GetExponent(GRANULARITY1_INDEX);
|
|
ulNewValue = CorrectExponent(ulReturn,sExponent,-2);
|
|
ulReturn= CentiAmpSecsToMilliWattHours(ulNewValue,pDevExt->m_pBattery->m_BatteryStatus.Voltage);
|
|
}
|
|
|
|
ScalePtr[0].Granularity = bResult ? ulReturn : 0;
|
|
bResult = pDevExt->m_pBattery->GetSetValue(GRANULARITY2_INDEX, &ulReturn,FALSE);
|
|
if(!pDevExt->m_pBattery->m_bRelative)
|
|
{
|
|
// convert from amps to watts
|
|
sExponent = pDevExt->m_pBattery->GetExponent(GRANULARITY2_INDEX);
|
|
ulNewValue = CorrectExponent(ulReturn,sExponent,-2);
|
|
ulReturn= CentiAmpSecsToMilliWattHours(ulNewValue,pDevExt->m_pBattery->m_BatteryStatus.Voltage);
|
|
}
|
|
ScalePtr[1].Granularity = bResult ? ulReturn : 0;
|
|
bResult = pDevExt->m_pBattery->GetSetValue(WARNING_CAPACITY_LIMIT_INDEX, &ulReturn,FALSE);
|
|
if(!pDevExt->m_pBattery->m_bRelative)
|
|
{
|
|
// convert from amps to watts
|
|
sExponent = pDevExt->m_pBattery->GetExponent(WARNING_CAPACITY_LIMIT_INDEX);
|
|
ulNewValue = CorrectExponent(ulReturn,sExponent,-2);
|
|
ulReturn= CentiAmpSecsToMilliWattHours(ulNewValue,pDevExt->m_pBattery->m_BatteryStatus.Voltage);
|
|
}
|
|
ScalePtr[0].Capacity = bResult ? ulReturn : 0;
|
|
bResult = pDevExt->m_pBattery->GetSetValue(DESIGN_CAPACITY_INDEX, &ulReturn,FALSE);
|
|
if(!pDevExt->m_pBattery->m_bRelative)
|
|
{
|
|
// convert from amps to watts
|
|
sExponent = pDevExt->m_pBattery->GetExponent(DESIGN_CAPACITY_INDEX);
|
|
ulNewValue = CorrectExponent(ulReturn,sExponent,-2);
|
|
ulReturn= CentiAmpSecsToMilliWattHours(ulNewValue,pDevExt->m_pBattery->m_BatteryStatus.Voltage);
|
|
}
|
|
ScalePtr[1].Capacity = bResult ? ulReturn : 0;
|
|
|
|
pReturnBuffer = ScalePtr;
|
|
ulReturnBufferLength = 2 * sizeof (BATTERY_REMAINING_SCALE);
|
|
}
|
|
break;
|
|
|
|
case BatteryTemperature:
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Temperature\n"));
|
|
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
|
|
break;
|
|
|
|
case BatteryEstimatedTime:
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Estimated time\n"));
|
|
bResult = pDevExt->m_pBattery->GetSetValue(RUNTIME_TO_EMPTY_INDEX, &ulReturn,FALSE);
|
|
|
|
if(!bResult)
|
|
{
|
|
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
|
|
} else
|
|
{
|
|
SHORT exponent;
|
|
|
|
exponent = pDevExt->m_pBattery->GetExponent(RUNTIME_TO_EMPTY_INDEX);
|
|
ulReturn = CorrectExponent (ulReturn, exponent, 0);
|
|
|
|
pReturnBuffer = &ulReturn;
|
|
ulReturnBufferLength = sizeof (ULONG);
|
|
}
|
|
break;
|
|
|
|
case BatteryDeviceName:
|
|
//
|
|
// Model Number must be returned as a wide string
|
|
//
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Device Name\n"));
|
|
if(pDevExt->m_pBattery->m_pProduct)
|
|
{
|
|
pReturnBuffer = pDevExt->m_pBattery->m_pProduct->m_String.Buffer;
|
|
ulReturnBufferLength = pDevExt->m_pBattery->m_pProduct->m_String.Length;
|
|
}
|
|
break;
|
|
|
|
case BatteryManufactureDate:
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Mfr Date\n"));
|
|
if(!pDevExt->m_pBattery->m_ManufactureDate.Day)
|
|
{
|
|
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
|
|
break;
|
|
}
|
|
pReturnBuffer = &pDevExt->m_pBattery->m_ManufactureDate;
|
|
ulReturnBufferLength = sizeof(pDevExt->m_pBattery->m_ManufactureDate);
|
|
break;
|
|
|
|
case BatteryManufactureName:
|
|
//
|
|
// Oem Info must be returned as wide string
|
|
//
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Mfr Name\n"));
|
|
if(pDevExt->m_pBattery->m_pManufacturer)
|
|
{
|
|
pReturnBuffer = pDevExt->m_pBattery->m_pManufacturer->m_String.Buffer;
|
|
ulReturnBufferLength = pDevExt->m_pBattery->m_pManufacturer->m_String.Length;
|
|
}
|
|
|
|
break;
|
|
|
|
case BatteryUniqueID:
|
|
//
|
|
// Concatenate the serial #, manufacturer name, and Product //
|
|
|
|
|
|
|
|
// start off with serial number
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Unique ID\n"));
|
|
if(pDevExt->m_pBattery->m_pSerialNumber) {
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Serial = %s\n", pDevExt->m_pBattery->m_pSerialNumber));
|
|
|
|
cUniqueID.Append(pDevExt->m_pBattery->m_pSerialNumber);
|
|
} else {
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Serial = NULL\n"));
|
|
CUString * pSTemp = new (NonPagedPool, HidBattTag) CUString(L"1000");
|
|
if (pSTemp) {
|
|
cUniqueID.Append(pSTemp);
|
|
delete pSTemp;
|
|
}
|
|
}
|
|
if(pDevExt->m_pBattery->m_pManufacturer)
|
|
cUniqueID.Append(pDevExt->m_pBattery->m_pManufacturer); // add mfr name
|
|
else
|
|
{
|
|
CUString * pSTemp = new (NonPagedPool, HidBattTag) CUString(L"Mfr");
|
|
if (pSTemp) {
|
|
cUniqueID.Append(pSTemp);
|
|
delete pSTemp;
|
|
}
|
|
}
|
|
if(pDevExt->m_pBattery->m_pProduct)
|
|
cUniqueID.Append(pDevExt->m_pBattery->m_pProduct); // add Product
|
|
else
|
|
{
|
|
CUString * pSTemp = new (NonPagedPool, HidBattTag) CUString(L"Prod");
|
|
if (pSTemp) {
|
|
cUniqueID.Append(pSTemp);
|
|
delete pSTemp;
|
|
}
|
|
}
|
|
pReturnBuffer = cUniqueID.m_String.Buffer;
|
|
ulReturnBufferLength = cUniqueID.m_String.Length;
|
|
break;
|
|
default:
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Default\n"));
|
|
ntStatus = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Done, return buffer if needed
|
|
//
|
|
|
|
*ReturnedLength = ulReturnBufferLength;
|
|
if (BufferLength < ulReturnBufferLength) {
|
|
ntStatus = STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
if (NT_SUCCESS(ntStatus) && pReturnBuffer) {
|
|
RtlCopyMemory (Buffer, pReturnBuffer, ulReturnBufferLength); // Copy what's needed
|
|
}
|
|
|
|
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattQueryInformation - Status = %08x Buffer = %08x\n", ntStatus, *(PULONG)Buffer));
|
|
|
|
IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
|
|
|
|
return ntStatus;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
HidBattIoCompletion(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp,
|
|
IN PVOID pdoIoCompletedEvent
|
|
)
|
|
{
|
|
HidBattPrint (HIDBATT_TRACE, ("HidBattIoCompletion\n"));
|
|
KeSetEvent((KEVENT *) pdoIoCompletedEvent,0, FALSE);
|
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
|
|
}
|