Discussion:
Using IOCTL_ACPI_EVAL_METHOD
(too old to reply)
hasyed
2010-08-05 20:26:03 UTC
Permalink
From my windows user-mode environment, I would like to read the temperature
of the thermal zones. I don't want to use WMI since those values are not
updated on most systems. I would like to use IOCTL_ACPI_EVAL_METHOD.

Using device manager, I see that the thermal zones don't really have a
driver associated with them. Nevertheless, I tried the following code below.

I am able to get a handle to the thermal zone using CreateFile

hDevice = CreateFile(szDevicePath, (DWORD)(GENERIC_READ | GENERIC_WRITE), 0,
NULL,OPEN_EXISTING,0,NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
return 0;
}

InBuf.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
InBuf.MethodName[0] = '_';
InBuf.MethodName[1] = 'T';
InBuf.MethodName[2] = 'M';
InBuf.MethodName[3] = 'P';

// Verify Driver version from driver
IoctlResult = DeviceIoControl(hDevice,
IOCTL_ACPI_EVAL_METHOD,
&InBuf, (DWORD) sizeof(InBuf), // Input
&OutBuff, (DWORD) sizeof(OutBuff), //
Output
&ReturnedLength,
NULL);

The IoctlResult in Vista returns a 1 and the OutBuff contains junk data. In
XP, IoctlResult is a 0 (fail).

To get the handle to the thermal zone, I used functions SetupDiGetClassDevs,
SetupDiEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail with the
thermalzone guid.

Am I on the right path? What am I missing?

Thanks for any guidance.
Maxim S. Shatskih
2010-08-06 06:29:46 UTC
Permalink
Post by hasyed
From my windows user-mode environment, I would like to read the temperature
of the thermal zones. I don't want to use WMI since those values are not
updated on most systems. I would like to use IOCTL_ACPI_EVAL_METHOD.
Well, if WMI is not implemented, then probably the ACPI thermal zones are also non-working.
--
Maxim S. Shatskih
Windows DDK MVP
***@storagecraft.com
http://www.storagecraft.com
hasyed
2010-08-06 14:00:03 UTC
Permalink
WMI is implemented. On a number of systems, if you use WMI to read the
thermal zone temperature, you will see the temperature does not change. Or it
won't change as regularly as you would like. Perhaps, the BIOS team decided
to only update through WMI once every 3 minutes.

So, if one want to read the thermal zone temperature every 5 seconds, one
can't go through WMI. One has to somehow evaluate the ACPI method (_TMP) that
is associated with a particular thermal zone.
hasyed
2010-08-06 15:10:03 UTC
Permalink
I don't know what happened to another reply that I made. Below is what I
tried to ask in that.

Part of my question is, "Do I need to build a driver for a particular
thermal zone" and then issue an IOCTL call (IOCTL_ACPI_EVAL_METHOD) to that
particular driver? In the msdn, it mentions, "To enhance the functionality of
an ACPI device, the vendor can supply a WDM function driver, which
communicates with the ACPI BIOS through an operation region supplied by the
driver"

Since I don't want to enhance the ACPI device, I assume that I don't need to
build a driver. I can just use CreateFile to get a handle to that device and
issue an IOCTL call.

Please correct me if I am wrong on this.

Thanks
Doron Holan [MSFT]
2010-08-06 17:24:52 UTC
Permalink
you cannot send this IOCTL from user mode, the driver will not process it

"hasyed" wrote in message news:B0870B4E-51EA-4310-95DA-***@microsoft.com...

I don't know what happened to another reply that I made. Below is what I
tried to ask in that.

Part of my question is, "Do I need to build a driver for a particular
thermal zone" and then issue an IOCTL call (IOCTL_ACPI_EVAL_METHOD) to that
particular driver? In the msdn, it mentions, "To enhance the functionality
of
an ACPI device, the vendor can supply a WDM function driver, which
communicates with the ACPI BIOS through an operation region supplied by the
driver"

Since I don't want to enhance the ACPI device, I assume that I don't need to
build a driver. I can just use CreateFile to get a handle to that device and
issue an IOCTL call.

Please correct me if I am wrong on this.

Thanks
hasyed
2010-08-06 18:40:03 UTC
Permalink
Doron,

Thanks for the reply.

So, I assume my only option is to build a driver for the device. But once I
do that, it is not completely clear to me what I am supposed to do. I assume
that I cannot use IOCTL_ACPI_EVAL_METHOD to get the thermal zone temperature.
I have to access on the operation region once I get a handle to it. Even
after reading the documentation on
http://msdn.microsoft.com/en-us/library/ff536161(VS.85).aspx, I still feel
that there is something chunk missing. What am I supposed to write to the
operation region so that I am returned the temperature?
Post by Doron Holan [MSFT]
you cannot send this IOCTL from user mode, the driver will not process it
hasyed
2010-08-09 19:33:03 UTC
Permalink
Doron,

Appreciate your response to my question posed below.

Thanks
Post by hasyed
Doron,
Thanks for the reply.
So, I assume my only option is to build a driver for the device. But once I
do that, it is not completely clear to me what I am supposed to do. I assume
that I cannot use IOCTL_ACPI_EVAL_METHOD to get the thermal zone temperature.
I have to access on the operation region once I get a handle to it. Even
after reading the documentation on
http://msdn.microsoft.com/en-us/library/ff536161(VS.85).aspx, I still feel
that there is something chunk missing. What am I supposed to write to the
operation region so that I am returned the temperature?
Post by Doron Holan [MSFT]
you cannot send this IOCTL from user mode, the driver will not process it
hasyed
2010-08-27 15:32:03 UTC
Permalink
Post by Doron Holan [MSFT]
you cannot send this IOCTL from user mode, the driver will not process it
I took one more crack at this from a device driver. The code fails in trying
to send IRP downstream. The device driver that I am doing this from is a
simple support driver that can do writes/reads to/from I/O ports.

NtStatus = IoGetDeviceInterfaces((LPGUID)&ThermalGuid , NULL, 0, &list);
if (NtStatus == STATUS_SUCCESS)
{
DbgPrint( "Succesful in getting thermal zone device interface\n");

if (list)
{
PWSTR pl = list;

if (*pl)
{
RtlInitUnicodeString( &sTemp, pl );
NtStatus = IoGetDeviceObjectPointer ( &sTemp, FILE_READ_DATA,
&pFileObjLower, &pThermalDevObj );
if (!NT_SUCCESS (NtStatus))
{
DbgPrint( "IoGetDeviceObjectPointer() failed returned %x\n");
}
else
{
DbgPrint( "IoGetDeviceObjectPointer() succeeded returned
%x\n");
}
ObDereferenceObject(pFileObjLower);
}

ExFreePool (list);
}
}
else
{
return NtStatus;
}

// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('_TMP');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

// Send the request along
NtStatus = SendDownStreamIrp(pThermalDevObj,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);

if (!NT_SUCCESS(NtStatus))
{
ObDereferenceObject(pThermalDevObj);
DbgPrint("Unsucessful in sending IRP down stream\n");
return NtStatus;
}

The error code is 0xc00000bb (STATUS_NOT_SUPPORTED)

One of the obvious things that could be wrong is that this is a support
driver. It is not associated with any device. It is loaded by the
application. Does that disqualify this as a WDM driver? Another requirement
of using IOCTL_ACPI_EVAL_METHOD was that the driver has to be in the same
namespace as the device object. I am trying to evaluate an ThermalZone
method. Since I have a support driver, does that not meet the requirement?
Loading...