ASL method gets called twice from wmi-acpi driver

Hi folks,

I implement ASL code to provide wmi to acpi mapping
based on the sample provided by Microsoft at
http://msdn.microsoft.com/en-us/library/cc526310.aspx.

While it works in general I have a strange issue with returning a
variable length array from acpi method to wmi.

In the mof file “Variable” class is defined and GetVariable methods
should return variable value for specified key in variable length array

class Variable
{
[WmiDataId(1), read, write, Description(“Status”)] uint32 Status = 0;
[WmiDataId(2), read, write, Description(“Key”)] uint32 Key = 0;
[WmiDataId(3), read, write, Description(“DataSize” )] uint32 DataLen = 1;
[WmiDataId(4), read, write, Description(“Data”), WmiSizeIs(“DataLen”)] uint8 Data = {0};
};

class VariableService
{
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented] void GetVariable([in]Variable dIn, [out]Variable dOut);
};

The corresponding ASL method copies data to output buffer and returns
Method(WMBC, 3)
{

NAME( OBUF, Buffer([12+DLEN]){} )
CreateDWordField( OBUF, 0, OSTA )
CreateDWordField( OBUF, 4, OKEY )
CreateDWordField( OBUF, 8, ODLN )
CreateField( OBUF,96,[DLEN*8],ODAT )
Store( SSTA, OSTA )
Store( SKEY, OKEY )
Store( DLEN, ODLN )
Store( SDAT, ODAT )
return( OBUF )
}

The method works and returns correct data,
but ASL code gets executed 2 times!!! for one wmi request.
It appears that it depends on DLEN.
If DLEN is 0 then the code works as expected, i.e. it is called only once,
but if DLEN is non-zero then the code is called 2 times.

Is that expected behavior of wmi-acpi mapper or may be I did something wrong?

I don't happen to remember the answer to your question. But send it
to xxxxx@microsoft.com. They'll try to resolve it.

--
Jake Oshins
Hyper-V I/O Architect
Microsoft

This post confers no rights and implies no warranties.

wrote in message news:xxxxx@ntdev...
> Hi folks,
>
> I implement ASL code to provide wmi to acpi mapping
> based on the sample provided by Microsoft at
> Microsoft Learn: Build skills that open doors in your career
>
> While it works in general I have a strange issue with returning a
> variable length array from acpi method to wmi.
>
> In the mof file "Variable" class is defined and GetVariable methods
> should return variable value for specified key in variable length
> array
>
> class Variable
> {
> [WmiDataId(1), read, write, Description("Status")] uint32 Status =
> 0;
> [WmiDataId(2), read, write, Description("Key")] uint32 Key = 0;
> [WmiDataId(3), read, write, Description("DataSize" )] uint32 DataLen
> = 1;
> [WmiDataId(4), read, write, Description("Data"),
> WmiSizeIs("DataLen")] uint8 Data = {0};
> };
>
> class VariableService
> {
> [key, read] string InstanceName;
> [read] boolean Active;
> [WmiMethodId(1), Implemented] void GetVariable([in]Variable dIn,
> [out]Variable dOut);
> };
>
> The corresponding ASL method copies data to output buffer and
> returns
> Method(WMBC, 3)
> {
> ...
> NAME( OBUF, Buffer([12+DLEN]){} )
> CreateDWordField( OBUF, 0, OSTA )
> CreateDWordField( OBUF, 4, OKEY )
> CreateDWordField( OBUF, 8, ODLN )
> CreateField( OBUF,96,[DLEN*8],ODAT )
> Store( SSTA, OSTA )
> Store( SKEY, OKEY )
> Store( DLEN, ODLN )
> Store( SDAT, ODAT )
> return( OBUF )
> }
>
> The method works and returns correct data,
> but ASL code gets executed 2 times!!! for one wmi request.
> It appears that it depends on DLEN.
> If DLEN is 0 then the code works as expected, i.e. it is called only
> once,
> but if DLEN is non-zero then the code is called 2 times.
>
> Is that expected behavior of wmi-acpi mapper or may be I did
> something wrong?
>
>
>
>

Thank you for advice.
I got following answer to my question.

This is the expected (though slightly flawed) behavior and is documented on MSDN. The kernel must allocate the buffer size for your returned data, but does not know how much to allocate at first. It first allocates a small buffer and asks you to execute your method. Your method generates more data than can fit into the buffer, and so the whole process must be re-attempted again with the correct buffer size, hence the second call to your method.

The MSDN page that describes IRP_MN_EXECUTE_METHOD (which is what is being used here by the wmiacpi.sys driver to run your AML) is:

http://msdn.microsoft.com/en-us/library/ms806174.aspx

Here’s a snippet of the relevant text:


If the method generates output, the driver should check the size of the output buffer in Parameters.WMI.BufferSize before performing any operation that might have side effects or that should not be performed twice. For example, if a method returns the values of a group of counters and then resets the counters, the driver should check the buffer size (and fail the IRP if the buffer is too small) before resetting the counters. This ensures that WMI can safely resend the request with a larger buffer.


The flaw here is that there is no way for your AML to know whether or not the method really succeeded; WMIACPI must run your AML to get the output, and then if the output won’t fit in the buffer it must fail the IRP_MN_EXECUTE_METHOD call. If calling the method does not generate side effects (i.e., it’s OK to call it twice in a row), then there really isn’t a problem. If it *does* generate side effects, you’ll need to switch to using fixed-size buffers (so that the correct buffer size can be calculated beforehand) or find some way of making it not have side effects.

Thanks,
Areg

Areg,

Thanks for taking the time to follow-up your question to post the answer you received.

This is very helpful for the archives.

Well done, and I’m glad to hear your problem got solved,

Peter
OSR