how to add wmi interfaces to scsiport and storport miniports
TRANSCRIPT
How to Add WMI Interfaces to SCSIPort and Storport Miniports
OutlineOutlineWhat is Windows Management Instrumentation?
Model for system management and specifying management data
Why is WMI great for MiniPorts?Standardized interfaces for MiniPortsAccessible through COMSecurity
How does it work?Interfaces are specified in a MOFProvider implements and registers interfaces with WMI serviceClients use COM to enumerate instances
Great, but how do I go about it?Define the interfaces (ie writing the MOF file)Using scsiwmi.lib (scsiport/storport version of wmilib.lib)Calling the interfaces from user mode
Advanced topicsSupporting standard interfaces (HBA API, iSCSI)Handling the WMI IRP yourself
Web Links and Questions
What is Windows Management Instrumentation ?What is Windows Management Instrumentation ?
A model for system management and specifying management data
Providers implement one or more instances of management objects
Management objects have properties and or methods
Why is WMI Great for MiniPorts ?Why is WMI Great for MiniPorts ?
Standardized interfaces for MiniPortsStandard providers for HBA API, iSCSI etc.
Generic tools can be written for standardized interfaces
Parameter checking is straight forward
Accessible through COMScriptable through VBS
Remote able
Security Default ACL’s are secure (Windows XP and later, ACL’s should reset for Windows 2000)
How Does It Work?How Does It Work?
Interfaces and data classes are specified in a MOF
Provider implements and registers interfaces with WMI service
Clients (applications) use COM to enumerate instances
WMI Diagram WMI Diagram
ScsiPort / Storport
WMI Service
COM
Applications
WmiProvHbaApi iScsi
Device Class Driver
ScsiWmi
Miniport
Provided by:Provided by:
MicrosoftMicrosoft
ISVISV
IHVIHV
Schema
Great, But How Do I Go About It?Great, But How Do I Go About It?
Define the interfaces (i.e., writing the MOF file)Define the data type classes (i.e., structs)
Define Query, Method and Event classes
Generate the guids and the header
Use scsiwmi.lib (scsiport/storport version of wmilib.lib)Initializing scsiwmi
Registering the interfaces/classes
Implementing the queries
Implementing the methods
Handling events
Call the interfaces from user modeWbemtest.exe (demo)
VBS example (the gotcha with dim, the clone stuff)
C/C++ example
Wmimofchk.exe generated html (demo)
Great, But How Do I Go About It? (con’t)Great, But How Do I Go About It? (con’t)
Define the interfaces (i.e., writing the MOF file)Define the data type classes (i.e., structs)
Define Query, Method and Event classes
Generate the guids and the header
Define The Interfaces (Data Type)Define The Interfaces (Data Type)
// A simple data class (expwmi.mof)
[WMI,
guid("{5beefb8d-e604-4b10-8671-1d5270c46e8a}")]
class ExampleMiniport_DataType
{
[WmiDataId(1)] sint32 Id;
[WmiDataId(2)] uint64 u64;
[MaxLen(16),
WmiDataId(3)] string name;
};
Define The Interfaces (Query Interface)Define The Interfaces (Query Interface)
[WMI, Dynamic, Description(“The first data blob for this instance"), Provider("WmiProv"), guid("{5e973a98-8edc-4856-acb1-b9345f084340}")]class ExampleMiniport_Query{ [key] // providers always need these 3 fields string InstanceName; boolean Active;
[WmiDataId(1)] uint32 Count; [WmiDataId(2)] ExampleMiniport_DataType Data;};
Define The Interfaces (Method Interface)Define The Interfaces (Method Interface)
[WMI, Dynamic, Provider("WmiProv"), guid("{7c01153f-58bb-4c56-bc9c-7f3153130f73}")]class ExampleMiniport_Method{ [key] string InstanceName; boolean Active;
[Implemented, WmiMethodId(1)] void GetCount( [out] uint32 Count );
Define The Interfaces (Method, con’t)Define The Interfaces (Method, con’t)
[Implemented, WmiMethodId(2)] void GetOneThing( [in] uint32 Id, [out] uint32 Status, [out] ExampleMiniport_DataType Data );
[Implemented, WmiMethodId(3)] void GetManyThing( [in] uint32 InCount, // num asked for [out] uint32 Status, [out] uint32 OutCount, [out, WmiSizeIs("OutCount")]
ExampleMiniport_DataType Data[ ] );
Define The Interfaces (Method, con’t)Define The Interfaces (Method, con’t)
[Implemented, WmiMethodId(4)]
void PutOneThing(
[in] ExampleMiniport_DataType Data,
[out] uint32 Status
);
};
Define The Interfaces (Event Data)Define The Interfaces (Event Data)
[WMI, Dynamic, Provider("WmiProv"), guid("{26d51a2b-b7d8-42df-bb53-33b730ccee18}")]class ExampleMiniport_Event : WmiEvent{ [key, read] string InstanceName; [read] boolean Active;
[WmiDataId(1)] uint32 EventType; [WmiDataId(2)] uint32 Id;};
Define The Interfaces (Event Method)Define The Interfaces (Event Method)
[WMI, Dynamic, Provider("WmiProv"), guid("{2729cdcf-0bff-4218-9312-c5e0532d4a43}")]class ExampleMiniport_EventMethod{ [key] string InstanceName; boolean Active;
[Implemented, WmiMethodId(1) ] void Monitor( [in] uint32 Id, [out] uint32 Status );};
Define The Interfaces (GUIDS and Headers)Define The Interfaces (GUIDS and Headers)
For GUIDS use uuidgen.exe Available in SDK or Visual Studio
Generate resource binary using mofcomp.exeAvailable in DDK (also on system)
*.bmf used in resource file and to generate header
Generate the header file using wmimofck.exeAvailable in DDK
Example:mofcomp /b:expwmi.bmf expwmi.mof
wmimofck -hexpwmi.h -m -u expwmi.bmf
Great, But How Do I Go About It? (con’t)Great, But How Do I Go About It? (con’t)
Use scsiwmi.lib (scsiport/storport version of wmilib.lib)
Initializing scsiwmi
Registering the interfaces/classes
Implementing the queries
Implementing the methods
Handling events
Use scsiwmi.libUse scsiwmi.lib
Link against scsiwmi.lib
Add WibLibContext (SCSI_WMILIB_CONTEXT) to HwDeviceExtension
Add custom data to HwDeviceExtension
In HwFindAdapter routineSet WmiDataProvider to TRUE in PORT_CONFIGURATION_INFORMATION
Initialize WibLibContext in HwDeviceExtension (See ExpWmiInitialize)
In HwStartIo routineProcess Srb->Function == SRB_FUNCTION_WMI (see ExpWmiSrb)
Use scsiwmi.lib (HwFindAdapter)Use scsiwmi.lib (HwFindAdapter)
ULONGHwFindAdapter( IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION PortConfigInfo, OUT PBOOLEAN Again
){
// do other stuff
PortConfigInfo->WmiDataProvider = TRUE;ExpWmiInitialize(HwDeviceExtension);
return SP_RETURN_FOUND;}
Use scsiwmi.lib (ExpWmiInitialize)Use scsiwmi.lib (ExpWmiInitialize)//// GUIDs are from generated expwmi.h (expwmi.c)//SCSIWMIGUIDREGINFO gGuidList[ ] = { {&ExampleMiniport_Query_GUID, 4, 0}, {&ExampleMiniport_Method_GUID, 1, 0}, {&ExampleMiniport_EventMethod_GUID, 1, 0}, {&ExampleMiniport_Event_GUID, 1, WMIREG_FLAG_EVENT_ONLY_GUID}//// keep the order the same as the gGuidList (these are the GuidIndexes)
//
enum {
ExampleMiniport_Query_INDEX = 0,
ExampleMiniport_Method_INDEX = 1,
ExampleMiniport_EventMethod_INDEX = 2,
ExampleMiniport_Event_INDEX = 3
};
Use scsiwmi.lib (ExpWmiInitialize, con’t)Use scsiwmi.lib (ExpWmiInitialize, con’t)voidExpWmiInitialize( PDEVICE_EXTENSION Extension ){ PSCSI_WMILIB_CONTEXT pWmiLibContext =
&Extension->WmiLibContext;
pWmiLibContext->GuidCount = ExampleMiniport_NUM_GUIDS; pWmiLibContext->GuidList = gGuidList; pWmiLibContext->QueryWmiRegInfo = ExpWmiQueryRegInfo; pWmiLibContext->QueryWmiDataBlock = ExpWmiQueryDataBlock; pWmiLibContext->SetWmiDataBlock = NULL; // not implemented pWmiLibContext->SetWmiDataItem = NULL; pWmiLibContext->ExecuteWmiMethod = ExpWmiExecuteMethod; pWmiLibContext->WmiFunctionControl = ExpWmiFunctionControl;}
Use scsiwmi.lib (HwStartIo)Use scsiwmi.lib (HwStartIo)
BOOLEANHwStartIo( IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb ){
if (Srb->Function == SRB_FUNCTION_WMI) { //
// Process the WMI request and return.//
return ExpWmiSrb( HwDeviceExtension,
(PSCSI_WMI_REQUEST_BLOCK) Srb);
}// do other stuff
Use scsiwmi.lib (ExpWmiSrb)Use scsiwmi.lib (ExpWmiSrb)
Call ScsiPortWmiDispatchFunction with WmiLibContext
Srb->WMIFlags with SRB_WMI_FLAGS_ADAPTER_REQUEST indicates adapter is target
Call ScsiPortWmiGetReturnSize to get DataTransferLength when request completes
Call ScsiPortWmiGetReturnStatus to get status when request completes
Use scsiwmi.lib (ExpWmiQueryRegInfo)Use scsiwmi.lib (ExpWmiQueryRegInfo)
Register the Schema
#define Exp_MofResourceName L”MofResource”
UCHARExpWmiQueryRegInfo( IN PVOID Context, IN PSCSIWMI_REQUEST_CONTEXT RequestContext, OUT PWCHAR *MofResourceName ){ *MofResourceName = Exp_MofResourceName;
return SRB_STATUS_SUCCESS;}
Use scsiwmi.lib (ExpWmiQueryDataBlock)Use scsiwmi.lib (ExpWmiQueryDataBlock)
Data blocks must be aligned on 8 byte boundaries InstanceLengthArray must be initialized if not NULL and SRB_STATUS_SUCCESSGuidIndex of methods should be handled for enumeration Generated header contains types, Data_SIZE definesCall ScsiPortWmiPostProcess to complete request
Complete with SRB_STATUS_OVERRUN if output buffer too small (size should be completed with required size)Failures complete with SRB_STATUS_ERROR and size of zeroSRB_STATUS_SUCCESS completes with size <= required size
Use scsiwmi.lib (ExpWmiExecuteMethod)Use scsiwmi.lib (ExpWmiExecuteMethod)
Non-method GuidIndex should be failedIn buffer and out buffer are the same addressGenerated Header contains
Method ids PMethod_IN and PMethod_OUT typesMethod_IN_SIZE Method_OUT_SIZE defines
Call ScsiPortWmiPostProcess to complete request
Complete with SRB_STATUS_OVERRUN if output buffer too small (size should be completed with required size)Failures complete with SRB_STATUS_ERROR and size of zero (in buffer too small is a failure)SRB_STATUS_SUCCESS completes with size <= required size
Use scsiwmi.lib (ExpWmiFunctionControl)Use scsiwmi.lib (ExpWmiFunctionControl)
Used to Enable/Disable event notfications
Should verify ScsiWmiEventControl Function
Call ScsiPortWmiPostProcess to complete request
Failures complete with SRB_STATUS_ERROR
Success complete with SRB_STATUS_SUCCESS
Call ScsiPortWmiFireAdapterEvent and/or ScsiPortWmiFireLogicalUnitEvent to send notifications
Great, But How Do I Go About It? (con’t)Great, But How Do I Go About It? (con’t)
Calling the interfaces from user modeWbemtest.exe
VBS example
C/C++ example
Wmimofchk.exe generated html
Advanced TopicsAdvanced Topics
Supporting standard interfaces (HBA API, iSCSI)
Handling the WMI IRP yourself
Additional ResourcesAdditional Resources
Search MSDN: http://msdn.microsoft.comWMI
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_reference.asp
ScsiPortWmiPostProcess (scsiwmi.lib api)
HBA APISNIA spec also available at: http://www.t10.org
© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.