PSHED プラグインの登録
PSHED プラグインは、PshedRegisterPlugin 関数を呼び出して PSHED に自身を登録し、初期化された WHEA_PSHED_PLUGIN_REGISTRATION_PACKET 構造にポインターを渡します。 通常、PSHED プラグインは、DriverEntry 関数またはその AddDevice 関数内から PshedRegisterPlugin 関数を呼び出します。
PSHED プラグインは、PshedRegisterPlugin を呼び出す前に、PshedIsSystemWheaEnabled を呼び出して、システムが WHEA 対応かどうかをチェックできます。
PSHED プラグインには 2 つのバージョンがあります。 2 つの主な違いは、V2 プラグインを登録解除できることです。 V1 PSHED プラグインが PSHED に正常に登録された後、オペレーティング システム セッションの間は登録を解除できません。 そのため、登録済みの PSHED プラグインをシステムからアンロードしたり、バグ チェックが発生したりしてはなりません。 V2 プラグインでは登録解除が可能です。
次のコード例は、エラー情報の取得とエラー レコードの永続化に関与する PSHED プラグインを登録する方法を示しています。 V1 と V2 の違いに注意してください。
// Prototypes for the callback functions for
// participating in error information retrieval
NTSTATUS
RetrieveErrorInfo(
IN OUT PVOID PluginContext,
IN PWHEA_ERROR_SOURCE_DESCRIPTOR ErrorSource,
IN ULONG64 BufferLength,
IN OUT PWHEA_ERROR_PACKET Packet
);
NTSTATUS
FinalizeErrorRecord(
IN OUT PVOID PluginContext,
IN PWHEA_ERROR_SOURCE_DESCRIPTOR ErrorSource,
IN ULONG BufferLength,
IN OUT PWHEA_ERROR_RECORD ErrorRecord
);
NTSTATUS
ClearErrorStatus(
IN OUT PVOID PluginContext,
IN PWHEA_ERROR_SOURCE_DESCRIPTOR ErrorSource,
IN ULONG BufferLength,
IN PWHEA_ERROR_RECORD ErrorRecord
);
// Prototypes for the callback functions for
// participating in error record persistence.
NTSTATUS
WriteErrorRecord(
IN OUT PVOID PluginContext,
IN ULONG Flags,
IN ULONG RecordLength,
IN PWHEA_ERROR_RECORD ErrorRecord
);
NTSTATUS
ReadErrorRecord(
IN OUT PVOID PluginContext,
IN ULONG Flags,
IN ULONGLONG ErrorRecordId
IN PULONGLONG NextErrorRecordId
IN OUT PULONG RecordLength,
OUT PWHEA_ERROR_RECORD *ErrorRecord
);
NTSTATUS
ClearErrorRecord(
IN OUT PVOID PluginContext,
IN ULONG Flags,
IN ULONGLONG ErrorRecordId
);
// The PSHED plug-in registration packet for a V1 PSHED plugin
WHEA_PSHED_PLUGIN_REGISTRATION_PACKET_V1 RegPacket =
{
sizeof(WHEA_PSHED_PLUGIN_REGISTRATION_PACKET_V1),
WHEA_PSHED_PLUGIN_REGISTRATION_PACKET_V1,
NULL,
PshedFAErrorInfoRetrieval | PshedFAErrorRecordPersistence,
0,
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
WriteErrorRecord,
ReadErrorRecord,
ClearErrorRecord,
RetrieveErrorInfo,
FinalizeErrorRecord,
ClearErrorStatus,
NULL,
NULL,
NULL
}
}
// The PSHED plug-in registration packet for a V2 PSHED plugin
WHEA_PSHED_PLUGIN_REGISTRATION_PACKET RegPacket =
{
sizeof(WHEA_PSHED_PLUGIN_REGISTRATION_PACKET),
WHEA_PLUGIN_REGISTRATION_PACKET_VERSION,
NULL,
PshedFAErrorInfoRetrieval | PshedFAErrorRecordPersistence,
0,
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
WriteErrorRecord,
ReadErrorRecord,
ClearErrorRecord,
RetrieveErrorInfo,
FinalizeErrorRecord,
ClearErrorStatus,
NULL,
NULL,
NULL
},
PluginHandle
}
//
// The PSHED plug-in's DriverEntry function for a V1 PSHED Plugin
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
BOOLEAN IsWheaEnabled;
NTSTATUS Status;
...
// No unload function for V1 PSHED plugins
DriverObject->DriverUnload = NULL;
// Query if the system is WHEA-enabled
IsWheaEnabled =
PshedIsSystemWheaEnabled(
);
// Check result
if (IsWheaEnabled == FALSE)
{
// Return "not supported" status
return STATUS_NOT_SUPPORTED;
}
// Register the PSHED plug-in
Status =
PshedRegisterPlugin(
&RegPacket
);
// Check status
if (Status != STATUS_SUCCESS)
{
// Handle error
...
}
...
// Return success
return STATUS_SUCCESS;
}
//
// The PSHED plug-in's DriverEntry function for a V2 PSHED Plugin
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
BOOLEAN IsWheaEnabled;
NTSTATUS Status;
...
// There is an unload function for V2 PSHED plugin
DriverObject->DriverUnload = PluginUnload;
// Query if the system is WHEA-enabled
IsWheaEnabled =
PshedIsSystemWheaEnabled(
);
// Check result
if (IsWheaEnabled == FALSE)
{
// Return "not supported" status
return STATUS_NOT_SUPPORTED;
}
// Register the PSHED plug-in
Status =
PshedRegisterPlugin(
&RegPacket
);
// Check status
if (Status != STATUS_SUCCESS)
{
// Handle error
...
}
...
// Return success
return STATUS_SUCCESS;
}