ACPI WMI雑記
14326 ワード
WMI ACPIについては、まず通読することをお勧めします:1.WMI ACPIが何を提供できるかを知ってから、MSDN 2を参照してください.また、3.1としてもよい.と入力します.特に説明する必要がある.中にはdemoプログラムが残っていて、一般の読者は環境テストがありません(実際の機械でテストすることもお勧めしません.万が一電源を入れないと損失が大きい場合)、私の文章を参考にして、既存のBIOSからMOFとWMIインタフェースを抽出して勉強に使うことができます.
本文は1文の原理の補充と総括であるべきで、主にMOF資源ファイルとACPIの中の各WMIインタフェースの関係を補充します.彼らの関係を明らかにするには、まず文で使用されているコードシートを使用します.
Mof記述ファイル:
ASL(WMI)ファイル:
MOF記述ファイルは最終的にユーザに呼び出されたインタフェースであり、WMI ACPIのASL code部分はMOFに記述されたClassの実装である.読者がMOF/ALLファイルを繰り返し読んで比較すると、ダイナミックリンクライブラリに似ていると感じます.MOFファイルはClassヘッダファイルのように、呼び出しインタフェースの約束とエクスポートを担当します.ASLはDLLファイルのようにDLL関数の実装を担当する.に至ってはWDGオブジェクトは、DLLのEAT(関数アドレステーブル)の仲介役として機能します(実際には_WDGオブジェクトに埋め込まれたMOFファイルにも依存しますが、後述します).もちろんEATテーブルにはいくつかのテーブル項目が構成されている可能性があります.WDGオブジェクトもそうです._WDGの単一のテーブル・アイテムには、次のデータ構造があります.
すべてのテーブルアイテムが結合すると、巨大なMapper[N]配列が形成され、この配列は最終的に_WDGオブジェクト.Mofリソースファイルの作成者(間違いなくOEMメーカー)は、_WDGオブジェクトごとにMapper[i]ごとにClassを作成します.クラスごとにMapper[i]があります.guid対応.
WMIの呼び出し者(DLLと想像する呼び出し者)は、MOFリソースファイル(Classヘッダファイルと想像する)で記述するWMIインタフェースに従って、ClassNameの形式でASL codeの(DLLファイルと想像する)を呼び出すとき、ACPI.SysはACPIネーミングスペースで先に検索します.WDGオブジェクト. 見つかった_WDGオブジェクトの後、そのMapper[N]配列を遍歴し、Mapper[i]に位置決めする.Flags=0の配列項目.この配列項目は、コンパイルされたMOFファイルを含むbufferを指し、MSDNは埋め込み型MOFリソースと呼ばれています. ACPI.Sysは、上位レイヤがClassを使用してWMIを呼び出すため、埋め込み型Mofリソースから一致するClassNameを検索します.前のMofリソース記述ファイルにguidとClassNameが含まれていることを思い出してみてください. ClassNameを取得すると、さらにインタフェース名のguidを取得して_に戻ることができます.WDGのMapper[N]配列では、Mapper[i]による.guidは呼び出し元GUIDに一致する配列項目を検索する. がGUIDにマッチする後、ACPI.SysはMapper[i]を取り出す.ObjectIDメンバー、メンバーにxx値、ACPIを含む.SysはWQ/WSとxxをつなぎ合わせてWQxxまたはWSxxを形成し、ACPIネーミングスペースに行って対応するWQxxまたはWSxxメソッドを呼び出す.demoプログラムとして、WDGオブジェクトのMapper[N]配列は1つの配列項のみであり,上記探索過程は反映されていない.だから、N>1の例を変えて、うーん、抽出したThinkPadの_WDGオブジェクト:
ThinkPad T 460部ですWDGオブジェクトは、5つの配列項目があり、最後に特殊な配列項目であり、しばらく議論しない.他のいくつかの配列項目に対応するWMIインタフェースは以下の通りである.
ThinkPadは埋め込みMOFを使用しているため、元のMofファイル(demowmi.mofのように)を取得できませんが、このvbsスクリプトを実行すると、mofの可能性のある内容を推測できます.
Wmi Code generateによって生成されたACPI WMIインタフェースのテストスクリプトには、多くのInstanceOfinstance文があります.
(以下は個人的に理解する:)Mofリソースファイルは_WDGオブジェクトの配列項目ごとにClassを編集します.オブジェクト指向思考を適用するには、メンバーにアクセスするにはクラスオブジェクト(インスタンス化Class)を作成する必要があるため、vbsスクリプトでは
Mofリソースファイルで説明されているLenovo_を作成する必要があります.PlatformSettingsクラスオブジェクトで、enumSetと名付けられます.
enumSetをクラスのオブジェクトとして理解すると、vbsスクリプトのinstanceは、Mofリソースファイルに記述されているクラスの各メンバー変数です.注意すべきは、vbsテストスクリプトを読むと、クラスオブジェクトの各メンバーにループしてアクセスしていることがわかります.したがって、クラスオブジェクトのメンバー変数のタイプが一致しているため、配列を構成することができます.また、特殊な場合、配列に1つしかない場合、配列は通常の変数に簡略化されます.のためにWDGオブジェクトにおけるMapper[N]配列区分は,Classにおけるタイプが一致するメンバー変数をItem配列で表す.Item配列の長さ(すなわちinstanceの数またはforループの回数)は_WDGオブジェクトのMapper[i].instanceCountでは、次のように指定されています.
ThinkPad T 460 Pを例にとると、
Class:Lenovo_PlatformSetting.InstanceCount=0x0A;
Class:Lenovo_SetPlarformSeting.InstanceCount=0x01;
これらはすべて_WDGオブジェクトMapper[i].InstanceCountで手がかりを見つけた:
ただし、Item配列の長さはMapper[i]に従う.InstanceCountの値は固定できますが、Item配列の配列項目タイプは指定されていません.簡単なのはUINTタイプのItem配列かもしれませんが、複雑なのはBufferまたはPackageタイプのItemかもしれません(ここではItem配列を使用しています).ThinkPad T 460 P Lenovo_PlarformSetingクラスを例にとると、Lenovo_PlarformSetingクラス関数はLenovo_PlarformSetingは、WMI ACPIでの実装:Method(WQA 9,1,NotSerialized)
Method WQA 9は、一意のパラメータArg 0に基づいてACPIネーミングスペースITEMオブジェクトから数値を取得する.ITEMオブジェクトについては、このように長いです.
ええと、この構造はちょっと複雑で、読めません.次のように整理します.
1.ACPI構文によれば、Packageは構造体と考えてもよいし、配列と考えてもよい.最内層のPackage(0 x 2)を2つのメンバ変数のみの構造体とする.
外層Packageは当然、このような構造体タイプのItem配列と考えられており、配列項目は計6項目(_WDGはその配列項目が10項目であるべきことを指定しているが、実際には6項目しかなく、アクセスオーバー部分にも異常は発生していない!):
私たちのタイトルに戻ります:VBSの中の“for each instance in enumSet”、vbsは1ラウンドごとに循環して、実はT 460 P[n]にアクセスします.T 460 P[n]のみにアクセスするなど、OEMメーカーによっては複雑なアクセスを行う場合がある.SettingValまたはT 460 P[n]である.SettingName.このとき,ASLコードに大量のDerefOf文が見られる.
各_WDGオブジェクトMapper[N]配列には、0 x 00の特殊なFlags値を持つ(一意の)特殊な配列項目があります.この特殊なMapper[i]配列項目は1つの役割しかありません:bufferを提供し、コンパイルされたMofリソースファイルを格納するので、このテーブル項目自体はMofリソース記述ファイルには表示されません.しかし、ACPI WMIインタフェースの呼び出しを構成する上で重要なステップであり、それがなければ、Class名からACPI Methodへの変換は実現できません.
本文は1文の原理の補充と総括であるべきで、主にMOF資源ファイルとACPIの中の各WMIインタフェースの関係を補充します.彼らの関係を明らかにするには、まず文で使用されているコードシートを使用します.
Mof記述ファイル:
// Author: bini.Yi http://www.ufoit.com 2008-09-24
// File: demowmi.mof
//{39142400-C6A3-40fa-BADB-8A2652834100}
//IMPLEMENT_OLECREATE
//0x39142400, 0xc6a3, 0x40fa, 0xba, 0xdb, 0x8a, 0x26, 0x52, 0x83, 0x41, 0x00);
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("Events"),
guid("{39142400-C6A3-40fa-BADB-8A2652834100}")
]
class DemoWMIData
{
[key, read]
string InstanceName;
[read] boolean Active;
[WmiDataId(1),
read, write,
Description("description")
] uint32 Data;
};
ASL(WMI)ファイル:
// Author: bini.Yi 2008-09-24
// File: demowmi.ASL
Device(DWMI)
{
// PNP0C14 is PNP ID assigned to WMI mapper
Name(_HID, EISAID("PNP0C14"))
Name(_UID, 0x0)
Name(_WDG, Buffer(){
// {39142400-C6A3-40fa-BADB-8A2652834100}
0x00, 0x24, 0x14, 0x39, 0xA3, 0xC6, 0xFA, 0x40,
0xBA, 0xDB, 0x8A, 0x26, 0x52, 0x83, 0x41, 0x00, //GUID
0x30, 0x30, //'00' Object ID
0x01, //Instance Num
0x01, // 00 = Demo
})
Name(DD00, 0)
Method(WQ00, 1)
{
DBGS("Demo Wmi Get Function:")
DW2H(DD00)
Return(DD00)
}
Method(WS00, 2)
{
DBGS("Demo Wmi Set Function:")
DW2H(ARG1)
Store(ARG1, DD00)
}
}
WMI ACPI呼び出しモデル:
MOF記述ファイルは最終的にユーザに呼び出されたインタフェースであり、WMI ACPIのASL code部分はMOFに記述されたClassの実装である.読者がMOF/ALLファイルを繰り返し読んで比較すると、ダイナミックリンクライブラリに似ていると感じます.MOFファイルはClassヘッダファイルのように、呼び出しインタフェースの約束とエクスポートを担当します.ASLはDLLファイルのようにDLL関数の実装を担当する.に至ってはWDGオブジェクトは、DLLのEAT(関数アドレステーブル)の仲介役として機能します(実際には_WDGオブジェクトに埋め込まれたMOFファイルにも依存しますが、後述します).もちろんEATテーブルにはいくつかのテーブル項目が構成されている可能性があります.WDGオブジェクトもそうです._WDGの単一のテーブル・アイテムには、次のデータ構造があります.
typedef struct _Mapper
{
GUID guid; // GUID that names data block
union
{
CHAR ObjectId[2]; // 2-character ACPI ID (Data Blocks and Methods)
struct
{
UCHAR NotificationValue; // Byte value passed by event handler control method
UCHAR Reserved[1];
} NotifyId;
}
USHORT InstanceCount; // Number of separate instances of data block
USHORT Flags; // Flags
}Mapper;
すべてのテーブルアイテムが結合すると、巨大なMapper[N]配列が形成され、この配列は最終的に_WDGオブジェクト.Mofリソースファイルの作成者(間違いなくOEMメーカー)は、_WDGオブジェクトごとにMapper[i]ごとにClassを作成します.クラスごとにMapper[i]があります.guid対応.
呼び出しプロセス(個人的な憶測ですが、理にかなっていると思います!):
Device (WMI2)
{
Name (_HID, EisaId ("PNP0C14") /* Windows Management Instrumentation Device */) // _HID: Hardware ID
Name (_UID, 0x02) // _UID: Unique ID
Name (_WDG, Buffer (0x64)
{
//==============Mapper[0]==============
0xF1, 0x24, 0xB4, 0xFC, 0x5A, 0x07, 0x0E, 0x4E,
0xBF, 0xC4, 0x62, 0xF3, 0xE7, 0x17, 0x71, 0xFA,
0x41, 0x37,
0x01,
0x01,
//==============Mapper[1]==============
0xE3, 0x5E, 0xBE, 0xE2, 0xDA, 0x42, 0xDB, 0x49,
0x83, 0x78, 0x1F, 0x52, 0x47, 0x38, 0x82, 0x02,
0x41, 0x38,
0x01,
0x02,
//==============Mapper[2]==============
0x9A, 0x01, 0x30, 0x74, 0xE9, 0xDC, 0x48, 0x45,
0xBA, 0xB0, 0x9F, 0xDE, 0x09, 0x35, 0xCA, 0xFF,
0x41, 0x39,
0x0A,
0x05,
//==============Mapper[3]==============
0x03, 0x70, 0xF4, 0x7F, 0x6C, 0x3B, 0x5E, 0x4E,
0xA2, 0x27, 0xE9, 0x79, 0x82, 0x4A, 0x85, 0xD1,
0x41, 0x41,
0x01,
0x06,
//==============Mapper[4]==============
0x21, 0x12, 0x90, 0x05, 0x66, 0xD5, 0xD1, 0x11,
0xB2, 0xF0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0x10,
0x42, 0x42,
0x01,
0x00
})
ThinkPad T 460部ですWDGオブジェクトは、5つの配列項目があり、最後に特殊な配列項目であり、しばらく議論しない.他のいくつかの配列項目に対応するWMIインタフェースは以下の通りである.
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set a = fso.CreateTextFile("lenvon.log", True)
Set Service = GetObject("winmgmts:{impersonationLevel=impersonate}!root/wmi")
Rem Lenovo_PreloadLanguage - Preload Language
Set enumSet = Service.InstancesOf ("Lenovo_PreloadLanguage")
a.WriteLine("Lenovo_PreloadLanguage")
for each instance in enumSet
a.WriteLine(" InstanceName=" & instance.InstanceName)
a.WriteLine(" instance.CurrentSetting=" & instance.CurrentSetting)
next 'instance
Rem Lenovo_SetPreloadLanguage - Set Preload Language
Set enumSet = Service.InstancesOf ("Lenovo_SetPreloadLanguage")
a.WriteLine("Lenovo_SetPreloadLanguage")
for each instance in enumSet
a.WriteLine(" InstanceName=" & instance.InstanceName)
next 'instance
Rem Lenovo_PlatformSetting - Platform Setting
Set enumSet = Service.InstancesOf ("Lenovo_PlatformSetting")
a.WriteLine("Lenovo_PlatformSetting")
for each instance in enumSet
a.WriteLine(" InstanceName=" & instance.InstanceName)
a.WriteLine(" instance.CurrentSetting=" & instance.CurrentSetting)
next 'instance
Rem Lenovo_SetPlatformSetting - Set Platform Setting
Set enumSet = Service.InstancesOf ("Lenovo_SetPlatformSetting")
a.WriteLine("Lenovo_SetPlatformSetting")
for each instance in enumSet
a.WriteLine(" InstanceName=" & instance.InstanceName)
next 'instance
a.Close
Wscript.Echo "lenvon Test Completed, see lenvon.log for details"
ThinkPadは埋め込みMOFを使用しているため、元のMofファイル(demowmi.mofのように)を取得できませんが、このvbsスクリプトを実行すると、mofの可能性のある内容を推測できます.
//entry 1
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("Platform Setting"),
guid("{0x9A, 0x01, 0x30, 0x74, 0xE9, 0xDC, 0x48, 0x45,
0xBA, 0xB0, 0x9F, 0xDE, 0x09, 0x35, 0xCA, 0xFF}")
]
class Lenovo_PlatformSetting
{
[key, read]
string InstanceName;
[read] boolean Active;
[WmiDataId(0x0A),
read, write,
Description("platfrom setting")
] String CurrentSetting;
};
//entry 2
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("Platform Setting"),
guid("{0x03, 0x70, 0xF4, 0x7F, 0x6C, 0x3B, 0x5E, 0x4E,
0xA2, 0x27, 0xE9, 0x79, 0x82, 0x4A, 0x85, 0xD1}")
]
class Lenovo_SetPlatformSetting
{
[key, read]
string InstanceName;
[read] boolean Active;
[WmiMethodId,
Description("Set platfrom setting")
]
}
//entry 3
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("Platform Setting"),
guid("{0xF1, 0x24, 0xB4, 0xFC, 0x5A, 0x07, 0x0E, 0x4E,
0xBF, 0xC4, 0x62, 0xF3, 0xE7, 0x17, 0x71, 0xFA}")
]
class Lenovo_PreloadLanguage
{
[key, read]
string InstanceName;
[read] boolean Active;
[WmiDataId(0x01),
read, write,
Description("Preload Langugage")
] String CurrentSetting;
}
//entry 4
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("Platform Setting"),
guid("{}")
]
class Lenovo_SetPreloadLanguage
{
[key, read]
string InstanceName;
[read] boolean Active;
[WmiMethodId,
Description("Set Set Preload Language")
]
}
VBSのInstanceOf:
Wmi Code generateによって生成されたACPI WMIインタフェースのテストスクリプトには、多くのInstanceOfinstance文があります.
Set enumSet = Service.InstancesOf ("Lenovo_PlatformSetting")
a.WriteLine("Lenovo_PlatformSetting")
for each instance in enumSet
a.WriteLine(" InstanceName=" & instance.InstanceName)
a.WriteLine(" instance.CurrentSetting=" & instance.CurrentSetting)
next 'instance
(以下は個人的に理解する:)Mofリソースファイルは_WDGオブジェクトの配列項目ごとにClassを編集します.オブジェクト指向思考を適用するには、メンバーにアクセスするにはクラスオブジェクト(インスタンス化Class)を作成する必要があるため、vbsスクリプトでは
Set enumSet = Service.InstancesOf ("Lenovo_PlatformSetting")
Mofリソースファイルで説明されているLenovo_を作成する必要があります.PlatformSettingsクラスオブジェクトで、enumSetと名付けられます.
VBSの「for each instance in enumSet」:
enumSetをクラスのオブジェクトとして理解すると、vbsスクリプトのinstanceは、Mofリソースファイルに記述されているクラスの各メンバー変数です.注意すべきは、vbsテストスクリプトを読むと、クラスオブジェクトの各メンバーにループしてアクセスしていることがわかります.したがって、クラスオブジェクトのメンバー変数のタイプが一致しているため、配列を構成することができます.また、特殊な場合、配列に1つしかない場合、配列は通常の変数に簡略化されます.のためにWDGオブジェクトにおけるMapper[N]配列区分は,Classにおけるタイプが一致するメンバー変数をItem配列で表す.Item配列の長さ(すなわちinstanceの数またはforループの回数)は_WDGオブジェクトのMapper[i].instanceCountでは、次のように指定されています.
// !
typedef struct _Mapper
{
GUID guid; // GUID that names data block
union
{
CHAR ObjectId[2]; // 2-character ACPI ID (Data Blocks and Methods)
struct
{
UCHAR NotificationValue; // Byte value passed by event handler control method
UCHAR Reserved[1];
} NotifyId;
}
USHORT InstanceCount; //
ThinkPad T 460 Pを例にとると、
Class:Lenovo_PlatformSetting.InstanceCount=0x0A;
Class:Lenovo_SetPlarformSeting.InstanceCount=0x01;
これらはすべて_WDGオブジェクトMapper[i].InstanceCountで手がかりを見つけた:
Device (WMI2)
{
Name (_HID, EisaId ("PNP0C14") /* Windows Management Instrumentation Device */) // _HID: Hardware ID
Name (_UID, 0x02) // _UID: Unique ID
Name (_WDG, Buffer (0x64)
{
...
//==============Mapper[2]==============
0x9A, 0x01, 0x30, 0x74, 0xE9, 0xDC, 0x48, 0x45,
0xBA, 0xB0, 0x9F, 0xDE, 0x09, 0x35, 0xCA, 0xFF,
0x41, 0x39,
0x0A,
ただし、Item配列の長さはMapper[i]に従う.InstanceCountの値は固定できますが、Item配列の配列項目タイプは指定されていません.簡単なのはUINTタイプのItem配列かもしれませんが、複雑なのはBufferまたはPackageタイプのItemかもしれません(ここではItem配列を使用しています).ThinkPad T 460 P Lenovo_PlarformSetingクラスを例にとると、Lenovo_PlarformSetingクラス関数はLenovo_PlarformSetingは、WMI ACPIでの実装:Method(WQA 9,1,NotSerialized)
Method (WQA9, 1, NotSerialized)
{
Acquire (\_SB.WMI1.MWMI, 0xFFFF)
If ((\WMIS (0x09, Arg0) != 0x00))
{
Release (\_SB.WMI1.MWMI)
Return ("")
}
Local0 = DerefOf (ITEM [\WITM])
Local1 = DerefOf (Local0 [0x00])
Local2 = DerefOf (Local0 [0x01])
Concatenate (Local2, ",", Local6)
Local3 = DerefOf (VSEL [Local1])
Concatenate (Local6, DerefOf (Local3 [\WSEL]), Local7)
Release (\_SB.WMI1.MWMI)
Return (Local7)
}
Method WQA 9は、一意のパラメータArg 0に基づいてACPIネーミングスペースITEMオブジェクトから数値を取得する.ITEMオブジェクトについては、このように長いです.
Name (ITEM, Package (0x06)
{
Package (0x02)
{
0x00,
"InhibitEnteringThinkPadSetup"
},
Package (0x02)
{
0x00,
"MTMSerialConcatenation"
},
Package (0x02)
{
0x00,
"SwapProductName"
},
Package (0x02)
{
0x00,
"ComputraceMsgDisable"
},
Package (0x02)
{
0x00,
"CpuDebugEnable"
},
Package (0x02)
{
0x00,
"PasswordAfterBootDeviceList"
}
})
ええと、この構造はちょっと複雑で、読めません.次のように整理します.
1.ACPI構文によれば、Packageは構造体と考えてもよいし、配列と考えてもよい.最内層のPackage(0 x 2)を2つのメンバ変数のみの構造体とする.
typedef struct _SettingEntry
{
UINT32 SettingVal;
char* SettingName;
}SettingEntry;
外層Packageは当然、このような構造体タイプのItem配列と考えられており、配列項目は計6項目(_WDGはその配列項目が10項目であるべきことを指定しているが、実際には6項目しかなく、アクセスオーバー部分にも異常は発生していない!):
SettingEntry T460P[] = {{0x00,"InhibitEnteringThinkPadSetup"},
{0x00,"MTMSerialConcatenation"},
{0x00,"SwapProductName"},
{0x00,"ComputraceMsgDisable"},
{0x00,"CpuDebugEnable"},
{0x00,"PasswordAfterBootDeviceList"}
};
私たちのタイトルに戻ります:VBSの中の“for each instance in enumSet”、vbsは1ラウンドごとに循環して、実はT 460 P[n]にアクセスします.T 460 P[n]のみにアクセスするなど、OEMメーカーによっては複雑なアクセスを行う場合がある.SettingValまたはT 460 P[n]である.SettingName.このとき,ASLコードに大量のDerefOf文が見られる.
_WDGの特殊なFlag:
各_WDGオブジェクトMapper[N]配列には、0 x 00の特殊なFlags値を持つ(一意の)特殊な配列項目があります.この特殊なMapper[i]配列項目は1つの役割しかありません:bufferを提供し、コンパイルされたMofリソースファイルを格納するので、このテーブル項目自体はMofリソース記述ファイルには表示されません.しかし、ACPI WMIインタフェースの呼び出しを構成する上で重要なステップであり、それがなければ、Class名からACPI Methodへの変換は実現できません.