diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /storage/iscsi/src | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'storage/iscsi/src')
| -rw-r--r-- | storage/iscsi/src/EmptyProject.vcxproj | 141 | ||||
| -rw-r--r-- | storage/iscsi/src/EmptyProject.vcxproj.Filters | 17 | ||||
| -rw-r--r-- | storage/iscsi/src/blockdir | 2 | ||||
| -rw-r--r-- | storage/iscsi/src/client/wmisample.c | 7990 | ||||
| -rw-r--r-- | storage/iscsi/src/common.mof | 848 | ||||
| -rw-r--r-- | storage/iscsi/src/config.mof | 487 | ||||
| -rw-r--r-- | storage/iscsi/src/def.mof | 34 | ||||
| -rw-r--r-- | storage/iscsi/src/iscsihba.mof | 13094 | ||||
| -rw-r--r-- | storage/iscsi/src/iscsiprf.mof | bin | 0 -> 46042 bytes | |||
| -rw-r--r-- | storage/iscsi/src/mgmt.mof | 1413 | ||||
| -rw-r--r-- | storage/iscsi/src/readme.txt | 49 |
11 files changed, 24075 insertions, 0 deletions
diff --git a/storage/iscsi/src/EmptyProject.vcxproj b/storage/iscsi/src/EmptyProject.vcxproj new file mode 100644 index 00000000..c9ad85f8 --- /dev/null +++ b/storage/iscsi/src/EmptyProject.vcxproj @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6DC3C926-3EE7-43D0-9575-9A77DF02F1C0}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <SupportsPackaging>false</SupportsPackaging> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A25DA04D-0F32-49B4-A66F-5A40647F7D7E}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>EmptyProject</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>EmptyProject</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>EmptyProject</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>EmptyProject</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <NoEntryPoint>true</NoEntryPoint> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <NoEntryPoint>true</NoEntryPoint> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <NoEntryPoint>true</NoEntryPoint> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <NoEntryPoint>true</NoEntryPoint> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/storage/iscsi/src/EmptyProject.vcxproj.Filters b/storage/iscsi/src/EmptyProject.vcxproj.Filters new file mode 100644 index 00000000..d0c6ac93 --- /dev/null +++ b/storage/iscsi/src/EmptyProject.vcxproj.Filters @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{389E59B5-5F73-4BF6-A7AB-E90ADCAAB13A}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{5435109E-A1E9-4A75-98B3-3A3D5711BD05}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{43B3CCA5-BAE4-4DDC-952D-F1D913E7C293}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/storage/iscsi/src/blockdir b/storage/iscsi/src/blockdir new file mode 100644 index 00000000..b300a602 --- /dev/null +++ b/storage/iscsi/src/blockdir @@ -0,0 +1,2 @@ +[Exclude] +iscsi=yes diff --git a/storage/iscsi/src/client/wmisample.c b/storage/iscsi/src/client/wmisample.c new file mode 100644 index 00000000..aff10be5 --- /dev/null +++ b/storage/iscsi/src/client/wmisample.c @@ -0,0 +1,7990 @@ +/*++ + +Copyright (C) Microsoft Corporation, 2000 + +Module Name: + + wmi.c + +Abstract: + + This file contains WMI routines for iSCSI miniport driver. + +Environment: + + kernel mode only + +--*/ + + +UCHAR iScsiQuerySecurityCapabilities( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferAvail, + PUCHAR Buffer, + PULONG InstanceLength, + PULONG SizeNeeded + ); + +UCHAR iScsiQueryDiscoveryConfig( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferAvail, + PUCHAR Buffer, + PULONG InstanceLength, + PULONG SizeNeeded + ); + +UCHAR iScsiAdvanceString( + OUT PWCHAR *String, + OUT PUSHORT StringLen, + IN OUT PUCHAR *Buffer, + IN OUT PULONG BufferSize + ); + +UCHAR iScsiSetDiscoveryConfig( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferSize, + PUCHAR Buffer + ); + +UCHAR iScsiAddPortalGroup( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN ULONG PortalCount + ); + +VOID iScsiCopyUTF8ToCounted( + PWCHAR p, + PUTF8CHAR UTF8, + ULONG UTF8Len + ); + +UCHAR iScsiAddPortalToGroup( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN ULONG Address, + IN PUTF8CHAR SymbolicName, + IN USHORT Socket, + IN ULONG SecurityBitmap, + IN ULONG KeySize, + IN PUCHAR Key + ); + +UCHAR iScsiAddDiscoveredTarget( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN PUTF8CHAR Name, + IN PUTF8CHAR Alias, + IN PUTF8CHAR DDName, + IN ULONG DDID, + IN ULONG PortalGroupCount + ); + +UCHAR iScsiReportDiscoveredTargets2( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferSize, + PULONG SizeNeeded, + PUCHAR Buffer + ); + +UCHAR +iSpReadTCPConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PUCHAR Buffer + ); + +UCHAR +iSpReadNICConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PUCHAR Buffer + ); + +UCHAR +iSpReadNICPerfData( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PUCHAR Buffer + ); + +UCHAR +iSpSetTCPConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN ULONG BufferSize, + IN PUCHAR Buffer + ); + +UCHAR +iScsiSetWmiDataBlock( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT DispatchConiScsiQueryWmiDataBlocktext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG BufferSize, + IN PUCHAR Buffer + ); + + +GUID iSCSI_Operations_GUID = MSiSCSI_OperationsGuid; +GUID iSCSI_HBAInformation_GUID = MSiSCSI_HBAInformationGuid; +GUID iScsiInitiatorInstanceStatisticsGuid = MSiSCSI_InitiatorInstanceStatisticsGuid; +GUID iScsiInitiatorInstanceFailureEventGuid = MSiSCSI_InitiatorInstanceFailureEventGuid; +GUID iScsiConnectStatisticsGuid = MSiSCSI_ConnectionStatisticsGuid; +GUID iScsiSessionStatisticsGuid = MSiSCSI_SessionStatisticsGuid; +GUID iScsi_InitiatorSessionInfo_GUID = MSiSCSI_InitiatorSessionInfoGuid; +GUID iScsi_InitiatorLoginStatistics_GUID = MSiSCSI_InitiatorLoginStatisticsGuid; +GUID iScsiInitiatorNodeFailureEventGuid = MSiSCSI_InitiatorInstanceFailureEventGuid; +GUID iScsiAdapterEventGuid = MSiSCSI_AdapterEventGuid; +GUID iScsiPortalInfoClassGuid = MSiSCSI_PortalInfoClassGuid; +GUID iScsiTargetMappingClassGuid = MSiSCSI_TargetMappingsGuid; +GUID iScsiPersistentLoginsClassGuid = MSiSCSI_PersistentLoginsGuid; +GUID iScsiLBOperationsGuid = MSiSCSI_LB_OperationsGuid; +GUID iScsiQueryLBPolicyGuid = MSiSCSI_QueryLBPolicyGuid; +GUID iSCSIEventlogGuid = MSiSCSI_EventlogGuid; +GUID iSCSIRedirectPortalGuid = MSiSCSI_RedirectPortalInfoClassGuid; +GUID iSCSIReqProcTimeGuid = MSiSCSI_RequestTimeStatisticsGuid; +GUID iSCSIBootInfoGuid = MSiSCSI_BootInformationGuid; + +GUID iScsiDiscoveryConfigGuid = MSiSCSI_DiscoveryConfigGuid; +GUID iSCSI_DiscoveryOperationsGuid = MSiSCSI_DiscoveryOperationsGuid; +GUID iSCSI_SecurityCapabilitiesGuid = MSiSCSI_SecurityCapabilitiesGuid; +GUID iSCSI_SecurityConfigOperationsGuid = MSiSCSI_SecurityConfigOperationsGuid; +GUID MSiScsiTCPConfigGuid = MSiSCSI_TCPIPConfigGuid; +GUID MSiScsiNICConfigGuid = MSiSCSI_NICConfigGuid; +GUID MSiScsiNICPerfGuid = MSiSCSI_NICPerformanceGuid; +GUID MSiSCSIManagementOperationsGuid= MSiSCSI_ManagementOperationsGuid; + +// +// This GUID will be replaced with the GUID for WMI Tracing in the port driver +// +GUID iSCSIDummyGuid = { 0,0,0, { 0,0,0,0,0,0,0,0 } }; + +// +// The index numbers should correspond to the offset in +// iScsiWmiGuidList array given below. +// +#define iSCSI_Operations_GUID_Index 0 +#define iSCSI_HBAInformation_GUID_Index 1 +#define iScsi_InitiatorInstanceStatistics_GUID_INDEX 2 +#define iScsi_InitiatorInstanceFailureEvent_GUID_INDEX 3 +#define iScsi_ConnectStatistics_GUID_INDEX 4 +#define iScsi_SessionStatistics_GUID_INDEX 5 +#define iScsi_InitiatorSessionInfo_GUID_INDEX 6 +#define iScsi_InitiatorLoginStatistics_GUID_INDEX 7 +#define iScsi_InitiatorNodeFailureEvent_GUID_INDEX 8 +#define iScsi_AdapterEvent_GUID_Index 9 +#define iScsi_PortalInfoClass_GUID_Index 10 +#define iScsi_TargetMapping_GUID_Index 11 +#define iScsi_PersistentLogin_GUID_Index 12 +#define iScsi_LB_Operations_GUID_Index 13 +#define iScsi_Query_LB_Policy_GUID_Index 14 +#define iScsi_Eventlog_GUID_Index 15 +#define iScsi_Redirect_Portal_GUID_Index 16 +#define iScsi_RequestProcessingTime_GUID_Index 17 +#define iScsi_BootInfo_GUID_Index 18 + +#define iScsi_MAX_GUID_INDEX iScsi_BootInfo_GUID_Index + +#define iScsiDiscoveryConfigGuid_INDEX iScsi_MAX_GUID_INDEX + 1 +#define iSCSI_DiscoveryOperationsGuid_INDEX iScsi_MAX_GUID_INDEX + 2 +#define iSCSI_SecurityCapabilitiesGuid_INDEX iScsi_MAX_GUID_INDEX + 3 +#define iSCSI_SecurityConfigOperationsGuid_INDEX iScsi_MAX_GUID_INDEX + 4 +#define iScsi_TCPConfig_GUID_Index iScsi_MAX_GUID_INDEX + 5 +#define iScsi_NICConfig_GUID_Index iScsi_MAX_GUID_INDEX + 6 +#define iScsi_NICPerf_GUID_Index iScsi_MAX_GUID_INDEX + 7 +#define iScsi_ManagementOperation_GUID_Index iScsi_MAX_GUID_INDEX + 8 + +// +// GUID List and number of GUIDs in the list +// +SCSIWMIGUIDREGINFO iScsiWmiGuidList[] = +{ + { + &iSCSI_Operations_GUID, + 1, + 0 + }, + + { + &iSCSI_HBAInformation_GUID, + 1, + 0 + }, + + { + &iScsiInitiatorInstanceStatisticsGuid, + 1, + 0 + }, + + { + &iScsiInitiatorInstanceFailureEventGuid, + 1, + WMIREG_FLAG_EVENT_ONLY_GUID + }, + + { + &iScsiConnectStatisticsGuid, + 0xffffffff, //dynamic instance names + 0 + }, + + { + &iScsiSessionStatisticsGuid, + 0xffffffff, //dynamic instance names + 0 + }, + + { + &iScsi_InitiatorSessionInfo_GUID, + 1, + 0 + }, + + { + &iScsi_InitiatorLoginStatistics_GUID, + 1, + 0 + }, + + { + &iScsiInitiatorNodeFailureEventGuid, + 1, + WMIREG_FLAG_EVENT_ONLY_GUID + }, + + { + &iScsiAdapterEventGuid, + 1, + WMIREG_FLAG_EVENT_ONLY_GUID + }, + + { + &iScsiPortalInfoClassGuid, + 1, + 0 + }, + + { + &iScsiTargetMappingClassGuid, + 1, + 0 + }, + + { + &iScsiPersistentLoginsClassGuid, + 1, + 0 + }, + + { + &iScsiLBOperationsGuid, + 1, + 0 + }, + + { + &iScsiQueryLBPolicyGuid, + 1, + 0 + }, + + { + &iSCSIEventlogGuid, + 1, + 0 + }, + + { + &iSCSIRedirectPortalGuid, + 1, + 0 + }, + + { + &iSCSIReqProcTimeGuid, + 0xffffffff, //dynamic instance names + 0 + }, + + { + &iSCSIBootInfoGuid, + 1, + 0 + }, + + { + &iScsiDiscoveryConfigGuid, + 1, + 0 + }, + + { + &iSCSI_DiscoveryOperationsGuid, + 1, + 0 + }, + + { + &iSCSI_SecurityCapabilitiesGuid, + 1, + 0 + }, + + { + &iSCSI_SecurityConfigOperationsGuid, + 1, + 0 + }, + + { + &MSiScsiTCPConfigGuid, + 1, + 0 + }, + + { + &MSiScsiNICConfigGuid, + 1, + 0 + }, + + { + &MSiScsiNICPerfGuid, + 1, + 0 + }, + + { + &MSiSCSIManagementOperationsGuid, + 1, + 0 + }, + +}; + +#define iScsiWmiGuidCount (sizeof(iScsiWmiGuidList) / sizeof(SCSIWMIGUIDREGINFO)) + +// +// WMI Guid list for the PDO +// +GUID iSCSI_LUNMappingInformationGuid = MSiSCSI_LUNMappingInformationGuid; + +#define MSiSCSI_LUNMappingInformation_Index 0 + +SCSIWMIGUIDREGINFO iScsiPDOWmiGuidList[] = +{ + { + &iSCSI_LUNMappingInformationGuid, + 1, + 0 + } +}; + +#define iScsiPDOWmiGuidCount (sizeof(iScsiPDOWmiGuidList) / sizeof(SCSIWMIGUIDREGINFO)) + +VOID +iScsiWmiInitializeContext( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension + ) +/*+++ + +Routine Description: + + This routine will initialize the wmilib context structure with the + guid list and the pointers to the wmilib callback functions. + +Arguments: + + AdapterExtension - Adpater extension + +Return Value: + + None. + +--*/ +{ + PSCSI_WMILIB_CONTEXT wmiLibContext; + + + // + // Initialize the wmilib context for the adapter + // + wmiLibContext = &(AdapterExtension->WmiLibContext); + + wmiLibContext->GuidList = iScsiWmiGuidList; + wmiLibContext->GuidCount = iScsiWmiGuidCount; + + // + // Set pointers to WMI callback routines + // + wmiLibContext->QueryWmiRegInfo = iScsiQueryWmiRegInfo; + wmiLibContext->QueryWmiDataBlock = iScsiQueryWmiDataBlock; + wmiLibContext->ExecuteWmiMethod = iScsiExecuteWmiMethod; + wmiLibContext->WmiFunctionControl = NULL; + wmiLibContext->SetWmiDataItem = NULL; + + + wmiLibContext->SetWmiDataBlock = iScsiSetWmiDataBlock; + + // + // Initialize discovery config + // + AdapterExtension->DiscoveryConfigFlags = (DISCOVERY_CONFIG_DO_DISCOVERY | + DISCOVERY_CONFIG_FIND_SNS_AUTOMATICALLY); + AdapterExtension->SNSServer[0] = 0; + + + // + // Initialize the wmilib context for the PDO + // + wmiLibContext = &(AdapterExtension->PDOWmiLibContext); + + wmiLibContext->GuidList = iScsiPDOWmiGuidList; + wmiLibContext->GuidCount = iScsiPDOWmiGuidCount; + + // + // Set pointers to WMI callback routines + // + wmiLibContext->QueryWmiRegInfo = iScsiQueryWmiRegInfo; + wmiLibContext->QueryWmiDataBlock = iScsiPDOQueryWmiDataBlock; + wmiLibContext->ExecuteWmiMethod = NULL; + wmiLibContext->WmiFunctionControl = NULL; + wmiLibContext->SetWmiDataItem = NULL; + wmiLibContext->SetWmiDataBlock = NULL; + + return; +} + +BOOLEAN +iScsiWmiSrb( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN OUT PSCSI_WMI_REQUEST_BLOCK Srb + ) +/*++ + +Routine Description: + + Called from StartIo routine to process an SRB_FUNCTION_WMI request. + Main entry point for all WMI routines. + +Arguments: + + AdapterExtension - ISCSI miniport driver's Adapter extension. + + Srb - IO request packet. + +Return Value: + + Always TRUE. + +--*/ +{ + PSCSIWMI_REQUEST_CONTEXT requestContext; + PISCSI_SRB_EXTENSION srbExtension; + BOOLEAN pending; + BOOLEAN completeRequest = TRUE; + BOOLEAN adapterRequest; + + + // + // Validate our assumptions. + // + NT_ASSERT(Srb->Function == SRB_FUNCTION_WMI); + NT_ASSERT(Srb->Length == sizeof(SCSI_WMI_REQUEST_BLOCK)); + + srbExtension = (PISCSI_SRB_EXTENSION) Srb->SrbExtension; + + requestContext = &(srbExtension->WmiRequestContext); + + // + // Save the pointer to the SRB in UserContext + // of SCSIWMI_REQUEST_CONTEXT + // + requestContext->UserContext = Srb; + + // + // Check if the WMI SRB is targetted for + // the iScsi adapter or one of the devices + // + adapterRequest = (Srb->WMIFlags & SRB_WMI_FLAGS_ADAPTER_REQUEST) == SRB_WMI_FLAGS_ADAPTER_REQUEST; + + // + // Process the incoming WMI request. + // + DebugPrint((iScsiPrtDebugTrace, + "Entering iScsiWmiSrb\n")); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "Entering iScsiWmiSrb\n"); + + pending = ScsiPortWmiDispatchFunction(adapterRequest ? + &AdapterExtension->WmiLibContext : + &AdapterExtension->PDOWmiLibContext, + Srb->WMISubFunction, + AdapterExtension, + requestContext, + Srb->DataPath, + Srb->DataTransferLength, + Srb->DataBuffer); + if (pending == FALSE) { + + // + // We can do this since we assume it is done synchronously + // + Srb->DataTransferLength = ScsiPortWmiGetReturnSize(requestContext);; + + // + // Adapter ready for next request. + // + Srb->SrbStatus = ScsiPortWmiGetReturnStatus(requestContext); + + } else { + completeRequest = FALSE; + } + + if (completeRequest == TRUE) { + ScsiPortNotification(RequestComplete, AdapterExtension, Srb); + } + + return TRUE; +} + +UCHAR +iScsiQueryWmiRegInfo( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT RequestContext, + _Out_ PWCHAR *MofResourceName + ) +/*+++ + +Routine Description: + + This routine returns MofResourceName for this driver. + +--*/ +{ + *MofResourceName = iScsiWmi_MofResourceName; + + return SRB_STATUS_SUCCESS; +} + +BOOLEAN +iScsiQueryWmiDataBlock( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG InstanceCount, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer + ) +/*+++ + +Routine Description : + + Called to query WMI Data blocks + +--*/ +{ + PISCSI_ADAPTER_EXTENSION adapterExtension; + PSCSI_WMI_REQUEST_BLOCK srb; + UCHAR status; + ULONG sizeNeeded = 0; + NTSTATUS ntStatus; + + + adapterExtension = (PISCSI_ADAPTER_EXTENSION) Context; + srb = (PSCSI_WMI_REQUEST_BLOCK) DispatchContext->UserContext; + + switch (GuidIndex) { + case iSCSI_Operations_GUID_Index: + case iScsi_LB_Operations_GUID_Index: { + + // + // Even though this class only has methods, we need to + // respond to any queries for it since WMI expects that + // there is an actual instance of the class on which to + // execute the method + // + + sizeNeeded = sizeof(ULONG); + if (BufferAvail >= sizeNeeded) { + *InstanceLengthArray = sizeNeeded; + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + case iSCSI_HBAInformation_GUID_Index: { + + PMSiSCSI_HBAInformation iScsiHBAInformation; + + sizeNeeded = sizeof(MSiSCSI_HBAInformation); + if (BufferAvail >= sizeNeeded) { + + *InstanceLengthArray = sizeNeeded; + + iScsiHBAInformation = (PMSiSCSI_HBAInformation) Buffer; + + ntStatus = iSpBuildHBAInformationBuffer(adapterExtension, iScsiHBAInformation); + + status = NT_SUCCESS(ntStatus) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR; + + } else { + + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + case iScsi_InitiatorInstanceStatistics_GUID_INDEX: { + + sizeNeeded = sizeof(MSiSCSI_InitiatorInstanceStatistics); + + if (BufferAvail >= sizeNeeded) { + + status = iSpReadInitiatorInstanceStatistics(adapterExtension, + Buffer); + + if (status != SRB_STATUS_ERROR) { + *InstanceLengthArray = sizeNeeded; + + status = SRB_STATUS_SUCCESS; + } + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + case iScsi_ConnectStatistics_GUID_INDEX: { + + status = iSpBuildConnectionStatistics(adapterExtension, + DispatchContext, + GuidIndex, + InstanceIndex, + InstanceCount, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + break; + } + + case iScsi_RequestProcessingTime_GUID_Index: { + + status = iSpBuildRequestTimeStatistics(adapterExtension, + DispatchContext, + GuidIndex, + InstanceIndex, + InstanceCount, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + break; + } + + case iScsi_SessionStatistics_GUID_INDEX: { + + + status = iSpBuildSessionStatistics(adapterExtension, + DispatchContext, + GuidIndex, + InstanceIndex, + InstanceCount, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + break; + } + + case iScsi_InitiatorLoginStatistics_GUID_INDEX: { + PWMI_CONNECTION_LIST connectionList; + ULONG numberOfSessions; + ULONG numberOfConnections; + + sizeNeeded = sizeof(MSiSCSI_InitiatorLoginStatistics); + if (BufferAvail >= sizeNeeded) + { + RtlZeroMemory(Buffer, sizeNeeded); + + connectionList = iSpGetConnectionList(adapterExtension, + &numberOfSessions, + &numberOfConnections); + + if (connectionList != NULL) + { + status = iSpReadInitiatorLoginStatistics(adapterExtension, + connectionList, + numberOfSessions, + Buffer); + + *InstanceLengthArray = sizeNeeded; + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + } else { + status = SRB_STATUS_ERROR; + } + + + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + break; + } + + case iScsi_InitiatorSessionInfo_GUID_INDEX: { + + status = iSpBuildInitiatorSessionInfo(adapterExtension, + DispatchContext, + BufferAvail, + Buffer, + &sizeNeeded); + + *InstanceLengthArray = sizeNeeded; + + break; + + } + + case iScsi_PortalInfoClass_GUID_Index: { + status = iSpBuildPortalInfo(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + break; + } + + case iScsi_TargetMapping_GUID_Index: { + + status = iSpBuildTargetMapping(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + break; + } + + case iScsi_PersistentLogin_GUID_Index: { + + status = iSpBuildPersistentLoginInfo(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + *InstanceLengthArray = sizeNeeded; + + break; + } + + case iScsi_Query_LB_Policy_GUID_Index: { + + status = iSpQueryLBPolicy(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + *InstanceLengthArray = sizeNeeded; + + break; + } + + case iScsi_Redirect_Portal_GUID_Index: { + + status = iSpBuildRedirectTargetInfo(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + *InstanceLengthArray = sizeNeeded; + + break; + } + + case iScsi_BootInfo_GUID_Index: { + + status = iSpBuildBootInfo(adapterExtension, + InstanceLengthArray, + BufferAvail, + Buffer, + &sizeNeeded); + + *InstanceLengthArray = sizeNeeded; + + break; + } + + + + case iSCSI_SecurityCapabilitiesGuid_INDEX: + { + status = iScsiQuerySecurityCapabilities(adapterExtension, + BufferAvail, + Buffer, + InstanceLengthArray, + &sizeNeeded); + break; + } + + case iScsiDiscoveryConfigGuid_INDEX: + { + status = iScsiQueryDiscoveryConfig(adapterExtension, + BufferAvail, + Buffer, + InstanceLengthArray, + &sizeNeeded); + break; + } + + case iSCSI_SecurityConfigOperationsGuid_INDEX: + case iSCSI_DiscoveryOperationsGuid_INDEX: + case iScsi_ManagementOperation_GUID_Index: + { + // + // Operations only has methods, but we need to support the + // query since WMI needs to be able to query before + // executing a method + // + sizeNeeded = sizeof(ULONG); + if (BufferAvail >= sizeNeeded) + { + *InstanceLengthArray = sizeNeeded; + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + break; + } + + case iScsi_TCPConfig_GUID_Index: + { + sizeNeeded = sizeof(MSiSCSI_TCPIPConfig); + if (BufferAvail >= sizeNeeded) { + *InstanceLengthArray = sizeNeeded; + status = iSpReadTCPConfigInfo(adapterExtension, Buffer); + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + case iScsi_NICConfig_GUID_Index: + { + sizeNeeded = sizeof(MSiSCSI_NICConfig); + + if (BufferAvail >= sizeNeeded) + { + *InstanceLengthArray = sizeNeeded; + status = iSpReadNICConfigInfo(adapterExtension, Buffer); + + } else { + + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + case iScsi_NICPerf_GUID_Index: + { + sizeNeeded = sizeof(MSiSCSI_NICPerformance); + + if (BufferAvail >= sizeNeeded) + { + *InstanceLengthArray = sizeNeeded; + status = iSpReadNICPerfData(adapterExtension, Buffer); + + } else { + + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + default: { + status = SRB_STATUS_ERROR; + break; + } + + } + + iSpCompleteWmiRequest(adapterExtension, srb, DispatchContext, status, sizeNeeded); + + // + // return SRB_STATUS_PENDING since the request has either already been + // completed in iSpCompleteWmiRequest or the status is really + // SRB_STATUS_PENDING. This implies that the iScsiWmiSrb routine + // may not touch the srb since it is already completed. + // + return SRB_STATUS_PENDING; + +} + +VOID +iScsiBuildLUNMapping( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + PMSiSCSI_LUNMappingInformation Mapping, + PSCSI_WMI_REQUEST_BLOCK Srb + ) +/*+++ + +Routine Description : + + This routine will fill in the target mapping information for a + particular lun + +--*/ +{ + PISCSI_SESSION iScsiSession; + + + iScsiSession = AdapterExtension->SessionLookupTable[Srb->TargetId]; + if (IsSessionValid(iScsiSession)) + { + Mapping->UniqueSessionId = iScsiSession->SessionId; + } + + + Mapping->UniqueAdapterId = (ULONGLONG) AdapterExtension; + Mapping->OSBus = Srb->PathId; + Mapping->OSTarget = Srb->TargetId; + Mapping->OSLUN = Srb->Lun; +} + +BOOLEAN +iScsiPDOQueryWmiDataBlock( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG InstanceCount, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer + ) +/*+++ + +Routine Description : + + Called to query WMI Data blocks + +--*/ +{ + PISCSI_ADAPTER_EXTENSION adapterExtension; + PSCSI_WMI_REQUEST_BLOCK srb; + UCHAR status; + ULONG sizeNeeded = 0; + PMSiSCSI_LUNMappingInformation mapping; + + + adapterExtension = (PISCSI_ADAPTER_EXTENSION) Context; + srb = (PSCSI_WMI_REQUEST_BLOCK) DispatchContext->UserContext; + + switch (GuidIndex) { + case MSiSCSI_LUNMappingInformation_Index: + { + sizeNeeded = sizeof(MSiSCSI_LUNMappingInformation); + + if (BufferAvail >= sizeNeeded) + { + mapping = (PMSiSCSI_LUNMappingInformation)Buffer; + + iScsiBuildLUNMapping(adapterExtension, mapping, srb); + + *InstanceLengthArray = sizeNeeded; + status = SRB_STATUS_SUCCESS; + + } else { + + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + default: { + status = SRB_STATUS_ERROR; + break; + } + + } + + iSpCompleteWmiRequest(adapterExtension, srb, DispatchContext, status, sizeNeeded); + + // + // return SRB_STATUS_PENDING since the request has either already been + // completed in iSpCompleteWmiRequest or the status is really + // SRB_STATUS_PENDING. This implies that the iScsiWmiSrb routine + // may not touch the srb since it is already completed. + // + return SRB_STATUS_PENDING; + +} + + + +UCHAR +iSpBuildTargetMapping( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + _Out_writes_bytes_(BufferAvail) OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PISCSI_SESSION iScsiSession; + PMSiSCSI_TargetMappings iSCSITargetMappings; + PISCSI_TargetMapping targetMapping; + PISCSI_SESSION *sessionTable; + NTSTATUS ntStatus; + ULONG inx, jnx; + ULONG targetCount; + UCHAR status = SRB_STATUS_SUCCESS; + + *SizeNeeded = sizeof(MSiSCSI_TargetMappings); + + if (sessionTable != NULL) { + + NT_ASSERT(targetCount > 0); + + inx = 0; + while (inx < targetCount) { + + iScsiSession = sessionTable[inx]; + if (iScsiSession != NULL) { + + ULONG lunCount = 0; + + jnx = 0; + while (jnx < ISCSI_MAX_LOGICAL_UNITS) { + + if (iScsiSession->TargetLUN[jnx] != ISCSI_INVALID_LUN) { + lunCount++; + } + + jnx++; + } + + *SizeNeeded += FIELD_OFFSET(ISCSI_TargetMapping, LUNList) + + (sizeof(ISCSI_LUNList) * lunCount); + } + + inx++; + } + + if (BufferAvail >= *SizeNeeded) { + + iSCSITargetMappings = (PMSiSCSI_TargetMappings) Buffer; + + RtlZeroMemory(iSCSITargetMappings, *SizeNeeded); + + iSCSITargetMappings->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + iSCSITargetMappings->TargetMappingCount = targetCount; + + targetMapping = iSCSITargetMappings->TargetMappings; + + inx = 0; + while (inx < targetCount) { + + iScsiSession = sessionTable[inx]; + if (iScsiSession != NULL) { + + ULONG targetMappingSize; + + targetMappingSize = + FIELD_OFFSET(ISCSI_TargetMapping, LUNList); + + // + // Size needed is computed above and it is checked above + // that the buffer size provided to the function is greater + // than the size needed to fill the buffer + // + targetMapping->OSBus = 0; + + targetMapping->OSTarget = iScsiSession->OSTargetId; + + targetMapping->UniqueSessionId = iScsiSession->SessionId; + + targetMapping->FromPersistentLogin = iScsiSession->PersistentLogin; + + targetMapping->LUNCount = 0; + + jnx = 0; + while (jnx < ISCSI_MAX_LOGICAL_UNITS) { + + if (iScsiSession->TargetLUN[jnx] != ISCSI_INVALID_LUN) { + +#pragma prefast ( suppress: __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "BufferAvail is being checked against SizeNeeded above") + targetMapping->LUNList[targetMapping->LUNCount].OSLUN = + jnx; + + targetMapping->LUNList[targetMapping->LUNCount].TargetLUN = + iScsiSession->TargetLUN[jnx]; + + targetMapping->LUNCount++; + + targetMappingSize += sizeof(ISCSI_LUNList); + } + + jnx++; + } + + *(targetMapping->TargetName) = MAX_TARGET_NAME * sizeof(WCHAR); + RtlCopyMemory((targetMapping->TargetName + 1), + iScsiSession->TargetName, + (MAX_TARGET_NAME * sizeof(WCHAR))); + + targetMapping = + (PISCSI_TargetMapping) (((PUCHAR)targetMapping) + + targetMappingSize); + } + + inx++; + } + + status = SRB_STATUS_SUCCESS; + + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + } else { + if (BufferAvail >= *SizeNeeded) { + RtlZeroMemory(Buffer, BufferAvail); + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + } + + *InstanceLengthArray = *SizeNeeded; + + return status; +} + + +UCHAR +iSpBuildPortalInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PMSiSCSI_PortalInfoClass portalInfoClass; + PISCSI_PortalInfo portalInfo; + ULONG ntStatus; + ULONG inx; + UCHAR status = SRB_STATUS_SUCCESS; + + + *SizeNeeded = FIELD_OFFSET(MSiSCSI_PortalInfoClass, PortalInformation); + + *InstanceLengthArray = *SizeNeeded; + + + *SizeNeeded += sizeof(ISCSI_PortalInfo) * gNumberOfIPAddresses; + + if (BufferAvail >= *SizeNeeded) { + + portalInfoClass = (PMSiSCSI_PortalInfoClass) Buffer; + + RtlZeroMemory(portalInfoClass, *SizeNeeded); + + // + // Number of entries in PortalInformation array + // + portalInfoClass->PortalInfoCount = gNumberOfIPAddresses; + + portalInfo = portalInfoClass->PortalInformation; + + inx = 0; + while (inx < gNumberOfIPAddresses) { + + portalInfo->Index = inx; + portalInfo->Port = inx; + portalInfo->PortalTag = 0; + portalInfo->Protocol = TCP; + portalInfo->PortalType = InitiatorPortals; + + iSpCopyIPAddress(&portalInfo->IPAddr, + &(gRegisteredTransports[inx]), + NULL); + + *portalInfo->IPAddr.TextAddress = 256 * sizeof(WCHAR); + + portalInfo++; + + inx++; + } + + *InstanceLengthArray = *SizeNeeded; + + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + } else { + status = SRB_STATUS_ERROR; + *InstanceLengthArray = 0; + } + + return status; +} + + +NTSTATUS +iSpBuildHBAInformationBuffer( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PMSiSCSI_HBAInformation IScsiHBAInformation + ) +{ + NTSTATUS status; + + + // + // Boolean fields in MSiSCSI_HBAInformation by default + // are set to FALSE through RtlZeroMemory + // + RtlZeroMemory(IScsiHBAInformation, sizeof(MSiSCSI_HBAInformation)); + + // + // Unique Id we return is a pointer to + // the miniport's adapater extension + // + IScsiHBAInformation->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + // + // We want WMI to send us IP Address in binary form. + // + IScsiHBAInformation->RequiresBinaryIpAddresses = TRUE; + + // + // We use TCP/IP integrated with Windows + // + IScsiHBAInformation->IntegratedTCPIP = TRUE; + + IScsiHBAInformation->MultifunctionDevice = FALSE; + + IScsiHBAInformation->CacheValid = FALSE; + + // + // iSCSI Version supported + // + IScsiHBAInformation->VersionMin = ISCSI_CLI_VERSION_MIN; + IScsiHBAInformation->VersionMax = ISCSI_CLI_VERSION_MAX; + + IScsiHBAInformation->NumberOfPorts = 1; + + IScsiHBAInformation->MaxCDBLength = 16; + + IScsiHBAInformation->Status = 0; + + IScsiHBAInformation->FunctionalitySupported = + (ISCSI_HBA_PRESHARED_KEY_CACHE | + ISCSI_HBA_ISCSI_AUTHENTICATION_CACHE | + ISCSI_HBA_IPSEC_TUNNEL_MODE); + + *IScsiHBAInformation->VendorID = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->VendorID+1), 255, + ISCSI_VENDOR_ID, wcslen(ISCSI_VENDOR_ID)); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->VendorModel = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->VendorModel+1), 255, + ISCSI_VENDOR_MODEL, + wcslen(ISCSI_VENDOR_MODEL)); + + NT_ASSERT(NT_SUCCESS(status)); + + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->VendorVersion = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->VendorVersion+1), 255, + ISCSI_VENDOR_VERSION, + wcslen(ISCSI_VENDOR_VERSION)); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->FirmwareVersion = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->FirmwareVersion+1), 255, + ISCSI_VENDOR_VERSION, + wcslen(ISCSI_VENDOR_VERSION)); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->AsicVersion = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->AsicVersion+1), 255, + ISCSI_VENDOR_VERSION, + wcslen(ISCSI_VENDOR_VERSION)); + + + NT_ASSERT(NT_SUCCESS(status)); + + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->OptionRomVersion = 255*sizeof(WCHAR); + + *IScsiHBAInformation->SerialNumber = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->SerialNumber+1), 255, + ISCSI_SERIAL_NUMBER, + wcslen(ISCSI_SERIAL_NUMBER)); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE){ + return status; + } + + *IScsiHBAInformation->DriverName = 255*sizeof(WCHAR); + + status = RtlStringCchCopyNW((IScsiHBAInformation->DriverName+1), 255, + ISCSI_INITIATOR_DRIVER_NAME, + wcslen(ISCSI_INITIATOR_DRIVER_NAME)); + + + NT_ASSERT(NT_SUCCESS(status)); + + return status; +} + +UCHAR +iSpBuildInitiatorSessionInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWMI_CONNECTION_LIST connectionList; + ULONG size, sessionInx; + ULONG numberOfSessions, numberOfConnections; + UCHAR status; + + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, numberOfConnections); + + // + // determine the size of buffer needed to build all of the session + // and connection data structures + // + + // + // Account for the fixed part of the iScsiInitiatorSessionInfo + // + size = FIELD_OFFSET(MSiSCSI_InitiatorSessionInfo, + SessionsList); + + if (connectionList == NULL) { + if (BufferAvail >= size) + { + PMSiSCSI_InitiatorSessionInfo sessionInfo; + + sessionInfo = (PMSiSCSI_InitiatorSessionInfo)Buffer; + sessionInfo->UniqueAdapterId = (ULONGLONG) AdapterExtension; + sessionInfo->SessionCount = 0; + *SizeNeeded = size; + return(SRB_STATUS_SUCCESS); + } else { + *SizeNeeded = size; + return(SRB_STATUS_DATA_OVERRUN); + } + } + + // + // Loop over all sessions and account for the space needed for each + // session plus all of the connections within each session + // + sessionInx = 0; + while (sessionInx < numberOfSessions) { + + // + // Since the session structure needs to be 8 bytes aligned, we + // pad out to 8 bytes + // + size = (size + 7) & ~7; + + // + // Add the fixed size needed for the session structure + // + size += FIELD_OFFSET(ISCSI_SessionStaticInfo, + ConnectionsList); + + // + // Account for the size of all connection structures, being + // sure that the connection structure is padded out to 8 bytes + // in order to maintain 8 byte alignment + // + size += connectionList[sessionInx].Count * + ( (sizeof(ISCSI_ConnectionStaticInfo)+7) & ~7); + + sessionInx++; + } + + *SizeNeeded = size; + if (size <= BufferAvail) + { + // + // If we do have enough space to build the session info data + // structures then we do so + // + RtlZeroMemory(Buffer, size); + + status = iSpReadInitiatorSessionInfo( + AdapterExtension, + connectionList, + numberOfSessions, + Buffer); + + } else { + // + // If there is not enough space to build the session info data + // structures then return this error + // + status = SRB_STATUS_DATA_OVERRUN; + } + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + + return status; +} + +UCHAR +iSpBuildConnectionStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG InstanceCount, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWMI_CONNECTION_LIST connectionList; + PISCSI_CONNECTION iScsiConnection; + PWCHAR NameOffset; + PUCHAR currentDataPos; + ULONG instanceInx; + ULONG newOutBufferAvil; + WMIString DynamicInstanceName; + ULONG numberOfSessions; + ULONG numberOfConnections; + UCHAR srbStatus; + + + srbStatus = SRB_STATUS_SUCCESS; + + *SizeNeeded = 0; + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + + if (connectionList == NULL) { + DebugPrint((iScsiPrtDebugError, + "Failed to allocate array for connections\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to allocate array for connections\n"); + + return SRB_STATUS_ERROR; + } + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections); + + if (DispatchContext->MinorFunction == IRP_MN_QUERY_ALL_DATA) { + + ULONG sessionInx; + ULONG connectionInx; + ULONG connectionCount; + BOOLEAN dynamicNameStatus; + + dynamicNameStatus = ScsiPortWmiSetInstanceCount(DispatchContext, + numberOfConnections, + &newOutBufferAvil, + SizeNeeded); + if (!dynamicNameStatus) + { + DebugPrint((iScsiPrtDebugError, + "iscsiprt: wnode is not for a dynamic instance named GUID\n")); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "iscsiprt: wnode is not for a dynamic instance named GUID\n"); + + *SizeNeeded = 0; + + srbStatus = SRB_STATUS_ERROR; + + } else { + + if (newOutBufferAvil == 0) { + + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + // + // For the data itself + // + instanceInx = 0; + + sessionInx = 0; + *SizeNeeded = 0; + while (sessionInx < numberOfSessions) { + + connectionCount = connectionList[sessionInx].Count; + + connectionInx = 0; + while (connectionInx < connectionCount) { + + iScsiConnection = connectionList[sessionInx].ISCSIConnection[connectionInx]; + + if (iScsiConnection != NULL) { + + currentDataPos = (PUCHAR) ScsiPortWmiSetData(DispatchContext, + instanceInx, + sizeof(MSiSCSI_ConnectionStatistics), + &newOutBufferAvil, + SizeNeeded); + if (newOutBufferAvil == 0) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + + if ((srbStatus != SRB_STATUS_DATA_OVERRUN) && + (currentDataPos != NULL)) { + + srbStatus = iSpReadConnStatistics(AdapterExtension, + iScsiConnection, + currentDataPos); + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + } + + RtlZeroMemory(&DynamicInstanceName, + sizeof(DynamicInstanceName)); + + srbStatus = iSpGetDynamicConnectionInstanceName( + iScsiConnection, + &DynamicInstanceName); + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + + NameOffset = ScsiPortWmiSetInstanceName( + DispatchContext, + instanceInx, + DynamicInstanceName.Length+sizeof(USHORT), + &newOutBufferAvil, + SizeNeeded); + + if ((newOutBufferAvil == 0) && (NameOffset == NULL)) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + if (srbStatus != SRB_STATUS_DATA_OVERRUN) + { + // + // copy the instance name into NameOffset + // + RtlCopyMemory(NameOffset, (PUCHAR)(&DynamicInstanceName), + (DynamicInstanceName.Length + sizeof(USHORT))); + } + + instanceInx++; + } + + connectionInx++; + } + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + + sessionInx++; + } + } + } else { + + PWMIString instanceName; + ULONG givenInstanceNameLength = 0; + ULONG dynInstanceNameLength = 0; + ULONG instanceNameLength; + ULONG sessionInx; + ULONG connectionInx; + ULONG connectionCount; + BOOLEAN found = FALSE; + + // + // single instance + // + + srbStatus = SRB_STATUS_ERROR; + + // + // get the instance name + // + instanceName = (PWMIString)ScsiPortWmiGetInstanceName(DispatchContext); + + if (instanceName != NULL) + { + givenInstanceNameLength = instanceName->Length / sizeof(instanceName->Buffer[0]); + + *SizeNeeded = sizeof(MSiSCSI_ConnectionStatistics); + if (BufferAvail < *SizeNeeded) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + + } else { + + instanceInx = 0; + + sessionInx = 0; + + while (sessionInx < numberOfSessions) { + + if (connectionList[sessionInx].Count) { + + connectionInx = 0; + + while (connectionInx < numberOfConnections) { + iScsiConnection = connectionList[sessionInx].ISCSIConnection[0]; + + if (iScsiConnection != NULL) { + + RtlZeroMemory(&DynamicInstanceName, + sizeof(DynamicInstanceName)); + + srbStatus = iSpGetDynamicConnectionInstanceName( + iScsiConnection, + &DynamicInstanceName); + + if (srbStatus != SRB_STATUS_ERROR) + { + dynInstanceNameLength = DynamicInstanceName.Length / sizeof(DynamicInstanceName.Buffer[0]); + + if ((givenInstanceNameLength == dynInstanceNameLength) && + !wcsncmp( + DynamicInstanceName.Buffer, + instanceName->Buffer, + dynInstanceNameLength)) { + + srbStatus = iSpReadConnStatistics(AdapterExtension, + iScsiConnection, + Buffer); + + if (srbStatus == SRB_STATUS_SUCCESS) + { + *InstanceLengthArray = *SizeNeeded; + } + + found = TRUE; + + break; + } + } + } + + connectionInx++; + } + } + + if (found == TRUE) { + break; + } + + sessionInx++; + } + } + } else { + srbStatus = SRB_STATUS_ERROR; + } + + if(srbStatus != SRB_STATUS_SUCCESS && + srbStatus != SRB_STATUS_DATA_OVERRUN) + { + *SizeNeeded = 0; + } + } + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + + return srbStatus; +} + +UCHAR +iSpBuildSessionStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG InstanceCount, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWCHAR NameOffset; + PUCHAR currentDataPos; + WMIString DynamicInstanceName; + ULONG connectionCount=0; + ULONG instanceInx; + ULONG newOutBufferAvil; + ULONG initiatorIndx; + ULONG instanceSize=0; + WMIString WMIformatString; + UCHAR srbStatus; + + PWMI_CONNECTION_LIST connectionList; + ULONG numberOfSessions; + ULONG numberOfConnections; + + + srbStatus = SRB_STATUS_SUCCESS; + *SizeNeeded = 0; + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + + if (connectionList == NULL) { + DebugPrint((iScsiPrtDebugError, + "Failed to allocate array for connections\n")); + + ETWDebugPrint(iScsiLevelError, iScsiFlagWmi, + "Failed to allocate array for connections\n"); + + return SRB_STATUS_ERROR; + } + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections); + + if (DispatchContext->MinorFunction == IRP_MN_QUERY_ALL_DATA) + { + + ULONG sessionInx; + BOOLEAN dynamicNameStatus; + + // + // instance counts + // + dynamicNameStatus = ScsiPortWmiSetInstanceCount(DispatchContext, + numberOfSessions, + &newOutBufferAvil, + SizeNeeded); + + if (!dynamicNameStatus) + { + DebugPrint((iScsiPrtDebugError, + "iscsiprt: wnode is not for a dynamic instance named GUID\n")); + + ETWDebugPrint(iScsiLevelError, iScsiFlagWmi, + "iscsiprt: wnode is not for a dynamic instance named GUID\n"); + + *SizeNeeded = 0; + srbStatus = SRB_STATUS_ERROR; + + } else { + + if (numberOfSessions == 0) + { + // + // no instances avaliable + // + } else { + + if (newOutBufferAvil == 0) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + // + // for the data itself + // + instanceInx = 0; + + sessionInx = 0; + + *SizeNeeded = 0; + + while (sessionInx < numberOfSessions) { + + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + + if (connectionList[sessionInx].Count > 0) { + + iScsiConnection = connectionList[sessionInx].ISCSIConnection[0]; + iScsiSession = iScsiConnection->ISCSISession; + + currentDataPos = (PUCHAR) ScsiPortWmiSetData(DispatchContext, + instanceInx, + sizeof(MSiSCSI_SessionStatistics), + &newOutBufferAvil, + SizeNeeded); + if (newOutBufferAvil == 0) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + if ((srbStatus != SRB_STATUS_DATA_OVERRUN) && + (currentDataPos != NULL)) + { + + srbStatus = iSpReadSessionStatistics(AdapterExtension, + iScsiSession, + &connectionList[sessionInx], + currentDataPos); + + } + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + + RtlZeroMemory(&DynamicInstanceName, + sizeof(DynamicInstanceName)); + + srbStatus = iSpGetDynamicSessionInstanceName(iScsiSession, + &DynamicInstanceName); + + NameOffset = ScsiPortWmiSetInstanceName(DispatchContext, + instanceInx, + DynamicInstanceName.Length+sizeof(USHORT), + &newOutBufferAvil, + SizeNeeded); + + if ((newOutBufferAvil == 0) && (NameOffset == NULL)) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + if (srbStatus != SRB_STATUS_DATA_OVERRUN) { + + // + // copy the instance name into NameOffset + // + RtlCopyMemory(NameOffset, + (PUCHAR)(&DynamicInstanceName), + (DynamicInstanceName.Length + sizeof(USHORT))); + } + + instanceInx++; + } + + sessionInx++; + } + + + } + } + } else { //single instance + + PWMIString instanceName; + ULONG givenInstanceNameLength = 0; + ULONG dynInstanceNameLength = 0; + ULONG instanceNameLength; + ULONG sessionInx; + BOOLEAN found = FALSE; + + srbStatus = SRB_STATUS_ERROR; + + // + // get the instance name + // + instanceName = (PWMIString) ScsiPortWmiGetInstanceName(DispatchContext); + + if (instanceName != NULL) + { + givenInstanceNameLength = instanceName->Length / sizeof(instanceName->Buffer[0]); + + *SizeNeeded = sizeof(MSiSCSI_SessionStatistics); + if (BufferAvail < *SizeNeeded) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } else { + + sessionInx = 0; + while (sessionInx < numberOfSessions) { + + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + + if (connectionList[sessionInx].Count > 0) { + + iScsiConnection = connectionList[sessionInx].ISCSIConnection[0]; + iScsiSession = iScsiConnection->ISCSISession; + + RtlZeroMemory(&DynamicInstanceName, sizeof(DynamicInstanceName)); + srbStatus = iSpGetDynamicSessionInstanceName(iScsiSession, + &DynamicInstanceName); + if (srbStatus == SRB_STATUS_SUCCESS) + { + dynInstanceNameLength = DynamicInstanceName.Length / sizeof(DynamicInstanceName.Buffer[0]); + + if (givenInstanceNameLength == dynInstanceNameLength + && !wcsncmp(DynamicInstanceName.Buffer, + instanceName->Buffer, + dynInstanceNameLength)) + { + srbStatus = iSpReadSessionStatistics(AdapterExtension, + iScsiSession, + &connectionList[sessionInx], + Buffer); + + if (srbStatus == SRB_STATUS_SUCCESS) + { + *InstanceLengthArray = *SizeNeeded; + } + + break; + } + } + } + + sessionInx++; + } + } + } else { + srbStatus = SRB_STATUS_ERROR; + } + + if(srbStatus != SRB_STATUS_SUCCESS && + srbStatus != SRB_STATUS_DATA_OVERRUN) + { + *SizeNeeded = 0; + } + } + + + return srbStatus; +} + +UCHAR +iSpBuildRequestTimeStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG InstanceCount, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWMI_CONNECTION_LIST connectionList; + PISCSI_CONNECTION iScsiConnection; + PWCHAR NameOffset; + PUCHAR currentDataPos; + ULONG instanceInx; + ULONG newOutBufferAvil; + WMIString DynamicInstanceName; + ULONG numberOfSessions; + ULONG numberOfConnections; + UCHAR srbStatus; + + + srbStatus = SRB_STATUS_SUCCESS; + + *SizeNeeded = 0; + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + if (connectionList == NULL) { + + DebugPrint((iScsiPrtDebugError, + "Failed to allocate array for connections\n")); + + ETWDebugPrint(iScsiLevelError, iScsiFlagWmi, + "Failed to allocate array for connections\n"); + + return SRB_STATUS_ERROR; + } + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections); + + if (DispatchContext->MinorFunction == IRP_MN_QUERY_ALL_DATA) { + + ULONG sessionInx; + ULONG connectionInx; + ULONG connectionCount; + BOOLEAN dynamicNameStatus; + + dynamicNameStatus = ScsiPortWmiSetInstanceCount(DispatchContext, + numberOfConnections, + &newOutBufferAvil, + SizeNeeded); + if (!dynamicNameStatus) + { + DebugPrint((iScsiPrtDebugError, + "iscsiprt: wnode is not for a dynamic instance named GUID\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "iscsiprt: wnode is not for a dynamic instance named GUID\n"); + + *SizeNeeded = 0; + + srbStatus = SRB_STATUS_ERROR; + + } else { + + if (newOutBufferAvil == 0) { + + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + // + // For the data itself + // + instanceInx = 0; + + sessionInx = 0; + + *SizeNeeded = 0; + + while (sessionInx < numberOfSessions) { + + connectionCount = connectionList[sessionInx].Count; + + connectionInx = 0; + while (connectionInx < connectionCount) { + + iScsiConnection = connectionList[sessionInx].ISCSIConnection[connectionInx]; + + if (iScsiConnection != NULL) { + + currentDataPos = (PUCHAR) ScsiPortWmiSetData(DispatchContext, + instanceInx, + sizeof(MSiSCSI_RequestTimeStatistics), + &newOutBufferAvil, + SizeNeeded); + if (newOutBufferAvil == 0) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + + if ((srbStatus != SRB_STATUS_DATA_OVERRUN) && + (currentDataPos != NULL)) { + + srbStatus = iSpReadRequestTimeStatistics(AdapterExtension, + iScsiConnection, + currentDataPos); + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + } + + RtlZeroMemory(&DynamicInstanceName, + sizeof(DynamicInstanceName)); + + srbStatus = iSpGetDynamicConnectionInstanceName( + iScsiConnection, + &DynamicInstanceName); + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + + NameOffset = ScsiPortWmiSetInstanceName( + DispatchContext, + instanceInx, + DynamicInstanceName.Length+sizeof(USHORT), + &newOutBufferAvil, + SizeNeeded); + + if ((newOutBufferAvil == 0) && (NameOffset == NULL)) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + if (srbStatus != SRB_STATUS_DATA_OVERRUN) + { + // + // copy the instance anme into NameOffset + // + RtlCopyMemory(NameOffset, (PUCHAR)(&DynamicInstanceName), + (DynamicInstanceName.Length + sizeof(USHORT))); + } + + instanceInx++; + } + + connectionInx++; + } + + if (srbStatus == SRB_STATUS_ERROR) + { + break; + } + + sessionInx++; + } + } + } else { + PWMIString instanceName; + ULONG givenInstanceNameLength = 0; + ULONG dynInstanceNameLength = 0; + ULONG instanceNameLength; + ULONG sessionInx; + ULONG connectionInx; + ULONG connectionCount; + BOOLEAN found = FALSE; + + // + // single instance + // + + srbStatus = SRB_STATUS_ERROR; + + // + // get the instance name + // + instanceName = (PWMIString)ScsiPortWmiGetInstanceName(DispatchContext); + + if (instanceName != NULL) + { + givenInstanceNameLength = instanceName->Length / sizeof(instanceName->Buffer[0]); + + *SizeNeeded = sizeof(MSiSCSI_RequestTimeStatistics); + if (BufferAvail < *SizeNeeded) + { + // + // The buffer passed to return the data is too small + // + srbStatus = SRB_STATUS_DATA_OVERRUN; + + } else { + + instanceInx = 0; + + sessionInx = 0; + + while (sessionInx < numberOfSessions) { + + if (connectionList[sessionInx].Count) { + + connectionInx = 0; + + while (connectionInx < numberOfConnections) { + iScsiConnection = connectionList[sessionInx].ISCSIConnection[0]; + + if (iScsiConnection != NULL) { + + srbStatus = iSpGetDynamicConnectionInstanceName( + iScsiConnection, + &DynamicInstanceName); + + if (srbStatus != SRB_STATUS_ERROR) + { + dynInstanceNameLength = DynamicInstanceName.Length / sizeof(DynamicInstanceName.Buffer[0]); + + if ((givenInstanceNameLength == dynInstanceNameLength) && + !wcsncmp(DynamicInstanceName.Buffer, + instanceName->Buffer, + dynInstanceNameLength)) + { + srbStatus = iSpReadRequestTimeStatistics(AdapterExtension, + iScsiConnection, + Buffer); + if (srbStatus == SRB_STATUS_SUCCESS) + { + *InstanceLengthArray = *SizeNeeded; + } + + found = TRUE; + + break; + } + } + } + connectionInx++; + } + } + + if (found == TRUE) { + break; + } + + sessionInx++; + } + } + } else { + srbStatus = SRB_STATUS_ERROR; + } + + if(srbStatus != SRB_STATUS_SUCCESS && + srbStatus != SRB_STATUS_DATA_OVERRUN) + { + *SizeNeeded = 0; + } + } + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + + return srbStatus; +} + + +UCHAR iScsiQuerySecurityCapabilities( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferAvail, + PUCHAR Buffer, + PULONG InstanceLength, + PULONG SizeNeeded + ) +/*+++ + +Routine Description : + + This routine implements the WMI query for the security capabilites + class. + +--*/ +{ + UCHAR status; + PMSiSCSI_SecurityCapabilities config; + + + *SizeNeeded = sizeof(MSiSCSI_SecurityCapabilities); + + if (BufferAvail >= sizeof(MSiSCSI_SecurityCapabilities)) + { + config = (PMSiSCSI_SecurityCapabilities)Buffer; + RtlZeroMemory(Buffer, sizeof(MSiSCSI_SecurityCapabilities)); + + config->ProtectiScsiTraffic = FALSE; + config->ProtectiSNSTraffic = FALSE; + config->CertificatesSupported = FALSE; + + config->EncryptionAvailableCount = 1; + config->EncryptionAvailable[0] = ISCSI_ENCRYPT_NONE; + + *InstanceLength = *SizeNeeded; + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + return(status); +} + +UCHAR iScsiQueryDiscoveryConfig( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferAvail, + PUCHAR Buffer, + PULONG InstanceLength, + PULONG SizeNeeded + ) +/*+++ + +Routine Description : + + This routine implements the WMI query for the discovery config + class. + +--*/ +{ + NTSTATUS rtlStatus; + UCHAR status; + PMSiSCSI_DiscoveryConfig config; + + + *SizeNeeded = sizeof(MSiSCSI_DiscoveryConfig); + + if (BufferAvail >= sizeof(MSiSCSI_DiscoveryConfig)) + { + config = (PMSiSCSI_DiscoveryConfig)Buffer; + RtlZeroMemory(Buffer, sizeof(MSiSCSI_DiscoveryConfig)); + if (AdapterExtension->DiscoveryConfigFlags & DISCOVERY_CONFIG_DO_DISCOVERY) + { + config->PerformiSNSDiscovery = TRUE; + } + + if (AdapterExtension->DiscoveryConfigFlags & DISCOVERY_CONFIG_FIND_SNS_AUTOMATICALLY) + { + config->AutomaticiSNSDiscovery = TRUE; + } + + config->InitiatorName[0] = 256 * sizeof(WCHAR); + + rtlStatus = RtlStringCchCopyNW(&config->InitiatorName[1], + MAX_INITIATOR_NAME, + AdapterExtension->InitiatorName, + MAX_INITIATOR_NAME); + + config->iSNSServer.Type = ISCSI_IP_ADDRESS_TEXT; + config->iSNSServer.TextAddress[0] = 256 * sizeof(WCHAR); + rtlStatus = RtlStringCchCopyNW(&config->iSNSServer.TextAddress[1], 256, + AdapterExtension->SNSServer, 256); + + *InstanceLength = *SizeNeeded; + status = SRB_STATUS_SUCCESS; + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + return(status); +} + +UCHAR iScsiAdvanceString( + OUT PWCHAR *String, + OUT PUSHORT StringLen, + IN OUT PUCHAR *Buffer, + IN OUT PULONG BufferSize + ) +{ + UCHAR status = SRB_STATUS_ERROR; + PUCHAR b; + ULONG bs; + USHORT len; + + b = *Buffer; + bs = *BufferSize; + + if (bs >= sizeof(USHORT)) + { + // + // Get the length of the string and advance beyond it + // + len = *((PUSHORT)b); + b += sizeof(USHORT); + bs -= sizeof(USHORT); + *String = (PWCHAR)b; + *StringLen = len; + + if (bs >= len) + { + b += len; + bs -= len; + + *Buffer = b; + *BufferSize = bs; + status = SRB_STATUS_SUCCESS; + } + } + return(status); +} + +UCHAR iScsiSetDiscoveryConfig( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferSize, + PUCHAR Buffer + ) +/*+++ + +Routine Description : + + This routine implements the WMI set for the discovery config + class. + +--*/ +{ + NTSTATUS rtlStatus; + UCHAR status; + PMSiSCSI_DiscoveryConfig config; + USHORT stringLen, initiatorNameLen; + PISCSI_IP_Address ipAddress; + PWCHAR string; + PWCHAR initiatorName; + ULONG pad; + + // + // Assume the buffer passed will be bad in some way + // + status = SRB_STATUS_ERROR; + + // + // Validate that the buffer passed is large enough for the + // beginning of the class + // + if (BufferSize >= FIELD_OFFSET(MSiSCSI_DiscoveryConfig, + InitiatorName)) + { + config = (PMSiSCSI_DiscoveryConfig)Buffer; + + // + // Advance buffer pointer past beginning of config struct + // + Buffer += FIELD_OFFSET(MSiSCSI_DiscoveryConfig, InitiatorName); + BufferSize -= FIELD_OFFSET(MSiSCSI_DiscoveryConfig, InitiatorName); + + // + // Now validate that there is a valid InitiatorName string + // + status = iScsiAdvanceString(&initiatorName, + &initiatorNameLen, + &Buffer, + &BufferSize); + + if (status == SRB_STATUS_SUCCESS) + { + status = SRB_STATUS_ERROR; + + // + // Pad Buffer to a 4 byte boundry since + // ISCSI_IP_Address is required to be on a 4 byte + // boundry + // + pad = (ULONG)((((ULONG_PTR)Buffer + 3) &~3) - (ULONG_PTR)Buffer); + if (BufferSize >= pad) + { + Buffer += pad; + BufferSize -= pad; + + // + // Now validate that there is enough room for the beginning of + // the IP address struct + // + if (BufferSize >= FIELD_OFFSET(ISCSI_IP_Address, + TextAddress)) + { + ipAddress = (PISCSI_IP_Address)Buffer; + + // + // Advance buffer pointer beyond IP address struct + // + Buffer += FIELD_OFFSET(ISCSI_IP_Address, TextAddress); + BufferSize -= FIELD_OFFSET(ISCSI_IP_Address, TextAddress); + + // + // Validate that the user passed a text addresss + // + if ((ipAddress->Type == ISCSI_IP_ADDRESS_TEXT) || + (ipAddress->Type == ISCSI_IP_ADDRESS_IPV4)) + { + // + // Validate that there is enough room for the string + // length + // + status = iScsiAdvanceString(&string, + &stringLen, + &Buffer, + &BufferSize); + + if (status == SRB_STATUS_SUCCESS) + { + status = SRB_STATUS_ERROR; + + // + // Finally copy out the values from the + // passed buffer into the device extension + // + + // + // Validate that the input string is not too large + // + if (initiatorNameLen <= MAX_INITIATOR_NAME) { + + rtlStatus = RtlStringCchCopyNW(AdapterExtension->InitiatorName, + MAX_INITIATOR_NAME, + initiatorName, + MAX_INITIATOR_NAME); + AdapterExtension->InitiatorName[(initiatorNameLen / sizeof(WCHAR))] = 0; + + if (ipAddress->Type == ISCSI_IP_ADDRESS_TEXT) + { + if (stringLen <= 256) + { + rtlStatus = RtlStringCchCopyNW(AdapterExtension->SNSServer, + 256, string, 256); + AdapterExtension->SNSServer[(stringLen / sizeof(WCHAR))] = 0; + } + + } else { + PUCHAR i; + + i = (PUCHAR)&ipAddress->IpV4Address; + + RtlStringCchPrintfW(AdapterExtension->SNSServer, + 256, + L"%d.%d.%d.%d", + i[0], i[1], i[2], i[3]); + } + AdapterExtension->DiscoveryConfigFlags = (config->PerformiSNSDiscovery) ? + DISCOVERY_CONFIG_DO_DISCOVERY : + 0; + + AdapterExtension->DiscoveryConfigFlags |= (config->AutomaticiSNSDiscovery) ? + DISCOVERY_CONFIG_FIND_SNS_AUTOMATICALLY : + 0; + + status = SRB_STATUS_SUCCESS; + } + } + } + } + } + } + } + return(status); +} + +UCHAR iScsiAddPortalGroup( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN ULONG PortalCount + ) +/*+++ + +Routine Description : + + This routine will allocate space of an + ISCSI_DiscoveredTargetPortalGroup structure that can be followed by + a set of ISCSI_DiscoveredTargetPortal data structures that describe + the portals associated with the portal group. + + *Buffer on entry has the current position in the buffer that the + data structures are being built. On return it is updated beyond + the ISCSI_DiscoveredTargetPortalGroup structure. + + *SizeLeft on entry has the number of bytes left in *Buffer. On + return it is updated with the number of bytes consumed by the + ISCSI_DiscoveredTargetPortalGroup structure. If there is not + enough bytes for the ISCSI_DiscoveredTargetPortalGroup + structure then it returns with 0 and SRB_STATUS_DATA_OVERRUN is + the return value from this function. If there is enough bytes + then SRB_STATUS_SUCCESS is returned. If a previous call to this + or iScsiAddPortalToGroup returned *SizeLeft as 0, then it is + permissible to keep calling so that *SizeNeeded gets updated so + that an accurate size for the entire data structure can be + computed. + + *SizeNeeded on entry has the number of bytes needed so far to complete the + request. On return it is updated to include the number of bytes + needed for the ISCSI_DiscoveredTargetPortalGroup structure. + + *PortalGroup returns pointing at the portal group for which space + was allocated by this routine. + +--*/ +{ + UCHAR status; + ULONG PadSize, GroupSize, TotalSize; + PISCSI_DiscoveredTargetPortalGroup2 PortalGroup; + + // + // Be sure that buffer is padded on a 4 byte boundry + // + PadSize = (ULONG)((((ULONG_PTR)*Buffer + 3) &~3) - ((ULONG_PTR)*Buffer)); + + // + // Compute size of portal groups + // + GroupSize = FIELD_OFFSET(ISCSI_DiscoveredTargetPortalGroup2, + Portals); + TotalSize = PadSize + GroupSize; + + // + // Update the size needed to complete the entire request + // + *SizeNeeded += TotalSize; + + if (*SizeLeft >= TotalSize) + { + // + // There is enough room to build the portal group. Return the + // pointer to the portal group. + // + RtlZeroMemory(*Buffer, TotalSize); + + PortalGroup = (PISCSI_DiscoveredTargetPortalGroup2)((PUCHAR)*Buffer + + PadSize); + PortalGroup->PortalCount = PortalCount; + + // + // Update pointer in current buffer and number of bytes left + // + *SizeLeft -= TotalSize; + status = SRB_STATUS_SUCCESS; + } else { + // + // There is not enough room left to build the portal group + // + *SizeLeft = 0; + status = SRB_STATUS_DATA_OVERRUN; + } + + // + // Advance buffer pointer, do this even if there is not enough room + // so the size calculations can take into account any padding + // + *Buffer += TotalSize; + + return(status); +} + +VOID +iScsiCopyUTF8ToCounted( + PWCHAR p, + PUTF8CHAR UTF8, + ULONG UTF8Len + ) +{ + ULONG i; + + *p++ = ((USHORT)UTF8Len * sizeof(WCHAR)); + for (i = 0; i < UTF8Len; i++) + { + // + // This is a quick and dirty conversion from UTF8 to + // UNICODE and is only valid for the US ANSI character set. + // See RFC 2044 for more details on converting UTF8 to + // UNICODE + // + *p++ = (WCHAR)*UTF8++; + } +} + +UCHAR iScsiAddPortalToGroup( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN ULONG Address, + IN PUTF8CHAR SymbolicName, + IN USHORT Socket, + IN ULONG SecurityBitmap, + IN ULONG KeySize, + IN PUCHAR Key + ) +/*+++ + +Routine Description : + + This routine will allocate space of an + ISCSI_DiscoveredTargetPortal structure and fill it with the + parameters passed as appropriate. + + *Buffer on entry has the current position in the buffer that the + data structures are being built. On return it is updated beyond + the ISCSI_DiscoveredTargetPortal structure. + + *SizeLeft on entry has the number of bytes left in *Buffer. On + return it is updated with the number of bytes consumed by the + ISCSI_DiscoveredTargetPortal structure. If there is not + enough bytes for the ISCSI_DiscoveredTargetPortal + structure then it returns with 0 and SRB_STATUS_DATA_OVERRUN is + the return value from this function. If there is enough bytes + then SRB_STATUS_SUCCESS is returned. If a previous call to this + or iScsiAddPortalGroup returned *SizeLeft as 0, then it is + permissible to keep calling so that *SizeNeeded gets updated so + that an accurate size for the entire data structure can be + computed. + + *SizeNeeded on entry has the number of bytes needed so far to complete the + request. On return it is updated to include the number of bytes + needed for the ISCSI_DiscoveredTargetPortal structure. + + Address has the IP Address of the portal + + SymbolicName is a pointer to a UTF8 string that has the portal + symbolic name. + + Socket has the socket number of the portal + + SecurityBitmap is the security bitmap + + KeySize is the number of bytes in the key + + Key is th preshared key + +--*/ +{ + UCHAR status; + PISCSI_DiscoveredTargetPortal2 Portal; + ULONG PadSize, SymbolicNamePos, SymbolicNameLen, PortalSize; + ULONG TotalSize, i; + PWCHAR p; + PULONG pu; + ULONG BitmapPos; + + // + // Portal must be padded on a 4 byte boundry + // + PadSize = (ULONG)((((ULONG_PTR)*Buffer + 3) &~3) - ((ULONG_PTR)*Buffer)); + + // + // Compute the portal size out of the size of the individual + // components. Since these structures are variable length we cannot + // use sizeof() without being very wasteful of memory + // + BitmapPos = FIELD_OFFSET(ISCSI_DiscoveredTargetPortal2, Address) + + FIELD_OFFSET(ISCSI_IP_Address, TextAddress) + + sizeof(USHORT); // 0 length for IP_Address->TextAddress + + SymbolicNamePos = BitmapPos + (2 * sizeof(ULONG)) + KeySize; + + SymbolicNameLen = SymbolicName ? strlen(SymbolicName) : 0; + PortalSize = SymbolicNamePos + + // USHORT for length and size in WCHAR of + // symbolic name + sizeof(USHORT) + (SymbolicNameLen * sizeof(WCHAR)); + + TotalSize = PadSize + PortalSize; + *SizeNeeded += TotalSize; + + if (*SizeLeft >= TotalSize) + { + // + // There is enough room for the portal so build the portal data + // structure + // + Portal = (PISCSI_DiscoveredTargetPortal2)((PUCHAR)*Buffer + PadSize); + + RtlZeroMemory(Portal, TotalSize); + Portal->Socket = Socket; + Portal->Address.Type = ISCSI_IP_ADDRESS_IPV4; + Portal->Address.IpV4Address = Address; + Portal->Address.TextAddress[0] = 0; + + pu = (PULONG)((PUCHAR)Portal + BitmapPos); + + *pu++ = SecurityBitmap; + *pu++ = KeySize; + + memcpy(pu, Key, KeySize); + + // + // FIll in symbolic name; length followed by unicode chars + // + p = (PWCHAR)((PUCHAR)Portal + SymbolicNamePos); + + iScsiCopyUTF8ToCounted(p, SymbolicName, SymbolicNameLen); + + // + // Update our current buffer pointers + // + *SizeLeft -= TotalSize; + + status = SRB_STATUS_SUCCESS; + } else { + // + // There is not enough room for the portal + // + *SizeLeft = 0; + status = SRB_STATUS_DATA_OVERRUN; + } + + // + // Advance buffer pointer, do this even if there is not enough room + // so the size calculations can take into account any padding + // + *Buffer += TotalSize; + + return(status); +} + +UCHAR iScsiAddDiscoveredTarget( + IN OUT PUCHAR *Buffer, + IN OUT PULONG SizeLeft, + IN OUT PULONG SizeNeeded, + IN PUTF8CHAR Name, + IN PUTF8CHAR Alias, + IN PUTF8CHAR DDName, + IN ULONG DDID, + IN ULONG PortalGroupCount + ) +/*+++ + +Routine Description : + + This routine will allocate space of an + ISCSI_DiscoveredTargetPortal structure and fill it with the + parameters passed as appropriate. + + *Buffer on entry has the current position in the buffer that the + data structures are being built. On return it is updated beyond + the ISCSI_DiscoveredTargetPortal structure. + + *SizeLeft on entry has the number of bytes left in *Buffer. On + return it is updated with the number of bytes consumed by the + ISCSI_DiscoveredTargetPortal structure. If there is not + enough bytes for the ISCSI_DiscoveredTargetPortal + structure then it returns with 0 and SRB_STATUS_DATA_OVERRUN is + the return value from this function. If there is enough bytes + then SRB_STATUS_SUCCESS is returned. If a previous call to this + or iScsiAddPortalGroup returned *SizeLeft as 0, then it is + permissible to keep calling so that *SizeNeeded gets updated so + that an accurate size for the entire data structure can be + computed. + + *SizeNeeded on entry has the number of bytes needed so far to complete the + request. On return it is updated to include the number of bytes + needed for the ISCSI_DiscoveredTargetPortal structure. + + Name is the target name + + Alias is the target alias + + DDName is the Discovery domain name + + DDID is dicovery domain id + +--*/ +{ + UCHAR status; + ULONG NameLen, AliasLen, DDNameLen, PadSize, TotalSize; + PWCHAR p; + PISCSI_DiscoveredTarget2 Target; + + NameLen = strlen(Name); + AliasLen = Alias ? strlen(Alias) : 0; + + PadSize = (ULONG)((((ULONG_PTR)*Buffer + 3) &~3) - ((ULONG_PTR)*Buffer)); + + TotalSize = FIELD_OFFSET(ISCSI_DiscoveredTarget2, TargetName) + + (((NameLen+1) + (AliasLen+1) ) * sizeof(WCHAR)) + + PadSize; + + *SizeNeeded += TotalSize; + + if (*SizeLeft >= TotalSize) + { + Target = (PISCSI_DiscoveredTarget2)((PUCHAR)*Buffer + PadSize); + + Target->TargetPortalGroupCount = PortalGroupCount; + + p = (PWCHAR)((PUCHAR)Target + FIELD_OFFSET(ISCSI_DiscoveredTarget2, + TargetName)); + iScsiCopyUTF8ToCounted(p, Name, NameLen); + p += NameLen + 1; + + iScsiCopyUTF8ToCounted(p, Alias, AliasLen); + p += AliasLen + 1; + + *SizeLeft -= TotalSize; + status = SRB_STATUS_SUCCESS; + } else { + // + // There is not enough room for the portal + // + *SizeLeft = 0; + status = SRB_STATUS_DATA_OVERRUN; + } + + // + // Advance buffer pointer, do this even if there is not enough room + // so the size calculations can take into account any padding + // + *Buffer += TotalSize; + + return(status); +} + +UCHAR iScsiSetPresharedKeyForId( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG InBufferSize, + ULONG OutBufferSize, + PULONG SizeNeeded, + PUCHAR Buffer + ) +{ + PSetPresharedKeyForId_IN in; + PSetPresharedKeyForId_OUT out; + UCHAR status; + ULONG sizeExpected; + PCHAR key; + + *SizeNeeded = sizeof(SetPresharedKeyForId_OUT); + + if (OutBufferSize >= *SizeNeeded) + { + status = SRB_STATUS_ERROR; + if (InBufferSize >= FIELD_OFFSET(SetPresharedKeyForId_IN, + Id)) + { + in = (PSetPresharedKeyForId_IN)Buffer; + sizeExpected = FIELD_OFFSET(SetPresharedKeyForId_IN, + Id) + + in->IdSize + + in->KeySize; + if (InBufferSize >= sizeExpected) + { + key = OffsetToPtr(in, FIELD_OFFSET(SetPresharedKeyForId_IN, + Id) + + in->IdSize); + + DebugPrint((iScsiPrtDebugError, + "iScsiSetPresharedKeyForId: in %p type %d idlen %x at %p KeyLen is %x at %p\n", + in, + in->IdType, + in->IdSize, + in->Id, + in->KeySize, + key)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "iScsiSetPresharedKeyForId: in %p type %d idlen %x at %p KeyLen is %x at %p\n", + in, + in->IdType, + in->IdSize, + in->Id, + in->KeySize, + key); + + out = (PSetPresharedKeyForId_OUT)Buffer; + out->Status = STATUS_SUCCESS; + status = SRB_STATUS_SUCCESS; + } + } + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + return(status); +} + + +UCHAR iScsiSetGroupPresharedKey( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG InBufferSize, + ULONG OutBufferSize, + PULONG SizeNeeded, + PUCHAR Buffer + ) +{ + PSetGroupPresharedKey_IN in; + PSetGroupPresharedKey_OUT out; + UCHAR status; + ULONG sizeExpected; + + *SizeNeeded = sizeof(SetGroupPresharedKey_OUT); + + if (OutBufferSize >= *SizeNeeded) + { + status = SRB_STATUS_ERROR; + if (InBufferSize >= FIELD_OFFSET(SetGroupPresharedKey_IN, + Key)) + { + in = (PSetGroupPresharedKey_IN)Buffer; + sizeExpected = FIELD_OFFSET(SetGroupPresharedKey_IN, + Key) + in->KeySize; + if (InBufferSize >= sizeExpected) + { + DebugPrint((iScsiPrtDebugError, + "iScsiSetGroupPresharedKey: in %p KeyLen is %x at %p\n", + in, + in->KeySize, + in->Key)); + + ETWDebugPrint(iScsiLevelError, iScsiFlagWmi, + "iScsiSetGroupPresharedKey: in %p KeyLen is %x at %p\n", + in, + in->KeySize, + in->Key); + + out = (PSetGroupPresharedKey_OUT)Buffer; + out->Status = STATUS_SUCCESS; + status = SRB_STATUS_SUCCESS; + } + } + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + return(status); +} + +UCHAR iScsiSetTunnelModeOuterAddress( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG InBufferSize, + ULONG OutBufferSize, + PULONG SizeNeeded, + PUCHAR Buffer + ) +{ + PSetTunnelModeOuterAddress_IN in; + PSetTunnelModeOuterAddress_OUT out; + UCHAR status; + ULONG sizeExpected; + + *SizeNeeded = sizeof(SetTunnelModeOuterAddress_OUT); + + if (OutBufferSize >= *SizeNeeded) + { + status = SRB_STATUS_ERROR; + if (InBufferSize >= sizeof(SetTunnelModeOuterAddress_IN)) + { + in = (PSetTunnelModeOuterAddress_IN)Buffer; + + DebugPrint((iScsiPrtDebugError, + "iScsiSetTunnelModeOuterAddress: in %p port %x\n", + in, + in->PortNumber)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "iScsiSetTunnelModeOuterAddress: in %p port %x\n", + in, + in->PortNumber); + + out = (PSetTunnelModeOuterAddress_OUT)Buffer; + out->Status = STATUS_SUCCESS; + status = SRB_STATUS_SUCCESS; + } + } else { + status = SRB_STATUS_DATA_OVERRUN; + } + + return(status); +} + +UCHAR iScsiReportDiscoveredTargets2( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG BufferSize, + PULONG SizeNeeded, + PUCHAR Buffer + ) +{ + UCHAR status; + PReportDiscoveredTargets2_OUT out; + ULONG size; + + + *SizeNeeded = FIELD_OFFSET(ReportDiscoveredTargets2_OUT, + Targets); + if (BufferSize >= *SizeNeeded) + { + out = (PReportDiscoveredTargets2_OUT)Buffer; + out->Status = STATUS_SUCCESS; + out->TargetCount = 3; + + BufferSize -= *SizeNeeded; + } + + // + // Advance buffer pointer, do this even if there is not enough room + // so the size calculations can take into account any padding + // + Buffer += *SizeNeeded; + + iScsiAddDiscoveredTarget(&Buffer, + &BufferSize, + SizeNeeded, + "Target1", + "Alias", + "DiscoveryDomain", + 3, + 1); + + iScsiAddPortalGroup(&Buffer, + &BufferSize, + SizeNeeded, + 1); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x12345678, + "SymbolicName", + 5003, + 0x11223344, + 0, + NULL + ); + + + // + // Target 2, 2 portal groups, 1 portal and 2 portals + // + iScsiAddDiscoveredTarget(&Buffer, + &BufferSize, + SizeNeeded, + "Target2", + NULL, + "DiscoveryDomain", + 3, + 2); + + iScsiAddPortalGroup(&Buffer, + &BufferSize, + SizeNeeded, + 1); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111111, + "SymbolicName", + 5003, + 0x44332211, + 8, + "12345678"); + + iScsiAddPortalGroup(&Buffer, + &BufferSize, + SizeNeeded, + 2); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x12345678, + "SymbolicName1", + 5003, + 0x23, + 8, + "12345678"); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x12345679, + "SymbolicName2", + 5003, + 0x34, + 8, + "12345678"); + + // + // Target 3 + // + iScsiAddDiscoveredTarget(&Buffer, + &BufferSize, + SizeNeeded, + "Target3", + NULL, + NULL, + 3, + 2); + + iScsiAddPortalGroup(&Buffer, + &BufferSize, + SizeNeeded, + 5); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111111, + "SymbolicName1", + 5003, + 0x23, + 0, + NULL); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111113, + "SymbolicName2", + 5003, + 0x23, + 0, + NULL); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111113, + NULL, + 5003, + 0x23, + 0, + NULL); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111114, + NULL, + 5003, + 0x23, + 0, + NULL); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x11111115, + "SymbolicName5", + 5003, + 0x23, + 0, + NULL); + + iScsiAddPortalGroup(&Buffer, + &BufferSize, + SizeNeeded, + 2); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x12345678, + "SymbolicName1", + 5003, + 0x23, + 0, + NULL); + + status = iScsiAddPortalToGroup(&Buffer, + &BufferSize, + SizeNeeded, + 0x12345679, + "SymbolicName2", + 5003, + 0x23, + 0, + NULL); + + return(status); +} + +UCHAR +iSpReadTCPConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PUCHAR Buffer + ) +/*++ + +Routine Description: + + Read the iScsi Initiator Instance TCP configuration into the OS buffer. + +Arguments: + + AdapterExtension - miniport drivers storage + Buffer - Used to store all the information of a paticular initiator + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_TCPIPConfig TCPConfigData; + UCHAR status; + + + TCPConfigData = (PMSiSCSI_TCPIPConfig)Buffer; + RtlZeroMemory(TCPConfigData, sizeof(MSiSCSI_TCPIPConfig)); + + RtlCopyMemory(TCPConfigData, + &(AdapterExtension->TCPConfigData), + sizeof(MSiSCSI_TCPIPConfig)); + + if (TCPConfigData->IpAddress.TextAddress[0] == 0) + { + TCPConfigData->IpAddress.TextAddress[0] = 256 * sizeof(WCHAR); + } + + if (TCPConfigData->DefaultGateway.TextAddress[0] == 0) + { + TCPConfigData->DefaultGateway.TextAddress[0] = 256 * sizeof(WCHAR); + } + + if (TCPConfigData->SubnetMask.TextAddress[0] == 0) + { + TCPConfigData->SubnetMask.TextAddress[0] = 256 * sizeof(WCHAR); + } + + if (TCPConfigData->PreferredDNSServer.TextAddress[0] == 0) + { + TCPConfigData->PreferredDNSServer.TextAddress[0] = 256 * sizeof(WCHAR); + } + + if (TCPConfigData->AlternateDNSServer.TextAddress[0] == 0) + { + TCPConfigData->AlternateDNSServer.TextAddress[0] = 256 * sizeof(WCHAR); + } + + return SRB_STATUS_SUCCESS; +} + + +UCHAR +iSpReadNICConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + OUT PUCHAR Buffer + ) +/*++ + +Routine Description: + + Read the iScsi Initiator Instance statistics information into the OS buffer. + +Arguments: + + AdapterExtension - miniport drivers storage + Buffer - Used to store all the information of a paticular initiator + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_NICConfig NICConfigData; + UCHAR status; + + + NICConfigData = (PMSiSCSI_NICConfig)Buffer; + + RtlZeroMemory(NICConfigData, sizeof(MSiSCSI_NICConfig)); + + // Link Speed + NICConfigData->LinkSpeed = 100000000; + + // Link State + NICConfigData->LinkState = ISCSI_NIC_LINKSTATE_CONNECTED; + + NICConfigData->MaxFrameSize = 65536; + + // Ethernet MAC Address + NICConfigData->MacAddress[0] = 0x31; + NICConfigData->MacAddress[1] = 0x32; + NICConfigData->MacAddress[2] = 0x33; + NICConfigData->MacAddress[3] = 0x34; + NICConfigData->MacAddress[4] = 0x35; + NICConfigData->MacAddress[5] = 0x36; + + status = SRB_STATUS_SUCCESS; + return status; +} + + +UCHAR +iSpSetTCPConfigInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN ULONG BufferSize, + IN PUCHAR Buffer + ) +/*++ + +Routine Description: + + Sets the content in the Buffer to the drivers adapterExtension + +Arguments: + + AdapterExtension - iScsi miniport driver's adapter data storage. + + BufferSize - Specifies the size in bytes of the buffer at Buffer. + + Buffer - Points to a buffer that contains new values for the instance. + +Return Value: + + UCHAR - SRB Status for this request + +--*/ +{ + PMSiSCSI_TCPIPConfig PTCPConfigBuffer; + PISCSI_IP_Address iScsiIPAddress; + PISCSI_IP_Address destiScsiIPAddress; + PUCHAR currentIpData; + ULONG sizeNeeded; + ULONG inx; + UCHAR status = SRB_STATUS_SUCCESS; + + PTCPConfigBuffer = (PMSiSCSI_TCPIPConfig)Buffer; + + sizeNeeded = FIELD_OFFSET(MSiSCSI_TCPIPConfig, IpAddress); + + if ((Buffer == NULL) || (BufferSize < sizeNeeded)) { + + return SRB_STATUS_ERROR; + } + + RtlZeroMemory(&(AdapterExtension->TCPConfigData), + sizeof(MSiSCSI_TCPIPConfig)); + + AdapterExtension->TCPConfigData.UseLinkLocalAddress = + PTCPConfigBuffer->UseLinkLocalAddress; + + AdapterExtension->TCPConfigData.EnableDHCP = + PTCPConfigBuffer->EnableDHCP; + + BufferSize -= sizeNeeded; + + iScsiIPAddress = &(PTCPConfigBuffer->IpAddress); + + destiScsiIPAddress = &(AdapterExtension->TCPConfigData.IpAddress); + + // + // 5 is the number of ISCSI_IP_Address entries + // in MSiSCSI_TCPIPConfig structure + // + inx = 0; + while (inx < 5) { + + status = SRB_STATUS_SUCCESS; + + sizeNeeded = FIELD_OFFSET(ISCSI_IP_Address, TextAddress) + sizeof(WCHAR); + + if (BufferSize < sizeNeeded) { + + status = SRB_STATUS_ERROR; + } else { + + sizeNeeded += iScsiIPAddress->TextAddress[0]; + + if (BufferSize < sizeNeeded) { + status = SRB_STATUS_ERROR; + } + } + + if (status == SRB_STATUS_SUCCESS) { + + BufferSize -= sizeNeeded; + + destiScsiIPAddress->Type = iScsiIPAddress->Type; + + iScsiIPAddress->TextAddress[0] = + MAX_ISCSI_TEXT_ADDRESS_LEN * sizeof(WCHAR); + + switch (iScsiIPAddress->Type) { + case ISCSI_IP_ADDRESS_TEXT: + { + RtlCopyMemory(&(destiScsiIPAddress->TextAddress[1]), + &(iScsiIPAddress->TextAddress[1]), + iScsiIPAddress->TextAddress[0]); + + break; + } + + case ISCSI_IP_ADDRESS_IPV4: + { + destiScsiIPAddress->IpV4Address = + iScsiIPAddress->IpV4Address; + + break; + } + + case ISCSI_IP_ADDRESS_IPV6: + { + RtlCopyMemory(destiScsiIPAddress->IpV6Address, + iScsiIPAddress->IpV6Address, + sizeof(iScsiIPAddress->IpV6Address)); + + destiScsiIPAddress->IpV6FlowInfo = + iScsiIPAddress->IpV6FlowInfo; + + destiScsiIPAddress->IpV6ScopeId = + iScsiIPAddress->IpV6ScopeId; + + break; + } + + default: + { + status = SRB_STATUS_ERROR; + return(status); + break; + } + } + + iScsiIPAddress = (PISCSI_IP_Address) ((PUCHAR)(iScsiIPAddress) + + ((sizeNeeded + 3) & ~3)); + + destiScsiIPAddress++; + + inx++; + + } else { + + break; + } + } + + return status; +} + +UCHAR +iScsiSetWmiDataBlock( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG BufferSize, + IN PUCHAR Buffer + ) +/*+++ + +Routine Description: + + This routine is called to set a WMI data block. + +--*/ +{ + PISCSI_ADAPTER_EXTENSION adapterExtension; + ULONG sizeNeeded = 0; + PSCSI_WMI_REQUEST_BLOCK srb; + UCHAR status; + + DebugPrint((iScsiPrtDebugTrace, + "SetWmiDataBlock : GuidIndex - %x\n", + GuidIndex)); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "SetWmiDataBlock : GuidIndex - %x\n", + GuidIndex); + + adapterExtension = (PISCSI_ADAPTER_EXTENSION) Context; + srb = (PSCSI_WMI_REQUEST_BLOCK) DispatchContext->UserContext; + + switch (GuidIndex) + { + case iScsiDiscoveryConfigGuid_INDEX: + { + status = iScsiSetDiscoveryConfig(adapterExtension, + BufferSize, + Buffer); + sizeNeeded = 0; + break; + } + + case iScsi_TCPConfig_GUID_Index: + { + status = iSpSetTCPConfigInfo(adapterExtension, BufferSize, Buffer); + break; + } + + default: + { + status = SRB_STATUS_ERROR; + break; + } + } + + iSpCompleteWmiRequest(adapterExtension, srb, DispatchContext, status, sizeNeeded); + + // + // return SRB_STATUS_PENDING since the request has either already been + // completed in iSpCompleteWmiRequest or the status is really + // SRB_STATUS_PENDING. This implies that the iScsiWmiSrb routine + // may not touch the srb since it is already completed. + // + return SRB_STATUS_PENDING; + +} + +UCHAR iScsiPerformPing( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + PISCSI_IP_Address IpAddress, + ULONG RequestCount, + ULONG RequestSize, + ULONG Timeout, + ISDSC_STATUS *Status, + ULONG *ResponseCount +) +{ + // + // Here is where the HBA should do the ping operations. Note that + // this code doesn't pend, but your code should pend as the ping + // operation could be lengthy. + // + *Status = STATUS_SUCCESS; + *ResponseCount = RequestCount; + + return(SRB_STATUS_SUCCESS); +} + +UCHAR iSCSIValidateIPAddress( + PISCSI_IP_Address IpAddress, + ULONG BufferSize + ) +{ + ULONG sizeUsed; + UCHAR srbStatus; + + sizeUsed = (FIELD_OFFSET(ISCSI_IP_Address, + TextAddress) + + sizeof(USHORT)); + + if (BufferSize >= sizeUsed) + { + BufferSize -= sizeUsed; + sizeUsed = IpAddress->TextAddress[0]; + + if (BufferSize >= sizeUsed) + { + srbStatus = SRB_STATUS_SUCCESS; + } else { + srbStatus = SRB_STATUS_INVALID_REQUEST; + } + } else { + srbStatus = SRB_STATUS_INVALID_REQUEST; + } + + return(srbStatus); +} + +UCHAR iSCSIPerformPingOperation( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ULONG InBufferSize, + ULONG OutBufferSize, + ULONG *SizeNeeded, + PUCHAR Buffer + ) +{ + ULONG requestCount; + ULONG requestSize; + ULONG timeout; + ULONG responseCount; + PISCSI_IP_Address ipAddress; + UCHAR srbStatus; + PPingIPAddress_OUT pingOut; + PPingIPAddress_IN pingIn; + ISDSC_STATUS status; + + + // + // Make sure there is enough room in out buffer + // + *SizeNeeded = sizeof(PingIPAddress_OUT); + + if (OutBufferSize >= *SizeNeeded) + { + if (InBufferSize > FIELD_OFFSET(PingIPAddress_IN, + Address)) + { + pingIn = (PPingIPAddress_IN)Buffer; + requestCount = pingIn->RequestCount; + requestSize = pingIn->RequestSize; + timeout = pingIn->Timeout; + ipAddress = &pingIn->Address; + + srbStatus = iSCSIValidateIPAddress(ipAddress, + InBufferSize - + FIELD_OFFSET(PingIPAddress_IN, + Address) + ); + + if (srbStatus == SRB_STATUS_SUCCESS) + { + srbStatus = iScsiPerformPing(AdapterExtension, + ipAddress, + requestCount, + requestSize, + timeout, + &status, + &responseCount); + + // + // return the results of the ping + // + pingOut = (PPingIPAddress_OUT)Buffer; + pingOut->Status = status; + pingOut->ResponsesReceived = responseCount; + } + + } else { + // + // Input buffer is not correct size + // + srbStatus = SRB_STATUS_INVALID_REQUEST; + } + + } else { + srbStatus = SRB_STATUS_DATA_OVERRUN; + } + + return(srbStatus); +} + + +UCHAR +iScsiExecuteWmiMethod( + IN PVOID Context, + IN PSCSIWMI_REQUEST_CONTEXT DispatchContext, + IN ULONG GuidIndex, + IN ULONG InstanceIndex, + IN ULONG MethodId, + IN ULONG InBufferSize, + IN ULONG OutBufferSize, + IN OUT PUCHAR Buffer + ) +/*+++ + +Routine Description: + + This routine is called to execute a WMI method. + The methods here include Login, Logout, SendTargets, etc + +--*/ +{ + PISCSI_ADAPTER_EXTENSION adapterExtension; + PSCSI_WMI_REQUEST_BLOCK srb; + PISCSI_SRB_EXTENSION srbExtension; + ULONG sizeNeeded = 0; + UCHAR status = SRB_STATUS_SUCCESS; + + DebugPrint((iScsiPrtDebugTrace, + "ExecuteWMIMethod : GuidIndex - %x, MethodId - %x\n", + GuidIndex, + MethodId)); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "ExecuteWMIMethod : GuidIndex - %x, MethodId - %x\n", + GuidIndex, + MethodId); + + adapterExtension = (PISCSI_ADAPTER_EXTENSION) Context; + + srb = (PSCSI_WMI_REQUEST_BLOCK) DispatchContext->UserContext; + + srbExtension = (PISCSI_SRB_EXTENSION) srb->SrbExtension; + + // + // Save the input parameters in the SRB extension + // + srbExtension->Buffer = Buffer; + srbExtension->InBufferSize = InBufferSize; + srbExtension->OutBufferSize = OutBufferSize; + + // + // Note that in all the WMI calls, if we are setting the status + // in Buffer (loginTargetOut, logoutTargetOut, etc), we should + // always return SRB_STATUS_SUCCESS. Status field will be set + // to STATUS_SUCCESS if the operation is successful, and will + // be set to the approproate error code if there was an error. + // + switch (GuidIndex) { + case iSCSI_Operations_GUID_Index: { + + DebugPrint((iScsiPrtDebugTrace, + "iSCSI Operations method %d\n", + MethodId)); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "iSCSI Operations method %d\n", + MethodId); + + switch (MethodId) { + case LoginToTarget: { + + PLoginToTarget_IN loginTargetIn; + + sizeNeeded = sizeof(LoginToTarget_OUT); + + if (InBufferSize < sizeof(LoginToTarget_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(LoginToTarget_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + loginTargetIn = (PLoginToTarget_IN) Buffer; + + status = iSpProcessLoginToTarget(adapterExtension, + loginTargetIn, + srb, + InBufferSize); + break; + } + + case LogoutFromTarget: { + + PLogoutFromTarget_IN logoutTargetIn; + + sizeNeeded = sizeof(LogoutFromTarget_OUT); + + if (InBufferSize < sizeof(LogoutFromTarget_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(LogoutFromTarget_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + logoutTargetIn = (PLogoutFromTarget_IN) Buffer; + + status = iSpProcessLogoutFromTarget(adapterExtension, + logoutTargetIn, + srb); + break; + } + + case AddConnectionToSession: { + + PAddConnectionToSession_IN addConnectionIn; + + sizeNeeded = sizeof(AddConnectionToSession_OUT); + + if (InBufferSize < sizeof(AddConnectionToSession_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(AddConnectionToSession_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + addConnectionIn = (PAddConnectionToSession_IN) Buffer; + + status = iSpProcessAddConnectionToSession(adapterExtension, + addConnectionIn, + srb, + InBufferSize); + break; + } + + case RemoveConnectionFromSession: { + + PRemoveConnectionFromSession_IN removeConnectionIn; + + if (InBufferSize < sizeof(RemoveConnectionFromSession_IN)) { + + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(RemoveConnectionFromSession_OUT)) { + + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + removeConnectionIn = (PRemoveConnectionFromSession_IN) Buffer; + + sizeNeeded = sizeof(RemoveConnectionFromSession_OUT); + + status = iSpProcessRemoveConnectionToSession(adapterExtension, + removeConnectionIn, + srb, + InBufferSize); + break; + } + + case SendTargets: { + + PSendTargets_IN sendTargetsIn; + + sizeNeeded = sizeof(SendTargets_OUT); + + if (InBufferSize < sizeof(SendTargets_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(SendTargets_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + sendTargetsIn = (PSendTargets_IN) Buffer; + + status = iSpProcessSendTargets(adapterExtension, + sendTargetsIn, + srb); + + break; + } + + case ScsiInquiry: { + + PScsiInquiry_IN scsiInquiryIn; + + sizeNeeded = sizeof(ScsiInquiry_OUT); + + if (InBufferSize < sizeof(ScsiInquiry_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(ScsiInquiry_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + scsiInquiryIn = (PScsiInquiry_IN) Buffer; + + status = iSpProcessScsiInquiry(adapterExtension, + scsiInquiryIn, + srb); + break; + } + + case ScsiReadCapacity: { + + PScsiReadCapacity_IN scsiReadCapacityIn; + + sizeNeeded = sizeof(ScsiReadCapacity_OUT); + + if (InBufferSize < sizeof(ScsiReadCapacity_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(ScsiReadCapacity_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + scsiReadCapacityIn = (PScsiReadCapacity_IN) Buffer; + + status = iSpProcessScsiReadCapacity(adapterExtension, + scsiReadCapacityIn, + srb); + + break; + } + + case ScsiReportLuns: { + + PScsiReportLuns_IN scsiReportLunsIn; + + sizeNeeded = sizeof(ScsiReportLuns_OUT); + + if (InBufferSize < sizeof(ScsiReportLuns_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(ScsiReportLuns_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + scsiReportLunsIn = (PScsiReportLuns_IN) Buffer; + + status = iSpProcessScsiReportLuns(adapterExtension, + scsiReportLunsIn, + srb); + break; + } + + case SetCHAPSharedSecret: { + + PSetCHAPSharedSecret_IN setCHAPSecretIn; + PSetCHAPSharedSecret_OUT setCHAPSecretOut; + ULONG secretSize; + ULONG bufferSizeNeeded; + + setCHAPSecretOut = (PSetCHAPSharedSecret_OUT) Buffer; + + sizeNeeded = 0; + + RtlZeroMemory(adapterExtension->InitiatorSecret, + sizeof(adapterExtension->InitiatorSecret)); + + adapterExtension->InitiatorSecretLen = 0; + + if (InBufferSize >= FIELD_OFFSET(SetCHAPSharedSecret_IN, + SharedSecret)) { + + setCHAPSecretIn = (PSetCHAPSharedSecret_IN) Buffer; + + secretSize = setCHAPSecretIn->SharedSecretSize; + + if (secretSize == 0) { + + setCHAPSecretOut->Status = STATUS_SUCCESS; + + status = SRB_STATUS_SUCCESS; + + } else if (secretSize > MAX_CHAP_SECRET_LENGTH) { + + setCHAPSecretOut->Status = ISDSC_NON_SPECIFIC_ERROR; + + status = SRB_STATUS_SUCCESS; + + } else { + + bufferSizeNeeded = secretSize + + FIELD_OFFSET(SetCHAPSharedSecret_IN, + SharedSecret); + + if (InBufferSize >= bufferSizeNeeded) { + + RtlCopyMemory(adapterExtension->InitiatorSecret, + setCHAPSecretIn->SharedSecret, + secretSize); + + adapterExtension->InitiatorSecretLen = secretSize; + + status = SRB_STATUS_SUCCESS; + + setCHAPSecretOut->Status = STATUS_SUCCESS; + } else { + + status = SRB_STATUS_INVALID_REQUEST; + + setCHAPSecretOut->Status = ISDSC_NON_SPECIFIC_ERROR; + } + } + + sizeNeeded = sizeof(SetCHAPSharedSecret_OUT); + + } else { + + status = SRB_STATUS_INVALID_REQUEST; + } + + break; + } + + case SetRADIUSSharedSecret: { + + PSetRADIUSSharedSecret_IN setRADIUSSecretIn; + PSetRADIUSSharedSecret_OUT setRADIUSSecretOut; + ULONG secretSize; + ULONG bufferSizeNeeded; + + setRADIUSSecretOut = (PSetRADIUSSharedSecret_OUT) Buffer; + + sizeNeeded = 0; + + RtlZeroMemory(adapterExtension->RadiusSecret, + sizeof(adapterExtension->RadiusSecret)); + + adapterExtension->RadiusSecretLen = 0; + + if (InBufferSize >= FIELD_OFFSET(SetRADIUSSharedSecret_IN, + SharedSecret)) { + + setRADIUSSecretIn = (PSetRADIUSSharedSecret_IN) Buffer; + + secretSize = setRADIUSSecretIn->SharedSecretSize; + + if (secretSize == 0) { + + setRADIUSSecretOut->Status = STATUS_SUCCESS; + + status = SRB_STATUS_SUCCESS; + + } else if (secretSize > MAX_RADIUS_SECRET_LENGTH) { + + setRADIUSSecretOut->Status = ISDSC_NON_SPECIFIC_ERROR; + + status = SRB_STATUS_SUCCESS; + + } else { + + bufferSizeNeeded = secretSize + + FIELD_OFFSET(SetRADIUSSharedSecret_IN, + SharedSecret); + + if (InBufferSize >= bufferSizeNeeded) { + + RtlCopyMemory(adapterExtension->RadiusSecret, + setRADIUSSecretIn->SharedSecret, + secretSize); + + adapterExtension->RadiusSecretLen = secretSize; + + status = SRB_STATUS_SUCCESS; + + setRADIUSSecretOut->Status = STATUS_SUCCESS; + } else { + + status = SRB_STATUS_INVALID_REQUEST; + + setRADIUSSecretOut->Status = ISDSC_NON_SPECIFIC_ERROR; + } + } + + sizeNeeded = sizeof(SetRADIUSSharedSecret_OUT); + + } else { + + status = SRB_STATUS_INVALID_REQUEST; + } + + break; + } + + case RemovePersistentLogin: { + + PRemovePersistentLogin_IN removePersistentLoginIn; + + sizeNeeded = sizeof(RemovePersistentLogin_OUT); + + if (InBufferSize < sizeof(RemovePersistentLogin_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(RemovePersistentLogin_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + removePersistentLoginIn = (PRemovePersistentLogin_IN) Buffer; + + status = iSpRemovePersistentLogin(adapterExtension, + removePersistentLoginIn, + srb); + break; + } + + case AddRADIUSServer: { + + PAddRADIUSServer_IN addRADIUSServerIn; + PAddRADIUSServer_OUT addRADIUSServerOut; + ULONG newServerNameLength; + PISCSI_IP_Address list; + ULONG count; + ULONG updatedCount; + ULONG size; + ULONG inx = 0; + BOOLEAN addressFound = FALSE; + + sizeNeeded = sizeof(AddRADIUSServer_OUT); + + if (InBufferSize < sizeof(AddRADIUSServer_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(AddRADIUSServer_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + addRADIUSServerIn = (PAddRADIUSServer_IN) Buffer; + + addRADIUSServerOut = (PAddRADIUSServer_OUT) Buffer; + + list = adapterExtension->RadiusServerList; + count = adapterExtension->RadiusServerListCount; + + while (inx < count) { + + if (RtlEqualMemory(&(list[inx]), + &(addRADIUSServerIn->RADIUSIPAddress), + sizeof(ISCSI_IP_Address))) { + + addressFound = TRUE; + + status = SRB_STATUS_SUCCESS; + + addRADIUSServerOut->Status = STATUS_SUCCESS; + + break; + } + + inx++; + } + + if (addressFound) { + break; + } + + updatedCount = count + 1; + size = updatedCount * sizeof(ISCSI_IP_Address); + + adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPool, + size, + 'vrSR'); + + if (adapterExtension->RadiusServerList != NULL) { + + RtlZeroMemory(adapterExtension->RadiusServerList, + size); + + RtlCopyMemory(adapterExtension->RadiusServerList, + &(addRADIUSServerIn->RADIUSIPAddress), + sizeof(ISCSI_IP_Address)); + + if (count > 0) { + + RtlCopyMemory((adapterExtension->RadiusServerList + 1), + list, + (count * sizeof(ISCSI_IP_Address))); + } + + adapterExtension->RadiusServerListCount = updatedCount; + + if (list != NULL) { + + ExFreePool(list); + } + + status = SRB_STATUS_SUCCESS; + + addRADIUSServerOut->Status = STATUS_SUCCESS; + + } else { + + adapterExtension->RadiusServerList = list; + + status = SRB_STATUS_INVALID_REQUEST; + + addRADIUSServerOut->Status = ISDSC_OUT_OF_RESOURCES; + + } + + break; + } + + case RemoveRADIUSServer: { + + PRemoveRADIUSServer_IN removeRADIUSServerIn; + PRemoveRADIUSServer_OUT removeRADIUSServerOut; + PISCSI_IP_Address removeAddress; + PISCSI_IP_Address list; + ULONG count; + PWCHAR updatedList; + ULONG updatedCount; + ULONG itr; + PISCSI_IP_Address itrList; + BOOLEAN found = FALSE; + ULONG size = 0; + + + sizeNeeded = sizeof(RemoveRADIUSServer_OUT); + + if (InBufferSize < sizeof(RemoveRADIUSServer_IN)) { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (OutBufferSize < sizeof(RemoveRADIUSServer_OUT)) { + status = SRB_STATUS_DATA_OVERRUN; + break; + } + + removeRADIUSServerIn = (PRemoveRADIUSServer_IN) Buffer; + + removeRADIUSServerOut = (PRemoveRADIUSServer_OUT) Buffer; + + list = adapterExtension->RadiusServerList; + count = adapterExtension->RadiusServerListCount; + + itr = 0; + itrList = list; + removeAddress = &(removeRADIUSServerIn->RADIUSIPAddress); + while (itr < count) { + + ULONG inx; + + if (itrList->Type == removeAddress->Type) { + + if (itrList->Type == ISCSI_IP_ADDRESS_IPV4) { + if (itrList->IpV4Address == removeAddress->IpV4Address) { + found = TRUE; + } + } + + if (itrList->Type == ISCSI_IP_ADDRESS_IPV6) { + for (inx = 0; inx < 16; inx++) { + if (itrList->IpV6Address[inx] == removeAddress->IpV6Address[inx]) { + found = TRUE; + } else { + found = FALSE; + break; + } + } + } + + if (itrList->Type == ISCSI_IP_ADDRESS_TEXT) { + if (wcscmp(itrList->TextAddress, removeAddress->TextAddress) == 0) { + found = TRUE; + } + } + } + + if (found) + break; + + itr++; + itrList++; + } + + if (found) { + + updatedCount = count - 1; + size = updatedCount * sizeof(ISCSI_IP_Address); + + if (updatedCount > 0) { + + adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPool, + size, + 'vrSR'); + + if (adapterExtension->RadiusServerList != NULL) { + + RtlZeroMemory(adapterExtension->RadiusServerList, + size); + + RtlCopyMemory(adapterExtension->RadiusServerList, + list, + (itr * sizeof(ISCSI_IP_Address))); + + itr++; + itrList++; + + if (itr < count) { + + RtlCopyMemory((adapterExtension->RadiusServerList) + (itr - 1), + itrList, + ((count - itr) * sizeof(ISCSI_IP_Address))); + } + + adapterExtension->RadiusServerListCount = updatedCount; + + ExFreePool(list); + + status = SRB_STATUS_SUCCESS; + + removeRADIUSServerOut->Status = STATUS_SUCCESS; + + } else { + + adapterExtension->RadiusServerList = list; + + status = SRB_STATUS_INVALID_REQUEST; + + removeRADIUSServerOut->Status = ISDSC_OUT_OF_RESOURCES; + + } + } else { + + adapterExtension->RadiusServerList = NULL; + + adapterExtension->RadiusServerListCount = updatedCount; + + ExFreePool(list); + + status = SRB_STATUS_SUCCESS; + + removeRADIUSServerOut->Status = STATUS_SUCCESS; + } + + } else { + + removeRADIUSServerOut->Status = ISDSC_NON_SPECIFIC_ERROR; + + status = SRB_STATUS_INVALID_REQUEST; + } + + break; + } + + default: { + + status = SRB_STATUS_INVALID_REQUEST; + + break; + } + } // switch (MethodId) + + break; + } // case iSCSI_Operations_GUID_Index: + + case iScsi_LB_Operations_GUID_Index: { + + DebugPrint((iScsiPrtDebugTrace, + "Set LB policy\n")); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "Set LB policy\n"); + + switch (MethodId) { + case SetLoadBalancePolicy: { + + sizeNeeded = sizeof(SetLoadBalancePolicy_OUT); + + if (OutBufferSize >= sizeNeeded) { + + status = iSpSetLoadBalancePolicy(adapterExtension, + srb, + Buffer, + InBufferSize); + } else { + + DebugPrint((iScsiPrtDebugError, + "Output buffer too small for SetLBPolicy\n")); + + ETWDebugPrint(iScsiLevelError, iScsiFlagWmi, + "Output buffer too small for SetLBPolicy\n"); + + status = SRB_STATUS_DATA_OVERRUN; + } + + break; + } + + default: { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + } + + break; + } // iScsi_LB_Operations_GUID_Index + + case iSCSI_DiscoveryOperationsGuid_INDEX: { + switch (MethodId) + { + case ReportDiscoveredTargets2: + { + status = iScsiReportDiscoveredTargets2(adapterExtension, + OutBufferSize, + &sizeNeeded, + Buffer); + break; + } + + default: { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + } + break; + } // case iSCSI_DiscoveryOperationsGuid_INDEX + + case iScsi_ManagementOperation_GUID_Index: { + switch (MethodId) + { + case PingIPAddress: + { + status = iSCSIPerformPingOperation(adapterExtension, + InBufferSize, + OutBufferSize, + &sizeNeeded, + Buffer); + break; + } + + default: { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + } + break; + } + + case iSCSI_SecurityConfigOperationsGuid_INDEX: + { + switch (MethodId) + { + case SetPresharedKeyForId: + { + status = iScsiSetPresharedKeyForId(adapterExtension, + InBufferSize, + OutBufferSize, + &sizeNeeded, + Buffer); + break; + } + + case SetGroupPresharedKey: + { + status = iScsiSetGroupPresharedKey(adapterExtension, + InBufferSize, + OutBufferSize, + &sizeNeeded, + Buffer); + break; + } + + case SetTunnelModeOuterAddress: + { + status = iScsiSetTunnelModeOuterAddress(adapterExtension, + InBufferSize, + OutBufferSize, + &sizeNeeded, + Buffer); + break; + } + + default: { + status = SRB_STATUS_INVALID_REQUEST; + break; + } + } + break; + } // case iSCSI_SecurityConfigOperationsGuid_INDEX + + default: { + + status = SRB_STATUS_INVALID_REQUEST; + + break; + } + } // switch (GuidIndex) + + // + // Complete the request here if the request is NOT pending + // + if (status != SRB_STATUS_PENDING) { + + iSpCompleteWmiRequest(adapterExtension, + srb, + DispatchContext, + status, + sizeNeeded); + } + + // + // return SRB_STATUS_PENDING since the request has either already been + // completed in iSpCompleteWmiRequest or the status is really + // SRB_STATUS_PENDING. This implies that the iScsiWmiSrb routine + // may not touch the srb since it is already completed. + // + return SRB_STATUS_PENDING; +} + + +ISDSC_STATUS +iSpValidateLoginParameters( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PLoginToTarget_IN LoginTargetIn, + IN ULONG InBufferSize + ) +{ + ULONG sizeNeeded; + ISCSI_AUTH_TYPES authType; + BOOLEAN inputValid; + + + // + // Ensure that the given buffer is large enough to hold + // all login input data + // + sizeNeeded = FIELD_OFFSET(LoginToTarget_IN, Mappings) + + FIELD_OFFSET(ISCSI_TargetMapping, LUNList); + + if (InBufferSize >= sizeNeeded ) { + + sizeNeeded += (LoginTargetIn->Mappings.LUNCount * sizeof(ISCSI_LUNList)) + + LoginTargetIn->KeySize + + LoginTargetIn->UsernameSize + + LoginTargetIn->PasswordSize; + } + + if (InBufferSize < sizeNeeded) { + + DebugPrint((iScsiPrtDebugError, + "Buffer too small for login. Given %d, Needed %d\n", + InBufferSize, sizeNeeded)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Buffer too small for login. Given %d, Needed %d\n", + InBufferSize, sizeNeeded); + + return ISDSC_LOGIN_USER_INFO_BAD; + } + + // + // Validate session type + // + if (LoginTargetIn->SessionType > ISCSI_LOGINTARGET_DATA) { + + DebugPrint((iScsiPrtDebugError, + "Invalid session type %d\n", + LoginTargetIn->SessionType)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid session type %d\n", + LoginTargetIn->SessionType); + + return ISDSC_SESSION_TYPE_NOT_SUPPORTED; + } + + // + // Make sure the size of the username and password, if given, + // are less than or equal to max length + // + if (LoginTargetIn->LoginOptions.InformationSpecified & ISCSI_LOGIN_OPTIONS_AUTH_TYPE) { + authType = LoginTargetIn->LoginOptions.AuthType; + } else { + authType = ISCSI_NO_AUTH_TYPE; + } + + if ((authType == ISCSI_CHAP_AUTH_TYPE) || + (authType == ISCSI_MUTUAL_CHAP_AUTH_TYPE)) { + + // + // A non-zero CHAP Username must be provided for CHAP + // + if ((LoginTargetIn->UsernameSize == 0) || + (LoginTargetIn->UsernameSize > MAX_CHAP_USERNAME_LENGTH)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid username size %d\n", + LoginTargetIn->UsernameSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid username size %d\n", + LoginTargetIn->UsernameSize); + + return ISDSC_INVALID_CHAP_USER_NAME; + } + + // + // If doing CHAP then we need to have the target's chap secret + // + if (((LoginTargetIn->PasswordSize == 0) && !(LoginTargetIn->LoginOptions.LoginFlags & ISCSI_LOGIN_FLAG_USE_RADIUS_RESPONSE))|| + (LoginTargetIn->PasswordSize > MAX_CHAP_SECRET_LENGTH)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid target secret size %d\n", + LoginTargetIn->PasswordSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid target secret size %d\n", + LoginTargetIn->PasswordSize); + + return ISDSC_INVALID_TARGET_CHAP_SECRET; + } + + // + // If we are performing mutual authentication ensure + // that initiator's secret is set, and it is not + // same as the target's secret. + // + if (authType == ISCSI_MUTUAL_CHAP_AUTH_TYPE) { + + PUCHAR userNamePtr; + PUCHAR targetSecret; + ULONG secretLen; + + if (!(LoginTargetIn->LoginOptions.LoginFlags & ISCSI_LOGIN_FLAG_USE_RADIUS_VERIFICATION)) { + + iSpGetUserNameAndPasswordForLogin(LoginTargetIn, + &userNamePtr, + &targetSecret); + + secretLen = AdapterExtension->InitiatorSecretLen; + if ((secretLen == 0) || + ((secretLen == LoginTargetIn->PasswordSize) && + (RtlCompareMemory(AdapterExtension->InitiatorSecret, + targetSecret, + secretLen) == secretLen))) { + + DebugPrint((iScsiPrtDebugError, + "Either no initiator secret is set or it is same as target secret\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagCHAP, + "Either no initiator secret is set or it is same as target secret\n"); + + return ISDSC_INVALID_INITIATOR_CHAP_SECRET; + } + } + } + } else if (authType != ISCSI_NO_AUTH_TYPE) { + + // + // Only chap and mutual chap are supported + // + + DebugPrint((iScsiPrtDebugError, + "Invalid authentication type %d\n", + authType)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid authentication type %d\n", + authType); + + return ISDSC_INVALID_LOGON_AUTH_TYPE; + } + + // + // Check the address type. We currently only support IPv4 and IPv6 + // + if ((LoginTargetIn->TargetPortal.Address.Type != ISCSI_IP_ADDRESS_IPV4) && + (LoginTargetIn->TargetPortal.Address.Type != ISCSI_IP_ADDRESS_IPV6)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid address type %d\n", + LoginTargetIn->TargetPortal.Address.Type)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid address type %d\n", + LoginTargetIn->TargetPortal.Address.Type); + + return ISDSC_ADDRESS_TYPE_NOT_SUPPORTED; + } + + inputValid = TRUE; + + // + // Check if target mappings are valid + // + if ((LoginTargetIn->Mappings.OSBus != -1) && + (LoginTargetIn->Mappings.OSBus >= ISCSI_MAX_BUSES)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid OSBus %x\n", + LoginTargetIn->Mappings.OSBus)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid OSBus %x\n", + LoginTargetIn->Mappings.OSBus); + + inputValid = FALSE; + } + + if ((inputValid == TRUE) && + (LoginTargetIn->Mappings.OSTarget != -1) && + (LoginTargetIn->Mappings.OSTarget >= ISCSI_MAX_TARGETS)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid OSTarget %x\n", + LoginTargetIn->Mappings.OSTarget)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid OSTarget %x\n", + LoginTargetIn->Mappings.OSTarget); + + inputValid = FALSE; + } + + if (inputValid == TRUE) { + + PISCSI_LUNList lunList; + ULONG inx; + + for (inx = 0; inx < LoginTargetIn->Mappings.LUNCount; inx++) { + + lunList = &(LoginTargetIn->Mappings.LUNList[inx]); + + if (lunList->OSLUN >= ISCSI_MAX_LOGICAL_UNITS) { + + DebugPrint((iScsiPrtDebugError, + "Invalid OSLun %x\n", + lunList->OSLUN)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid OSLun %x\n", + lunList->OSLUN); + + inputValid = FALSE; + + break; + } + } + } + + if (inputValid == FALSE) { + return ISDSC_INVALID_TARGET_MAPPING; + } + + return STATUS_SUCCESS; +} + + +ISDSC_STATUS +iSpValidateAddConnectionParameters( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PAddConnectionToSession_IN AddConnectionIn, + IN ULONG InBufferSize + ) +{ + ISDSC_STATUS status = STATUS_SUCCESS; + ULONG sizeNeeded; + ISCSI_AUTH_TYPES authType; + + + // + // Make sure the given buffer is large enough to hold + // all add connection input data. + // + sizeNeeded = FIELD_OFFSET(AddConnectionToSession_IN, Key); + if (sizeNeeded <= InBufferSize) { + + sizeNeeded += AddConnectionIn->KeySize + + AddConnectionIn->UsernameSize + + AddConnectionIn->PasswordSize; + } + + if (sizeNeeded > InBufferSize) { + + DebugPrint((iScsiPrtDebugError, + "Add connection: Size Needed %d, Given %d\n", + sizeNeeded, + InBufferSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Add connection: Size Needed %d, Given %d\n", + sizeNeeded, + InBufferSize); + + return ISDSC_LOGIN_USER_INFO_BAD; + } + + // + // Check the address type. We currently only support IPv4 and IPv6 + // + if ((AddConnectionIn->TargetPortal.Address.Type != ISCSI_IP_ADDRESS_IPV4) && + (AddConnectionIn->TargetPortal.Address.Type != ISCSI_IP_ADDRESS_IPV6)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid address type %d\n", + AddConnectionIn->TargetPortal.Address.Type)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid address type %d\n", + AddConnectionIn->TargetPortal.Address.Type); + + return ISDSC_ADDRESS_TYPE_NOT_SUPPORTED; + } + + // + // Make sure the size of the username and password, if given, + // are less than or equal to max length + // + if (AddConnectionIn->LoginOptions.InformationSpecified & ISCSI_LOGIN_OPTIONS_AUTH_TYPE) { + authType = AddConnectionIn->LoginOptions.AuthType; + } else { + authType = ISCSI_NO_AUTH_TYPE; + } + + if ((authType == ISCSI_CHAP_AUTH_TYPE) || + (authType == ISCSI_MUTUAL_CHAP_AUTH_TYPE)) { + + // + // A non-zero CHAP Username must be provided for CHAP + // + if ((AddConnectionIn->UsernameSize == 0) || + (AddConnectionIn->UsernameSize > MAX_CHAP_USERNAME_LENGTH)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid username size %d\n", + AddConnectionIn->UsernameSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid username size %d\n", + AddConnectionIn->UsernameSize); + + return ISDSC_INVALID_CHAP_USER_NAME; + } + + // + // If doing CHAP then we need to have the target's chap secret + // + if (((AddConnectionIn->PasswordSize == 0) && + !(AddConnectionIn->LoginOptions.LoginFlags & ISCSI_LOGIN_FLAG_USE_RADIUS_RESPONSE)) || + (AddConnectionIn->PasswordSize > MAX_CHAP_SECRET_LENGTH)) { + + DebugPrint((iScsiPrtDebugError, + "Invalid target secret size %d\n", + AddConnectionIn->PasswordSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid target secret size %d\n", + AddConnectionIn->PasswordSize); + + return ISDSC_INVALID_TARGET_CHAP_SECRET; + } + + // + // If we are performing mutual authentication ensure + // that initiator's secret is set, and it is not + // same as the target's secret. + // + if (authType == ISCSI_MUTUAL_CHAP_AUTH_TYPE) { + + PUCHAR userNamePtr; + PUCHAR targetSecret; + ULONG secretLen; + + if (!(AddConnectionIn->LoginOptions.LoginFlags & ISCSI_LOGIN_FLAG_USE_RADIUS_VERIFICATION)) { + + iSpGetUserNameAndPasswordForAddConnection(AddConnectionIn, + &userNamePtr, + &targetSecret); + + secretLen = AdapterExtension->InitiatorSecretLen; + if ((secretLen == 0) || + ((secretLen == AddConnectionIn->PasswordSize) && + (RtlCompareMemory(AdapterExtension->InitiatorSecret, + targetSecret, + secretLen) == secretLen))) { + + DebugPrint((iScsiPrtDebugError, + "Either no initiator secret is set or it is same as target secret\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Either no initiator secret is set or it is same as target secret\n"); + + return ISDSC_INVALID_INITIATOR_CHAP_SECRET; + } + } + } + } else if (authType != ISCSI_NO_AUTH_TYPE) { + + // + // Only chap and mutual chap are supported + // + + DebugPrint((iScsiPrtDebugError, + "Invalid authentication type %d\n", + authType)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "Invalid authentication type %d\n", + authType); + + return ISDSC_INVALID_LOGON_AUTH_TYPE; + } + + return STATUS_SUCCESS; +} + + +ULONGLONG +iSpGetSessionID( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + PISCSI_SESSION IScsiSession, + USHORT UniqueSessionId + ) +/*+++ + +Routine Description: + + This routine returns a unique session id. The session id + is made up of ISID and Microsoft signature byte + +Arguements: + + AdapterExtension - Adapter Extension + + IScsiSession - Pointer to the session + + UniqueSessionId - Two byte session id passed by iSCSI Service + +Return Value: + + 8 Byte SessionId +--*/ +{ + ULONGLONG retVal; + ULONG tempUlong; + + NT_ASSERT((IScsiSession->InitiatorID[0] == 0) && + (IScsiSession->InitiatorID[1] == 0)); + + // + // If SessionId is not initialized, generate a new session id. + // Else, return the saved session id + // + if (IScsiSession->SessionId == 0) { + + tempUlong = (ULONG) UniqueSessionId; + + SetUlongIn2ByteArray((IScsiSession->InitiatorID), tempUlong); + + // + // The unique 64 Bit Session Id is composed this way - + // + // Out of 8 bytes : + // + // Most Significant 4 Bytes are composed of the byte + // ISID_TYPE_ENTERPRISE_NUMBER and the value MSFT_ENTERPRISE_NUMBER + // The Least Significant 4 Bytes are taken from InitiatorSessionID + // + retVal = ((ULONGLONG) ISID_TYPE_ENTERPRISE_NUMBER << 24) | MSFT_ENTERPRISE_NUMBER; + retVal <<= 32; + + retVal |= InterlockedIncrement(&AdapterExtension->InitiatorSessionID); + + IScsiSession->SessionId = retVal; + } else { + + retVal = IScsiSession->SessionId; + } + + DebugPrint((iScsiPrtDebugInfo, + "Session Id returned - 0x%016I64x\n", + retVal)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Session Id returned - 0x%016I64x\n", + retVal); + + return retVal; +} + +UCHAR +iSpReadInitiatorSessionInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PWMI_CONNECTION_LIST ConnectionList, + IN ULONG NumberOfSessions, + OUT PUCHAR Buffer +) +/*++ + +Routine Description: + + Purpose of this routine is to gather initiatorNode information specified in the mof from + the port driver and place them in the incoming Buffer. + +Arguments: + + AdapterExtension - Adpater extension + + SessionListHead - pointer to the first session we have got a remove lock for + + SessionListTail - pointer ot the last session we have got a remove lock for + + InitiatorName - Name of initiator, used to pick out the sessions wanted + + Buffer - Used to store all the information of a paticular initiator + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_InitiatorSessionInfo initiatorSessionInfo; + PISCSI_SessionStaticInfo sessionStaticInfo; + PISCSI_ConnectionStaticInfo connectionStaticInfo; + ULONG sessionIndex; + ULONG connectionIndex; + ULONG inx, skip; + PWMIString WMIformatString; + UCHAR status; + + + status = SRB_STATUS_SUCCESS; + + initiatorSessionInfo = (PMSiSCSI_InitiatorSessionInfo) Buffer; + + initiatorSessionInfo->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + // + // initialize Session count to 0 + // + initiatorSessionInfo->SessionCount=0; + sessionStaticInfo = &(initiatorSessionInfo->SessionsList[0]); + + if (ConnectionList == NULL) { + + DebugPrint((iScsiPrtDebugError, + "Connectionlist NULL in iSpReadInitiatorSessionInfo\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Connectionlist NULL in iSpReadInitiatorSessionInfo\n"); + + return status; + } + + inx = 0; + while (inx < NumberOfSessions) { + + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + + iScsiSession = ConnectionList[inx].ISCSISession; + + if (iScsiSession == NULL) { + + inx++; + + continue; + } + + sessionStaticInfo->UniqueSessionId = iScsiSession->SessionId; + + WMIformatString = (PWMIString)sessionStaticInfo->InitiatoriSCSIName; + WMIformatString->Length = (MAX_INITIATOR_NAME) * sizeof(WCHAR); + RtlCopyMemory(WMIformatString->Buffer, + iScsiSession->InitiatorName, + (MAX_INITIATOR_NAME * sizeof(WCHAR))); + + WMIformatString = (PWMIString)sessionStaticInfo->TargetiSCSIName; + WMIformatString->Length = (MAX_TARGET_NAME) * sizeof(WCHAR); + RtlCopyMemory(WMIformatString->Buffer, + iScsiSession->TargetName, + (MAX_TARGET_NAME * sizeof(WCHAR))); + + sessionStaticInfo->TSID = iScsiSession->TSIH[1] + (iScsiSession->TSIH[0] << 8); + + sessionStaticInfo->ISID[0] = ISID_TYPE_ENTERPRISE_NUMBER; + sessionStaticInfo->ISID[1] = (MSFT_ENTERPRISE_NUMBER & 0xFF0000) >> 16; + sessionStaticInfo->ISID[2] = (MSFT_ENTERPRISE_NUMBER & 0xFF00) >> 8; + sessionStaticInfo->ISID[3] = MSFT_ENTERPRISE_NUMBER & 0xFF; + sessionStaticInfo->ISID[4] = iScsiSession->InitiatorID[0]; + sessionStaticInfo->ISID[5] = iScsiSession->InitiatorID[1]; + + sessionStaticInfo->InitialR2t = iScsiSession->IScsiSessionParams.InitialR2T; + sessionStaticInfo->ImmediateData = iScsiSession->IScsiSessionParams.ImmediateData; + + sessionStaticInfo->Type = iScsiSession->LogonType; + + //False indicates that data PDU Sequences may + //be transferred in any order. True indicates that data PDU + //Sequences must be transferred using continuously increasing offsets, + //except during error recovery. + sessionStaticInfo->DataSequenceInOrder = TRUE; + + //False indicates that data PDUs within Sequences may be in any order. + //True indicates that data PDUs within sequences must be at continuously + //increasing addresses, with no gaps or overlay between PDUs. + sessionStaticInfo->DataPduInOrder = TRUE; + + + //The level of error recovery negotiated between the initiator and the target. + //Higher numbers represent more detailed recovery schemes. + sessionStaticInfo->ErrorRecoveryLevel = (UCHAR) iScsiSession->IScsiSessionParams.ErrorRecoveryLevel; + + sessionStaticInfo->MaxOutstandingR2t = 1; + + //The maximum length supported for unsolicited data + //sent within this session, in units of 512 bytes. + sessionStaticInfo->FirstBurstLength = iScsiSession->IScsiSessionParams.FirstBurstLength; + + //The maximum length supported for unsolicited data + //sent within this session, in units of 512 bytes. + sessionStaticInfo->MaxBurstLength = iScsiSession->IScsiSessionParams.MaxBurstLength; + + //The maximum number of connections that will be + //allowed within this session + sessionStaticInfo->MaxConnections = iScsiSession->IScsiSessionParams.MaxConnections; + + // + // initialize connection count for this session to 0 + // + sessionStaticInfo->ConnectionCount = 0; + + connectionStaticInfo = &(sessionStaticInfo->ConnectionsList[0]); + + for (connectionIndex = 0; + connectionIndex < ConnectionList[inx].Count; + connectionIndex++) + { + + iScsiConnection = ConnectionList[inx].ISCSIConnection[connectionIndex]; + if (iScsiConnection != NULL) { + + ULONG socket; + + connectionStaticInfo->UniqueConnectionId = iScsiConnection->UniqueConnectionID; + connectionStaticInfo->CID = iScsiConnection->ConnectionID[1] + + (iScsiConnection->ConnectionID[0] << 8); + + connectionStaticInfo->HeaderIntegrity = + (UCHAR) iScsiConnection->IScsiConnectionParams.HeaderDigest; + + connectionStaticInfo->DataIntegrity = + (UCHAR) iScsiConnection->IScsiConnectionParams.DataDigest; + + // + // The maximum data payload size supported for command + // or data PDUs within this session, in units of 512 bytes. + // + connectionStaticInfo->MaxRecvDataSegmentLength = + iScsiConnection->IScsiConnectionParams.MaxRecvDataLength; + + connectionStaticInfo->AuthType = iScsiConnection->AuthType; + + + //login - The TCP connection has been established, but a valid iScsi + // login response with the final bit set has not been sent or received. + //full - A valid iScsi login response with the final bit set + // has been sent or received. + //logout - A valid iScsi logout command has been sent or received, but + // the TCP connection has not yet been closed. + connectionStaticInfo->State = iScsiConnection->CurrentProtocolState; + //NOTE: CurrentProtocol enum is different then State enum !?!?!?! + + + //The transport protocol over which this connection instance is running. + connectionStaticInfo->Protocol = TCP; //not saved in deviceExtension yet + + //The Local Inet address used by this connection instance + iSpCopyIPAddress(&connectionStaticInfo->LocalAddr, + &iScsiConnection->LocalIPAddress, + &socket); + + // + // Local TCP port is stored in host byte order in LocalIPAddress. + // Convert that to network byte order here. + // + connectionStaticInfo->LocalPort = htons(socket); + + connectionStaticInfo->LocalAddr.TextAddress[0] = MAX_ISCSI_TEXT_ADDRESS_LEN*sizeof(WCHAR); + + + //The Remote Inet address used by this connection instance + + iSpCopyIPAddress(&connectionStaticInfo->RemoteAddr, + &iScsiConnection->TargetIPAddress, + &connectionStaticInfo->RemotePort); + + connectionStaticInfo->RemoteAddr.TextAddress[0] = MAX_ISCSI_TEXT_ADDRESS_LEN*sizeof(WCHAR); + + connectionStaticInfo->EstimatedThroughput = iScsiConnection->EstimatedThroughput.QuadPart; + + connectionStaticInfo->MaxDatagramSize = iScsiConnection->MaxDatagramSize; + + //increment the connectionStaticInfo pointer to the next 4 byte alligned address; + (PUCHAR) connectionStaticInfo += ((sizeof(ISCSI_ConnectionStaticInfo)+7) & ~7); + + //The number of TCP connections that currently belong to this session + sessionStaticInfo->ConnectionCount ++; + } + } + + // + // Advance to next place to write session information + // + skip = FIELD_OFFSET(ISCSI_SessionStaticInfo, + ConnectionsList) + + (ConnectionList[inx].Count * + ((sizeof(ISCSI_ConnectionStaticInfo)+7) & ~7)); + + skip = (skip +7) & ~7; + + (PUCHAR)sessionStaticInfo += skip; + + initiatorSessionInfo->SessionCount++; + + inx++; + } + + return status; +} + +UCHAR +iSpReadConnStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PISCSI_CONNECTION IScsiConnection, + OUT PUCHAR Buffer + ) +/*++ + +Routine Description: + + Read the iScsi connection statistics information into the OS buffer. + +Arguments: + + IScsiConnection - iScsi miniport driver's connection data storage. + + Buffer - Buffer to hold iScsi connection statistics information. + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_ConnectionStatistics ConnectStatistics; + PWMIString WMIformatString; + UCHAR status; + + + status = SRB_STATUS_SUCCESS; + + ConnectStatistics = (PMSiSCSI_ConnectionStatistics)Buffer; + RtlZeroMemory(Buffer, sizeof(MSiSCSI_ConnectionStatistics)); + + WMIformatString = (PWMIString)ConnectStatistics->iSCSIName; + WMIformatString->Length = MAX_INITIATOR_NAME * sizeof(WCHAR); + RtlCopyMemory(WMIformatString->Buffer, + IScsiConnection->ISCSISession->InitiatorName, + (MAX_INITIATOR_NAME * sizeof(WCHAR))); + + ConnectStatistics->CID = (IScsiConnection->ConnectionID[0] << 8) + + IScsiConnection->ConnectionID[1]; + + // + // A uniquely generated session ID used only internally. + // Do not mix this with ISID. + // + if (IScsiConnection->ISCSISession != NULL) { + + ConnectStatistics->USID = IScsiConnection->ISCSISession->SessionId; + } + + ConnectStatistics->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + ConnectStatistics->BytesSent = IScsiConnection->BytesSent; + ConnectStatistics->BytesReceived = IScsiConnection->BytesReceived; + ConnectStatistics->PDUCommandsSent = IScsiConnection->PDUCommandsSent; + ConnectStatistics->PDUResponsesReceived = IScsiConnection->PDUResponsesReceived; + + return status; +} + +UCHAR +iSpReadSessionStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PISCSI_SESSION IScsiSession, + IN PWMI_CONNECTION_LIST ConnectionList, + OUT PUCHAR Buffer + ) +/*++ + +Routine Description: + + Read the iScsi session statistics information into the OS buffer. + +Arguments: + + IScsiSession - iScsi miniport driver's session data storage. + + Buffer - Buffer to hold iScsi connection statistics information. + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_SessionStatistics SessionStatistics; + PISCSI_CONNECTION connection; + PWMIString WMIformatString; + ULONG inx; + UCHAR status; + + + status = SRB_STATUS_SUCCESS; + + SessionStatistics = (PMSiSCSI_SessionStatistics)Buffer; + RtlZeroMemory(Buffer, sizeof(MSiSCSI_SessionStatistics)); + + if (IScsiSession != NULL) { + + WMIformatString = (PWMIString)SessionStatistics->iSCSIName; + WMIformatString->Length = MAX_INITIATOR_NAME * sizeof(WCHAR); + RtlCopyMemory(WMIformatString->Buffer, + IScsiSession->InitiatorName, + (MAX_INITIATOR_NAME * sizeof(WCHAR))); + + SessionStatistics->USID = IScsiSession->SessionId; + + SessionStatistics->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + SessionStatistics->BytesSent = 0; + SessionStatistics->BytesReceived = 0; + SessionStatistics->PDUCommandsSent = 0; + SessionStatistics->PDUResponsesReceived = 0; + + inx = 0; + while (inx < ConnectionList->Count) + { + PISCSI_CONNECTION iScsiConnection; + + iScsiConnection = ConnectionList->ISCSIConnection[inx]; + if (iScsiConnection != NULL) { + SessionStatistics->BytesSent += iScsiConnection->BytesSent; + SessionStatistics->BytesReceived += iScsiConnection->BytesReceived; + SessionStatistics->PDUCommandsSent += iScsiConnection->PDUCommandsSent; + SessionStatistics->PDUResponsesReceived += iScsiConnection->PDUResponsesReceived; + } + + inx++; + } + } + + return status; +} + +UCHAR +iSpReadInitiatorLoginStatistics( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PWMI_CONNECTION_LIST ConnectionList, + IN ULONG NumberOfSessions, + OUT PUCHAR Buffer + ) +/*++ + +Routine Description: + + Read the iScsi Initiator Node statistics information into the OS buffer. + +Arguments: + + SessionListHead - pointer to the first session we have got a remove lock for + + SessionListTail - pointer ot the last session we have got a remove lock for + + InitiatorName - Name of initiator, used to pick out the sessions wanted + + Buffer - Used to store all the information of a paticular initiator + +Return Value: + + Status - SRB Status for this request + +--*/ +{ + PMSiSCSI_InitiatorLoginStatistics initiatorLoginStatistics; + UCHAR status; + ULONG inx; + + + status = SRB_STATUS_SUCCESS; + + initiatorLoginStatistics = (PMSiSCSI_InitiatorLoginStatistics) Buffer; + + initiatorLoginStatistics->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + initiatorLoginStatistics->LogoutNormals = AdapterExtension->LogoutNormals; + + initiatorLoginStatistics->LogoutOtherCodes = AdapterExtension->LogoutOtherRsps; + + inx = 0; + while (inx < NumberOfSessions) { + + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + + if ((ConnectionList != NULL) && (ConnectionList[inx].Count > 0)) { + + iScsiConnection = ConnectionList[inx].ISCSIConnection[0]; + NT_ASSERT(iScsiConnection != NULL); + + iScsiSession = iScsiConnection->ISCSISession; + + if (iScsiSession != NULL) { + + initiatorLoginStatistics->LoginAcceptRsps += iScsiSession->LoginAcceptRsps; + + initiatorLoginStatistics->LoginOtherFailRsps += iScsiSession->LoginOtherFailRsps; + + initiatorLoginStatistics->LoginRedirectRsps += iScsiSession->LoginRedirectRsps; + + initiatorLoginStatistics->LoginAuthFailRsps += iScsiSession->LoginAuthFailRsps; + + initiatorLoginStatistics->LoginAuthenticateFails += iScsiSession->LoginAuthenticateFails; + + initiatorLoginStatistics->LoginNegotiateFails += iScsiSession->LoginNegotiateFails; + + initiatorLoginStatistics->LoginFailures += iScsiSession->LoginFailures; + + } + } + + inx++; + } + + return status; +} + + +VOID +iSpCompleteWmiRequest( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + PSCSI_WMI_REQUEST_BLOCK Srb, + PSCSIWMI_REQUEST_CONTEXT DispatchContext, + UCHAR Status, + ULONG SizeNeeded + ) +/*+++ + +Routine Description: + + This routine calls iScsiPrt to notify that a request + is completed. + +Arguements: + + AdapterExtension - Adapater extension for the initiator + + Srb - The request being completed + + DispatchContext - WMI request context. + + Status - SRB Status for this request + + SizeNeeded - Buffer size needed to process this request + +Return Value: + + None +--*/ +{ + // + // Complete the request if the status is NOT pending or NOT + // already completed within the callback. + // + if (Status != SRB_STATUS_PENDING) { + + // + // Request completed successfully or there was an error. + // + ScsiPortWmiPostProcess(DispatchContext, + Status, + SizeNeeded); + + Srb->SrbStatus = ScsiPortWmiGetReturnStatus(DispatchContext); + Srb->DataTransferLength = ScsiPortWmiGetReturnSize(DispatchContext); + + // + // Adapter ready for next request. + // + ScsiPortNotification(RequestComplete, AdapterExtension, Srb); + } +} + +UCHAR +iSpGetDynamicConnectionInstanceName( + IN PISCSI_CONNECTION IScsiConnection, + IN OUT PWMIString InstanceName + ) +/*++ + +Routine Description: + + Get the instanceName for the specified connection. Instance names are formatted as + follows: "targetname_#:#" where the first # is the display session ID, and the second + # is the CID. + +Arguments: + + IScsiConnection - iScsi miniport driver's connection data storage. + + InstanceName - A pointer to WMIString, on return contains the dynamic instance name for the + specified connection. + +Return Value: + + UCHAR - SRB Status for this request + +--*/ +{ + + WCHAR uniCodeString[MAX_UNICODE_STR_LENGTH]; + PWCHAR currentPos; + ULONG InstanceNameLength; + PWMIString WMIformatString; + KIRQL oldIrql; + ULONG displaySessionID; + PISCSI_SESSION sessionListHead; + PISCSI_SESSION sessionListTail; + PISCSI_SESSION iScsiSession; + PISCSI_ADAPTER_EXTENSION adapterExtension; + NTSTATUS rtlStatus; + UCHAR status; + USHORT convertedLength; + USHORT maxBufferSize; + UCHAR numString[MAX_UNICODE_STR_LENGTH]; + + + status = SRB_STATUS_SUCCESS; + + RtlZeroMemory(uniCodeString, sizeof(uniCodeString)); + + maxBufferSize = sizeof(uniCodeString) / sizeof(WCHAR); + + rtlStatus = RtlStringCchCopyNW(uniCodeString, maxBufferSize, + IScsiConnection->ISCSISession->TargetName, + wcslen(IScsiConnection->ISCSISession->TargetName)); + if (rtlStatus != STATUS_SUCCESS) { + return SRB_STATUS_ERROR; + } + + convertedLength = (USHORT)wcslen(IScsiConnection->ISCSISession->TargetName); + + (PUCHAR)currentPos = (PUCHAR)uniCodeString + convertedLength*sizeof(WCHAR); + + maxBufferSize = (sizeof(uniCodeString)/sizeof(WCHAR)) - convertedLength; + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + rtlStatus = RtlStringCchCopyW(currentPos, maxBufferSize, L"_"); + if (rtlStatus != STATUS_SUCCESS) { + return SRB_STATUS_ERROR; + } + (PUCHAR)currentPos += sizeof(WCHAR); + maxBufferSize--; + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + displaySessionID = IScsiConnection->ISCSISession->DisplaySessionID; + + RtlZeroMemory(numString, sizeof(numString)); + (void) _itoa_s(displaySessionID, numString, _countof(numString), 10); + + convertedLength = AsciiStringToWideCharString( + currentPos, + numString, + maxBufferSize); + + // + // AsciiStringToWideCharString returns the number of characters including the terminating NULL. + // + maxBufferSize = maxBufferSize - (convertedLength - 1); + (PUCHAR)currentPos += ((convertedLength -1 )* sizeof(WCHAR)); + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + rtlStatus = RtlStringCchCopyW(currentPos, maxBufferSize, L":"); + if (rtlStatus != STATUS_SUCCESS) { + return SRB_STATUS_ERROR; + } + (PUCHAR)currentPos += sizeof(WCHAR); + maxBufferSize--; + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + RtlZeroMemory(numString, sizeof(numString)); + (void) _itoa_s((IScsiConnection->ConnectionID[0]<<8) + IScsiConnection->ConnectionID[1], numString, _countof(numString), 10); + convertedLength = AsciiStringToWideCharString(currentPos, + numString, + (USHORT)maxBufferSize); + + // + // AsciiStringToWideCharString returns the number of characters including the terminating NULL. + // + (PUCHAR)currentPos += ((convertedLength - 1)* sizeof(WCHAR)); + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + InstanceNameLength = (ULONG)((PUCHAR)currentPos - (PUCHAR)uniCodeString); + + InstanceName->Length = (USHORT)InstanceNameLength; + + RtlStringCchCopyW(InstanceName->Buffer, InstanceName->Length, uniCodeString); + + return status; + +} + +UCHAR +iSpGetDynamicSessionInstanceName( + IN PISCSI_SESSION IScsiSession, + IN OUT PWMIString InstanceName + ) +/*++ + +Routine Description: + + Get the instanceName for the specified session. Instance names are formatted as + follows: "targetname_#" where the # is the display session ID + +Arguments: + + IScsiSession - iScsi miniport driver's session data storage. + + InstanceName - A pointer to WMIString, on return contains the dynamic instance name for the + specified connection. + +Return Value: + + UCHAR - SRB Status for this request + +--*/ +{ + + WCHAR uniCodeString[MAX_UNICODE_STR_LENGTH + 1]; + PWCHAR currentPos; + ULONG InstanceNameLength; + PWMIString WMIformatString; + KIRQL oldIrql; + ULONG displaySessionID; + PISCSI_SESSION sessionListHead; + PISCSI_SESSION sessionListTail; + PISCSI_SESSION iScsiSession; + PISCSI_ADAPTER_EXTENSION adapterExtension; + NTSTATUS rtlStatus; + UCHAR status = SRB_STATUS_SUCCESS; + USHORT convertedLength; + USHORT maxBufferSize; + UCHAR numString[MAX_UNICODE_STR_LENGTH]; + + + RtlZeroMemory(uniCodeString, sizeof(uniCodeString)); + + convertedLength = (USHORT) wcslen(IScsiSession->TargetName); + + rtlStatus = RtlStringCchCopyNW(uniCodeString, MAX_UNICODE_STR_LENGTH, + IScsiSession->TargetName, + convertedLength); + + if (rtlStatus != STATUS_SUCCESS) { + return SRB_STATUS_ERROR; + } + + (PUCHAR)currentPos = (PUCHAR)uniCodeString + convertedLength*sizeof(WCHAR); + + maxBufferSize = (sizeof(uniCodeString)/sizeof(WCHAR)) - convertedLength; + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + rtlStatus = RtlStringCchCopyW(currentPos, maxBufferSize, L"_"); + if (rtlStatus != STATUS_SUCCESS) { + return SRB_STATUS_ERROR; + } + (PUCHAR)currentPos += sizeof(WCHAR); + maxBufferSize--; + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + + displaySessionID = IScsiSession->DisplaySessionID; + + RtlZeroMemory(numString, sizeof(numString)); + (void) _itoa_s(displaySessionID, numString, _countof(numString), 10); + convertedLength = AsciiStringToWideCharString(currentPos, + numString, + maxBufferSize); + + // + // AsciiStringToWideCharString returns the number of characters including the terminating NULL. + // + (PUCHAR)currentPos += ((convertedLength -1) * sizeof(WCHAR)); + + if (currentPos > uniCodeString + sizeof(uniCodeString)/sizeof(WCHAR)) { + return SRB_STATUS_ERROR; + } + + InstanceNameLength = (ULONG)((PUCHAR)currentPos - (PUCHAR)uniCodeString); + + if(InstanceNameLength > MAX_UNICODE_STR_LENGTH) + { + status = SRB_STATUS_ERROR; + } else { + + rtlStatus = RtlStringCchCopyNW( + InstanceName->Buffer, + MAX_UNICODE_STR_LENGTH, + uniCodeString, + InstanceNameLength); + + if(NT_SUCCESS(rtlStatus) == FALSE) + { + status = SRB_STATUS_ERROR; + } else { + status = SRB_STATUS_SUCCESS; + } + } + + if(status != SRB_STATUS_SUCCESS) + { + InstanceName->Length = 0; + } else { + InstanceName->Length = (USHORT)InstanceNameLength; + } + + return status; +} + + +VOID +iScsiFireAdapterEvent( + PISCSI_ADAPTER_EXTENSION AdapterExtension, + ISCSI_ADAPTER_EVENT_CODE EventCode + ) +{ + ScsiPortWmiFireAdapterEvent(AdapterExtension, + &iScsiAdapterEventGuid, + 0, + sizeof(ULONG), + &EventCode); +} + + +UCHAR +iSpQueryLBPolicy( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN OUT PULONG InstanceLengthArray, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWMI_CONNECTION_LIST connectionList; + ULONG size, sessionInx; + ULONG numberOfSessions, numberOfConnections; + UCHAR status = SRB_STATUS_SUCCESS;; + + + *SizeNeeded = 0; + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections); + + // + // Determine the size of buffer needed to return LB policy settings + // for all the sessions on this adapter. + // + + // + // First account for the fixed part of MSiSCSI_Supported_LB_Policies + // + size = FIELD_OFFSET(MSiSCSI_QueryLBPolicy, + LoadBalancePolicies); + + if (connectionList == NULL) { + + if (BufferAvail >= size) { + PMSiSCSI_QueryLBPolicy queryLBPolicy; + + queryLBPolicy = (PMSiSCSI_QueryLBPolicy) Buffer; + queryLBPolicy->UniqueAdapterId = (ULONGLONG) AdapterExtension; + queryLBPolicy->SessionCount = 0; + *SizeNeeded = size; + + return SRB_STATUS_SUCCESS; + } else { + + *SizeNeeded = size; + + return SRB_STATUS_SUCCESS; + } + } + + // + // Loop over all sessions and account for the space needed for each + // session plus all of the connections within each session + // + sessionInx = 0; + while (sessionInx < numberOfSessions) { + + // + // Since the session structure needs to be 8 bytes aligned, we + // pad out to 8 bytes + // + size = (size + 7) & ~7; + + // + // Add the fixed size needed for the session structure + // + size += FIELD_OFFSET(ISCSI_Supported_LB_Policies, + iSCSI_Paths); + + // + // Account for the size of all connection structures, being + // sure that the connection structure is padded out to 8 bytes + // in order to maintain 8 byte alignment + // + size += connectionList[sessionInx].Count * + ((sizeof(ISCSI_Path) + 7) & ~7); + + sessionInx++; + } + + *SizeNeeded = size; + + if (size <= BufferAvail) { + + // + // There is enough space to build the LB policy info data + // for all the sessions on this adapter. + // + RtlZeroMemory(Buffer, size); + + status = iSpReadLBPolicyInfo(AdapterExtension, + connectionList, + numberOfSessions, + (PMSiSCSI_QueryLBPolicy) Buffer); + + } else { + + // + // There is not enough space to build the LB policy info data + // for all the sessions on this adapter. + // + status = SRB_STATUS_DATA_OVERRUN; + } + + *InstanceLengthArray = *SizeNeeded; + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + + return status; +} + +UCHAR +iSpReadLBPolicyInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PWMI_CONNECTION_LIST ConnectionList, + IN ULONG NumberOfSessions, + OUT PMSiSCSI_QueryLBPolicy QueryLBPolicy + ) +{ + PISCSI_Supported_LB_Policies supportedLBPolicies; + PISCSI_Path iScsiPath; + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + ULONG sessionInx; + ULONG connectionInx; + ULONG skip; + UCHAR status = SRB_STATUS_SUCCESS; + + QueryLBPolicy->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + QueryLBPolicy->SessionCount = 0; + + supportedLBPolicies = QueryLBPolicy->LoadBalancePolicies; + + sessionInx = 0; + while (sessionInx < NumberOfSessions) { + + iScsiSession = ConnectionList[sessionInx].ISCSISession; + + supportedLBPolicies->UniqueSessionId = iScsiSession->SessionId; + + supportedLBPolicies->LoadBalancePolicy = iScsiSession->LoadBalancePolicy; + + supportedLBPolicies->iSCSI_PathCount = 0; + connectionInx = 0; + while (connectionInx < ConnectionList[sessionInx].Count) { + + iScsiConnection = ConnectionList[sessionInx].ISCSIConnection[connectionInx]; + if (iScsiConnection != NULL) { + + iScsiPath = &(supportedLBPolicies->iSCSI_Paths[connectionInx]); + + iScsiPath->UniqueConnectionId = (ULONGLONG) iScsiConnection->UniqueConnectionID; + + iScsiPath->EstimatedLinkSpeed = iScsiConnection->EstimatedThroughput.QuadPart; + + iScsiPath->PathWeight = iScsiConnection->PathWeight; + + iScsiPath->PrimaryPath = iScsiConnection->CurrentPathStatus; + + iScsiPath->TCPOffLoadAvailable = 0; + + switch (iScsiConnection->ConnectionState) { + case ConnectionStateConnected : { + iScsiPath->ConnectionStatus = CONNECTION_STATE_CONNECTED; + break; + } + + case ConnectionStateDisconnected : + case ConnectionStateStopping: { + iScsiPath->ConnectionStatus = CONNECTION_STATE_DISCONNECTED; + break; + } + + case ConnectionStateConnecting : { + iScsiPath->ConnectionStatus = CONNECTION_STATE_RECONNECTING; + break; + } + + default : { + iScsiPath->ConnectionStatus = CONNECTION_STATE_DISCONNECTED; + break; + } + } + + supportedLBPolicies->iSCSI_PathCount++; + } + + connectionInx++; + } + + // + // Advance to next place to write session information + // + skip = FIELD_OFFSET(ISCSI_Supported_LB_Policies, iSCSI_Paths) + + (ConnectionList[sessionInx].Count * ((sizeof(ISCSI_Path) + 7) & ~7)); + + skip = (skip + 7) & ~7; + + (PUCHAR)supportedLBPolicies += skip; + + QueryLBPolicy->SessionCount++; + + sessionInx++; + } + + return status; +} + +UCHAR +iSpSetLoadBalancePolicy( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PSCSI_WMI_REQUEST_BLOCK Srb, + IN PUCHAR Buffer, + IN ULONG InBufferSize + ) +{ + PSetLoadBalancePolicy_IN setLBPolicyIN; + PSetLoadBalancePolicy_OUT setLBPolicyOUT; + PISCSI_Supported_LB_Policies supportedLBPolicy; + PISCSI_SESSION iScsiSession; + PPERSISTENT_TARGET_LB_POLICY LBPolicy = NULL; + PLB_POLICY_DATA LBPolicyData; + ULONG iScsiStatus; + ULONG inx; + BOOLEAN persistLBPolicy = FALSE; + KIRQL oldIrql; + NTSTATUS ntStatus; + + setLBPolicyIN = (PSetLoadBalancePolicy_IN) Buffer; + + setLBPolicyOUT = (PSetLoadBalancePolicy_OUT) Buffer; + + iScsiStatus = iSpValidateLoadBalancePolicy(setLBPolicyIN, + InBufferSize); + if (iScsiStatus != STATUS_SUCCESS) { + + setLBPolicyOUT->Status = iScsiStatus; + + return SRB_STATUS_SUCCESS; + } + + supportedLBPolicy = &(setLBPolicyIN->LoadBalancePolicies); + + iScsiSession = iSpGetIScsiSession(AdapterExtension, + supportedLBPolicy->UniqueSessionId, + Srb); + if (iScsiSession == NULL) { + + DebugPrint((iScsiPrtDebugWarning, + "Invalid session id given %I64x for SetLBPolicy\n", + supportedLBPolicy->UniqueSessionId)); + + ETWDebugPrint(iScsiLevelWarning, + iScsiFlagWmi, + "Invalid session id given %I64x for SetLBPolicy\n", + supportedLBPolicy->UniqueSessionId); + + setLBPolicyOUT->Status = ISDSC_INVALID_SESSION_ID; + + return SRB_STATUS_SUCCESS; + } + + KeAcquireSpinLock(&iScsiSession->SessionLock, &oldIrql); + + iScsiStatus = iSpValidateConnectionIds(iScsiSession, supportedLBPolicy); + + if (iScsiStatus == STATUS_SUCCESS) { + + switch (supportedLBPolicy->LoadBalancePolicy) { + case MSiSCSI_LB_FAILOVER: { + + iScsiStatus = iSpSetLBFailOverOnly(iScsiSession, + supportedLBPolicy); + + break; + } + + case MSiSCSI_LB_DYN_LEAST_QUEUE_DEPTH: + case MSiSCSI_LB_WEIGHTED_PATHS: { + + iScsiStatus = iSpSetLB_LQD_WP(iScsiSession, supportedLBPolicy); + + break; + } + + case MSiSCSI_LB_ROUND_ROBIN: + case MSiSCSI_LB_ROUND_ROBIN_WITH_SUBSET: { + + iScsiStatus = iSpSetLBRoundRobinSubset(iScsiSession, + supportedLBPolicy); + + break; + } + + default: { + + // + // Should never get here since the input policy has already + // been validated in iSpValidateLoadBalancePolicy. + // + iScsiStatus = ISDSC_INVALID_LOAD_BALANCE_POLICY; + } + } + } + + // + // Check if we need to persist the new LB policy + // + if ((iScsiStatus == STATUS_SUCCESS) && + (wcslen(iScsiSession->TargetKeyNameSuffix) > 0)) { + + ULONG sizeNeeded = 0; + ULONG tempUlong; + BOOLEAN overFlow = TRUE; + + if (ULongMult(sizeof(LB_POLICY_DATA), + (iScsiSession->NumberOfConnections - 1), + &tempUlong) == S_OK) { + + if (ULongAdd(sizeof(PERSISTENT_TARGET_LB_POLICY), + tempUlong, &sizeNeeded) == S_OK) { + + overFlow = FALSE; + } + } + + // + // This is a persistent target. Need to save the new LB policy + // in the registry for this persistent target. + // + if (!overFlow) { + + LBPolicy = iSpAllocatePool(NonPagedPool, + sizeNeeded, + ISCSI_TAG_LB_POLICY); + if (LBPolicy != NULL) { + + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + + persistLBPolicy = TRUE; + + RtlStringCchCopyW(LBPolicy->TargetKeyName, + MAX_TARGET_NAME + TARGET_KEYNAME_SUFFIX_SIZE + 1, + iScsiSession->TargetName); + + RtlStringCchCatW(LBPolicy->TargetKeyName, + MAX_TARGET_NAME + TARGET_KEYNAME_SUFFIX_SIZE + 1, + iScsiSession->TargetKeyNameSuffix); + + LBPolicy->LoadBalancePolicy = supportedLBPolicy->LoadBalancePolicy; + + LBPolicy->ConnectionCount = iScsiSession->NumberOfConnections; + + for (inx = 0; inx < supportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(supportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + LBPolicyData = &(LBPolicy->PolicyData[inx]); + + LBPolicyData->ConnectionNumber = iScsiConnection->ConnectionNumber; + + LBPolicyData->PathWeight = iScsiConnection->PathWeight; + + LBPolicyData->PrimaryPath = iScsiConnection->CurrentPathStatus; + } + } else { + + DebugPrint((iScsiPrtDebugError, + "Failed to allocate memory for persisting LB policy\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to allocate memory for persisting LB policy\n"); + } + } + } + + KeReleaseSpinLock(&iScsiSession->SessionLock, oldIrql); + + if (persistLBPolicy) { + + NT_ASSERT(LBPolicy != NULL); + + ntStatus = iSpPersisteLBPolicy(AdapterExtension, LBPolicy); + + if(NT_SUCCESS(ntStatus) == FALSE) + { + iScsiStatus = ISDSC_FAILURE_TO_PERSIST_LB_POLICY; + } + + ExFreePool(LBPolicy); + } + + // + // Release the reference taken in iSpGetIScsiSession + // + IoReleaseRemoveLock(iScsiSession->RemoveLock, REMOVELOCK_TAG(Srb)); + + setLBPolicyOUT->Status = iScsiStatus; + + return SRB_STATUS_SUCCESS; +} + +ULONG +iSpValidateLoadBalancePolicy( + IN PSetLoadBalancePolicy_IN SetLBPolicyIN, + IN ULONG InBufferSize + ) +{ + PISCSI_Supported_LB_Policies supportedLBPolicy; + PISCSI_Path iScsiPath0; + PISCSI_Path iScsiPath1; + ULONG iScsiStatus = STATUS_SUCCESS; + ULONG sizeNeeded; + ULONG inx, jnx; + KIRQL oldIrql; + + sizeNeeded = FIELD_OFFSET(ISCSI_Supported_LB_Policies, iSCSI_Paths); + if (InBufferSize < sizeNeeded) { + + DebugPrint((iScsiPrtDebugError, + "Input buffer too small for SetLBPolicy. Expected %d, Given %d\n", + sizeNeeded, + InBufferSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Input buffer too small for SetLBPolicy. Expected %d, Given %d\n", + sizeNeeded, + InBufferSize); + + return ISDSC_BUFFER_TOO_SMALL; + } + + supportedLBPolicy = &(SetLBPolicyIN->LoadBalancePolicies); + + sizeNeeded += supportedLBPolicy->iSCSI_PathCount * + ((sizeof(ISCSI_Path) + 7) & ~7); + + if (InBufferSize < sizeNeeded) { + + DebugPrint((iScsiPrtDebugError, + "Input buffer too small for SetLBPolicy. Expected %d, Given %d\n", + sizeNeeded, + InBufferSize)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Input buffer too small for SetLBPolicy. Expected %d, Given %d\n", + sizeNeeded, + InBufferSize); + + return ISDSC_BUFFER_TOO_SMALL; + } + + if ((supportedLBPolicy->LoadBalancePolicy < MSiSCSI_LB_FAILOVER) || + (supportedLBPolicy->LoadBalancePolicy > MSiSCSI_LB_WEIGHTED_PATHS)){ + + DebugPrint((iScsiPrtDebugError, + "Invalid Load Balance Policy %d\n", + supportedLBPolicy->LoadBalancePolicy)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Invalid Load Balance Policy %d\n", + supportedLBPolicy->LoadBalancePolicy); + + return ISDSC_INVALID_LOAD_BALANCE_POLICY; + } + + // + // Make sure user did not provide duplicate path ids + // + for (inx = 0; inx < supportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath0 = &(supportedLBPolicy->iSCSI_Paths[inx]); + + for (jnx = 0; jnx < supportedLBPolicy->iSCSI_PathCount; jnx++) { + + iScsiPath1 = &(supportedLBPolicy->iSCSI_Paths[jnx]); + + if ((inx != jnx) && + (iScsiPath0->UniqueConnectionId == iScsiPath1->UniqueConnectionId)) { + + DebugPrint((iScsiPrtDebugError, + "Duplicate path ids at %d and %d\n", + inx, + jnx)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Duplicate path ids at %d and %d\n", + inx, + jnx); + + iScsiStatus = ISDSC_DUPLICATE_PATH_SPECIFIED; + + break; + } + + jnx++; + } + + if (iScsiStatus != STATUS_SUCCESS) { + break; + } + + inx++; + } + + return iScsiStatus; +} + +ULONG +iSpValidateConnectionIds( + IN PISCSI_SESSION IScsiSession, + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + PLIST_ENTRY connectionEntry; + ULONG iScsiStatus = STATUS_SUCCESS; + ULONG inx; + BOOLEAN found; + + if (IScsiSession->NumberOfConnections != SupportedLBPolicy->iSCSI_PathCount) { + + DebugPrint((iScsiPrtDebugError, + "Number of connections %d does not match path count %d\n", + IScsiSession->NumberOfConnections, + SupportedLBPolicy->iSCSI_PathCount)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Number of connections %d does not match path count %d\n", + IScsiSession->NumberOfConnections, + SupportedLBPolicy->iSCSI_PathCount); + + return ISDSC_PATH_COUNT_MISMATCH; + } + + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + found = FALSE; + + connectionEntry = IScsiSession->ConnectionList.Flink; + while (connectionEntry != &IScsiSession->ConnectionList) { + + iScsiConnection = CONTAINING_RECORD(connectionEntry, + ISCSI_CONNECTION, + NextConnection); + + connectionEntry = connectionEntry->Flink; + + // + // Path Id that is returned in QueryLBPolicy is UniqueConnectionID + // + if (iScsiConnection->UniqueConnectionID == iScsiPath->UniqueConnectionId) { + + // + // Set the pointer to iscsi_connection in UniqueConnectionId. This will + // be used in SetLBPolicy routine to set the load balance policy. + // + iScsiPath->UniqueConnectionId = (ULONGLONG) iScsiConnection; + + found = TRUE; + + break; + } + } + + if (!found) { + + DebugPrint((iScsiPrtDebugError, + "Path Id %I64x not found\n", + iScsiPath->UniqueConnectionId)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Path Id %I64x not found\n", + iScsiPath->UniqueConnectionId); + + iScsiStatus = ISDSC_INVALID_PATH_ID; + + break; + } + } + + return iScsiStatus; +} + +ULONG +iSpSetLBFailOverOnly( + IN PISCSI_SESSION IScsiSession, + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + ULONG inx; + ULONG iScsiStatus = STATUS_SUCCESS; + BOOLEAN activeFound = FALSE; + + // + // Save the current value of path status. + // + iSpSavePrimaryPath(SupportedLBPolicy); + + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + if (iScsiPath->PrimaryPath) { + + // + // Primary path specified. Make sure one hasn't been + // specified earlier since only one primary path is + // allowed for FailOverOnly policy. + // + if (!activeFound) { + + DebugPrint((iScsiPrtDebugInfo, + "%p specified as Primary Path\n", + iScsiConnection)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "%p specified as Primary Path\n", + iScsiConnection); + + iScsiConnection->CurrentPathStatus = TRUE; + + activeFound = TRUE; + } else { + + DebugPrint((iScsiPrtDebugError, + "Multiple primary paths given for LBFailOverOnly\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Multiple primary paths given for LBFailOverOnly\n"); + + iScsiStatus = ISDSC_MULTIPLE_PRIMARY_PATHS_SPECIFIED; + } + } else { + + // + // This is a standby path + // + iScsiConnection->CurrentPathStatus = FALSE; + } + } + + if (!activeFound) { + + DebugPrint((iScsiPrtDebugError, + "No active path given for FO Only\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "No active path given for FO Only\n"); + + iScsiStatus = ISDSC_NO_PRIMARY_PATH_SPECIFIED; + } + + if (NT_SUCCESS(iScsiStatus)) { + + DebugPrint((iScsiPrtDebugInfo, + "FailOverOnly set successfully for %p\n", + IScsiSession)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "FailOverOnly set successfully for %p\n", + IScsiSession); + + IScsiSession->LoadBalancePolicy = LB_FAIL_OVER_ONLY; + } else { + + // + // Failed to set user given LB settings. Restore the value of + // path status from the saved value. + // + iSpRestorePrimaryPath(SupportedLBPolicy); + } + + return iScsiStatus; +} + +ULONG +iSpSetLB_LQD_WP( + IN PISCSI_SESSION IScsiSession, + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + ULONG inx; + + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + iScsiConnection->CurrentPathStatus = TRUE; + + if (SupportedLBPolicy->LoadBalancePolicy == LB_LEAST_WEIGHT_PATH) { + iScsiConnection->PathWeight = iScsiPath->PathWeight; + } + } + + IScsiSession->LoadBalancePolicy = SupportedLBPolicy->LoadBalancePolicy; + + return STATUS_SUCCESS; +} + +ULONG +iSpSetLBRoundRobinSubset( + IN PISCSI_SESSION IScsiSession, + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + ULONG iScsiStatus = STATUS_SUCCESS; + ULONG inx; + BOOLEAN activeFound = FALSE; + + // + // Save the current value of path status. + // + iSpSavePrimaryPath(SupportedLBPolicy); + + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + if (iScsiPath->PrimaryPath) { + + iScsiConnection->CurrentPathStatus = TRUE; + + activeFound = TRUE; + } else { + + iScsiConnection->CurrentPathStatus = FALSE; + } + } + + if (!activeFound) { + + DebugPrint((iScsiPrtDebugError, + "No active path given for Round Robin.\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "No active path given for Round Robin.\n"); + + iScsiStatus = ISDSC_NO_PRIMARY_PATH_SPECIFIED; + } + + if (NT_SUCCESS(iScsiStatus)) { + + DebugPrint((iScsiPrtDebugInfo, + "Successfully set LB policy\n")); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagWmi, + "Successfully set LB policy\n"); + + IScsiSession->LoadBalancePolicy = SupportedLBPolicy->LoadBalancePolicy; + } else { + + // + // Failed to set user given LB settings. Restore the value of + // path status from the saved value. + // + iSpRestorePrimaryPath(SupportedLBPolicy); + } + + return iScsiStatus; +} + +FORCEINLINE +iSpSavePrimaryPath( + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + ULONG inx; + + // + // Save the current LB policy settings before setting new values. + // In case the update fails, we'll restore the old LB settings. + // + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + iScsiConnection->PrevPathStatus = iScsiConnection->CurrentPathStatus; + } +} + +FORCEINLINE +iSpRestorePrimaryPath( + IN PISCSI_Supported_LB_Policies SupportedLBPolicy + ) +/*+++ + + Note: This routine should be called with IScsiSession->SessionLock held + +--*/ +{ + PISCSI_Path iScsiPath; + PISCSI_CONNECTION iScsiConnection; + ULONG inx; + + // + // Restore the LB settings from the saved value. + // + for (inx = 0; inx < SupportedLBPolicy->iSCSI_PathCount; inx++) { + + iScsiPath = &(SupportedLBPolicy->iSCSI_Paths[inx]); + + iScsiConnection = (PISCSI_CONNECTION) iScsiPath->UniqueConnectionId; + + iScsiConnection->CurrentPathStatus = iScsiConnection->PrevPathStatus; + } +} + + +VOID +iSpLogError( + IN PDEVICE_OBJECT DeviceObject, + _In_reads_bytes_opt_(ErrorDataSize) PUCHAR ErrorData, + IN ULONG ErrorDataSize, + _In_opt_ PWSTR TargetName, + IN ULONG ErrorCode + ) +/*+++ + +Routine Description : + + This routine will build a WMI event for the MSiSCSI_Eventlog class + and then fire it. The WMI eventlog consumer provider has classes + that intercept the WMI event and will redirect it to the system + eventlog. + +Arguements: + + DeviceObject is the device object of the adapter + + ErrorData is the data to be placed in the additional data field of + the eventlog + + ErrorDataSize is the number of bytes of additional data + + TargetName is the name of the target + + ErrorCode is the iSCSI eventlog error code (see iscsilog.h) + +Return Value: + +--*/ +{ + PMSiSCSI_Eventlog eventLog; + PUCHAR dumpData; + ULONG totalSize; + ULONG dumpDataSize; + ULONG targetNameSize; + NTSTATUS status; + GUID eventLogGUID = MSiSCSI_EventlogGuid; + + if (TargetName != NULL) { + targetNameSize = wcslen(TargetName) * sizeof(WCHAR); + } else { + targetNameSize = 0; + } + + totalSize = sizeof(MSiSCSI_Eventlog) + + ErrorDataSize + + targetNameSize; + + // + // Allocate memory for MSiSCSI_Eventlog object + // + + + if (eventLog != NULL) { + dumpDataSize = totalSize - FIELD_OFFSET(MSiSCSI_Eventlog, + AdditionalData); + eventLog->Type = ErrorCode; + eventLog->LogToEventlog = 1; + + dumpData = eventLog->AdditionalData; + + // + // Copy the entire error data followed by the target name if given. + // + if ((ErrorData != NULL) && (ErrorDataSize > 0)) { + RtlCopyMemory(dumpData, ErrorData, ErrorDataSize); + dumpData += ErrorDataSize; + } + + if (targetNameSize > 0) { + RtlCopyMemory(dumpData, TargetName, targetNameSize); + } + + eventLog->Size = dumpDataSize; + + // + // Fire the WMI event using eventLogGUID GUID, and + // Free the memory allocated for MSiSCSI_Eventlog object. + // + + } +} + + + +UCHAR +iSpBuildBootInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PULONG InstanceLength, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + UCHAR status; + ULONG size; + + size = sizeof(MSiSCSI_BootInformation); + + if (BufferAvail >= size) { + PMSiSCSI_BootInformation bootInfo; + + bootInfo = (PMSiSCSI_BootInformation)Buffer; + + bootInfo->SharedSecretLength = AdapterExtension->BootSecretLength; + RtlCopyMemory(bootInfo->SharedSecret, AdapterExtension->BootSecret, 255); + RtlCopyMemory(bootInfo->NodeName, + AdapterExtension->BootNodeName, + MAX_INITIATOR_NAME); + *SizeNeeded = size; + + status = SRB_STATUS_SUCCESS; + + } else { + + *SizeNeeded = size; + + status = SRB_STATUS_DATA_OVERRUN; + } + + *InstanceLength = *SizeNeeded; + + return status; +} + +UCHAR +iSpBuildRedirectTargetInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PULONG InstanceLength, + IN ULONG BufferAvail, + OUT PUCHAR Buffer, + OUT PULONG SizeNeeded + ) +{ + PWMI_CONNECTION_LIST connectionList; + ULONG size, sessionInx; + ULONG numberOfSessions, numberOfConnections; + UCHAR status; + + + connectionList = iSpGetConnectionList(AdapterExtension, + &numberOfSessions, + &numberOfConnections); + + DebugPrint((iScsiPrtDebugInfo, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Number of Sessions %d, Number of Connections %d\n", + numberOfSessions, + numberOfConnections); + + // + // determine the size of buffer needed to build all of the session + // and connection data structures + // + + // + // Account for the fixed part of the iScsiInitiatorSessionInfo + // + size = FIELD_OFFSET(MSiSCSI_RedirectPortalInfoClass, RedirectSessionList); + + if (connectionList == NULL) { + + if (BufferAvail >= size) + { + PMSiSCSI_RedirectPortalInfoClass redirectPortalInfo; + + redirectPortalInfo = (PMSiSCSI_RedirectPortalInfoClass)Buffer; + + redirectPortalInfo->UniqueAdapterId = (ULONGLONG) AdapterExtension; + redirectPortalInfo->SessionCount = 0; + *SizeNeeded = size; + + status = SRB_STATUS_SUCCESS; + } else { + + *SizeNeeded = size; + + status = SRB_STATUS_DATA_OVERRUN; + } + + *InstanceLength = *SizeNeeded; + + return status; + } + + // + // Loop over all sessions and account for the space needed for each + // session plus all of the connections within each session + // + sessionInx = 0; + while (sessionInx < numberOfSessions) { + + // + // Since the session structure needs to be 8 bytes aligned, we + // pad out to 8 bytes + // + size = (size + 7) & ~7; + + // + // Add the fixed size needed for the session structure + // + size += FIELD_OFFSET(ISCSI_RedirectSessionInfo, + RedirectPortalList); + + // + // Account for the size of all connection structures, being + // sure that the connection structure is padded out to 8 bytes + // in order to maintain 8 byte alignment + // + size += connectionList[sessionInx].Count * + ((sizeof(ISCSI_RedirectPortalInfo) + 7) & ~7); + + sessionInx++; + } + + *SizeNeeded = size; + if (size <= BufferAvail) + { + // + // If we do have enough space to build the session info data + // structures then we do so + // + RtlZeroMemory(Buffer, size); + + status = iSpReadRedirectTargetPortalInfo(AdapterExtension, + connectionList, + numberOfSessions, + Buffer); + + } else { + // + // If there is not enough space to build the session info data + // structures then return this error + // + status = SRB_STATUS_DATA_OVERRUN; + } + + iSpReleaseConnectionReferences(connectionList, + numberOfSessions); + + + return status; +} + +UCHAR +iSpReadRedirectTargetPortalInfo( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PWMI_CONNECTION_LIST ConnectionList, + IN ULONG NumberOfSessions, + IN PUCHAR Buffer + ) +{ + PISCSI_RedirectPortalInfo redirectPortalInfo; + PISCSI_RedirectSessionInfo redirectSessionInfo; + PMSiSCSI_RedirectPortalInfoClass redirectPortalInfoClass; + ULONG sessionIndex; + ULONG connectionIndex; + ULONG inx, skip; + PWMIString WMIformatString; + UCHAR status = SRB_STATUS_SUCCESS; + + + if (ConnectionList == NULL) { + + DebugPrint((iScsiPrtDebugError, + "Connectionlist NULL in iSpReadInitiatorSessionInfo\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Connectionlist NULL in iSpReadInitiatorSessionInfo\n"); + + return status; + } + + redirectPortalInfoClass = (PMSiSCSI_RedirectPortalInfoClass) Buffer; + + redirectPortalInfoClass->UniqueAdapterId = (ULONGLONG) AdapterExtension; + + // + // initialize Session count to 0 + // + redirectPortalInfoClass->SessionCount = 0; + + redirectSessionInfo = redirectPortalInfoClass->RedirectSessionList; + + inx = 0; + while (inx < NumberOfSessions) { + + PISCSI_SESSION iScsiSession; + PISCSI_CONNECTION iScsiConnection; + + iScsiSession = ConnectionList[inx].ISCSISession; + + if (iScsiSession == NULL) { + + inx++; + + continue; + } + + redirectSessionInfo->UniqueSessionId = iScsiSession->SessionId; + + redirectSessionInfo->TargetPortalGroupTag = iScsiSession->TargetPortalGroupTag; + + redirectSessionInfo->ConnectionCount = 0; + + redirectPortalInfo = redirectSessionInfo->RedirectPortalList; + + for (connectionIndex = 0; + connectionIndex < ConnectionList[inx].Count; + connectionIndex++) + { + + iScsiConnection = ConnectionList[inx].ISCSIConnection[connectionIndex]; + if (iScsiConnection != NULL) { + + redirectPortalInfo->UniqueConnectionId = iScsiConnection->UniqueConnectionID; + + iSpCopyIPAddress(&redirectPortalInfo->OriginalIPAddr, + &iScsiConnection->PermanentTargetIPAddress, + &redirectPortalInfo->OriginalPort); + + redirectPortalInfo->OriginalIPAddr.TextAddress[0] = MAX_ISCSI_TEXT_ADDRESS_LEN*sizeof(WCHAR); + + redirectPortalInfo->Redirected = iScsiConnection->TargetMoved; + + if (iScsiConnection->TargetMoved) { + + iSpCopyIPAddress(&redirectPortalInfo->RedirectedIPAddr, + &iScsiConnection->TargetIPAddress, + &redirectPortalInfo->RedirectedPort); + + redirectPortalInfo->RedirectedIPAddr.TextAddress[0] = MAX_ISCSI_TEXT_ADDRESS_LEN*sizeof(WCHAR); + + redirectPortalInfo->TemporaryRedirect = iScsiConnection->TargetMoveTemporary; + } + + //increment the connectionStaticInfo pointer to the next 4 byte alligned address; + (PUCHAR) redirectPortalInfo += ((sizeof(ISCSI_RedirectPortalInfo)+7) & ~7); + + //The number of TCP connections that currently belong to this session + redirectSessionInfo->ConnectionCount ++; + } + } + + // + // Advance to next place to write session information + // + skip = FIELD_OFFSET(ISCSI_RedirectSessionInfo, RedirectPortalList) + + (ConnectionList[inx].Count * + ((sizeof(ISCSI_RedirectPortalInfo) + 7) & ~7)); + + skip = (skip + 7) & ~7; + + (PUCHAR) redirectSessionInfo += skip; + + redirectPortalInfoClass->SessionCount++; + + inx++; + } + + return status; +} + +NTSTATUS +iSpFindPersistentTargetKey( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + _In_ PWSTR TargetName, + IN PISCSI_TargetPortal TargetPortal, + IN ULONG PortNumber, + OUT PHANDLE TargetKey, + _Out_writes_opt_ (TargetKeyNameSize) PWCHAR TargetKeyName, OPTIONAL + IN ULONG TargetKeyNameSize + ) +{ + HANDLE persistentTargetsKey = NULL; + HANDLE pnpDriverKey; + NTSTATUS status; + + *TargetKey = NULL; + + status = iSpOpenPnPDriverKey(AdapterExtension->PhysicalDeviceObject, + PERSISTENT_TARGETS, + KEY_ALL_ACCESS, + &pnpDriverKey, + &persistentTargetsKey); + if (NT_SUCCESS(status)) { + + KEY_BASIC_INFORMATION keyInfo[ISCSI_KEY_BASIC_INFO_SIZE]; + ULONG resultSize; + ULONG index; + BOOLEAN found; + + index = 0; + found = FALSE; + + while (!found) { + + resultSize = ISCSI_KEY_BASIC_INFO_SIZE * sizeof(KEY_BASIC_INFORMATION); + + RtlZeroMemory(keyInfo, resultSize); + + // + // Enumerate all the keys under PersistentTargets key + // + status = ZwEnumerateKey(persistentTargetsKey, + index, + KeyBasicInformation, + keyInfo, + resultSize, + &resultSize); + if (NT_SUCCESS(status)) { + + PUCHAR regValue; + HANDLE targetNameKey; + OBJECT_ATTRIBUTES objectAttributes; + UNICODE_STRING subKeyName; + WCHAR targetKeyName[512]; + ULONG nameLength; + ULONG targetnameLen; + ULONG regValueSize; + + nameLength = keyInfo->NameLength; + + if (nameLength > ISCSI_KEY_BASIC_INFO_NAME_MAXLEN) { + nameLength = ISCSI_KEY_BASIC_INFO_NAME_MAXLEN; + } + + // + // Find the key which matches the given target name + // + + status = RtlStringCchCopyNW( + targetKeyName, + sizeof(targetKeyName)/sizeof(targetKeyName[0]), + keyInfo->Name, + nameLength); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE) + { + goto NextKey; + } + + targetnameLen = wcslen(TargetName); + + if (!wcsncmp(TargetName, targetKeyName, targetnameLen)) { + + // + // Open LoginTarget under this target key + // + RtlStringCchCatW(targetKeyName, 255, L"\\"); + + RtlStringCchCatW(targetKeyName, 255, LOGIN_TARGET_STR); + + RtlInitUnicodeString(&subKeyName, targetKeyName); + + DebugPrint((iScsiPrtDebugInfo, + "Persistent Target Key %ws\n", + targetKeyName)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Persistent Target Key %ws\n", + targetKeyName); + + RtlZeroMemory(&objectAttributes, sizeof(OBJECT_ATTRIBUTES)); + + InitializeObjectAttributes(&objectAttributes, + &subKeyName, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + persistentTargetsKey, + (PSECURITY_DESCRIPTOR) NULL); + + status = ZwOpenKey(&targetNameKey, + KEY_ALL_ACCESS, + &objectAttributes); + if (NT_SUCCESS(status)) { + + status = iSpQueryRegistryValue(targetNameKey, LOGIN_TARGET_IN, + ISCSI_TAG_LOGINTARGET_IN, + ®Value, ®ValueSize); + if (NT_SUCCESS(status)) { + PLoginToTarget_IN loginTargetIN; + PISCSI_TargetPortal targetPortal; + + loginTargetIN = (PLoginToTarget_IN) regValue; + + targetPortal = &(loginTargetIN->TargetPortal); + + if ((PortNumber == loginTargetIN->PortNumber) && + (targetPortal->Address.Type != ISCSI_IP_ADDRESS_EMPTY) && + (IsSamePortal(TargetPortal, targetPortal))) { + + found = TRUE; + + // + // Open the TargetName key and return a handle to that + // + status = RtlStringCchCopyNW( + targetKeyName, + sizeof(targetKeyName)/sizeof(targetKeyName[0]), + keyInfo->Name, + nameLength); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == TRUE) + { + RtlInitUnicodeString(&subKeyName, targetKeyName); + + RtlZeroMemory(&objectAttributes, sizeof(OBJECT_ATTRIBUTES)); + + InitializeObjectAttributes(&objectAttributes, + &subKeyName, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + persistentTargetsKey, + (PSECURITY_DESCRIPTOR) NULL); + + status = ZwOpenKey(TargetKey, + KEY_ALL_ACCESS, + &objectAttributes); + if (NT_SUCCESS(status)) { + + if (TargetKeyName != NULL) { + + NT_ASSERT(TargetKeyNameSize > 0); + + status = RtlStringCchCopyNW( + TargetKeyName, + TargetKeyNameSize, + targetKeyName, + sizeof(targetKeyName)/sizeof(targetKeyName[0])); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE) + { + DebugPrint((iScsiPrtDebugError, + "Failed to copy TargetKeyName %ws\n", + targetKeyName)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to copy TargetKeyName %ws\n", + targetKeyName); + + *TargetKey = NULL; + } + } + } else { + *TargetKey = NULL; + } + } else { + + DebugPrint((iScsiPrtDebugError, + "Failed to copy target name from KeyInfo.\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to copy target name from KeyInfo.\n"); + } + } else { + + DebugPrint((iScsiPrtDebugError, + "Portal mismatch. Port Numbers %x, %x\n", + PortNumber, loginTargetIN->PortNumber)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Portal mismatch. Port Numbers %x, %x\n", + PortNumber, loginTargetIN->PortNumber); + } + + ExFreePool(regValue); + } + + ZwClose(targetNameKey); + } + } + } else if (status == STATUS_NO_MORE_ENTRIES) { + + DebugPrint((iScsiPrtDebugError, + "Enumerated all persistent targets\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Enumerated all persistent targets\n"); + + break; + } else { + + DebugPrint((iScsiPrtDebugError, + "ZwEnumerateKey failed for persistent targets. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "ZwEnumerateKey failed for persistent targets. Status %x\n", + status); + + break; + } +NextKey: + index++; + } + + iSpClosePnPDriverKey(&pnpDriverKey, &persistentTargetsKey); + } + + return status; +} + +NTSTATUS +iSpDeleteKeyAndSubkeys( + IN HANDLE RootKey + ) +{ + KEY_BASIC_INFORMATION keyInfo[ISCSI_KEY_BASIC_INFO_SIZE]; + NTSTATUS status = STATUS_SUCCESS; + ULONG resultSize; + ULONG index; + BOOLEAN deleted = FALSE; + + index = 0; + + // + // Enumerate all the keys under the given key and delete each one of them. + // Note that this routine assumes there are no subkeys and the subkeys + // to the Root Key. This routine can only delete a registry tree with + // one sub level below the Root Key. + // + while (status == STATUS_SUCCESS) { + + resultSize = ISCSI_KEY_BASIC_INFO_SIZE * sizeof(KEY_BASIC_INFORMATION); + + RtlZeroMemory(keyInfo, resultSize); + + // + // Enumerate all the keys under the given key + // + status = ZwEnumerateKey(RootKey, + index, + KeyBasicInformation, + keyInfo, + resultSize, + &resultSize); + if (NT_SUCCESS(status)) { + + HANDLE subKeyHandle; + UNICODE_STRING subKey; + WCHAR subKeyName[ISCSI_KEY_BASIC_INFO_NAME_MAXLEN + 1]; // add 1 for null terminator + OBJECT_ATTRIBUTES objectAttributes; + ULONG nameLength; + + deleted = FALSE; + + nameLength = keyInfo->NameLength; + if (nameLength > ISCSI_KEY_BASIC_INFO_NAME_MAXLEN) { + nameLength = ISCSI_KEY_BASIC_INFO_NAME_MAXLEN; + } + + status = RtlStringCchCopyNW( + subKeyName, + sizeof(subKeyName) / sizeof(subKeyName[0]), + keyInfo->Name, + nameLength); + + NT_ASSERT(NT_SUCCESS(status)); + + if(NT_SUCCESS(status) == FALSE) + { + break; + } + + RtlInitUnicodeString(&subKey, subKeyName); + + RtlZeroMemory(&objectAttributes, sizeof(OBJECT_ATTRIBUTES)); + + InitializeObjectAttributes(&objectAttributes, + &subKey, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + RootKey, + (PSECURITY_DESCRIPTOR) NULL); + + // + // Open this subkey and delete it. + // + status = ZwOpenKey(&subKeyHandle, + KEY_ALL_ACCESS, + &objectAttributes); + if (NT_SUCCESS(status)) { + + // + // Note that there should be no subkeys under this key. Otherwise + // ZwDeleteKey will fail with error STATUS_CANNOT_DELETE. + // + status = ZwDeleteKey(subKeyHandle); + if (NT_SUCCESS(status)) { + + DebugPrint((iScsiPrtDebugInfo, + "Deleted subkey %ws\n", + subKeyName)); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagGeneral, + "Deleted subkey %ws\n", + subKeyName); + + deleted = TRUE; + } else { + + + DebugPrint((iScsiPrtDebugError, + "Failed to delete subkey %ws. Status %x\n", + subKeyName, status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagGeneral, + "Failed to delete subkey %ws. Status %x\n", + subKeyName, status); + } + + ZwClose(subKeyHandle); + + } + } else if (status != STATUS_NO_MORE_ENTRIES) { + + DebugPrint((iScsiPrtDebugError, + "Failed to enumerate subkeys in delete key and subkeys. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagGeneral, + "Failed to enumerate subkeys in delete key and subkeys. Status %x\n", + status); + } + + // + // If the key was successfully deleted do not increment the index since + // the number of keys under RootKey is now lesser by one. + // + if (!deleted) { + index++; + } + } + + if (!NT_SUCCESS(status) && (status == STATUS_NO_MORE_ENTRIES)) { + + // + // This indicates that all the subkeys under Root Key have been + // enumerated and they have been deleted successfully. It is now + // safe to delete the Root Key. + // + status = STATUS_SUCCESS; + + status = ZwDeleteKey(RootKey); + if (!NT_SUCCESS(status)) { + + DebugPrint((iScsiPrtDebugError, + "Failed to delete Root Key. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagGeneral, + "Failed to delete Root Key. Status %x\n", + status); + } else { + + DebugPrint((iScsiPrtDebugTrace, + "Successfully delete all keys and subkeys\n")); + + ETWDebugPrint(iScsiLevelTrace, + iScsiFlagGeneral, + "Successfully delete all keys and subkeys\n"); + } + } else { + + DebugPrint((iScsiPrtDebugError, + "Failed to delete key and all subkeys. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagGeneral, + "Failed to delete key and all subkeys. Status %x\n", + status); + } + + return status; +} + +NTSTATUS +iSpPersisteLBPolicy( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PPERSISTENT_TARGET_LB_POLICY LBPolicy + ) +{ + HANDLE persistentTargetsKey; + HANDLE pnpDriverKey; + PLB_POLICY_DATA LBPolicyData; + ULONG inx; + ULONG lbPolicy; + NTSTATUS status; + + PAGED_CODE(); + + status = iSpOpenPnPDriverKey(AdapterExtension->PhysicalDeviceObject, + PERSISTENT_TARGETS, + KEY_ALL_ACCESS, + &pnpDriverKey, + &persistentTargetsKey); + if (NT_SUCCESS(status)) { + + OBJECT_ATTRIBUTES objectAttributes; + HANDLE subKeyHandle; + HANDLE loginTargetKey; + UNICODE_STRING subKey; + WCHAR subKeyName[32]; + + RtlZeroMemory(subKeyName,sizeof(subKeyName)); + + RtlInitUnicodeString(&subKey, LBPolicy->TargetKeyName); + + RtlZeroMemory(&objectAttributes, sizeof(OBJECT_ATTRIBUTES)); + + InitializeObjectAttributes(&objectAttributes, + &subKey, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + persistentTargetsKey, + (PSECURITY_DESCRIPTOR) NULL); + + status = ZwOpenKey(&subKeyHandle, + KEY_ALL_ACCESS, + &objectAttributes); + + if (NT_SUCCESS(status)) { + + // + // Save the new Load Balance policy for this target + // + status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, + subKeyHandle, + LOAD_BALANCE_POLICY, + REG_DWORD, + &LBPolicy->LoadBalancePolicy, + sizeof(ISCSI_LOAD_BALANCE_POLICY)); + NT_ASSERT(NT_SUCCESS(status)); + + for (inx = 0; NT_SUCCESS(status) && inx < LBPolicy->ConnectionCount; inx++) { + + // + // Save the PrimaryPath and PathWeight for each connection + // + LBPolicyData = &(LBPolicy->PolicyData[inx]); + + if (LBPolicyData->ConnectionNumber == -1) { + + RtlStringCchCopyW(subKeyName, 32, LOGIN_TARGET_STR); + } else { + + RtlStringCchPrintfW(subKeyName, + ((sizeof(subKeyName) - sizeof(WCHAR))/sizeof(WCHAR)), + L"%ws%d", + ADD_CONNECTION_STR, + LBPolicyData->ConnectionNumber); + } + + DebugPrint((iScsiPrtDebugInfo, + "Will open subkey %ws\n", + subKeyName)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagWmi, + "Will open subkey %ws\n", + subKeyName); + + RtlInitUnicodeString(&subKey, subKeyName); + + RtlZeroMemory(&objectAttributes, sizeof(OBJECT_ATTRIBUTES)); + + InitializeObjectAttributes(&objectAttributes, + &subKey, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + subKeyHandle, + (PSECURITY_DESCRIPTOR) NULL); + + status = ZwOpenKey(&loginTargetKey, + KEY_ALL_ACCESS, + &objectAttributes); + if (NT_SUCCESS(status)) { + + // + // Save PathWeight and PrimaryPath + // + status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, + loginTargetKey, + PATH_WEIGHT, + REG_DWORD, + &LBPolicyData->PathWeight, + sizeof(ULONG)); + if (!NT_SUCCESS(status)) { + + DebugPrint((iScsiPrtDebugError, + "Failed to save Path Weight. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to save Path Weight. Status %x\n", + status); + } + + status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, + loginTargetKey, + PRIMARY_PATH, + REG_DWORD, + &LBPolicyData->PrimaryPath, + sizeof(ULONG)); + if (!NT_SUCCESS(status)) { + + DebugPrint((iScsiPrtDebugError, + "Failed to save Path Weight. Status %x\n", + status)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to save Path Weight. Status %x\n", + status); + } + + ZwClose(loginTargetKey); + } else { + + DebugPrint((iScsiPrtDebugError, + "Failed to open subkey subKeyName to save LB Policy\n")); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagWmi, + "Failed to open subkey subKeyName to save LB Policy\n"); + } + } + + ZwClose(subKeyHandle); + } + + iSpClosePnPDriverKey(&pnpDriverKey, &persistentTargetsKey); + } + + return status; +} + +NTSTATUS +iSpSetTargetNameSuffix( + IN PISCSI_ADAPTER_EXTENSION AdapterExtension, + IN PLoginToTarget_IN LoginTargetIn + ) +{ + PISCSI_SESSION iScsiSession = NULL; + HANDLE removeTargetKey = NULL; + WCHAR targetName[MAX_TARGET_NAME + 1]; + WCHAR targetKeyName[MAX_TARGET_NAME + TARGET_KEYNAME_SUFFIX_SIZE + 1]; + ULONG bytesToCopy; + KIRQL oldIrql; + NTSTATUS rtlStatus = ERROR_SUCCESS; + + if (LoginTargetIn->SessionType != ISCSI_LOGINTARGET_DATA) { + return STATUS_INVALID_PARAMETER; + } + + RtlZeroMemory(targetKeyName, sizeof(targetKeyName)); + RtlZeroMemory(targetName, sizeof(targetName)); + + bytesToCopy = *(LoginTargetIn->TargetName); + if (bytesToCopy > (MAX_TARGET_NAME * sizeof(WCHAR))) { + bytesToCopy = MAX_TARGET_NAME * sizeof(WCHAR); + } + + RtlCopyMemory(targetName, + (LoginTargetIn->TargetName + 1), + bytesToCopy); + + rtlStatus = iSpFindPersistentTargetKey( + AdapterExtension, + targetName, + &(LoginTargetIn->TargetPortal), + LoginTargetIn->PortNumber, + &removeTargetKey, + targetKeyName, + sizeof(targetKeyName)/sizeof(targetKeyName[0])); + + if (NT_SUCCESS(rtlStatus) && removeTargetKey != NULL) { + + PWCHAR suffixPtr; + PISCSI_CONNECTION iScsiConnection; + PLIST_ENTRY sessionEntry; + PLIST_ENTRY connectionEntry; + PISCSI_TRANSPORT_ADDRESS targetIPAddress; + ISCSI_TargetPortal targetPortal; + BOOLEAN found = FALSE; + + suffixPtr = wcschr(targetKeyName, L'#'); + if (suffixPtr != NULL) { + + DebugPrint((iScsiPrtDebugInfo, + "Suffix is %ws\n", + suffixPtr)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagProtocolLogInOut, + "Suffix is %ws\n", + suffixPtr); + + RtlZeroMemory(&targetPortal, sizeof(targetPortal)); + + KeAcquireSpinLock(&AdapterExtension->AdapterLock, &oldIrql); + + sessionEntry = AdapterExtension->IScsiSessionList.Flink; + while (sessionEntry != &AdapterExtension->IScsiSessionList) { + + iScsiSession = CONTAINING_RECORD(sessionEntry, + ISCSI_SESSION, + NextSession); + + sessionEntry = sessionEntry->Flink; + + if (wcsncmp(targetName, + iScsiSession->TargetName, + MAX_TARGET_NAME) == 0) { + + connectionEntry = iScsiSession->ConnectionList.Flink; + while (connectionEntry != &iScsiSession->ConnectionList) { + + iScsiConnection = CONTAINING_RECORD(connectionEntry, + ISCSI_CONNECTION, + NextConnection); + + connectionEntry = connectionEntry->Flink; + + targetIPAddress = &(iScsiConnection->TargetIPAddress); + + if (targetIPAddress->AddressType == TDI_ADDRESS_TYPE_IP) { + + targetPortal.Address.Type = ISCSI_IP_ADDRESS_IPV4; + + targetPortal.Socket = + targetIPAddress->IPAddress.IPv4Address.sin_port; + + targetPortal.Address.IpV4Address = + targetIPAddress->IPAddress.IPv4Address.in_addr; + } else { + + targetPortal.Address.Type = ISCSI_IP_ADDRESS_IPV6; + + targetPortal.Socket = + targetIPAddress->IPAddress.IPv6Address.sin6_port; + + targetPortal.Address.IpV6FlowInfo = + targetIPAddress->IPAddress.IPv6Address.sin6_flowinfo; + + targetPortal.Address.IpV6ScopeId = + targetIPAddress->IPAddress.IPv6Address.sin6_scope_id; + + RtlCopyMemory(targetPortal.Address.IpV6Address, + targetIPAddress->IPAddress.IPv6Address.sin6_addr, + sizeof(targetPortal.Address.IpV6Address)); + } + + if (IsSamePortal(&targetPortal, &(LoginTargetIn->TargetPortal))) { + + DebugPrint((iScsiPrtDebugInfo, + "Found session %p\n", + iScsiSession)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagProtocolLogInOut, + "Found session %p\n", + iScsiSession); + + found = TRUE; + break; + } + } + } + + if (found) { + break; + } + } + + KeReleaseSpinLock(&AdapterExtension->AdapterLock, oldIrql); + + if (found) { + + DebugPrint((iScsiPrtDebugInfo, + "Will copy suffix %ws to session %p\n", + suffixPtr, + iScsiSession)); + + ETWDebugPrint(iScsiLevelInfo, + iScsiFlagProtocolLogInOut, + "Will copy suffix %ws to session %p\n", + suffixPtr, + iScsiSession); + + rtlStatus = RtlStringCchCopyNW(iScsiSession->TargetKeyNameSuffix, + TARGET_KEYNAME_SUFFIX_SIZE, + suffixPtr, + (TARGET_KEYNAME_SUFFIX_SIZE - 1)); + + iScsiSession->PersistentLogin = TRUE; + } + } else { + + DebugPrint((iScsiPrtDebugError, + "No suffix found for target %ws\n", + targetKeyName)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "No suffix found for target %ws\n", + targetKeyName); + } + + ZwClose(removeTargetKey); + } else { + + DebugPrint((iScsiPrtDebugError, + "%ws is probably not a persistent target\n", + targetName)); + + ETWDebugPrint(iScsiLevelError, + iScsiFlagProtocolLogInOut, + "%ws is probably not a persistent target\n", + targetName); + + } + + return rtlStatus; +} + diff --git a/storage/iscsi/src/common.mof b/storage/iscsi/src/common.mof new file mode 100644 index 00000000..730f4794 --- /dev/null +++ b/storage/iscsi/src/common.mof @@ -0,0 +1,848 @@ +//*************************************************************************** +// +// common.mof +// +// Module: iScsi Discovery api +// +// Purpose: Common definitions used for iscsi mofs +// +// Copyright (c) 2001 Microsoft Corporation +// +//*************************************************************************** + +// +// Include common definitions +// +#define MOFCOMP_PASS +#include "iscsidsc.h" +#include "iscsierr.h" + +// +// ISCSI method execution status code +// +#define ISCSI_STATUS uint32 + +#define ISCSI_STATUS_QUALIFIERS \ + Description("Status code resulting from operation") : amended, \ + Values { "Success", \ + "Non Specific Error", \ + "Login Failed", \ + "Connection Failed", \ + "Initiator Node Already Exists", \ + "Initiator Node Does Not Exist", \ + "Target Moved Temporarily", \ + "Target Moved Permamently", \ + "Initiator Error", \ + "Authentication Failure", \ + "Authorization Failure", \ + "Not Found", \ + "Target Removed", \ + "Unsupported Version", \ + "Too many Connections", \ + "Missing Parameter", \ + "Can not include in session", \ + "Session type not supported", \ + "Target Error", \ + "Service Unavailable", \ + "Out of Resources", \ + "Connections already exist on initiator node", \ + "Session Already Exists", \ + "Initiator Instance Does Not Exist", \ + "Target Already Exists", \ + "The iscsi driver implementation did not complete an operation correctly", \ + "An invalid key text was encountered", \ + "Invalid SendTargets response text was encountered", \ + "Invalid Session Id", \ + "The scsi request failed", \ + "Exceeded max sessions for this initiator.", \ + "Session is busy since a request is already in progress.", \ + "The target mapping is not available", \ + "The Target Address type given is not supported", \ + "Logon Failed", \ + "TCP Send Failed", \ + "TCP Transport Error", \ + "iSCSI Version Mismatch", \ + "The Target Mapping Address passed is out of range for the adapter configuration", \ + "The preshared key for the target or IKE identification payload is not available.", \ + "The authentication information for the target is not available", \ + "The target name is not found or is marked as hidden from login.", \ + "One or more parameters specified in LoginTargetIN structure is invalid.", \ + "Given target mapping already exists.", \ + "The HBA security information cache is full.", \ + "The port number passed is not valid for the initiator.", \ + "Operation was not successful for all initiators.", \ + "The HBA security information cache is not supported by this adapter.", \ + "The IKE id payload type specified is not supported.", \ + "The IKE id payload size specified is not correct.", \ + "Target Portal Structure Already Exists.", \ + "Target Address Structure Already Exists.", \ + "There is no IKE authentication information available.", \ + "There is no tunnel mode outer address specified.", \ + "Authentication or tunnel address cache is corrupted.", \ + "The request or operation is not supported.", \ + "The target does not have enough resources to process the given request.", \ + "The initiator service did not respond to the request sent by the driver.", \ + "The iSNS server was not found or is unavailable.", \ + "The operation was successful but requires a driver reload or reboot to become effective.", \ + "There is no target portal available to complete the login.", \ + "Cannot remove the last connection for a session.", \ + "The Microsoft iSCSI Initiator Service is not running. Please start the service and retry.", \ + "The target has already been logged in via an iSCSI session.", \ + "The session cannot be logged out since a device on that session is currently being used.", \ + "Failed to save persistent login information.", \ + "Failed to remove persistent login information.", \ + "The specified initiator name was not found.", \ + "The specified portal was not found.", \ + "The specified discovery mechanism was not found.", \ + "iSCSI does not support IPSEC for this version of the OS.", \ + "The iSCSI service timed out waiting for all persistent logins to complete.", \ + "The specified CHAP secret is less than 96 bits and will not be usable for authenticating over non ipsec connections.", \ + "The evaluation period for the iSCSI initiator service has expired.", \ + "CHAP secret given does not conform to the standard. Please see system event log for more information.", \ + "Target CHAP secret given is invalid.", \ + "Initiator CHAP secret given is invalid.", \ + "CHAP Username given is invalid.", \ + "Logon Authentication type given is invalid.", \ + "Target Mapping information given is invalid.", \ + "Target Id given in Target Mapping is invalid.", \ + "The iSCSI name specified contains invalid characters or is too long.", \ + "The iSNS version number returned from the iSNS server is not compatible with this version of the iSNS client.", \ + "Initiator failed to configure IPSec for the given connection. This could be because of low resources.", \ + "The buffer given for processing the request is too small.", \ + "The given Load Balance policy is not recognized by iScsi initiator.", \ + "One or more paramaters specified is not valid.", \ + "Duplicate PathIds were specified in the call to set Load Balance Policy.", \ + "Number of paths specified in Set Load Balance Policy does not match the number of paths to the target.", \ + "Path Id specified in the call to set Load Balance Policy is not valid.", \ + "Multiple primary paths specified when only one primary path is expected.", \ + "No primary path specified when at least one is expected.", \ + "Volume is already a persistently bound volume.", \ + "Volume was not found.", \ + "The volume specified does not originate from an iSCSI disk.", \ + "The DNS name specified was not resolved.", \ + "There is no connection available in the iSCSI session to process the request.", \ + "The given Load Balance policy is not supported.", \ + "A remove connection request is already in progress for this session.", \ + "Given connection was not found in the session.", \ + "The leading connection in the session cannot be removed." \ + }, \ + ValueMap { "0", \ + "0xEFFF0001", \ + "0xEFFF0002", \ + "0xEFFF0003", \ + "0xEFFF0004", \ + "0xEFFF0005", \ + "0xEFFF0006", \ + "0xEFFF0007", \ + "0xEFFF0008", \ + "0xEFFF0009", \ + "0xEFFF000A", \ + "0xEFFF000B", \ + "0xEFFF000C", \ + "0xEFFF000D", \ + "0xEFFF000E", \ + "0xEFFF000F", \ + "0xEFFF0010", \ + "0xEFFF0011", \ + "0xEFFF0012", \ + "0xEFFF0013", \ + "0xEFFF0014", \ + "0xEFFF0015", \ + "0xEFFF0016", \ + "0xEFFF0017", \ + "0xEFFF0018", \ + "0xEFFF0019", \ + "0xEFFF001A", \ + "0xEFFF001B", \ + "0xEFFF001C", \ + "0xEFFF001D", \ + "0xEFFF001E", \ + "0xEFFF001F", \ + "0xEFFF0020", \ + "0xEFFF0021", \ + "0xEFFF0022", \ + "0xEFFF0023", \ + "0xEFFF0024", \ + "0xEFFF0025", \ + "0xEFFF0026", \ + "0xEFFF0027", \ + "0xEFFF0028", \ + "0xEFFF0029", \ + "0xEFFF002A", \ + "0xEFFF002B", \ + "0xEFFF002C", \ + "0xEFFF002D", \ + "0xEFFF002E", \ + "0xEFFF002F", \ + "0xEFFF0030", \ + "0xEFFF0031", \ + "0xEFFF0032", \ + "0xEFFF0033", \ + "0xEFFF0034", \ + "0xEFFF0035", \ + "0xEFFF0036", \ + "0xEFFF0037", \ + "0xEFFF0038", \ + "0xEFFF0039", \ + "0xEFFF003A", \ + "0xAFFF003B", \ + "0xEFFF003C", \ + "0xEFFF003D", \ + "0xEFFF003E", \ + "0xEFFF003F", \ + "0xEFFF0040", \ + "0xEFFF0041", \ + "0xEFFF0042", \ + "0xEFFF0043", \ + "0xEFFF0044", \ + "0xEFFF0045", \ + "0xEFFF0046", \ + "0xEFFF0047", \ + "0xAFFF0048", \ + "0xEFFF0049", \ + "0xEFFF004A", \ + "0xEFFF004B", \ + "0xEFFF004C", \ + "0xAFFF004D", \ + "0xEFFF004E", \ + "0xEFFF004F", \ + "0xEFFF0050", \ + "0xEFFF0051", \ + "0xEFFF0052", \ + "0xEFFF0053", \ + "0xEFFF0054", \ + "0xEFFF0055", \ + "0xEFFF0056", \ + "0xEFFF0057", \ + "0xEFFF0058", \ + "0xEFFF0059", \ + "0xEFFF005A", \ + "0xEFFF005B", \ + "0xEFFF005C", \ + "0xEFFF005D", \ + "0xEFFF005E", \ + "0xEFFF005F", \ + "0xEFFF0060", \ + "0xEFFF0061", \ + "0xEFFF0062", \ + "0xEFFF0063", \ + "0xEFFF0064" \ + } + + +[ + WmiGenerateHeader(GENERATE_HEADER), + WMI, + DisplayName("IP Address") : amended, + guid("{9AC5D4A1-1A1A-48ec-8E79-735806E9A1FA}"), + cpp_quote(MODULE_HEADER +ISCSI_SECURITY_FLAGS_CPPQUOTE +"\n" +"//\n" +"// Types of addresses that can be passed by management app to driver\n" +"//\n" +"typedef enum {\n" +" // Text based host name. This needs to be resolved to binary form\n" +" ISCSI_IP_ADDRESS_TEXT = 0,\n" +" // Binary IPv4 address\n" +" ISCSI_IP_ADDRESS_IPV4 = 1,\n" +" // Binary IPv6 address\n" +" ISCSI_IP_ADDRESS_IPV6 = 2,\n" +" // Empty address\n" +" ISCSI_IP_ADDRESS_EMPTY = 3\n" +"} ISCSIIPADDRESSTYPE, *PISCSIIPADDRESSTYPE;\n" + ) +] +class ISCSI_IP_Address +{ + [WmiDataId(1), + read, write, + DisplayName("Address Format") : amended, + description("Type of address specified. It can be text: a DNS or dotted address or it can be a binary ipv4 or ipv6 address") : amended, + Values{ "Text Address", + "IpV4 Address", + "IpV6 Address", + "Empty Address"}, + ValueMap{ "0", + "1", + "2", + "3"} + ] +#define ISCSIIPADDRESSTYPE uint32 + ISCSIIPADDRESSTYPE Type; + + [WmiDataId(2), + read, write, + DisplayInHex, + DisplayName("IPV4 Address"): amended, + description("If IPV4 Address is specified as the Address Format then this conains the binary IPv4 ip address") : amended + ] + uint32 IpV4Address; + + [WmiDataId(3), + DisplayName("IPV6 Address"): amended, + read, write, + description("If IPV6 Address is specified as the Address Format then this conains the binary IPv6 ip address") : amended + ] + uint8 IpV6Address[16]; + + [WmiDataId(4), + read, write, + DisplayName("IPV6 Flow Information") : amended, + description("IPV6 flow information") : amended + ] + uint32 IpV6FlowInfo; + + [WmiDataId(5), + read, write, + DisplayName("IPV6 Scope Id") : amended, + description("IPV6 scope id") : amended + ] + uint32 IpV6ScopeId; + + [WmiDataId(6), + read, write, + DisplayName("Text Address") : amended, + description("Text address, either a DNS address or dotted address") : amended, + MaxLen(MAX_ISCSI_TEXT_ADDRESS_LEN) + ] + string TextAddress; +}; + + +[ + WmiGenerateHeader(GENERATE_HEADER), + WMI, + guid("{DE5051A7-BF27-48f1-BD12-07CADE92AEFD}"), + description("ISCSI target portal") : amended +] +class ISCSI_TargetPortal +{ + [WmiDataId(1), + Description("Network Address") : amended + ] + ISCSI_IP_Address Address; + + [WmiDataId(2), + Description("Reserved") : amended + ] + uint32 Reserved; + + [WmiDataId(3), + Description("Socket number") : amended + ] + uint16 Socket; +}; + +[WMI, + WmiGenerateHeader(GENERATE_HEADER), + guid("{3081F2A5-95F5-4d2a-813D-EE59864C6FC5}"), + description("iSCSI target portal group") : amended +] +class ISCSI_TargetPortalGroup +{ + [WmiDataId(1), + description("Number of portals in group") : amended + ] + uint32 PortalCount; + + [WmiDataId(2), + WmiSizeIs("PortalCount"), + description("Target portals in group") : amended + ] + ISCSI_TargetPortal Portals[]; +}; + + +[WMI, + WmiGenerateHeader(GENERATE_HEADER), + guid("{3011A7BD-0491-478e-8C79-3C76424D05E2}"), + cpp_quote(ISCSI_DIGEST_CPPQUOTE), + Description("These are options that can be used for logging into a target") +] +class ISCSI_LoginOptions +{ + [WmiDataId(1), + description("Bit flags that specify which login option values are specified") : amended, + ISCSI_LOGIN_OPTIONS_INFO_QUALIFIERS, + cpp_quote(ISCSI_LOGIN_OPTIONS_INFO_CPPQUOTE) + ] ISCSI_LOGIN_OPTIONS_INFO_SPECIFIED InformationSpecified; + + [WmiDataId(2), + ValueMap{ ISCSI_DIGEST_TYPE_NONE, + ISCSI_DIGEST_TYPE_CRC32C }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 HeaderDigest; + + [WmiDataId(3), + ValueMap{ ISCSI_DIGEST_TYPE_NONE, + ISCSI_DIGEST_TYPE_CRC32C }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 DataDigest; + + [WmiDataId(4), + Description("Maximum number of connections, 0 implies no limit") : amended + ] + uint32 MaximumConnections; + + [WmiDataId(5), + Description("The initiator and target negotiate the minimum time, in seconds, to wait before attempting an explicit/implicit logout or active task reassignment after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Wait; + + [WmiDataId(6), + Description(" The initiator and target negotiate the maximum time, in seconds after an initial wait (Time2Wait), before which an explicit/implicit connection Logout or active task reassignment is still possible after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Retain; + + [WmiDataId(7), + Description("Flags that affect how login occurs") : amended, + cpp_quote(ISCSI_LOGIN_FLAGS_CPPQUOTE), + ISCSI_LOGIN_FLAGS_QUALIFIERS + ] + ISCSI_LOGIN_FLAGS LoginFlags; + + [WmiDataId(8), + Description("Authentication method specified for login") : amended, + ISCSI_AUTH_TYPES_QUALIFIERS + ] + ISCSI_AUTH_TYPES AuthType; +}; + + +[WMI, + WmiGenerateHeader(GENERATE_HEADER), + guid("{994FF278-3512-4d9b-A241-54CEF45F5A25}"), + description("This class describes a mapping from a an OS LUN to target device LUN") : amended +] +class ISCSI_LUNList +{ + [WmiDataId(1), + description("Target LUN") : amended + ] + uint64 TargetLUN; + + [WmiDataId(2), + description("OS Scsi bus number target is mapped to") : amended + ] + uint32 OSLUN; + + [WmiDataId(3), + description("Reserved") : amended + ] + uint32 Reserved; +}; + + +[WMI, + WmiGenerateHeader(GENERATE_HEADER), + guid("{21A28820-3C4C-4944-AC4F-DA7FEBA21168}"), + description("This class describes a mapping from a target LUN to a Windows port driver LUN") : amended +] +class ISCSI_TargetMapping +{ + [WmiDataId(1), + description("OS Scsi bus number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSBus; + + [WmiDataId(2), + description("OS Scsi Target number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSTarget; + + [WmiDataId(3), + Description("Unique Session ID for the target mapping") : amended + ] uint64 UniqueSessionId; + + [WmiDataId(4), + description("Count of LUNs mapped for this target") : amended + ] + uint32 LUNCount; + + [WmiDataId(5), + MaxLen(MAX_ISCSI_NAME_LEN), + description("Target Name") : amended + ] + string TargetName; + + [WmiDataId(6), + Description("TRUE if session created from a persistent login") : amended + ] + boolean FromPersistentLogin; + + [WmiDataId(7), + description("Reserved") : amended + ] + uint64 Reserved; + + [WmiDataId(8), + WmiSizeIs("LunCount"), + description("List of LUNs mapped for this target") : amended + ] + ISCSI_LUNList LUNList[]; +}; + + +// +// Perfmon counter types +// +// +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// +// PERF_COUNTER_DEFINITION.CounterType field values +// +// +// Counter ID Field Definition: +// +// 3 2 2 2 2 1 1 1 +// 1 8 4 2 0 6 2 0 8 0 +// +--------+--------+----+----+--------+--------+----+----+----------------+ +// |Display |Calculation |Time|Counter | |Ctr |Size| | +// |Flags |Modifiers |Base|SubType |Reserved|Type|Fld | Reserved | +// +--------+--------+----+----+--------+--------+----+----+----------------+ +// +// +// The counter type is the "or" of the following values as described below +// +// select one of the following to indicate the counter's data size +// +#define PERF_SIZE_DWORD 0x00000000 // 32 bit field +#define PERF_SIZE_LARGE 0x00000100 // 64 bit field +#define PERF_SIZE_ZERO 0x00000200 // for Zero Length fields +#define PERF_SIZE_VARIABLE_LEN 0x00000300 // length is in CounterLength field + // of Counter Definition struct +// +// select one of the following values to indicate the counter field usage +// +#define PERF_TYPE_NUMBER 0x00000000 // a number (not a counter) +#define PERF_TYPE_COUNTER 0x00000400 // an increasing numeric value +#define PERF_TYPE_TEXT 0x00000800 // a text field +#define PERF_TYPE_ZERO 0x00000C00 // displays a zero +// +// If the PERF_TYPE_NUMBER field was selected, then select one of the +// following to describe the Number +// +#define PERF_NUMBER_HEX 0x00000000 // display as HEX value +#define PERF_NUMBER_DECIMAL 0x00010000 // display as a decimal integer +#define PERF_NUMBER_DEC_1000 0x00020000 // display as a decimal/1000 +// +// If the PERF_TYPE_COUNTER value was selected then select one of the +// following to indicate the type of counter +// +#define PERF_COUNTER_VALUE 0x00000000 // display counter value +#define PERF_COUNTER_RATE 0x00010000 // divide ctr / delta time +#define PERF_COUNTER_FRACTION 0x00020000 // divide ctr / base +#define PERF_COUNTER_BASE 0x00030000 // base value used in fractions +#define PERF_COUNTER_ELAPSED 0x00040000 // subtract counter from current time +#define PERF_COUNTER_QUEUELEN 0x00050000 // Use Queuelen processing func. +#define PERF_COUNTER_HISTOGRAM 0x00060000 // Counter begins or ends a histogram +#define PERF_COUNTER_PRECISION 0x00070000 // divide ctr / private clock +// +// If the PERF_TYPE_TEXT value was selected, then select one of the +// following to indicate the type of TEXT data. +// +#define PERF_TEXT_UNICODE 0x00000000 // type of text in text field +#define PERF_TEXT_ASCII 0x00010000 // ASCII using the CodePage field +// +// Timer SubTypes +// +#define PERF_TIMER_TICK 0x00000000 // use system perf. freq for base +#define PERF_TIMER_100NS 0x00100000 // use 100 NS timer time base units +#define PERF_OBJECT_TIMER 0x00200000 // use the object timer freq +// +// Any types that have calculations performed can use one or more of +// the following calculation modification flags listed here +// +#define PERF_DELTA_COUNTER 0x00400000 // compute difference first +#define PERF_DELTA_BASE 0x00800000 // compute base diff as well +#define PERF_INVERSE_COUNTER 0x01000000 // show as 1.00-value (assumes: +#define PERF_MULTI_COUNTER 0x02000000 // sum of multiple instances +// +// Select one of the following values to indicate the display suffix (if any) +// +#define PERF_DISPLAY_NO_SUFFIX 0x00000000 // no suffix +#define PERF_DISPLAY_PER_SEC 0x10000000 // "/sec" +#define PERF_DISPLAY_PERCENT 0x20000000 // "%" +#define PERF_DISPLAY_SECONDS 0x30000000 // "secs" +#define PERF_DISPLAY_NOSHOW 0x40000000 // value is not displayed +// +// Predefined counter types +// + +// 32-bit Counter. Divide delta by delta time. Display suffix: "/sec" +#define PERF_COUNTER_COUNTER 0x10410400 +// (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ +// PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC) + + +// 64-bit Timer. Divide delta by delta time. Display suffix: "%" +#define PERF_COUNTER_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT) + +// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. +#define PERF_COUNTER_QUEUELEN_TYPE \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN |\ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. +#define PERF_COUNTER_LARGE_QUEUELEN_TYPE \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN |\ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +// Queue Length Space-Time Product using 100 Ns timebase. +// Divide delta by delta time. No Display Suffix. +#define PERF_COUNTER_100NS_QUEUELEN_TYPE \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN |\ + PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +// Queue Length Space-Time Product using Object specific timebase. +// Divide delta by delta time. No Display Suffix. +#define PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN |\ + PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +// 64-bit Counter. Divide delta by delta time. Display Suffix: "/sec" +#define PERF_COUNTER_BULK_COUNT 0x10410500 +// (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ +// PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC) + +// Indicates the counter is not a counter but rather Unicode text Display as text. +#define PERF_COUNTER_TEXT \ + (PERF_SIZE_VARIABLE_LEN | PERF_TYPE_TEXT | PERF_TEXT_UNICODE |\ + PERF_DISPLAY_NO_SUFFIX) + +// Indicates the data is a counter which should not be +// time averaged on display (such as an error counter on a serial line) +// Display as is. No Display Suffix. +#define PERF_COUNTER_RAWCOUNT 0x00010000 +// (PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL |\ +// PERF_DISPLAY_NO_SUFFIX) + +// Same as PERF_COUNTER_RAWCOUNT except its size is a large integer +#define PERF_COUNTER_LARGE_RAWCOUNT 0x00010100 +// (PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL |\ +// PERF_DISPLAY_NO_SUFFIX) + +// Special case for RAWCOUNT that want to be displayed in hex +// Indicates the data is a counter which should not be +// time averaged on display (such as an error counter on a serial line) +// Display as is. No Display Suffix. +#define PERF_COUNTER_RAWCOUNT_HEX \ + (PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_HEX |\ + PERF_DISPLAY_NO_SUFFIX) + +// Same as PERF_COUNTER_RAWCOUNT_HEX except its size is a large integer +#define PERF_COUNTER_LARGE_RAWCOUNT_HEX \ + (PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_HEX |\ + PERF_DISPLAY_NO_SUFFIX) + + +// A count which is either 1 or 0 on each sampling interrupt (% busy) +// Divide delta by delta base. Display Suffix: "%" +#define PERF_SAMPLE_FRACTION \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION |\ + PERF_DELTA_COUNTER | PERF_DELTA_BASE | PERF_DISPLAY_PERCENT) + +// A count which is sampled on each sampling interrupt (queue length) +// Divide delta by delta time. No Display Suffix. +#define PERF_SAMPLE_COUNTER \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +// A label: no data is associated with this counter (it has 0 length) +// Do not display. +#define PERF_COUNTER_NODATA \ + (PERF_SIZE_ZERO | PERF_DISPLAY_NOSHOW) + +// 64-bit Timer inverse (e.g., idle is measured, but display busy %) +// Display 100 - delta divided by delta time. Display suffix: "%" +#define PERF_COUNTER_TIMER_INV \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | \ + PERF_DISPLAY_PERCENT) + +// The divisor for a sample, used with the previous counter to form a +// sampled %. You must check for >0 before dividing by this! This +// counter will directly follow the numerator counter. It should not +// be displayed to the user. +#define PERF_SAMPLE_BASE \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE |\ + PERF_DISPLAY_NOSHOW |\ + 0x00000001) // for compatibility with pre-beta versions + +// A timer which, when divided by an average base, produces a time +// in seconds which is the average time of some operation. This +// timer times total operations, and the base is the number of opera- +// tions. Display Suffix: "sec" +#define PERF_AVERAGE_TIMER \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION |\ + PERF_DISPLAY_SECONDS) + +// Used as the denominator in the computation of time or count +// averages. Must directly follow the numerator counter. Not dis- +// played to the user. +#define PERF_AVERAGE_BASE \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE |\ + PERF_DISPLAY_NOSHOW |\ + 0x00000002) // for compatibility with pre-beta versions + + +// A bulk count which, when divided (typically) by the number of +// operations, gives (typically) the number of bytes per operation. +// No Display Suffix. +#define PERF_AVERAGE_BULK \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION |\ + PERF_DISPLAY_NOSHOW) + +// 64-bit Timer in object specific units. Display delta divided by +// delta time as returned in the object type header structure. Display suffix: "%" +#define PERF_OBJ_TIME_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT) + + +// 64-bit Timer in 100 nsec units. Display delta divided by +// delta time. Display suffix: "%" +#define PERF_100NSEC_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT) + +// 64-bit Timer inverse (e.g., idle is measured, but display busy %) +// Display 100 - delta divided by delta time. Display suffix: "%" +#define PERF_100NSEC_TIMER_INV \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER |\ + PERF_DISPLAY_PERCENT) + +// 64-bit Timer. Divide delta by delta time. Display suffix: "%" +// Timer for multiple instances, so result can exceed 100%. +#define PERF_COUNTER_MULTI_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_DELTA_COUNTER | PERF_TIMER_TICK | PERF_MULTI_COUNTER |\ + PERF_DISPLAY_PERCENT) + +// 64-bit Timer inverse (e.g., idle is measured, but display busy %) +// Display 100 * _MULTI_BASE - delta divided by delta time. +// Display suffix: "%" Timer for multiple instances, so result +// can exceed 100%. Followed by a counter of type _MULTI_BASE. +#define PERF_COUNTER_MULTI_TIMER_INV \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\ + PERF_DELTA_COUNTER | PERF_MULTI_COUNTER | PERF_TIMER_TICK |\ + PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT) + +// Number of instances to which the preceding _MULTI_..._INV counter +// applies. Used as a factor to get the percentage. +#define PERF_COUNTER_MULTI_BASE \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE |\ + PERF_MULTI_COUNTER | PERF_DISPLAY_NOSHOW) + +// 64-bit Timer in 100 nsec units. Display delta divided by delta time. +// Display suffix: "%" Timer for multiple instances, so result can exceed 100%. +#define PERF_100NSEC_MULTI_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER |\ + PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER |\ + PERF_DISPLAY_PERCENT) + +// 64-bit Timer inverse (e.g., idle is measured, but display busy %) +// Display 100 * _MULTI_BASE - delta divided by delta time. +// Display suffix: "%" Timer for multiple instances, so result +// can exceed 100%. Followed by a counter of type _MULTI_BASE. +#define PERF_100NSEC_MULTI_TIMER_INV \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER |\ + PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER |\ + PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT) + +// Indicates the data is a fraction of the following counter which +// should not be time averaged on display (such as free space over +// total space.) Display as is. Display the quotient as "%". +#define PERF_RAW_FRACTION \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION |\ + PERF_DISPLAY_PERCENT) + +#define PERF_LARGE_RAW_FRACTION \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION |\ + PERF_DISPLAY_PERCENT) + +// Indicates the data is a base for the preceding counter which should +// not be time averaged on display (such as free space over total space.) +#define PERF_RAW_BASE \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE |\ + PERF_DISPLAY_NOSHOW |\ + 0x00000003) // for compatibility with pre-beta versions + +#define PERF_LARGE_RAW_BASE \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE |\ + PERF_DISPLAY_NOSHOW ) + +// The data collected in this counter is actually the start time of the +// item being measured. For display, this data is subtracted from the +// sample time to yield the elapsed time as the difference between the two. +// In the definition below, the PerfTime field of the Object contains +// the sample time as indicated by the PERF_OBJECT_TIMER bit and the +// difference is scaled by the PerfFreq of the Object to convert the time +// units into seconds. +#define PERF_ELAPSED_TIME \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_ELAPSED |\ + PERF_OBJECT_TIMER | PERF_DISPLAY_SECONDS) +// +// The following counter type can be used with the preceding types to +// define a range of values to be displayed in a histogram. +// + +#define PERF_COUNTER_HISTOGRAM_TYPE 0x80000000 + // Counter begins or ends a histogram +// +// This counter is used to display the difference from one sample +// to the next. The counter value is a constantly increasing number +// and the value displayed is the difference between the current +// value and the previous value. Negative numbers are not allowed +// which shouldn't be a problem as long as the counter value is +// increasing or unchanged. +// +#define PERF_COUNTER_DELTA \ + (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE |\ + PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) + +#define PERF_COUNTER_LARGE_DELTA \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE |\ + PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX) +// +// The precision counters are timers that consist of two counter values: +// 1) the count of elapsed time of the event being monitored +// 2) the "clock" time in the same units +// +// the precition timers are used where the standard system timers are not +// precise enough for accurate readings. It's assumed that the service +// providing the data is also providing a timestamp at the same time which +// will eliminate any error that may occur since some small and variable +// time elapses between the time the system timestamp is captured and when +// the data is collected from the performance DLL. Only in extreme cases +// has this been observed to be problematic. +// +// when using this type of timer, the definition of the +// PERF_PRECISION_TIMESTAMP counter must immediately follow the +// definition of the PERF_PRECISION_*_TIMER in the Object header +// +// The timer used has the same frequency as the System Performance Timer +#define PERF_PRECISION_SYSTEM_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | \ + PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ) +// +// The timer used has the same frequency as the 100 NanoSecond Timer +#define PERF_PRECISION_100NS_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | \ + PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ) +// +// The timer used is of the frequency specified in the Object header's +// PerfFreq field (PerfTime is ignored) +#define PERF_PRECISION_OBJECT_TIMER \ + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | \ + PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ) +// +// This is the timestamp to use in the computation of the timer specified +// in the previous description block +#define PERF_PRECISION_TIMESTAMP PERF_LARGE_RAW_BASE diff --git a/storage/iscsi/src/config.mof b/storage/iscsi/src/config.mof new file mode 100644 index 00000000..4f758f80 --- /dev/null +++ b/storage/iscsi/src/config.mof @@ -0,0 +1,487 @@ +//*************************************************************************** +// +// config.mof +// +// Module: iScsi Discovery api +// +// Purpose: Definitions for configuring HBA cards +// +// Copyright (c) 2001 Microsoft Corporation +// +//*************************************************************************** + +#define MODULE_HEADER \ +"\n" \ +"//***************************************************************************\n" \ +"//\n" \ +"// iscsicfg.h\n" \ +"// \n" \ +"// Module: iScsi Discovery api\n" \ +"//\n" \ +"// Purpose: Header defining interface between user mode configuration\n" \ +"// apps and HBA driver miniport.\n" \ +"//\n" \ +"// Copyright (c) 2001 Microsoft Corporation\n" \ +"//\n" \ +"//***************************************************************************\n\n" + +// +// Do not cause headers to be generated from common.mof +// +#define GENERATE_HEADER FALSE + +// +// Include common definitions +// +#include "common.mof" + + + +// +// TCP/IP configuration class, implement one instance for each port on +// your adapter +// +[ + WMI, + guid("{7A2C6C2B-E5A5-49ad-AD68-133089ACD74D}"), + Dynamic, + Provider("wmiprov"), + DisplayName("TCP/IP configuration") : amended, + cpp_quote(MODULE_HEADER + "#include <iscsidef.h>\n\n" +"//\n" +"//\n" +"// This class is required.\n" +"//\n" +"// TCP/IP configuration class, implement one instance for each IP address on\n" +"// your adapter. For example, if you adapter supports 3 IP addresses then\n" +"// your adapter would implement 3 instances of this class.\n" +"//\n" +"// This class uses PDO instance names with 1 instance for each TCP/IP interface.\n" +"//\n" + ) +] +class MSiSCSI_TCPIPConfig +{ + [key] + string InstanceName; + + boolean Active; + + [read, write, + WmiDataId(1), + DisplayName("Use Link Local Address") : amended, + description("TRUE if the adapter should use an autogenerated and non routable (link local) address as its IP address.") : amended + ] + boolean UseLinkLocalAddress; + + [read, write, + WmiDataId(2), + displayName("DHCP Enabled") : amended, + description("TRUE if the adapter should use DHCP to discovery its IP address information.") : amended + ] + boolean EnableDHCP; + + [read, write, + WmiDataId(3), + displayName("Use DHCP for DNS") : amended, + description("TRUE if the adapter should use DHCP to discover DNS addresses.") : amended + ] + boolean UseDHCPForDNS; + + [read, + WmiDataId(4), + description("IP Versions supported **Add #defines**") : amended, + BitValues{ "IPV4", "IPV6"}, + BitMap{"0x00000001", "0x00000002"} + ] + uint32 IPVersions; + + [read, write, + WmiDataId(5), + DisplayName("IP Address") : amended, + description("IP address of the adapter") : amended + ] + ISCSI_IP_Address IpAddress; + + [read, write, + WmiDataId(6), + DisplayName("Default Gateway") : amended, + Description("Static Default Gateway IP address") : amended + ] + ISCSI_IP_Address DefaultGateway; + + [read, write, + WmiDataId(7), + DisplayName("Subnet Mask") : amended, + Description("Static Subnet Mask") : amended + ] + ISCSI_IP_Address SubnetMask; + + [read, write, + WmiDataId(8), + DisplayName("Preferred DNS Server") : amended, + Description("Preferred DNS Server") : amended + ] + ISCSI_IP_Address PreferredDNSServer; + + [read, write, + WmiDataId(9), + DisplayName("Alternate DNS Server") : amended, + Description("Alternate DNS Server") : amended + ] + ISCSI_IP_Address AlternateDNSServer; + +}; + +// +// NIC Port configuration class, implement one instance for each port on +// your adapter +// +[ + WMI, + guid("{C75258E9-BE79-4a48-A23D-EEB6F8FB940C}"), + Dynamic, + DisplayName("NIC Port Configuration") : amended, + Provider("wmiprov"), +cpp_quote( +"//\n" +"// This class is optional.\n" +"//\n" +"// NIC Port configuration class, implement one instance for each physical \n" +"// network interface port on your adapter.\n" +"//\n" +"// This class uses PDO instance names with 1 instance for each physical\n" +"// network interface port on your adapter.\n" +"//\n" +"\n" +"typedef enum \n" +"{\n" +" ISCSI_NIC_LINKSTATE_DISCONNECTED = 0,\n" +" ISCSI_NIC_LINKSTATE_CONNECTED = 1\n" +"} ISCSI_NIC_LINKSTATE, *PISCSI_NIC_LINKSTATE;\n" +) +] +class MSiSCSI_NICConfig +{ + [key] + string InstanceName; + + boolean Active; + + [read, + WmiDataId(1), + DisplayName("Link Speed") : amended, + Description("Speed of network link in megabits per second.") : amended + ] + uint32 LinkSpeed; + + [read, + WmiDataId(2), + DisplayName("Max Link Speed") : amended, + Description("Maximum Speed of network link in megabits per second.") : amended + ] + uint32 MaxLinkSpeed; + + [read, + WmiDataId(3), + DisplayName("Link State") : amended, + description("Link State **typedef**") : amended, + Values{"Media Disconnected", "Media Connected"} : amended, + ValueMap{"0", "1"} + ] + uint32 LinkState; + + [read, + WmiDataId(4), + DisplayName("Max Frame Size") : amended, + description("Maximum frame size") : amended + ] + uint32 MaxFrameSize; + + [read, + WmiDataId(5), + DisplayName("MAC Address") : amended, + description("Ethernet MAC Address") : amended + ] + uint8 MacAddress[6]; + +}; + +[WMI, + guid("{53EF8D5F-36F3-4124-8B76-C6AD521A1021}"), + Dynamic, Provider("wmiprov"), + DisplayName("Boot device configuration") : amended, + cpp_quote( +"//\n" +"// This class is optional.\n" +"//\n" +"// This class exposes the boot configuration if the adapter is configured to\n" +"// boot from an iSCSI disk.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_BootConfiguration +{ + [key] + string InstanceName; + + boolean Active; + + [read, + write, + WmiDataId(1), + Description("LUN on target to use as boot device.") : amended, + DisplayName("Target LUN") : amended + ] + uint64 LUN; + + [ read, write, + WmiDataId(2), + SECURITY_FLAG_QUALIFIERS + ] + ISCSI_SECURITY_FLAGS SecurityFlags; + + [ read, write, + WmiDataId(3), + description("Size in bytes of Target Username.") : amended + ] uint32 UsernameSize; + + [ read, write, + WmiDataId(4), + description("Size in bytes of Target Password.") : amended + ] uint32 PasswordSize; + + [ read, write, + WmiDataId(5), + description("If TRUE dynamically discover boot device.") : amended + ] + boolean DiscoverBootDevice; + + [ read, write, + WmiDataId(6), + MaxLen(MAX_ISCSI_NAME_LEN), + description("The InitiatorNode specifies the iSCSI name of the initiator node to use for the connection. If empty, then the adapter can choose any initiator node name.") : amended + ] string InitiatorNode; + + [ read, write, + WmiDataId(7), + MaxLen(MAX_ISCSI_NAME_LEN), + description("TargetName specifies the iSCSI target name on which the boot device resides.") : amended + ] string TargetName; + + [ read, write, + WmiDataId(8), + description("Target portal to use for connection to the target.") : amended + ] ISCSI_TargetPortal TargetPortal; + + [read, write, + WmiDataId(9), + description("Options that affect how login is performed. See ISCSI_LoginOptions") : amended + ] ISCSI_LoginOptions LoginOptions; + + [ read, write, + WmiDataId(10), + WmiSizeIs("UsernameSize"), + description("**extra fields** Authentication Username, for CHAP this is the CHAP Name (CHAP_N) use when authenticating with the target. NOTE: This field is a variable length array, the field that follows this field starts immediately after the end of this field subject to appropriate padding.") : amended + ] uint8 Username[]; + + [ read, write, + WmiDataId(11), + WmiSizeIs("PasswordSize"), + description("Authentication Password, for CHAP this is the shared secret to use when generating the response to the target challange. This field is a variable length array.") : amended + ] uint8 Password[]; +}; + + +// +// Types of encryption supported +// +#define ENCRYPTION_TYPES_QUALIFIERS \ + Values {"No Encryption/Authentication", \ + "3DES HMAC/SHA1", \ + "AES-CTR/CBC-MAC with XCBC"} : amended, \ + ValueMap{ "0", "1", "2" } + + +[ + WMI, + guid("{225B9D64-47A9-41c8-81CD-69BC02652D87}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Security Capabilities") : amended, + cpp_quote( +"//\n" +"// This class is required if adapter supports IPSEC.\n" +"//\n" +"// This class exposes the security capabilities if the adapter \n" +"// supports IPSEC.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" +"typedef enum {\n" +" ISCSI_ENCRYPT_NONE = 0,\n" +" ISCSI_ENCRYPT_3DES_HMAC_SHA1 = 1,\n" +" ISCSI_ENCRYPT_AES_CTR = 2 \n" +"} ISCSI_ENCRYPTION_TYPES, *PISCSI_ENCRYPTION_TYPES;\n\n" + ) +] +class MSiSCSI_SecurityCapabilities +{ + [key] + string InstanceName; + + boolean Active; + + [read, + DisplayName("Protect iSCSI") : amended, + WmiDataId(1), + description("TRUE if the adapter can use IPSEC to protect iSCSI traffic.") : amended + ] + boolean ProtectiScsiTraffic; + + + [read, + WmiDataId(2), + DisplayName("Protect iSNS") : amended, + description("TRUE if the adapter can use IPSEC to protect iSNS traffic.") : amended + ] + boolean ProtectiSNSTraffic; + + [read, + WmiDataId(3), + DisplayName("Certificates Supported") : amended, + description("TRUE if adapter supports certificates") : amended + ] + boolean CertificatesSupported; + + [read, + WmiDataId(4), + DisplayName("Encryption Types Available") : amended, + description("Number of encryption types available.") + ] + uint32 EncryptionAvailableCount; + + [ read, + WmiDataId(5), + WmiSizeIs("EncryptionAvailableCount"), + ENCRYPTION_TYPES_QUALIFIERS, + DisplayName("Encryption Types") : amended, + description("**typedef** Array of encryption types. This field is a variable length array.") + ] + uint32 EncryptionAvailable[]; +}; + + +[WMI, + guid("{45755098-4291-43df-9720-B58642DD63DF}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Discovery Configuration") : amended, + cpp_quote( +"//\n" +"// This class is required.\n" +"//\n" +"// This class exposes the configuration capabilities for the adapter to be able to\n" +"// perform target discovery. An adapter needs to support target discovery\n" +"// if it is ever placed on a separate network from the PC NIC. Although\n" +"// the iSCSI Initiator service can use this class with any discovery mechanism\n" +"// the best results are obtained by using iSNS.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_DiscoveryConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + description("TRUE if adapter should perform target discovery via iSNS.") : amended + ] boolean PerformiSNSDiscovery; + + [WmiDataId(2), + read, write, + description("TRUE if adapter should perform target discovery via SLP.") : amended + ] boolean PerformSLPDiscovery; + + [WmiDataId(3), + read, write, + description("TRUE if adapter should perform automatic discovery of iSNS server.") : amended + ] boolean AutomaticiSNSDiscovery; + + [WmiDataId(4), + read, write, + MaxLen(256), + description("Default initiator name for registering with iSNS.") : amended + ] string InitiatorName; + + [WmiDataId(5), + read, write, + description("If AutomaticiSNSDiscovery is FALSE then this contains the fixed addresses of iSNS servers") : amended + ] ISCSI_IP_Address iSNSServer; + +}; + +[WMI, + guid("{8EAEF9D8-C053-49d3-9205-65C703C2ECC1}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Radius Configuration") : amended, + cpp_quote( +"//\n" +"// This class is required if adapter supports using RADIUS for CHAP authentication.\n" +"//\n" +"// This class exposes the configuration capabilities if the adapter able to\n" +"// use radius to perform CHAP authentication. Using RADIUS is encouraged\n" +"// since it allows centralized management of CHAP credentials.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_RADIUSConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + description("TRUE if adapter should use RADIUS for CHAP authentication") : amended + ] boolean UseRADIUSForCHAP; + + [WmiDataId(2), + read, write, + description("Size in bytes of shared secret used to communicate with RADIUS servers") : amended + ] uint32 SharedSecretSizeInBytes; + + [WmiDataId(3), + read, write, + description("Fixed address of primary RADIUS server") : amended + ] ISCSI_IP_Address RADIUSServer; + + [WmiDataId(4), + read, write, + description("Fixed address of backup RADIUS server") : amended + ] ISCSI_IP_Address BackupRADIUSServer; + + [WmiDataId(5), + Description("Must be zero") + ] + uint32 Reserved; + + [WmiDataId(6), + read, write, + WmiSizeIs("SharedSecretSizeInBytes"), + description("Shared secret for communicating with primary and backup RADIUS servers. This field is a variable length array.") : amended + ] uint8 SharedSecret[]; + +};
\ No newline at end of file diff --git a/storage/iscsi/src/def.mof b/storage/iscsi/src/def.mof new file mode 100644 index 00000000..039f586e --- /dev/null +++ b/storage/iscsi/src/def.mof @@ -0,0 +1,34 @@ +//*************************************************************************** +// +// def.mof +// +// Module: iScsi Discovery api +// +// Purpose: +// +// Copyright (c) 2001 Microsoft Corporation +// +//*************************************************************************** + +// +// Cause headers to be generated from common.mof +// +#define GENERATE_HEADER TRUE + +#define MODULE_HEADER \ +"\n" \ +"//***************************************************************************\n" \ +"//\n" \ +"// iscsidef.h\n" \ +"// \n" \ +"// Module: iScsi Discovery api\n" \ +"//\n" \ +"// Purpose: Internal header defining interface between user mode discovery\n" \ +"// api dll and HBA driver miniport.\n" \ +"//\n" \ +"// Copyright (c) 2001 Microsoft Corporation\n" \ +"//\n" \ +"//***************************************************************************\n\n" + +#include "common.mof" + diff --git a/storage/iscsi/src/iscsihba.mof b/storage/iscsi/src/iscsihba.mof new file mode 100644 index 00000000..5a2e9f01 --- /dev/null +++ b/storage/iscsi/src/iscsihba.mof @@ -0,0 +1,13094 @@ +//*************************************************************************** +// +// +// Module: iScsi Discovery api +// +// Purpose: +// +// Copyright (c) 2001 Microsoft Corporation +// +//*************************************************************************** + + +#pragma namespace("\\\\.\\Root\\WMI") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ + WmiGenerateHeader(TRUE), + WMI, + DisplayName("IP Address") : amended, + guid("{9AC5D4A1-1A1A-48ec-8E79-735806E9A1FA}"), + cpp_quote("\n" "//***************************************************************************\n" "//\n" "// iscsidef.h\n" "// \n" "// Module: iScsi Discovery api\n" "//\n" "// Purpose: Internal header defining interface between user mode discovery\n" "// api dll and HBA driver miniport.\n" "//\n" "// Copyright (c) 2001 Microsoft Corporation\n" "//\n" "//***************************************************************************\n\n" +"//\n" "// Definitions for iscsi security flags. These flags provide\n" "// information about the security expectations of a target portal and\n" "// are needed to insure a successful IKE/IPSEC negotiation. Note that\n" "// the flags and values are taken directly from the iSNS spec\n" "//\n" "\n" " // 1 = Tunnel Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TUNNEL_MODE_PREFERRED 0x00000040\n" "\n" " // 1 = Transport Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TRANSPORT_MODE_PREFERRED 0x00000020\n" " \n" " // 1 = PFS Enabled; 0 = PFS Disabled\n" "#define ISCSI_SECURITY_FLAG_PFS_ENABLED 0x00000010\n" " \n" " // 1 = Aggressive Mode Enabled; 0 = Disabled\n" "#define ISCSI_SECURITY_FLAG_AGGRESSIVE_MODE_ENABLED 0x00000008\n" " \n" " // 1 = Main Mode Enabled; 0 = MM Disabled\n" "#define ISCSI_SECURITY_FLAG_MAIN_MODE_ENABLED 0x00000004\n" " \n" " // 1 = IKE/IPSec Enabled; 0 = IKE/IPSec Disabled\n" "#define ISCSI_SECURITY_FLAG_IKE_IPSEC_ENABLED 0x00000002\n" "\n" " // If set then all other ISCSI_SECURITY_FLAGS are valid \n" "#define ISCSI_SECURITY_FLAG_VALID 0x00000001 \n" "\n" +"\n" +"//\n" +"// Types of addresses that can be passed by management app to driver\n" +"//\n" +"typedef enum {\n" +" // Text based host name. This needs to be resolved to binary form\n" +" ISCSI_IP_ADDRESS_TEXT = 0,\n" +" // Binary IPv4 address\n" +" ISCSI_IP_ADDRESS_IPV4 = 1,\n" +" // Binary IPv6 address\n" +" ISCSI_IP_ADDRESS_IPV6 = 2,\n" +" // Empty address\n" +" ISCSI_IP_ADDRESS_EMPTY = 3\n" +"} ISCSIIPADDRESSTYPE, *PISCSIIPADDRESSTYPE;\n" + ) +] +class ISCSI_IP_Address +{ + [WmiDataId(1), + read, write, + DisplayName("Address Format") : amended, + description("Type of address specified. It can be text: a DNS or dotted address or it can be a binary ipv4 or ipv6 address") : amended, + Values{ "Text Address", + "IpV4 Address", + "IpV6 Address", + "Empty Address"}, + ValueMap{ "0", + "1", + "2", + "3"} + ] + + uint32 Type; + + [WmiDataId(2), + read, write, + DisplayInHex, + DisplayName("IPV4 Address"): amended, + description("If IPV4 Address is specified as the Address Format then this conains the binary IPv4 ip address") : amended + ] + uint32 IpV4Address; + + [WmiDataId(3), + DisplayName("IPV6 Address"): amended, + read, write, + description("If IPV6 Address is specified as the Address Format then this conains the binary IPv6 ip address") : amended + ] + uint8 IpV6Address[16]; + + [WmiDataId(4), + read, write, + DisplayName("IPV6 Flow Information") : amended, + description("IPV6 flow information") : amended + ] + uint32 IpV6FlowInfo; + + [WmiDataId(5), + read, write, + DisplayName("IPV6 Scope Id") : amended, + description("IPV6 scope id") : amended + ] + uint32 IpV6ScopeId; + + [WmiDataId(6), + read, write, + DisplayName("Text Address") : amended, + description("Text address, either a DNS address or dotted address") : amended, + MaxLen(256) + ] + string TextAddress; +}; + + +[ + WmiGenerateHeader(TRUE), + WMI, + guid("{DE5051A7-BF27-48f1-BD12-07CADE92AEFD}"), + description("ISCSI target portal") : amended +] +class ISCSI_TargetPortal +{ + [WmiDataId(1), + Description("Network Address") : amended + ] + ISCSI_IP_Address Address; + + [WmiDataId(2), + Description("Reserved") : amended + ] + uint32 Reserved; + + [WmiDataId(3), + Description("Socket number") : amended + ] + uint16 Socket; +}; + +[WMI, + WmiGenerateHeader(TRUE), + guid("{3081F2A5-95F5-4d2a-813D-EE59864C6FC5}"), + description("iSCSI target portal group") : amended +] +class ISCSI_TargetPortalGroup +{ + [WmiDataId(1), + description("Number of portals in group") : amended + ] + uint32 PortalCount; + + [WmiDataId(2), + WmiSizeIs("PortalCount"), + description("Target portals in group") : amended + ] + ISCSI_TargetPortal Portals[]; +}; + + +[WMI, + WmiGenerateHeader(TRUE), + guid("{3011A7BD-0491-478e-8C79-3C76424D05E2}"), + cpp_quote("#ifndef _ISCSI_ISCSIDSC_\n" "typedef enum\n" "{\n" " ISCSI_DIGEST_TYPE_NONE = 0,\n" " ISCSI_DIGEST_TYPE_CRC32C = 1\n" "} ISCSI_DIGEST_TYPES, *PISCSI_DIGEST_TYPES;\n" "\n" "typedef enum\n" "{\n" " ISCSI_NO_AUTH_TYPE = 0,\n" " ISCSI_CHAP_AUTH_TYPE = 1,\n" " ISCSI_MUTUAL_CHAP_AUTH_TYPE = 2 \n" "} ISCSI_AUTH_TYPES, *PISCSI_AUTH_TYPES;\n" "#endif\n"), + Description("These are options that can be used for logging into a target") +] +class ISCSI_LoginOptions +{ + [WmiDataId(1), + description("Bit flags that specify which login option values are specified") : amended, + BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010" }, BitValues{"HeaderDigest", "DataDigest", "MaxConnections", "DefaultTime2Wait", "DefaultTime2Retain" } : amended, + cpp_quote("//\n" "// Bit flags for InformationSpecifies\n" "//\n" "#define ISCSI_LOGIN_OPTIONS_HEADER_DIGEST 0x00000001\n" "#define ISCSI_LOGIN_OPTIONS_DATA_DIGEST 0x00000002\n" "#define ISCSI_LOGIN_OPTIONS_MAXIMUM_CONNECTIONS 0x00000004\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_WAIT 0x00000008\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_RETAIN 0x00000010\n" "#define ISCSI_LOGIN_OPTIONS_USERNAME 0x00000020\n" "#define ISCSI_LOGIN_OPTIONS_PASSWORD 0x00000040\n" "#define ISCSI_LOGIN_OPTIONS_AUTH_TYPE 0x00000080\n" "\n") + ] uint32 InformationSpecified; + + [WmiDataId(2), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 HeaderDigest; + + [WmiDataId(3), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 DataDigest; + + [WmiDataId(4), + Description("Maximum number of connections, 0 implies no limit") : amended + ] + uint32 MaximumConnections; + + [WmiDataId(5), + Description("The initiator and target negotiate the minimum time, in seconds, to wait before attempting an explicit/implicit logout or active task reassignment after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Wait; + + [WmiDataId(6), + Description(" The initiator and target negotiate the maximum time, in seconds after an initial wait (Time2Wait), before which an explicit/implicit connection Logout or active task reassignment is still possible after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Retain; + + [WmiDataId(7), + Description("Flags that affect how login occurs") : amended, + cpp_quote("//\n" "// bit flags for ISCSI_LOGIN_FLAGS\n" "//\n" "#ifndef _ISCSI_ISCSIDSC_\n" "#define ISCSI_LOGIN_FLAGS ULONG\n\n" "#define ISCSI_LOGIN_FLAG_REQUIRE_IPSEC 0x00000001\n" "#define ISCSI_LOGIN_FLAG_MULTIPATH_ENABLED 0x00000002\n" "#define ISCSI_LOGIN_FLAG_RESERVED1 0x00000004\n" "#define ISCSI_LOGIN_FLAG_ALLOW_PORTAL_HOPPING 0x00000008\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_RESPONSE 0x00000010\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_VERIFICATION 0x00000020\n" "\n" "#endif\n"), + BitValues{"Require IPSEC", "Multipath Enabled", "Reserved1", "Allow Portal Hopping"}, BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008" } + ] + uint32 LoginFlags; + + [WmiDataId(8), + Description("Authentication method specified for login") : amended, + Values{"No Authentication", "CHAP", "Mutual CHAP" } : amended, ValueMap{"0", "1", "2"} + ] + uint32 AuthType; +}; + + +[WMI, + WmiGenerateHeader(TRUE), + guid("{994FF278-3512-4d9b-A241-54CEF45F5A25}"), + description("This class describes a mapping from a an OS LUN to target device LUN") : amended +] +class ISCSI_LUNList +{ + [WmiDataId(1), + description("Target LUN") : amended + ] + uint64 TargetLUN; + + [WmiDataId(2), + description("OS Scsi bus number target is mapped to") : amended + ] + uint32 OSLUN; + + [WmiDataId(3), + description("Reserved") : amended + ] + uint32 Reserved; +}; + + +[WMI, + WmiGenerateHeader(TRUE), + guid("{21A28820-3C4C-4944-AC4F-DA7FEBA21168}"), + description("This class describes a mapping from a target LUN to a Windows port driver LUN") : amended +] +class ISCSI_TargetMapping +{ + [WmiDataId(1), + description("OS Scsi bus number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSBus; + + [WmiDataId(2), + description("OS Scsi Target number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSTarget; + + [WmiDataId(3), + Description("Unique Session ID for the target mapping") : amended + ] uint64 UniqueSessionId; + + [WmiDataId(4), + description("Count of LUNs mapped for this target") : amended + ] + uint32 LUNCount; + + [WmiDataId(5), + MaxLen(223), + description("Target Name") : amended + ] + string TargetName; + + [WmiDataId(6), + Description("TRUE if session created from a persistent login") : amended + ] + boolean FromPersistentLogin; + + [WmiDataId(7), + description("Reserved") : amended + ] + uint64 Reserved; + + [WmiDataId(8), + WmiSizeIs("LunCount"), + description("List of LUNs mapped for this target") : amended + ] + ISCSI_LUNList LUNList[]; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ + WmiGenerateHeader(FALSE), + WMI, + DisplayName("IP Address") : amended, + guid("{9AC5D4A1-1A1A-48ec-8E79-735806E9A1FA}"), + cpp_quote("\n" "//***************************************************************************\n" "//\n" "// iscsicfg.h\n" "// \n" "// Module: iScsi Discovery api\n" "//\n" "// Purpose: Header defining interface between user mode configuration\n" "// apps and HBA driver miniport.\n" "//\n" "// Copyright (c) 2001 Microsoft Corporation\n" "//\n" "//***************************************************************************\n\n" +"//\n" "// Definitions for iscsi security flags. These flags provide\n" "// information about the security expectations of a target portal and\n" "// are needed to insure a successful IKE/IPSEC negotiation. Note that\n" "// the flags and values are taken directly from the iSNS spec\n" "//\n" "\n" " // 1 = Tunnel Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TUNNEL_MODE_PREFERRED 0x00000040\n" "\n" " // 1 = Transport Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TRANSPORT_MODE_PREFERRED 0x00000020\n" " \n" " // 1 = PFS Enabled; 0 = PFS Disabled\n" "#define ISCSI_SECURITY_FLAG_PFS_ENABLED 0x00000010\n" " \n" " // 1 = Aggressive Mode Enabled; 0 = Disabled\n" "#define ISCSI_SECURITY_FLAG_AGGRESSIVE_MODE_ENABLED 0x00000008\n" " \n" " // 1 = Main Mode Enabled; 0 = MM Disabled\n" "#define ISCSI_SECURITY_FLAG_MAIN_MODE_ENABLED 0x00000004\n" " \n" " // 1 = IKE/IPSec Enabled; 0 = IKE/IPSec Disabled\n" "#define ISCSI_SECURITY_FLAG_IKE_IPSEC_ENABLED 0x00000002\n" "\n" " // If set then all other ISCSI_SECURITY_FLAGS are valid \n" "#define ISCSI_SECURITY_FLAG_VALID 0x00000001 \n" "\n" +"\n" +"//\n" +"// Types of addresses that can be passed by management app to driver\n" +"//\n" +"typedef enum {\n" +" // Text based host name. This needs to be resolved to binary form\n" +" ISCSI_IP_ADDRESS_TEXT = 0,\n" +" // Binary IPv4 address\n" +" ISCSI_IP_ADDRESS_IPV4 = 1,\n" +" // Binary IPv6 address\n" +" ISCSI_IP_ADDRESS_IPV6 = 2,\n" +" // Empty address\n" +" ISCSI_IP_ADDRESS_EMPTY = 3\n" +"} ISCSIIPADDRESSTYPE, *PISCSIIPADDRESSTYPE;\n" + ) +] +class ISCSI_IP_Address +{ + [WmiDataId(1), + read, write, + DisplayName("Address Format") : amended, + description("Type of address specified. It can be text: a DNS or dotted address or it can be a binary ipv4 or ipv6 address") : amended, + Values{ "Text Address", + "IpV4 Address", + "IpV6 Address", + "Empty Address"}, + ValueMap{ "0", + "1", + "2", + "3"} + ] + + uint32 Type; + + [WmiDataId(2), + read, write, + DisplayInHex, + DisplayName("IPV4 Address"): amended, + description("If IPV4 Address is specified as the Address Format then this conains the binary IPv4 ip address") : amended + ] + uint32 IpV4Address; + + [WmiDataId(3), + DisplayName("IPV6 Address"): amended, + read, write, + description("If IPV6 Address is specified as the Address Format then this conains the binary IPv6 ip address") : amended + ] + uint8 IpV6Address[16]; + + [WmiDataId(4), + read, write, + DisplayName("IPV6 Flow Information") : amended, + description("IPV6 flow information") : amended + ] + uint32 IpV6FlowInfo; + + [WmiDataId(5), + read, write, + DisplayName("IPV6 Scope Id") : amended, + description("IPV6 scope id") : amended + ] + uint32 IpV6ScopeId; + + [WmiDataId(6), + read, write, + DisplayName("Text Address") : amended, + description("Text address, either a DNS address or dotted address") : amended, + MaxLen(256) + ] + string TextAddress; +}; + + +[ + WmiGenerateHeader(FALSE), + WMI, + guid("{DE5051A7-BF27-48f1-BD12-07CADE92AEFD}"), + description("ISCSI target portal") : amended +] +class ISCSI_TargetPortal +{ + [WmiDataId(1), + Description("Network Address") : amended + ] + ISCSI_IP_Address Address; + + [WmiDataId(2), + Description("Reserved") : amended + ] + uint32 Reserved; + + [WmiDataId(3), + Description("Socket number") : amended + ] + uint16 Socket; +}; + +[WMI, + WmiGenerateHeader(FALSE), + guid("{3081F2A5-95F5-4d2a-813D-EE59864C6FC5}"), + description("iSCSI target portal group") : amended +] +class ISCSI_TargetPortalGroup +{ + [WmiDataId(1), + description("Number of portals in group") : amended + ] + uint32 PortalCount; + + [WmiDataId(2), + WmiSizeIs("PortalCount"), + description("Target portals in group") : amended + ] + ISCSI_TargetPortal Portals[]; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{3011A7BD-0491-478e-8C79-3C76424D05E2}"), + cpp_quote("#ifndef _ISCSI_ISCSIDSC_\n" "typedef enum\n" "{\n" " ISCSI_DIGEST_TYPE_NONE = 0,\n" " ISCSI_DIGEST_TYPE_CRC32C = 1\n" "} ISCSI_DIGEST_TYPES, *PISCSI_DIGEST_TYPES;\n" "\n" "typedef enum\n" "{\n" " ISCSI_NO_AUTH_TYPE = 0,\n" " ISCSI_CHAP_AUTH_TYPE = 1,\n" " ISCSI_MUTUAL_CHAP_AUTH_TYPE = 2 \n" "} ISCSI_AUTH_TYPES, *PISCSI_AUTH_TYPES;\n" "#endif\n"), + Description("These are options that can be used for logging into a target") +] +class ISCSI_LoginOptions +{ + [WmiDataId(1), + description("Bit flags that specify which login option values are specified") : amended, + BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010" }, BitValues{"HeaderDigest", "DataDigest", "MaxConnections", "DefaultTime2Wait", "DefaultTime2Retain" } : amended, + cpp_quote("//\n" "// Bit flags for InformationSpecifies\n" "//\n" "#define ISCSI_LOGIN_OPTIONS_HEADER_DIGEST 0x00000001\n" "#define ISCSI_LOGIN_OPTIONS_DATA_DIGEST 0x00000002\n" "#define ISCSI_LOGIN_OPTIONS_MAXIMUM_CONNECTIONS 0x00000004\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_WAIT 0x00000008\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_RETAIN 0x00000010\n" "#define ISCSI_LOGIN_OPTIONS_USERNAME 0x00000020\n" "#define ISCSI_LOGIN_OPTIONS_PASSWORD 0x00000040\n" "#define ISCSI_LOGIN_OPTIONS_AUTH_TYPE 0x00000080\n" "\n") + ] uint32 InformationSpecified; + + [WmiDataId(2), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 HeaderDigest; + + [WmiDataId(3), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 DataDigest; + + [WmiDataId(4), + Description("Maximum number of connections, 0 implies no limit") : amended + ] + uint32 MaximumConnections; + + [WmiDataId(5), + Description("The initiator and target negotiate the minimum time, in seconds, to wait before attempting an explicit/implicit logout or active task reassignment after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Wait; + + [WmiDataId(6), + Description(" The initiator and target negotiate the maximum time, in seconds after an initial wait (Time2Wait), before which an explicit/implicit connection Logout or active task reassignment is still possible after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Retain; + + [WmiDataId(7), + Description("Flags that affect how login occurs") : amended, + cpp_quote("//\n" "// bit flags for ISCSI_LOGIN_FLAGS\n" "//\n" "#ifndef _ISCSI_ISCSIDSC_\n" "#define ISCSI_LOGIN_FLAGS ULONG\n\n" "#define ISCSI_LOGIN_FLAG_REQUIRE_IPSEC 0x00000001\n" "#define ISCSI_LOGIN_FLAG_MULTIPATH_ENABLED 0x00000002\n" "#define ISCSI_LOGIN_FLAG_RESERVED1 0x00000004\n" "#define ISCSI_LOGIN_FLAG_ALLOW_PORTAL_HOPPING 0x00000008\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_RESPONSE 0x00000010\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_VERIFICATION 0x00000020\n" "\n" "#endif\n"), + BitValues{"Require IPSEC", "Multipath Enabled", "Reserved1", "Allow Portal Hopping"}, BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008" } + ] + uint32 LoginFlags; + + [WmiDataId(8), + Description("Authentication method specified for login") : amended, + Values{"No Authentication", "CHAP", "Mutual CHAP" } : amended, ValueMap{"0", "1", "2"} + ] + uint32 AuthType; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{994FF278-3512-4d9b-A241-54CEF45F5A25}"), + description("This class describes a mapping from a an OS LUN to target device LUN") : amended +] +class ISCSI_LUNList +{ + [WmiDataId(1), + description("Target LUN") : amended + ] + uint64 TargetLUN; + + [WmiDataId(2), + description("OS Scsi bus number target is mapped to") : amended + ] + uint32 OSLUN; + + [WmiDataId(3), + description("Reserved") : amended + ] + uint32 Reserved; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{21A28820-3C4C-4944-AC4F-DA7FEBA21168}"), + description("This class describes a mapping from a target LUN to a Windows port driver LUN") : amended +] +class ISCSI_TargetMapping +{ + [WmiDataId(1), + description("OS Scsi bus number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSBus; + + [WmiDataId(2), + description("OS Scsi Target number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSTarget; + + [WmiDataId(3), + Description("Unique Session ID for the target mapping") : amended + ] uint64 UniqueSessionId; + + [WmiDataId(4), + description("Count of LUNs mapped for this target") : amended + ] + uint32 LUNCount; + + [WmiDataId(5), + MaxLen(223), + description("Target Name") : amended + ] + string TargetName; + + [WmiDataId(6), + Description("TRUE if session created from a persistent login") : amended + ] + boolean FromPersistentLogin; + + [WmiDataId(7), + description("Reserved") : amended + ] + uint64 Reserved; + + [WmiDataId(8), + WmiSizeIs("LunCount"), + description("List of LUNs mapped for this target") : amended + ] + ISCSI_LUNList LUNList[]; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ + WMI, + guid("{7A2C6C2B-E5A5-49ad-AD68-133089ACD74D}"), + Dynamic, + Provider("wmiprov"), + DisplayName("TCP/IP configuration") : amended, + cpp_quote("\n" "//***************************************************************************\n" "//\n" "// iscsicfg.h\n" "// \n" "// Module: iScsi Discovery api\n" "//\n" "// Purpose: Header defining interface between user mode configuration\n" "// apps and HBA driver miniport.\n" "//\n" "// Copyright (c) 2001 Microsoft Corporation\n" "//\n" "//***************************************************************************\n\n" + "#include <iscsidef.h>\n\n" +"//\n" +"//\n" +"// This class is required.\n" +"//\n" +"// TCP/IP configuration class, implement one instance for each IP address on\n" +"// your adapter. For example, if you adapter supports 3 IP addresses then\n" +"// your adapter would implement 3 instances of this class.\n" +"//\n" +"// This class uses PDO instance names with 1 instance for each TCP/IP interface.\n" +"//\n" + ) +] +class MSiSCSI_TCPIPConfig +{ + [key] + string InstanceName; + + boolean Active; + + [read, write, + WmiDataId(1), + DisplayName("Use Link Local Address") : amended, + description("TRUE if the adapter should use an autogenerated and non routable (link local) address as its IP address.") : amended + ] + boolean UseLinkLocalAddress; + + [read, write, + WmiDataId(2), + displayName("DHCP Enabled") : amended, + description("TRUE if the adapter should use DHCP to discovery its IP address information.") : amended + ] + boolean EnableDHCP; + + [read, write, + WmiDataId(3), + displayName("Use DHCP for DNS") : amended, + description("TRUE if the adapter should use DHCP to discover DNS addresses.") : amended + ] + boolean UseDHCPForDNS; + + [read, + WmiDataId(4), + description("IP Versions supported **Add #defines**") : amended, + BitValues{ "IPV4", "IPV6"}, + BitMap{"0x00000001", "0x00000002"} + ] + uint32 IPVersions; + + [read, write, + WmiDataId(5), + DisplayName("IP Address") : amended, + description("IP address of the adapter") : amended + ] + ISCSI_IP_Address IpAddress; + + [read, write, + WmiDataId(6), + DisplayName("Default Gateway") : amended, + Description("Static Default Gateway IP address") : amended + ] + ISCSI_IP_Address DefaultGateway; + + [read, write, + WmiDataId(7), + DisplayName("Subnet Mask") : amended, + Description("Static Subnet Mask") : amended + ] + ISCSI_IP_Address SubnetMask; + + [read, write, + WmiDataId(8), + DisplayName("Preferred DNS Server") : amended, + Description("Preferred DNS Server") : amended + ] + ISCSI_IP_Address PreferredDNSServer; + + [read, write, + WmiDataId(9), + DisplayName("Alternate DNS Server") : amended, + Description("Alternate DNS Server") : amended + ] + ISCSI_IP_Address AlternateDNSServer; + +}; + + + + + +[ + WMI, + guid("{C75258E9-BE79-4a48-A23D-EEB6F8FB940C}"), + Dynamic, + DisplayName("NIC Port Configuration") : amended, + Provider("wmiprov"), +cpp_quote( +"//\n" +"// This class is optional.\n" +"//\n" +"// NIC Port configuration class, implement one instance for each physical \n" +"// network interface port on your adapter.\n" +"//\n" +"// This class uses PDO instance names with 1 instance for each physical\n" +"// network interface port on your adapter.\n" +"//\n" +"\n" +"typedef enum \n" +"{\n" +" ISCSI_NIC_LINKSTATE_DISCONNECTED = 0,\n" +" ISCSI_NIC_LINKSTATE_CONNECTED = 1\n" +"} ISCSI_NIC_LINKSTATE, *PISCSI_NIC_LINKSTATE;\n" +) +] +class MSiSCSI_NICConfig +{ + [key] + string InstanceName; + + boolean Active; + + [read, + WmiDataId(1), + DisplayName("Link Speed") : amended, + Description("Speed of network link in megabits per second.") : amended + ] + uint32 LinkSpeed; + + [read, + WmiDataId(2), + DisplayName("Max Link Speed") : amended, + Description("Maximum Speed of network link in megabits per second.") : amended + ] + uint32 MaxLinkSpeed; + + [read, + WmiDataId(3), + DisplayName("Link State") : amended, + description("Link State **typedef**") : amended, + Values{"Media Disconnected", "Media Connected"} : amended, + ValueMap{"0", "1"} + ] + uint32 LinkState; + + [read, + WmiDataId(4), + DisplayName("Max Frame Size") : amended, + description("Maximum frame size") : amended + ] + uint32 MaxFrameSize; + + [read, + WmiDataId(5), + DisplayName("MAC Address") : amended, + description("Ethernet MAC Address") : amended + ] + uint8 MacAddress[6]; + +}; + +[WMI, + guid("{53EF8D5F-36F3-4124-8B76-C6AD521A1021}"), + Dynamic, Provider("wmiprov"), + DisplayName("Boot device configuration") : amended, + cpp_quote( +"//\n" +"// This class is optional.\n" +"//\n" +"// This class exposes the boot configuration if the adapter is configured to\n" +"// boot from an iSCSI disk.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_BootConfiguration +{ + [key] + string InstanceName; + + boolean Active; + + [read, + write, + WmiDataId(1), + Description("LUN on target to use as boot device.") : amended, + DisplayName("Target LUN") : amended + ] + uint64 LUN; + + [ read, write, + WmiDataId(2), + description("Security flags") : amended, BitMap{ "0x00000040", "0x00000020", "0x00000010", "0x00000008", "0x00000004", "0x00000002", "0x00000001" }, BitValues{ "Tunnel mode preferred", "Transport mode preferred", "PFS Enabled", "Aggressive mode enabled", "Main Mode Enabled", "IKE/IPSec Enabled", "ISCSI_SECURITY_FLAGS are valid" } : amended + ] + uint64 SecurityFlags; + + [ read, write, + WmiDataId(3), + description("Size in bytes of Target Username.") : amended + ] uint32 UsernameSize; + + [ read, write, + WmiDataId(4), + description("Size in bytes of Target Password.") : amended + ] uint32 PasswordSize; + + [ read, write, + WmiDataId(5), + description("If TRUE dynamically discover boot device.") : amended + ] + boolean DiscoverBootDevice; + + [ read, write, + WmiDataId(6), + MaxLen(223), + description("The InitiatorNode specifies the iSCSI name of the initiator node to use for the connection. If empty, then the adapter can choose any initiator node name.") : amended + ] string InitiatorNode; + + [ read, write, + WmiDataId(7), + MaxLen(223), + description("TargetName specifies the iSCSI target name on which the boot device resides.") : amended + ] string TargetName; + + [ read, write, + WmiDataId(8), + description("Target portal to use for connection to the target.") : amended + ] ISCSI_TargetPortal TargetPortal; + + [read, write, + WmiDataId(9), + description("Options that affect how login is performed. See ISCSI_LoginOptions") : amended + ] ISCSI_LoginOptions LoginOptions; + + [ read, write, + WmiDataId(10), + WmiSizeIs("UsernameSize"), + description("**extra fields** Authentication Username, for CHAP this is the CHAP Name (CHAP_N) use when authenticating with the target. NOTE: This field is a variable length array, the field that follows this field starts immediately after the end of this field subject to appropriate padding.") : amended + ] uint8 Username[]; + + [ read, write, + WmiDataId(11), + WmiSizeIs("PasswordSize"), + description("Authentication Password, for CHAP this is the shared secret to use when generating the response to the target challange. This field is a variable length array.") : amended + ] uint8 Password[]; +}; + + + + + + + + + + + + +[ + WMI, + guid("{225B9D64-47A9-41c8-81CD-69BC02652D87}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Security Capabilities") : amended, + cpp_quote( +"//\n" +"// This class is required if adapter supports IPSEC.\n" +"//\n" +"// This class exposes the security capabilities if the adapter \n" +"// supports IPSEC.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" +"typedef enum {\n" +" ISCSI_ENCRYPT_NONE = 0,\n" +" ISCSI_ENCRYPT_3DES_HMAC_SHA1 = 1,\n" +" ISCSI_ENCRYPT_AES_CTR = 2 \n" +"} ISCSI_ENCRYPTION_TYPES, *PISCSI_ENCRYPTION_TYPES;\n\n" + ) +] +class MSiSCSI_SecurityCapabilities +{ + [key] + string InstanceName; + + boolean Active; + + [read, + DisplayName("Protect iSCSI") : amended, + WmiDataId(1), + description("TRUE if the adapter can use IPSEC to protect iSCSI traffic.") : amended + ] + boolean ProtectiScsiTraffic; + + + [read, + WmiDataId(2), + DisplayName("Protect iSNS") : amended, + description("TRUE if the adapter can use IPSEC to protect iSNS traffic.") : amended + ] + boolean ProtectiSNSTraffic; + + [read, + WmiDataId(3), + DisplayName("Certificates Supported") : amended, + description("TRUE if adapter supports certificates") : amended + ] + boolean CertificatesSupported; + + [read, + WmiDataId(4), + DisplayName("Encryption Types Available") : amended, + description("Number of encryption types available.") + ] + uint32 EncryptionAvailableCount; + + [ read, + WmiDataId(5), + WmiSizeIs("EncryptionAvailableCount"), + Values {"No Encryption/Authentication", "3DES HMAC/SHA1", "AES-CTR/CBC-MAC with XCBC"} : amended, ValueMap{ "0", "1", "2" }, + DisplayName("Encryption Types") : amended, + description("**typedef** Array of encryption types. This field is a variable length array.") + ] + uint32 EncryptionAvailable[]; +}; + + +[WMI, + guid("{45755098-4291-43df-9720-B58642DD63DF}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Discovery Configuration") : amended, + cpp_quote( +"//\n" +"// This class is required.\n" +"//\n" +"// This class exposes the configuration capabilities for the adapter to be able to\n" +"// perform target discovery. An adapter needs to support target discovery\n" +"// if it is ever placed on a separate network from the PC NIC. Although\n" +"// the iSCSI Initiator service can use this class with any discovery mechanism\n" +"// the best results are obtained by using iSNS.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_DiscoveryConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + description("TRUE if adapter should perform target discovery via iSNS.") : amended + ] boolean PerformiSNSDiscovery; + + [WmiDataId(2), + read, write, + description("TRUE if adapter should perform target discovery via SLP.") : amended + ] boolean PerformSLPDiscovery; + + [WmiDataId(3), + read, write, + description("TRUE if adapter should perform automatic discovery of iSNS server.") : amended + ] boolean AutomaticiSNSDiscovery; + + [WmiDataId(4), + read, write, + MaxLen(256), + description("Default initiator name for registering with iSNS.") : amended + ] string InitiatorName; + + [WmiDataId(5), + read, write, + description("If AutomaticiSNSDiscovery is FALSE then this contains the fixed addresses of iSNS servers") : amended + ] ISCSI_IP_Address iSNSServer; + +}; + +[WMI, + guid("{8EAEF9D8-C053-49d3-9205-65C703C2ECC1}"), + Dynamic, + Provider("wmiprov"), + DisplayName("Radius Configuration") : amended, + cpp_quote( +"//\n" +"// This class is required if adapter supports using RADIUS for CHAP authentication.\n" +"//\n" +"// This class exposes the configuration capabilities if the adapter able to\n" +"// use radius to perform CHAP authentication. Using RADIUS is encouraged\n" +"// since it allows centralized management of CHAP credentials.\n" +"//\n" +"// This class uses PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_RADIUSConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + description("TRUE if adapter should use RADIUS for CHAP authentication") : amended + ] boolean UseRADIUSForCHAP; + + [WmiDataId(2), + read, write, + description("Size in bytes of shared secret used to communicate with RADIUS servers") : amended + ] uint32 SharedSecretSizeInBytes; + + [WmiDataId(3), + read, write, + description("Fixed address of primary RADIUS server") : amended + ] ISCSI_IP_Address RADIUSServer; + + [WmiDataId(4), + read, write, + description("Fixed address of backup RADIUS server") : amended + ] ISCSI_IP_Address BackupRADIUSServer; + + [WmiDataId(5), + Description("Must be zero") + ] + uint32 Reserved; + + [WmiDataId(6), + read, write, + WmiSizeIs("SharedSecretSizeInBytes"), + description("Shared secret for communicating with primary and backup RADIUS servers. This field is a variable length array.") : amended + ] uint8 SharedSecret[]; + +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ + WmiGenerateHeader(FALSE), + WMI, + DisplayName("IP Address") : amended, + guid("{9AC5D4A1-1A1A-48ec-8E79-735806E9A1FA}"), + cpp_quote("\n" "//***************************************************************************\n" "//\n" "// iscsimgt.h\n" "// \n" "// Module: iScsi Discovery api\n" "//\n" "// Purpose: Internal header defining interface between user mode discovery\n" "// api dll and HBA driver miniport.\n" "//\n" "// Copyright (c) 2001 Microsoft Corporation\n" "//\n" "//***************************************************************************\n\n" +"//\n" "// Definitions for iscsi security flags. These flags provide\n" "// information about the security expectations of a target portal and\n" "// are needed to insure a successful IKE/IPSEC negotiation. Note that\n" "// the flags and values are taken directly from the iSNS spec\n" "//\n" "\n" " // 1 = Tunnel Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TUNNEL_MODE_PREFERRED 0x00000040\n" "\n" " // 1 = Transport Mode Preferred; 0 = No Preference\n" "#define ISCSI_SECURITY_FLAG_TRANSPORT_MODE_PREFERRED 0x00000020\n" " \n" " // 1 = PFS Enabled; 0 = PFS Disabled\n" "#define ISCSI_SECURITY_FLAG_PFS_ENABLED 0x00000010\n" " \n" " // 1 = Aggressive Mode Enabled; 0 = Disabled\n" "#define ISCSI_SECURITY_FLAG_AGGRESSIVE_MODE_ENABLED 0x00000008\n" " \n" " // 1 = Main Mode Enabled; 0 = MM Disabled\n" "#define ISCSI_SECURITY_FLAG_MAIN_MODE_ENABLED 0x00000004\n" " \n" " // 1 = IKE/IPSec Enabled; 0 = IKE/IPSec Disabled\n" "#define ISCSI_SECURITY_FLAG_IKE_IPSEC_ENABLED 0x00000002\n" "\n" " // If set then all other ISCSI_SECURITY_FLAGS are valid \n" "#define ISCSI_SECURITY_FLAG_VALID 0x00000001 \n" "\n" +"\n" +"//\n" +"// Types of addresses that can be passed by management app to driver\n" +"//\n" +"typedef enum {\n" +" // Text based host name. This needs to be resolved to binary form\n" +" ISCSI_IP_ADDRESS_TEXT = 0,\n" +" // Binary IPv4 address\n" +" ISCSI_IP_ADDRESS_IPV4 = 1,\n" +" // Binary IPv6 address\n" +" ISCSI_IP_ADDRESS_IPV6 = 2,\n" +" // Empty address\n" +" ISCSI_IP_ADDRESS_EMPTY = 3\n" +"} ISCSIIPADDRESSTYPE, *PISCSIIPADDRESSTYPE;\n" + ) +] +class ISCSI_IP_Address +{ + [WmiDataId(1), + read, write, + DisplayName("Address Format") : amended, + description("Type of address specified. It can be text: a DNS or dotted address or it can be a binary ipv4 or ipv6 address") : amended, + Values{ "Text Address", + "IpV4 Address", + "IpV6 Address", + "Empty Address"}, + ValueMap{ "0", + "1", + "2", + "3"} + ] + + uint32 Type; + + [WmiDataId(2), + read, write, + DisplayInHex, + DisplayName("IPV4 Address"): amended, + description("If IPV4 Address is specified as the Address Format then this conains the binary IPv4 ip address") : amended + ] + uint32 IpV4Address; + + [WmiDataId(3), + DisplayName("IPV6 Address"): amended, + read, write, + description("If IPV6 Address is specified as the Address Format then this conains the binary IPv6 ip address") : amended + ] + uint8 IpV6Address[16]; + + [WmiDataId(4), + read, write, + DisplayName("IPV6 Flow Information") : amended, + description("IPV6 flow information") : amended + ] + uint32 IpV6FlowInfo; + + [WmiDataId(5), + read, write, + DisplayName("IPV6 Scope Id") : amended, + description("IPV6 scope id") : amended + ] + uint32 IpV6ScopeId; + + [WmiDataId(6), + read, write, + DisplayName("Text Address") : amended, + description("Text address, either a DNS address or dotted address") : amended, + MaxLen(256) + ] + string TextAddress; +}; + + +[ + WmiGenerateHeader(FALSE), + WMI, + guid("{DE5051A7-BF27-48f1-BD12-07CADE92AEFD}"), + description("ISCSI target portal") : amended +] +class ISCSI_TargetPortal +{ + [WmiDataId(1), + Description("Network Address") : amended + ] + ISCSI_IP_Address Address; + + [WmiDataId(2), + Description("Reserved") : amended + ] + uint32 Reserved; + + [WmiDataId(3), + Description("Socket number") : amended + ] + uint16 Socket; +}; + +[WMI, + WmiGenerateHeader(FALSE), + guid("{3081F2A5-95F5-4d2a-813D-EE59864C6FC5}"), + description("iSCSI target portal group") : amended +] +class ISCSI_TargetPortalGroup +{ + [WmiDataId(1), + description("Number of portals in group") : amended + ] + uint32 PortalCount; + + [WmiDataId(2), + WmiSizeIs("PortalCount"), + description("Target portals in group") : amended + ] + ISCSI_TargetPortal Portals[]; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{3011A7BD-0491-478e-8C79-3C76424D05E2}"), + cpp_quote("#ifndef _ISCSI_ISCSIDSC_\n" "typedef enum\n" "{\n" " ISCSI_DIGEST_TYPE_NONE = 0,\n" " ISCSI_DIGEST_TYPE_CRC32C = 1\n" "} ISCSI_DIGEST_TYPES, *PISCSI_DIGEST_TYPES;\n" "\n" "typedef enum\n" "{\n" " ISCSI_NO_AUTH_TYPE = 0,\n" " ISCSI_CHAP_AUTH_TYPE = 1,\n" " ISCSI_MUTUAL_CHAP_AUTH_TYPE = 2 \n" "} ISCSI_AUTH_TYPES, *PISCSI_AUTH_TYPES;\n" "#endif\n"), + Description("These are options that can be used for logging into a target") +] +class ISCSI_LoginOptions +{ + [WmiDataId(1), + description("Bit flags that specify which login option values are specified") : amended, + BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010" }, BitValues{"HeaderDigest", "DataDigest", "MaxConnections", "DefaultTime2Wait", "DefaultTime2Retain" } : amended, + cpp_quote("//\n" "// Bit flags for InformationSpecifies\n" "//\n" "#define ISCSI_LOGIN_OPTIONS_HEADER_DIGEST 0x00000001\n" "#define ISCSI_LOGIN_OPTIONS_DATA_DIGEST 0x00000002\n" "#define ISCSI_LOGIN_OPTIONS_MAXIMUM_CONNECTIONS 0x00000004\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_WAIT 0x00000008\n" "#define ISCSI_LOGIN_OPTIONS_DEFAULT_TIME_2_RETAIN 0x00000010\n" "#define ISCSI_LOGIN_OPTIONS_USERNAME 0x00000020\n" "#define ISCSI_LOGIN_OPTIONS_PASSWORD 0x00000040\n" "#define ISCSI_LOGIN_OPTIONS_AUTH_TYPE 0x00000080\n" "\n") + ] uint32 InformationSpecified; + + [WmiDataId(2), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 HeaderDigest; + + [WmiDataId(3), + ValueMap{ "0", + "1" }, + Values{ "None", "CRC32C" }, + description("cyclic integrity checksums that can be negotiated for the header digests") : amended + ] uint32 DataDigest; + + [WmiDataId(4), + Description("Maximum number of connections, 0 implies no limit") : amended + ] + uint32 MaximumConnections; + + [WmiDataId(5), + Description("The initiator and target negotiate the minimum time, in seconds, to wait before attempting an explicit/implicit logout or active task reassignment after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Wait; + + [WmiDataId(6), + Description(" The initiator and target negotiate the maximum time, in seconds after an initial wait (Time2Wait), before which an explicit/implicit connection Logout or active task reassignment is still possible after an unexpected connection termination or a connection reset.") : amended + ] + uint32 DefaultTime2Retain; + + [WmiDataId(7), + Description("Flags that affect how login occurs") : amended, + cpp_quote("//\n" "// bit flags for ISCSI_LOGIN_FLAGS\n" "//\n" "#ifndef _ISCSI_ISCSIDSC_\n" "#define ISCSI_LOGIN_FLAGS ULONG\n\n" "#define ISCSI_LOGIN_FLAG_REQUIRE_IPSEC 0x00000001\n" "#define ISCSI_LOGIN_FLAG_MULTIPATH_ENABLED 0x00000002\n" "#define ISCSI_LOGIN_FLAG_RESERVED1 0x00000004\n" "#define ISCSI_LOGIN_FLAG_ALLOW_PORTAL_HOPPING 0x00000008\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_RESPONSE 0x00000010\n" "#define ISCSI_LOGIN_FLAG_USE_RADIUS_VERIFICATION 0x00000020\n" "\n" "#endif\n"), + BitValues{"Require IPSEC", "Multipath Enabled", "Reserved1", "Allow Portal Hopping"}, BitMap{ "0x00000001", "0x00000002", "0x00000004", "0x00000008" } + ] + uint32 LoginFlags; + + [WmiDataId(8), + Description("Authentication method specified for login") : amended, + Values{"No Authentication", "CHAP", "Mutual CHAP" } : amended, ValueMap{"0", "1", "2"} + ] + uint32 AuthType; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{994FF278-3512-4d9b-A241-54CEF45F5A25}"), + description("This class describes a mapping from a an OS LUN to target device LUN") : amended +] +class ISCSI_LUNList +{ + [WmiDataId(1), + description("Target LUN") : amended + ] + uint64 TargetLUN; + + [WmiDataId(2), + description("OS Scsi bus number target is mapped to") : amended + ] + uint32 OSLUN; + + [WmiDataId(3), + description("Reserved") : amended + ] + uint32 Reserved; +}; + + +[WMI, + WmiGenerateHeader(FALSE), + guid("{21A28820-3C4C-4944-AC4F-DA7FEBA21168}"), + description("This class describes a mapping from a target LUN to a Windows port driver LUN") : amended +] +class ISCSI_TargetMapping +{ + [WmiDataId(1), + description("OS Scsi bus number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSBus; + + [WmiDataId(2), + description("OS Scsi Target number target is mapped to. If 0xffffffff then any value can be picked by the miniport.") : amended + ] + uint32 OSTarget; + + [WmiDataId(3), + Description("Unique Session ID for the target mapping") : amended + ] uint64 UniqueSessionId; + + [WmiDataId(4), + description("Count of LUNs mapped for this target") : amended + ] + uint32 LUNCount; + + [WmiDataId(5), + MaxLen(223), + description("Target Name") : amended + ] + string TargetName; + + [WmiDataId(6), + Description("TRUE if session created from a persistent login") : amended + ] + boolean FromPersistentLogin; + + [WmiDataId(7), + description("Reserved") : amended + ] + uint64 Reserved; + + [WmiDataId(8), + WmiSizeIs("LunCount"), + description("List of LUNs mapped for this target") : amended + ] + ISCSI_LUNList LUNList[]; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#pragma autorecover + +[ + WMI, + cpp_quote("\n" "//***************************************************************************\n" "//\n" "// iscsimgt.h\n" "// \n" "// Module: iScsi Discovery api\n" "//\n" "// Purpose: Internal header defining interface between user mode discovery\n" "// api dll and HBA driver miniport.\n" "//\n" "// Copyright (c) 2001 Microsoft Corporation\n" "//\n" "//***************************************************************************\n\n" + "#include <iscsidef.h>\n\n" +"//\n" +"//\n" +"// This class is required.\n" +"//\n" +"// Adapter Information class. The iSCSI initiator service relies upon this\n" +"// class in order to interface with your adapter. Implement one instance\n" +"// per adapter instance.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ), + guid("{58515BF3-2F59-4f37-B74F-85AEEC652AD6}"), + Dynamic, + DisplayName("HBA Information") : amended, + Provider("wmiprov") +] +class MSiSCSI_HBAInformation +{ + + + + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique for all instances of iSCSI initiators. Use the address of the Adapter Extension or another address owned by the device driver.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + DisplayName("Integrated Networking") : amended, + description("TRUE if TCP/IP traffic is integrated with the Windows networking TCP/IP stack via a software only initiator. An adapter with its own TCP/IP stack would set this to FALSE.") : amended + ] + boolean IntegratedTCPIP; + + [WmiDataId(3), + Displayname("Requires Binary Addresses") : amended, + description("If TRUE the iSCSI Initiator service will perform any DNS lookup and pass binary IP addresses to the adapter; the adapter must be on the same network as the Windows TCP/IP stack. If FALSE then DNS must be available on adapter.") : amended + ] + boolean RequiresBinaryIpAddresses; + + [read, + WmiDataId(4), + DisplayName("Minimum iSCSI Version") : amended, + description("Minimum version number of the iScsi spec supported by adapter") : amended + ] uint8 VersionMin; + + [read, + WmiDataId(5), + DisplayName("Maximum iSCSI Version") : amended, + description("Maximum version number of the iSCSI spec supported by adapter") : amended + ] uint8 VersionMax; + + [read, + WmiDataId(6), + DisplayName("Multifunction Device") : amended, + description("TRUE if this adapter is a multifunction device, that is it also exposes a netcard interface") : amended + ] boolean MultifunctionDevice; + + [read, + WmiDataId(7), + DisplayName("Valid Cache") : amended, + description("TRUE if the adapter caches are valid") : amended + ] boolean CacheValid; + + [read, + WmiDataId(8), + Displayname("Number of ports") : amended, + description("Number of ports (or TCP/IP addresses) on the adapter") : amended + ] uint32 NumberOfPorts; + + + [read, + WmiDataId(9), + Displayname("Status") : amended, + description("**typedef** Current status of adapter") : amended, + Values{ "Working", "Degraded", "Critical", "Failed"}, + ValueMap{ "0", "1", "2", "3" }, + cpp_quote( +"#define ISCSI_HBA_STATUS_WORKING 0\n" +"#define ISCSI_HBA_STATUS_DEGRADED 1\n" +"#define ISCSI_HBA_STATUS_CRITICAL 2\n" +"#define ISCSI_HBA_STATUS_FAILED 3\n" +) + ] uint32 Status; + + [read, + WmiDataId(10), + DisplayName("Functionality Supported") : amended, + Description("**typedef** Bit flags that indicate various functionality supported") : amended, + BitValueMap{"0x00000001", + "0x00000002", + "0x00000004", + "0x00000008", + "0x00000010", + "0x00000020" + }, + BitValues{"Preshared Key Cache", + "iSCSI Authentication Cache", + "Tunnel Mode", + "CHAP authentication via RADIUS", + "Discovery via iSNS", + "Discovery via SLP" + } : amended, + cpp_quote( +"\n" +"//\n" +"// Flags that define the functionality supported by the HBA\n" +"//\n" +"#define ISCSI_HBA_PRESHARED_KEY_CACHE 0x00000001\n" +"#define ISCSI_HBA_ISCSI_AUTHENTICATION_CACHE 0x00000002\n" +"#define ISCSI_HBA_IPSEC_TUNNEL_MODE 0x00000004\n" +"#define ISCSI_HBA_CHAP_VIA_RADIUS 0x00000008\n" +"#define ISCSI_HBA_ISNS_DISCOVERY 0x00000010\n" +"#define ISCSI_HBA_SLP_DISCOVERY 0x00000020\n" +"\n" +) + ] uint32 FunctionalitySupported; + + [read, + WmiDataId(11), + DisplayName("Generational Guid") : amended, + Description("This is the GUID value last set by the SetGenerationalGuid method in the MSiSCSI_Operations class.") : amended + ] uint8 GenerationalGuid[16]; + + [read, + WmiDataId(12), + DisplayName("Max CDB Length") : amended, + Description("Maxumum CDB length supported by the adapter") : amended + ] uint32 MaxCDBLength; + + [read, + WmiDataId(13), + DisplayName("Bi-directionsal SCSI comamnd supported") : amended, + Description("TRUE if Bi-directionsal SCSI comamnd supported") : amended + ] boolean BiDiScsiCommands; + + [read, + WmiDataId(14), + DisplayName("Manufacturer") : amended, + description("A text string describing the manufacturer of adapter") : amended, + MaxLen(255)] string VendorID; + + [read, + WmiDataId(15), + Displayname("Model") : amended, + description("A text string set by the manufacturer describing the model of adapter") : amended, + MaxLen(255)] string VendorModel; + + [read, + WmiDataId(16), + Displayname("Version") : amended, + description("A text string set by the manufacturer describing the version of adapter") : amended, + MaxLen(255)] string VendorVersion; + + [read, + WmiDataId(17), + displayName("Firmware Version") : amended, + description("A text string set by the manufacturer describing the firmware version of adapter") : amended, + MaxLen(255)] string FirmwareVersion; + + [read, + WmiDataId(18), + displayName("ASIC Version") : amended, + description("A text string set by the manufacturer describing the Asic version") : amended, + MaxLen(255)] string AsicVersion; + + [read, + WmiDataId(19), + displayName("Option Rom Version") : amended, + description("A text string set by the manufacturer describing the option rom version of adapter") : amended, + MaxLen(255)] string OptionRomVersion; + + [read, + WmiDataId(20), + Displayname("Serial Number") : amended, + description("A text string set by the manufacturer describing the serial number of adapter") : amended, + MaxLen(255)] string SerialNumber; + + [read, + WmiDataId(21), + Displayname("Driver Name") : amended, + description("A text string specifying the name of the driver for the adapter") : amended, + MaxLen(255)] string DriverName; +}; + + +[WMI, Dynamic, Provider("wmiprov"), + DisplayName("HBA Session Default Configuration") : amended, + guid("{B35694DE-D323-49d2-ABB2-8139209AD150}"), + cpp_quote( +"//\n" +"//\n" +"// This class is optional.\n" +"//\n" +"// This class allows the default session configuration to be managed. It \n" +"// contains the default values to use when establishing a session.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_HBASessionConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + Description("The InitialR2T key is used to turn off the default use of R2T, thus allowing an initiator to start sending data to a target as if it has received an initial R2T with Buffer Offset=0 and Desired Data Transfer Length=min (FirstBurstSize, Expected Data Transfer Length).") : amended + ] + boolean InitialR2T; + + [WmiDataId(2), + read, write, + Description("The initiator and target negotiate support for immediate data. To turn immediate data off, the initiator or target must state its desire to do so. ImmediateData can be turned on if both the initiator and target have ImmediateData=Yes.") : amended + ] + boolean ImmediateData; + + [WmiDataId(3), + read, write, + Description("Maximum data segment length in bytes they can receive in an iSCSI PDU.") : amended + ] + uint32 MaxRecvDataSegmentLength; + + [WmiDataId(4), + read, write, + Description("Maximum SCSI data payload in bytes in an Data-In or a solicited Data-Out iSCSI sequence.") : amended + ] + uint32 MaxBurstLength; + + [WmiDataId(5), + read, write, + Description("maximum amount in bytes of unsolicited data an iSCSI initiator may send to the target, during the execution of a single SCSI command. This covers the immediate data (if any) and the sequence of unsolicited Data-Out PDUs (if any) that follow the command.") : amended + ] + uint32 FirstBurstLength; + + [WmiDataId(6), + read, write, + Description("Initiator and target negotiate the maximum number of outstanding R2Ts per task, excluding any implied initial R2T that might be part of that task. An R2T is considered outstanding until the last data PDU (with the F bit set to 1) is transferred, or a sequence reception timeout (section 6.12.1) is encountered for that data sequence.") : amended + ] + uint32 MaxOutstandingR2T; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ + WMI, + Description ("iSCSI Static Connection Statistics Information") : amended, + guid ("{3CE2D6A0-7346-4826-972F-F2C19779D1D1}") +] +class ISCSI_ConnectionStaticInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated connection ID. Do not confuse this with CID."): amended + ] uint64 UniqueConnectionId; + + [read, + WmiDataId(2), + Description("The iSCSI connection ID for this connection instance."): amended + ] uint16 CID; + + [read, + WmiDataId(3), + ValueMap{"0", "1","2"}, Values{ "login", "full", "logout" }, DefineValues {"login", "full", "logout"}, + Description("**typedef** Indicates the current state of this connection"): amended, + cpp_quote("\n" + " //login - The TCP connection has been established, but a valid iSCSI\n" + " // login response with the final bit set has not been sent or received.\n" + " //full - A valid iSCSI login response with the final bit set \n" + " // has been sent or received.\n" + " //logout - A valid iSCSI logout command has been sent or received, but\n" + " // the TCP connection has not yet been closed.\n" + "\n" + ) + ] uint8 State; + + + [read, + WmiDataId(4), + ValueMap{"6"}, Values{ "TCP" }, DefineValues {"TCP"}, + Description("**typedef** The transport protocol over which this connection instance is running."): amended + ] uint8 Protocol; + + [read, + WmiDataId(5), + ValueMap{"0", "1"}, Values{ "None", "crc32c" }, DefineValues {"None", "crc32c" }, + description("**typedef** The name of the iSCSI header digest scheme in use within this session."), + WmiVersion(1) + ] uint8 HeaderIntegrity; + + [read, + WmiDataId(6), + ValueMap{"0", "1"}, Values{ "None", "crc32c" }, DefineValues {"None", "crc32c" }, + description("**typedef** The name of the iSCSI data digest scheme in use within this session."), + WmiVersion(1) + ] uint8 DataIntegrity; + + [read, + WmiDataId(7), + description("Must be zero") + ] uint16 Reserved; + + [read, + WmiDataId(8), + description("The maximum data payload size supported for command or data PDUs within this session."), + WmiVersion(1)] uint32 MaxRecvDataSegmentLength; + + [read, + WmiDataId(9), + Values{"No Authentication", "CHAP", "Mutual CHAP" } : amended, ValueMap{"0", "1", "2"}, + description("**typedef** Authentication type used when establishing the connection.") + ] uint32 AuthType; + + + [read, + WmiDataId(10), + Description("The local network address used for the connection"): amended + ] ISCSI_IP_Address LocalAddr; + + [read, + WmiDataId(11), + Description("The local port used for the connection"): amended + ] uint32 LocalPort; + + [read, + WmiDataId(12), + Description("The remote network address used for the connection"): amended + ] ISCSI_IP_Address RemoteAddr; + + [read, + WmiDataId(13), + Description("The remote port used for the connection"): amended + ] uint32 RemotePort; + + [read, + WmiDataId(14), + Description("Estimated throughput of the link in bytes per second"): amended + ] uint64 EstimatedThroughput; + + [read, + WmiDataId(15), + Description("Maximum Datagram size supported by the transport in bytes"): amended + ] uint32 MaxDatagramSize; +}; + + +[ + WMI, + Description ("iSCSI Static Sessions Statistics Information") : amended, + guid ("{B71D2538-57E2-4228-888B-1AF9B3BD01CD}") +] +class ISCSI_SessionStaticInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated session ID, it is the same id returned by the LoginToTarget method. Do not confuse this with ISID or SSID."): amended, + WmiVersion(1)] uint64 UniqueSessionId; + + [read, + WmiDataId(2), + WmiVersion(1), + description("Initiator node name used to establish the session"), + MaxLen(223)] string InitiatoriSCSIName; + + [read, + WmiDataId(3), + WmiVersion(1), + Description("iSCSI node name of the target"): amended, + MaxLen(223)] String TargetiSCSIName; + + [read, + WmiDataId(4), + Description("Target-defined portion of the iSCSI Session ID"): amended, + WmiVersion(1)] uint16 TSID; + + [read, + WmiDataId(5), + Description("Initiator-defined portion of the iSCSI Session ID"): amended, + WmiVersion(1)] uint8 ISID[6]; + + [read, + WmiDataId(6), + description("If TRUE, the initiator must wait for an R2T before sending data to the target. If FALSE, the initiator may send data immediately, within limits set by FirstBurstSize and the expected data transfer length of the request."), + WmiVersion(1)] boolean InitialR2t; + + [read, + WmiDataId(7), + description("If TRUE indicates whether the initiator and target have agreed to support immediate commands on this session."), + WmiVersion(1)] boolean ImmediateData; + + [read, + WmiDataId(8), + Description("**typedef** Type of iSCSI session") : amended, \ + ValueMap{"0", "1","2","3"}, Values{ "discoverySession", "informationalSession", "dataSession", "bootSession" }, DefineValues { "discoverySession", "informationalSession", "dataSession", "bootSession" }, + cpp_quote("\n" + " // Type of iSCSI session\n" + " // discoverySession - session is being used only for discovery\n" + " // informationalSession - session is used for a limited number of scsi commands\n" + " // dataSession - session is being used as a full feature session\n" + " // bootSession - session is being used to boot an initiator\n" + "\n" + ), + WmiVersion(1)] uint8 Type; + + [read, + WmiDataId(9), + description("If FALSE indicates that data PDU Sequences may be transferred in any order. If TRUE indicates that data PDU sequences must be transferred using continuously increasing offsets, except during error recovery."), + WmiVersion(1)] boolean DataSequenceInOrder; + + [read, + WmiDataId(10), + description("If FALSE indicates that data PDUs within sequences may be in any order. If TRUE indicates that data PDUs within sequences must be at continuously increasing addresses, with no gaps or overlay between PDUs."), + WmiVersion(1)] boolean DataPduInOrder; + + [read, + WmiDataId(11), + description("The level of error recovery negotiated between the initiator and the target."), + WmiVersion(1)] uint8 ErrorRecoveryLevel; + + [read, + WmiDataId(12), + description("The maximum number of outstanding request-to-transmit (R2T) per task within this session"), + WmiVersion(1)] uint32 MaxOutstandingR2t; + + [read, + WmiDataId(13), + description("The maximum length supported for unsolicited data sent within this session"), + WmiVersion(1)] uint32 FirstBurstLength; + + [read, + WmiDataId(14), + description("The maximum number of bytes which can be sent within a single sequence of Data-In or Data-Out PDUs"), + WmiVersion(1)] uint32 MaxBurstLength; + + [read, + WmiDataId(15), + description("The maximum number of connections that will be allowed within this session"), + WmiVersion(1)] uint32 MaxConnections; + + [read, + WmiDataId(16), + description("The number of connections that currently belong to this session"), + WmiVersion(1)] uint16 ConnectionCount; + + [WmiDataId(17), + read, + DisplayName("List of Connections") : amended, + Description("List of ISCSI_ConnectionStaticInfo. ConnectionCount specifies the number of elements in the array. NOTE: This is a variable length array.") : amended, + WmiSizeIs("ConnectionCount") + ] ISCSI_ConnectionStaticInfo ConnectionsList[]; +}; + + +[ + WMI, + Description ("iSCSI Portal Info") : amended, + guid ("{4FB9130E-1FEF-4ae6-9E48-77839204D413}") +] +class ISCSI_PortalInfo +{ + [read, + WmiDataId(1), + description("An integer used to uniquely identify a paticular port"), + WmiVersion(1)] uint32 Index; + + [read, + WmiDataId(2), + ValueMap{"0", "1"}, Values{ "Initiator", "Target" }, DefineValues {"InitiatorPortals", "TargetPortals"}, + description("**typedef** The type of portal (Initiator or Target) \n"), + WmiVersion(1)] uint8 PortalType; + + [read, + WmiDataId(3), + ValueMap{"6"}, Values{ "TCP" }, DefineValues {"TCP"}, + + description("The portal's transport protocol"), + WmiVersion(1)] uint8 Protocol; + + [read, + WmiDataId(4), + WmiVersion(1)] uint8 Reserved1; + + [read, + WmiDataId(5), + WmiVersion(1)] uint8 Reserved2; + + [read, + WmiDataId(6), + description("The portal's network address"), + WmiVersion(1)] ISCSI_IP_Address IPAddr; + + [read, + WmiDataId(7), + description("The portal's socket number"), + WmiVersion(1)] uint32 Port; + + [read, + WmiDataId(8), + description("The portal's aggregation tag"), + WmiVersion(1)] uint16 PortalTag; +}; + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iScsi Portal Information Class") : amended, + guid ("{84CA6FD6-B152-4e6a-8869-FDE5E37B6157}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class exposes portal information.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_PortalInfoClass +{ + [read,key] String InstanceName; + [read] boolean Active; + + [WmiDataId(1), + read, + DisplayName("Count of Elements in iScsiPortalInfo array") : amended, + Description("Number of elements in iScsiPortalInfo array") : amended + ] uint32 PortalInfoCount; + + [WmiDataId(2), + read, + DisplayName("List Of Portals") : amended, + Description("Variable length array of iScsiPortalInfo. PortalInfoCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("PortalInfoCount") + ] ISCSI_PortalInfo PortalInformation[]; + +}; +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Static Initiator Session Information") : amended, + guid ("{D7931411-0376-4869-A491-8D679BFC004A}"), + cpp_quote( +"//\n" +"//\n" +"// This class is required. \n" +"//\n" +"// This class exposes session and connection information on the initiator.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorSessionInfo +{ + [read,key] String InstanceName; + + [read] boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique to each instance of each adapter. Using the address of the Adapter Extension is a good idea.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + read, + DisplayName("Count of Elements in SessionList array") : amended, + Description("Number of elements in SessionList array") : amended + ] uint32 SessionCount; + + [WmiDataId(3), + read, + DisplayName("List Of Sessions") : amended, + Description("Variable length array of sessions. SessionCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("SessionCount") + ] ISCSI_SessionStaticInfo SessionsList[]; + +}; + + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Initiator Node Failure Event") : amended, + guid ("{1221948A-6332-4ac2-AA04-268AABCECE4F}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class fires an event when a node failure occurs.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorNodeFailureEvent : __ExtrinsicEvent +{ + [read,key] String InstanceName; + [read] boolean Active; + + [read, + WmiDataId(1), + WmiTimeStamp, + Description("Timestamp denoting time failure occured"), + WmiVersion(1)] uint64 FailureTime; + + [read, + WmiDataId(2), + Description("**typedef** Types of initiator node failure") : amended, \ + ValueMap{"0", "1","2","3","4"}, Values{ "LoginOtherFail", "LoginAuthFail", "LoginAuthenticateFail", "LoginNegotiateFail", "LogoutOthers" }, DefineValues {"LoginOtherFail", "LoginAuthFail", "LoginAuthenticateFail", "LoginNegotiateFail", "LogoutOthers"}, + WmiVersion(1)] uint8 FailureType; + + [read, + WmiDataId(3), + description("Name of target involved in failure"), + WmiVersion(1), + MaxLen(223)] string TargetFailureName; + + [read, + WmiDataId(4), + description("Network address of target involved in failure"), + WmiVersion(1)] ISCSI_IP_Address TargetFailureAddr; +}; + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Initiator Instance Failure Event") : amended, + guid ("{E67E1BDB-D130-4143-9EB2-8BEE1899FD52}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class fires an event when an initiator failure occurs.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorInstanceFailureEvent : __ExtrinsicEvent +{ + [read,key] String InstanceName; + [read] boolean Active; + + [read, + WmiDataId(1), + description("**typedef** Type of failure"), + ValueMap{"0", "1","2"}, Values{ "SessionDigestError", "SessionCxnTimeoutError", "SessionFormatError" }, DefineValues {"SessionDigestError", "SessionCxnTimeoutError", "SessionFormatError"}, + WmiVersion(1)] uint8 FailureType; + + [read, + WmiDataId(2), + description("Name of target involved in failure"), + WmiVersion(1), + MaxLen(223)] string RemoteNodeName; +}; + + + + + +[ + WMI, + guid("{C8775641-5430-4220-BA25-7DA561CB64CE}"), + Description("This class describes an iSCSI Path (A TCP Connection to the target)") : amended +] +class ISCSI_Path +{ + [WmiDataId(1), + Description("iSCSI Unique connection id") : amended + ] + uint64 UniqueConnectionId; + + [WmiDataId(2), + Description("Estimated speed of the connection in MegaBits Per Second") : amended + ] + uint64 EstimatedLinkSpeed; + + [WmiDataId(3), + Description("Weight assigned to the path") : amended + ] + uint32 PathWeight; + + [WmiDataId(4), + Description("Flag set to 1 if the path is a primary path, 0 otherwise.") : amended + ] + uint32 PrimaryPath; + + [WmiDataId(5), + Description("Status of the path - connected, disconnected, reconnecting") : amended, + Values{"Connected", + "Disconnected", + "Reconnecting"} : amended, + DefineValues{"CONNECTION_STATE_CONNECTED", + "CONNECTION_STATE_DISCONNECTED", + "CONNECTION_STATE_RECONNECTING" + }, + ValueMap{"1", "2", "3"} + ] + uint32 ConnectionStatus; + + [WmiDataId(6), + Description("Flag set to 1 if TCP offload is supported for this connection, 0 otherwise.") : amended + ] + uint32 TCPOffLoadAvailable; +}; + +[WMI, + guid("{749AFE4D-804D-4662-A68B-DC696655C79A}"), + Description("iSCSI Initiator Load Balance Policies supported") : amended +] +class ISCSI_Supported_LB_Policies { + + [WmiDataId(1), + description("Id that is unique to this session within this adapter. ") : amended + ] + uint64 UniqueSessionId; + + [WmiDataId(2), + Description("Load Balance policy supported by the iSCSI Initiator") : amended, + Values{"Fail Over Only", + "Round Robin", + "Round Robin with Subset", + "Dynamic Least Queue Depth", + "Weighted Paths", + "Vendor Specific"} : amended, + DefineValues{"MSiSCSI_LB_FAILOVER", + "MSiSCSI_LB_ROUND_ROBIN", + "MSiSCSI_LB_ROUND_ROBIN_WITH_SUBSET", + "MSiSCSI_LB_DYN_LEAST_QUEUE_DEPTH", + "MSiSCSI_LB_WEIGHTED_PATHS", + "MSiSCSI_LB_VENDOR_SPECIFIC"}, + ValueMap{"1", "2", "3", "4", "5", "6"} + ] + uint32 LoadBalancePolicy; + + + + + + + + [WmiDataId(3), + Description("Number of entries in MSiSCSI_Paths array") : amended + ] + + uint32 iSCSI_PathCount; + + [WmiDataId(4), + WmiSizeIs("iSCSI_PathCount"), + Description("Describes iSCSI Initiator Paths") : amended + ] + ISCSI_Path iSCSI_Paths[]; +}; + +[WMI, + Dynamic, + Provider("WmiProv"), + Description("Set iSCSI Initiator Load Balance Policies"), + guid("{A7DFE761-B6BC-4490-91B0-D9CF4A24D37C}") +] +class MSiSCSI_LB_Operations { + + [key, read] + string InstanceName; + + [read] + boolean Active; + + + + + [WmiMethodId(10), + Implemented, + Description("Sets Load Balance Policy for the iSCSI Initiator") : amended, + cpp_quote( + "//\n" + "// SetLoadBalancePolicy instructs the iSCSI Initiator what Load Balance\n" + "// policy to use.\n" + "//\n" + ) + ] + void SetLoadBalancePolicy( + [in, + Description("New Load Balance policy to be set") + ] ISCSI_Supported_LB_Policies LoadBalancePolicies, + + [out, + Description("Status of the operation") + ] uint32 Status + ); +}; + +[ + WMI, + guid("{E0AECAEE-B311-426f-B67A-18D5E55D0996}"), + Dynamic, + DisplayName("iSCSI Initiator Query LoadBalance Policy") : amended, + Provider("wmiprov"), + description("Query Load Balance policy used by iSCSI Initiator") : amended, + cpp_quote( +"//\n" +"// MSiSCSI_QueryLBPolicy class is used to query the Initiator about\n" +"// the load balance policy that is currently used.\n" +"//\n" + ) +] +class MSiSCSI_QueryLBPolicy +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + Description("Id that is globally unique to each instance of each adapter. Using the address of the Adapter Extension is a good idea.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + read, + DisplayName("Reserved field") : amended + ] uint32 Reserved; + + [WmiDataId(3), + read, + DisplayName("Count of Elements in LoadBalancePolicies array") : amended, + cpp_quote("\n // Number of elements in LoadBalancePolicies array\n"), + Description("Number of elements in LoadBalancePolicies array") : amended + ] uint32 SessionCount; + + [WmiDataId(4), + DisplayName("Load Balance Policy for each session") : amended, + description("Load Balance Policy that is currently being used by iSCSI Initiator - one element for each session on the adapter") : amended, + WmiSizeIs("SessionCount") + ] + ISCSI_Supported_LB_Policies LoadBalancePolicies[]; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[WMI, + guid("{E6B8552B-7C62-4c6e-99EB-67CE6087894C}"), + description("iSCSI Eventlog generation event") : amended, + Dynamic, + Provider("wmiprov"), + cpp_quote( +"//\n" +"// Miniports can fire this event to cause eventlog entries to be\n" +"// included in the system eventlog. This is useful as the iscsilog.h\n" +"// header has many iSCSI specific eventlog messages that are useful for\n" +"// troubleshooting, but can't be fired directly by a miniport. By\n" +"// firing this WMI event appropriately a miniport can cause a useful\n" +"// eventlog entry to be included in the system eventlog\n" +"//\n") +] +class MSiSCSI_Eventlog : __ExtrinsicEvent +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + Values{ "ISCSI_ERR_TDI_CONNECT_FAILED", "ISCSI_ERR_INSUFFICIENT_SESSION_RESOURCES", "ISCSI_ERR_INVALID_COMMAND_SEQUENCE_NUMBER", "ISCSI_ERR_INVALID_BURST_LENGTH", "ISCSI_ERR_SETUP_NETWORK_NODE", "ISCSI_ERR_INSUFFICIENT_CONNECTION_RESOURCES", "ISCSI_ERR_SEND_FAILED", "ISCSI_ERR_ISCSI_REQUEST_TIMEOUT", "ISCSI_ERR_SCSI_REQUEST_TIMEOUT", "ISCSI_ERR_LOGIN_FAILED", "ISCSI_ERR_LOGIN_PDU_ERROR", "ISCSI_ERR_INVALID_LOGIN_REDIRECT_DATA", "ISCSI_ERR_INVALID_AUTHMETHOD", "ISCSI_ERR_INVALID_CHAP_ALGORITHM", "ISCSI_ERR_INVALID_CHAP_CHALLENGE", "ISCSI_ERR_INVALID_KEY_DURING_CHAP", "ISCSI_ERR_INVALID_CHAP_RESPONSE", "ISCSI_ERR_HEADER_DIGEST_NEEDED", "ISCSI_ERR_HEADER_DATA_NEEDED", "ISCSI_ERR_CONNECTION_LOST", "ISCSI_ERR_INVALID_DATA_SEGMENT_LENGTH", "ISCSI_ERR_HEADER_DIGEST_ERROR", "ISCSI_ERR_ISCSI_PDU_ERROR", "ISCSI_ERR_UNKNOWN_ISCSI_OPCODE", "ISCSI_ERR_DATA_DIGEST_ERROR", "ISCSI_ERR_EXCESS_DATA_SENT", "ISCSI_ERR_UNEXPECTED_PDU", "ISCSI_ERR_INVALID_RTT_PDU", "ISCSI_ERR_ISCSI_PDU_REJECTED", "ISCSI_ERR_INSUFFICIENT_WORKITEM_RESOURCES", "ISCSI_ERR_INSUFFICIENT_REQ_PACKET_RESOURCES", "ISCSI_WRN_RECEIVED_ASYNC_LOGOUT", "ISCSI_ERR_INVALID_CHAP_CHALLENGE_SIZE", "ISCSI_INFO_RECONNECTED_TO_TARGET", "ISCSI_ERR_INVALID_TARGET_CHAP_SECRET", "ISCSI_ERR_INVALID_INITIATOR_CHAP_SECRET", "ISCSI_ERR_FIPS_NOT_AVAILABLE", "ISCSI_ERR_CHAP_NOT_OFFERED", "ISCSI_ERR_DEVICE_RESET", "ISCSI_ERR_CHAP_OFFERED", "ISCSI_ERR_AUTH_METHOD_NOT_OFFERED", "ISCSI_ERR_INVALID_STATUS_SEQ_NUM" }, ValueMap{ "0xC0000001", "0xC0000002", "0xC0000003", "0xC0000004", "0xC0000005", "0xC0000006", "0xC0000007", "0xC0000008", "0xC0000009", "0xC000000A", "0xC000000B", "0xC000000C", "0xC000000D", "0xC000000E", "0xC000000F", "0xC0000010", "0xC0000011", "0xC0000012", "0xC0000013", "0xC0000014", "0xC0000015", "0xC0000016", "0xC0000017", "0xC0000018", "0xC0000019", "0xC000001A", "0xC000001B", "0xC000001C", "0xC000001D", "0xC000001E", "0xC000001F", "0x80000020", "0xC0000021", "0x40000022", "0xC0000023", "0xC0000024", "0xC0000025", "0xC0000026", "0xC0000027", "0xC0000028", "0xC0000029", "0xC000002A" }, Description("Type of eventlog message") : amended + ] + uint32 Type; + + [WmiDataId(2), + Description("If zero then this event is not logged to system eventlog") : amended + ] + uint32 LogToEventlog; + + [WmiDataId(3), + Description("Size of Additional Data") : amended + ] + uint32 Size; + + [WmiDataId(4), + WmiSizeIs("Size"), + Description("Additional data to include in eventlog message, typically iSCSI Header") : amended + ] + uint8 AdditionalData[]; +}; + +[ + WMI, + Description ("iSCSI Redirect Portal Info") : amended, + guid ("{F6004CE6-9507-4d86-AE1E-E9D64F166F2F}") +] +class ISCSI_RedirectPortalInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated connection ID. Do not confuse this with CID."): amended, + WmiVersion(1) + ] uint64 UniqueConnectionId; + + [read, + WmiDataId(2), + Description("Original Target IP Address given in the login"): amended, + WmiVersion(1)] ISCSI_IP_Address OriginalIPAddr; + + [read, + WmiDataId(3), + Description("Original Target portal's socket number given in the login"): amended, + WmiVersion(1)] uint32 OriginalPort; + + [read, + WmiDataId(4), + Description("Redirected Target IP Address"): amended, + WmiVersion(1)] ISCSI_IP_Address RedirectedIPAddr; + + [read, + WmiDataId(5), + Description("Redirected Target portal's socket number"): amended, + WmiVersion(1)] uint32 RedirectedPort; + + [read, + WmiDataId(6), + Description("TRUE if login was redirected. RedirectedIPAddr and RedirectedPort are valid then."): amended, + WmiVersion(1)] uint8 Redirected; + + [read, + WmiDataId(7), + Description("TRUE if the redirection is temporary. FALSE otherwise"): amended, + WmiVersion(1)] uint8 TemporaryRedirect; +}; + +[ + WMI, + Description ("iSCSI Redirect Session Info") : amended, + guid ("{ED60BC3F-3D56-42f0-B4D0-81DD16E28515}") +] +class ISCSI_RedirectSessionInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated session ID, it is the same id returned by the LoginToTarget method. Do not confuse this with ISID or SSID."): amended, + WmiVersion(1)] uint64 UniqueSessionId; + + [read, + WmiDataId(2), + Description("Target portal group tag for this Session "): amended, + WmiVersion(1)] uint32 TargetPortalGroupTag; + + [read, + WmiDataId(3), + DisplayName("Number of elements in RedirectPortalList array") : amended, + cpp_quote("\n // Number of elements in RedirectPortalList array\n"), + Description("Number of elements in RedirectPortalList array") : amended, + WmiVersion(1) + ] uint32 ConnectionCount; + + [read, + WmiDataId(4), + DisplayName("Redirect Portal info for each connection") : amended, + Description("Redirect portal info - one element for each connection in the session") : amended, + WmiSizeIs("ConnectionCount"), + WmiVersion(1) + ] ISCSI_RedirectPortalInfo RedirectPortalList[]; +}; + +[ + WMI, Dynamic, Provider("WMIProv"), + Description ("iScsi Redirect Portal Information Class") : amended, + guid ("{DAF7F63A-F9EA-4869-87E1-AE8A7C2261E2}"), +cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class exposes portal information. It provides the original and \n" +"// redirected target portal information for an iSCSI Connection.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_RedirectPortalInfoClass +{ + [read,key] String InstanceName; + + [read] boolean Active; + + [read, + WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique for all instances of iSCSI initiators.") : amended, + WmiVersion(1) + ] + uint64 UniqueAdapterId; + + [read, + WmiDataId(2), + DisplayName("Number of session on the adapter : Number of elements in RedirectSessionInfo array") : amended, + Description("Number of elements in RedirectSessionInfo array") : amended, + WmiVersion(1) + ] uint32 SessionCount; + + [read, + WmiDataId(3), + DisplayName("List Of ISCSI_RedirectSessionInfo ") : amended, + Description("Variable length array of ISCSI_RedirectSessionInfo. SessionCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("SessionCount"), + WmiVersion(1) + ] ISCSI_RedirectSessionInfo RedirectSessionList[]; +}; + +[ + WMI, + guid("{B8D765F0-2D93-4da2-8186-A187622B4302}"), + Dynamic, + Provider("wmiprov"), + cpp_quote( +"\n" +"//\n" +"//\n" +"// This class is recommended.\n" +"//\n" +"// iSCSI management applications rely upon this\n" +"// class in order to interface with the adapter. Implement one instance\n" +"// per miniport instance (adapter). \n" +"//\n" +"// This class must be registered using PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_ManagementOperations +{ + + + + [key] + string InstanceName; + + boolean Active; + + [WmiMethodId(10), + Implemented, + Description("Perform an ICMP ping") : amended, + cpp_quote( +"//\n" +"// This method is recommended.\n" +"//\n" +"// Ping will perform ICMP ping requests to the destination address \n" +"// and return the number of ping responses received. This is only supported\n" +"// by some HBA, use the ping command for the software initiator.\n" +"//\n" + ) + ] + void PingIPAddress( + [in, + Description("Number of requests to send") : amended + ] uint32 RequestCount, + + [in, + Description("Number of bytes in each request") : amended + ] uint32 RequestSize, + + [in, + Description("Number of ms to wait for response") : amended + ] uint32 Timeout, + + [in, + description("IP address to ping") : amended + ] ISCSI_IP_Address Address, + + [out, + Description("Status code resulting from operation") : amended, Values { "Success", "Non Specific Error", "Login Failed", "Connection Failed", "Initiator Node Already Exists", "Initiator Node Does Not Exist", "Target Moved Temporarily", "Target Moved Permamently", "Initiator Error", "Authentication Failure", "Authorization Failure", "Not Found", "Target Removed", "Unsupported Version", "Too many Connections", "Missing Parameter", "Can not include in session", "Session type not supported", "Target Error", "Service Unavailable", "Out of Resources", "Connections already exist on initiator node", "Session Already Exists", "Initiator Instance Does Not Exist", "Target Already Exists", "The iscsi driver implementation did not complete an operation correctly", "An invalid key text was encountered", "Invalid SendTargets response text was encountered", "Invalid Session Id", "The scsi request failed", "Exceeded max sessions for this initiator.", "Session is busy since a request is already in progress.", "The target mapping is not available", "The Target Address type given is not supported", "Logon Failed", "TCP Send Failed", "TCP Transport Error", "iSCSI Version Mismatch", "The Target Mapping Address passed is out of range for the adapter configuration", "The preshared key for the target or IKE identification payload is not available.", "The authentication information for the target is not available", "The target name is not found or is marked as hidden from login.", "One or more parameters specified in LoginTargetIN structure is invalid.", "Given target mapping already exists.", "The HBA security information cache is full.", "The port number passed is not valid for the initiator.", "Operation was not successful for all initiators.", "The HBA security information cache is not supported by this adapter.", "The IKE id payload type specified is not supported.", "The IKE id payload size specified is not correct.", "Target Portal Structure Already Exists.", "Target Address Structure Already Exists.", "There is no IKE authentication information available.", "There is no tunnel mode outer address specified.", "Authentication or tunnel address cache is corrupted.", "The request or operation is not supported.", "The target does not have enough resources to process the given request.", "The initiator service did not respond to the request sent by the driver.", "The iSNS server was not found or is unavailable.", "The operation was successful but requires a driver reload or reboot to become effective.", "There is no target portal available to complete the login.", "Cannot remove the last connection for a session.", "The Microsoft iSCSI Initiator Service is not running. Please start the service and retry.", "The target has already been logged in via an iSCSI session.", "The session cannot be logged out since a device on that session is currently being used.", "Failed to save persistent login information.", "Failed to remove persistent login information.", "The specified initiator name was not found.", "The specified portal was not found.", "The specified discovery mechanism was not found.", "iSCSI does not support IPSEC for this version of the OS.", "The iSCSI service timed out waiting for all persistent logins to complete.", "The specified CHAP secret is less than 96 bits and will not be usable for authenticating over non ipsec connections.", "The evaluation period for the iSCSI initiator service has expired.", "CHAP secret given does not conform to the standard. Please see system event log for more information.", "Target CHAP secret given is invalid.", "Initiator CHAP secret given is invalid.", "CHAP Username given is invalid.", "Logon Authentication type given is invalid.", "Target Mapping information given is invalid.", "Target Id given in Target Mapping is invalid.", "The iSCSI name specified contains invalid characters or is too long.", "The iSNS version number returned from the iSNS server is not compatible with this version of the iSNS client.", "Initiator failed to configure IPSec for the given connection. This could be because of low resources.", "The buffer given for processing the request is too small.", "The given Load Balance policy is not recognized by iScsi initiator.", "One or more paramaters specified is not valid.", "Duplicate PathIds were specified in the call to set Load Balance Policy.", "Number of paths specified in Set Load Balance Policy does not match the number of paths to the target.", "Path Id specified in the call to set Load Balance Policy is not valid.", "Multiple primary paths specified when only one primary path is expected.", "No primary path specified when at least one is expected.", "Volume is already a persistently bound volume.", "Volume was not found.", "The volume specified does not originate from an iSCSI disk.", "The DNS name specified was not resolved.", "There is no connection available in the iSCSI session to process the request.", "The given Load Balance policy is not supported.", "A remove connection request is already in progress for this session.", "Given connection was not found in the session.", "The leading connection in the session cannot be removed." }, ValueMap { "0", "0xEFFF0001", "0xEFFF0002", "0xEFFF0003", "0xEFFF0004", "0xEFFF0005", "0xEFFF0006", "0xEFFF0007", "0xEFFF0008", "0xEFFF0009", "0xEFFF000A", "0xEFFF000B", "0xEFFF000C", "0xEFFF000D", "0xEFFF000E", "0xEFFF000F", "0xEFFF0010", "0xEFFF0011", "0xEFFF0012", "0xEFFF0013", "0xEFFF0014", "0xEFFF0015", "0xEFFF0016", "0xEFFF0017", "0xEFFF0018", "0xEFFF0019", "0xEFFF001A", "0xEFFF001B", "0xEFFF001C", "0xEFFF001D", "0xEFFF001E", "0xEFFF001F", "0xEFFF0020", "0xEFFF0021", "0xEFFF0022", "0xEFFF0023", "0xEFFF0024", "0xEFFF0025", "0xEFFF0026", "0xEFFF0027", "0xEFFF0028", "0xEFFF0029", "0xEFFF002A", "0xEFFF002B", "0xEFFF002C", "0xEFFF002D", "0xEFFF002E", "0xEFFF002F", "0xEFFF0030", "0xEFFF0031", "0xEFFF0032", "0xEFFF0033", "0xEFFF0034", "0xEFFF0035", "0xEFFF0036", "0xEFFF0037", "0xEFFF0038", "0xEFFF0039", "0xEFFF003A", "0xAFFF003B", "0xEFFF003C", "0xEFFF003D", "0xEFFF003E", "0xEFFF003F", "0xEFFF0040", "0xEFFF0041", "0xEFFF0042", "0xEFFF0043", "0xEFFF0044", "0xEFFF0045", "0xEFFF0046", "0xEFFF0047", "0xAFFF0048", "0xEFFF0049", "0xEFFF004A", "0xEFFF004B", "0xEFFF004C", "0xAFFF004D", "0xEFFF004E", "0xEFFF004F", "0xEFFF0050", "0xEFFF0051", "0xEFFF0052", "0xEFFF0053", "0xEFFF0054", "0xEFFF0055", "0xEFFF0056", "0xEFFF0057", "0xEFFF0058", "0xEFFF0059", "0xEFFF005A", "0xEFFF005B", "0xEFFF005C", "0xEFFF005D", "0xEFFF005E", "0xEFFF005F", "0xEFFF0060", "0xEFFF0061", "0xEFFF0062", "0xEFFF0063", "0xEFFF0064" } + ] uint32 Status, + + [out, + Description("Number of responses received") : amended + ] uint32 ResponsesReceived + + ); + + +}; + diff --git a/storage/iscsi/src/iscsiprf.mof b/storage/iscsi/src/iscsiprf.mof Binary files differnew file mode 100644 index 00000000..fef8f750 --- /dev/null +++ b/storage/iscsi/src/iscsiprf.mof diff --git a/storage/iscsi/src/mgmt.mof b/storage/iscsi/src/mgmt.mof new file mode 100644 index 00000000..74f3cf07 --- /dev/null +++ b/storage/iscsi/src/mgmt.mof @@ -0,0 +1,1413 @@ +//*************************************************************************** +// +// mgmt.mof +// +// Module: iScsi Discovery api +// +// Purpose: +// +// Copyright (c) 2001 Microsoft Corporation +// +//*************************************************************************** + +#define MODULE_HEADER \ +"\n" \ +"//***************************************************************************\n" \ +"//\n" \ +"// iscsimgt.h\n" \ +"// \n" \ +"// Module: iScsi Discovery api\n" \ +"//\n" \ +"// Purpose: Internal header defining interface between user mode discovery\n" \ +"// api dll and HBA driver miniport.\n" \ +"//\n" \ +"// Copyright (c) 2001 Microsoft Corporation\n" \ +"//\n" \ +"//***************************************************************************\n\n" + +// +// Do not cause headers to be generated from common.mof +// +#define GENERATE_HEADER FALSE + +// +// Include common definitions +// +#include "common.mof" + +#pragma autorecover + +[ + WMI, + cpp_quote(MODULE_HEADER + "#include <iscsidef.h>\n\n" +"//\n" +"//\n" +"// This class is required.\n" +"//\n" +"// Adapter Information class. The iSCSI initiator service relies upon this\n" +"// class in order to interface with your adapter. Implement one instance\n" +"// per adapter instance.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ), + guid("{58515BF3-2F59-4f37-B74F-85AEEC652AD6}"), + Dynamic, + DisplayName("HBA Information") : amended, + Provider("wmiprov") +] +class MSiSCSI_HBAInformation +{ + // + // This class must be registered using PDO instance names + // + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique for all instances of iSCSI initiators. Use the address of the Adapter Extension or another address owned by the device driver.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + DisplayName("Integrated Networking") : amended, + description("TRUE if TCP/IP traffic is integrated with the Windows networking TCP/IP stack via a software only initiator. An adapter with its own TCP/IP stack would set this to FALSE.") : amended + ] + boolean IntegratedTCPIP; + + [WmiDataId(3), + Displayname("Requires Binary Addresses") : amended, + description("If TRUE the iSCSI Initiator service will perform any DNS lookup and pass binary IP addresses to the adapter; the adapter must be on the same network as the Windows TCP/IP stack. If FALSE then DNS must be available on adapter.") : amended + ] + boolean RequiresBinaryIpAddresses; + + [read, + WmiDataId(4), + DisplayName("Minimum iSCSI Version") : amended, + description("Minimum version number of the iScsi spec supported by adapter") : amended + ] uint8 VersionMin; + + [read, + WmiDataId(5), + DisplayName("Maximum iSCSI Version") : amended, + description("Maximum version number of the iSCSI spec supported by adapter") : amended + ] uint8 VersionMax; + + [read, + WmiDataId(6), + DisplayName("Multifunction Device") : amended, + description("TRUE if this adapter is a multifunction device, that is it also exposes a netcard interface") : amended + ] boolean MultifunctionDevice; + + [read, + WmiDataId(7), + DisplayName("Valid Cache") : amended, + description("TRUE if the adapter caches are valid") : amended + ] boolean CacheValid; + + [read, + WmiDataId(8), + Displayname("Number of ports") : amended, + description("Number of ports (or TCP/IP addresses) on the adapter") : amended + ] uint32 NumberOfPorts; + + + [read, + WmiDataId(9), + Displayname("Status") : amended, + description("**typedef** Current status of adapter") : amended, + Values{ "Working", "Degraded", "Critical", "Failed"}, + ValueMap{ "0", "1", "2", "3" }, + cpp_quote( +"#define ISCSI_HBA_STATUS_WORKING 0\n" +"#define ISCSI_HBA_STATUS_DEGRADED 1\n" +"#define ISCSI_HBA_STATUS_CRITICAL 2\n" +"#define ISCSI_HBA_STATUS_FAILED 3\n" +) + ] uint32 Status; + + [read, + WmiDataId(10), + DisplayName("Functionality Supported") : amended, + Description("**typedef** Bit flags that indicate various functionality supported") : amended, + BitValueMap{"0x00000001", + "0x00000002", + "0x00000004", + "0x00000008", + "0x00000010", + "0x00000020" + }, + BitValues{"Preshared Key Cache", + "iSCSI Authentication Cache", + "Tunnel Mode", + "CHAP authentication via RADIUS", + "Discovery via iSNS", + "Discovery via SLP" + } : amended, + cpp_quote( +"\n" +"//\n" +"// Flags that define the functionality supported by the HBA\n" +"//\n" +"#define ISCSI_HBA_PRESHARED_KEY_CACHE 0x00000001\n" +"#define ISCSI_HBA_ISCSI_AUTHENTICATION_CACHE 0x00000002\n" +"#define ISCSI_HBA_IPSEC_TUNNEL_MODE 0x00000004\n" +"#define ISCSI_HBA_CHAP_VIA_RADIUS 0x00000008\n" +"#define ISCSI_HBA_ISNS_DISCOVERY 0x00000010\n" +"#define ISCSI_HBA_SLP_DISCOVERY 0x00000020\n" +"\n" +) + ] uint32 FunctionalitySupported; + + [read, + WmiDataId(11), + DisplayName("Generational Guid") : amended, + Description("This is the GUID value last set by the SetGenerationalGuid method in the MSiSCSI_Operations class.") : amended + ] uint8 GenerationalGuid[16]; + + [read, + WmiDataId(12), + DisplayName("Max CDB Length") : amended, + Description("Maxumum CDB length supported by the adapter") : amended + ] uint32 MaxCDBLength; + + [read, + WmiDataId(13), + DisplayName("Bi-directionsal SCSI comamnd supported") : amended, + Description("TRUE if Bi-directionsal SCSI comamnd supported") : amended + ] boolean BiDiScsiCommands; + + [read, + WmiDataId(14), + DisplayName("Manufacturer") : amended, + description("A text string describing the manufacturer of adapter") : amended, + MaxLen(255)] string VendorID; + + [read, + WmiDataId(15), + Displayname("Model") : amended, + description("A text string set by the manufacturer describing the model of adapter") : amended, + MaxLen(255)] string VendorModel; + + [read, + WmiDataId(16), + Displayname("Version") : amended, + description("A text string set by the manufacturer describing the version of adapter") : amended, + MaxLen(255)] string VendorVersion; + + [read, + WmiDataId(17), + displayName("Firmware Version") : amended, + description("A text string set by the manufacturer describing the firmware version of adapter") : amended, + MaxLen(255)] string FirmwareVersion; + + [read, + WmiDataId(18), + displayName("ASIC Version") : amended, + description("A text string set by the manufacturer describing the Asic version") : amended, + MaxLen(255)] string AsicVersion; + + [read, + WmiDataId(19), + displayName("Option Rom Version") : amended, + description("A text string set by the manufacturer describing the option rom version of adapter") : amended, + MaxLen(255)] string OptionRomVersion; + + [read, + WmiDataId(20), + Displayname("Serial Number") : amended, + description("A text string set by the manufacturer describing the serial number of adapter") : amended, + MaxLen(255)] string SerialNumber; + + [read, + WmiDataId(21), + Displayname("Driver Name") : amended, + description("A text string specifying the name of the driver for the adapter") : amended, + MaxLen(255)] string DriverName; +}; + + +[WMI, Dynamic, Provider("wmiprov"), + DisplayName("HBA Session Default Configuration") : amended, + guid("{B35694DE-D323-49d2-ABB2-8139209AD150}"), + cpp_quote( +"//\n" +"//\n" +"// This class is optional.\n" +"//\n" +"// This class allows the default session configuration to be managed. It \n" +"// contains the default values to use when establishing a session.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_HBASessionConfig +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + read, write, + Description("The InitialR2T key is used to turn off the default use of R2T, thus allowing an initiator to start sending data to a target as if it has received an initial R2T with Buffer Offset=0 and Desired Data Transfer Length=min (FirstBurstSize, Expected Data Transfer Length).") : amended + ] + boolean InitialR2T; + + [WmiDataId(2), + read, write, + Description("The initiator and target negotiate support for immediate data. To turn immediate data off, the initiator or target must state its desire to do so. ImmediateData can be turned on if both the initiator and target have ImmediateData=Yes.") : amended + ] + boolean ImmediateData; + + [WmiDataId(3), + read, write, + Description("Maximum data segment length in bytes they can receive in an iSCSI PDU.") : amended + ] + uint32 MaxRecvDataSegmentLength; + + [WmiDataId(4), + read, write, + Description("Maximum SCSI data payload in bytes in an Data-In or a solicited Data-Out iSCSI sequence.") : amended + ] + uint32 MaxBurstLength; + + [WmiDataId(5), + read, write, + Description("maximum amount in bytes of unsolicited data an iSCSI initiator may send to the target, during the execution of a single SCSI command. This covers the immediate data (if any) and the sequence of unsolicited Data-Out PDUs (if any) that follow the command.") : amended + ] + uint32 FirstBurstLength; + + [WmiDataId(6), + read, write, + Description("Initiator and target negotiate the maximum number of outstanding R2Ts per task, excluding any implied initial R2T that might be part of that task. An R2T is considered outstanding until the last data PDU (with the F bit set to 1) is transferred, or a sequence reception timeout (section 6.12.1) is encountered for that data sequence.") : amended + ] + uint32 MaxOutstandingR2T; +}; + + +#define ISCSI_DHCP_STATUS uint8 +// +// Common qualifiers needed for WMIDHCPStatus values +// +#define ISCSI_DHCP_STATUS_QUALIFIERS \ + Description("Enumeration of all the DHCP status") : amended, \ + ValueMap{"0", "1"},\ + Values{ \ + "DHCPEnabled", \ + "DHCPDisabled" \ + },\ + DefineValues {"DHCPEnabled", \ + "DHCPDisabled"} + +#define ISCSI_AUTO_METRIC_STATUS uint8 +// +// Common qualifiers needed for ISCSI_AUTO_METRIC_STATUS values +// +#define ISCSI_AUTO_METRIC_STATUS_QUALIFIERS \ + Description("Enumeration of all the Auto Metric status") : amended, \ + ValueMap{"0", "1"},\ + Values{ \ + "AutoMetricEnabled", \ + "AutoMetricDisabled" \ + },\ + DefineValues {"AutoMetricEnabled", \ + "AutoMetricDisabled"} + +#define ISCSI_LMHOSTLOOKUP_STATUS uint8 +// +// Common qualifiers needed for ISCSI_LMHOSTLOOKUP_STATUS values +// +#define ISCSI_LMHOST_LOOKUP_QUALIFIERS \ + Description("Enumeration of all the LM Host Lookup status") : amended, \ + ValueMap{"0", "1"},\ + Values{ \ + "LMHostLookupEnabled", \ + "LMHostLookupDisabled" \ + },\ + DefineValues {"LMHostLookupEnabled", \ + "LMHostLookupDisabled"} + +#define ISCSI_TCP_IP_FLITERING_STATUS uint8 +// +// Common qualifiers needed for ISCSI_TCP_IP_FLITERING_STATUS values +// +#define ISCSI_TCP_IP_FLITERING_STATUS_QUALIFIER \ + Description("Enumeration of all the ISCSI_TCP_IP_FLITERING status") : amended, \ + ValueMap{"0", "1"},\ + Values{ \ + "TcpIPFilteringEnabled", \ + "TcpIPFilteringDisabled" \ + },\ + DefineValues {"TcpIPFilteringEnabled", \ + "TcpIPFilteringDisabled"} + +#define ISCSI_CONNECTION_STATE_TYPE uint8 +// +// Common qualifiers needed for ISCSI_CONNECTION_STATE_TYPE values +// +#define ISCSI_CONNECTION_STATE_TYPE_QUALIFIERS \ + ValueMap{"0", "1","2"},\ + Values{ \ + "login", \ + "full", \ + "logout" \ + },\ + DefineValues {"login", \ + "full",\ + "logout"} + +#define ISCSI_CONNECTION_PROTOCOL_TYPE uint8 +// +// Common qualifiers needed for ISCSI_CONNECTION_PROTOCOL_TYPE values +// +#define ISCSI_CONNECTION_PROTOCOL_TYPE_QUALIFIERS \ + ValueMap{"6"},\ + Values{ \ + "TCP" \ + },\ + DefineValues {"TCP"} + +#define ISCSI_SESSION_TYPE uint8 +// +// Common qualifiers needed for ISCSI_SESSION_TYPE values +// +#define ISCSI_SESSION_TYPE_QUALIFIERS \ + ValueMap{"0", "1","2","3"},\ + Values{ \ + "discoverySession", \ + "informationalSession", \ + "dataSession", \ + "bootSession" \ + },\ + DefineValues { \ + "discoverySession",\ + "informationalSession", \ + "dataSession", \ + "bootSession" \ + } + + +#define ISCSI_HEADER_INTEGRITY_TYPE uint8 +// +// Common qualifiers needed for ISCSI_HEADER_INTEGRITY_TYPE values +// +#define ISCSI_HEADER_INTEGRITY_TYPE_QUALIFIERS \ + ValueMap{"0", "1"},\ + Values{ \ + "None", \ + "crc32c" \ + },\ + DefineValues {"None", \ + "crc32c" } + +#define ISCSI_DATA_INTEGRITY_TYPE uint8 +// +// Common qualifiers needed for ISCSI_DATA_INTEGRITY_TYPE values +// +#define ISCSI_DATA_INTEGRITY_TYPE_QUALIFIERS \ + ValueMap{"0", "1"},\ + Values{ \ + "None", \ + "crc32c" \ + },\ + DefineValues {"None", \ + "crc32c" } + + +#define ISCSI_PORTAL_TYPE uint8 +// +// Common qualifiers needed for ISCSI_PORTAL_TYPE values +// +#define ISCSI_PORTAL_TYPE_QUALIFIERS \ + ValueMap{"0", "1"},\ + Values{ \ + "Initiator", \ + "Target" \ + },\ + DefineValues {"InitiatorPortals", \ + "TargetPortals"} + +#define ISCSI_INITIATOR_NODE_FAILURE_TYPE uint8 +// +// Common qualifiers needed for ISCSI_INITIATOR_NODE_FAILURE_TYPE values +// +#define ISCSI_INITIATOR_NODE_FAILURE_TYPE_QUALIFIERS \ + ValueMap{"0", "1","2"},\ + Values{ \ + "SessionDigestError", \ + "SessionCxnTimeoutError", \ + "SessionFormatError" \ + },\ + DefineValues {"SessionDigestError", \ + "SessionCxnTimeoutError", \ + "SessionFormatError"} + + +#define ISCSI_INITIATOR_FAILURE_TYPE uint8 +// +// Common qualifiers needed for ISCSI_INITIATOR_FAILURE_TYPE values +// +#define ISCSI_INITIATOR_FAILURE_TYPE_QUALIFIERS \ + ValueMap{"0", "1","2","3","4"},\ + Values{ \ + "LoginOtherFail", \ + "LoginAuthFail", \ + "LoginAuthenticateFail", \ + "LoginNegotiateFail", \ + "LogoutOthers" \ + },\ + DefineValues {"LoginOtherFail", \ + "LoginAuthFail", \ + "LoginAuthenticateFail", \ + "LoginNegotiateFail", \ + "LogoutOthers"} + +[ + WMI, + Description ("iSCSI Static Connection Statistics Information") : amended, + guid ("{3CE2D6A0-7346-4826-972F-F2C19779D1D1}") +] +class ISCSI_ConnectionStaticInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated connection ID. Do not confuse this with CID."): amended + ] uint64 UniqueConnectionId; + + [read, + WmiDataId(2), + Description("The iSCSI connection ID for this connection instance."): amended + ] uint16 CID; //session wide namespace + + [read, + WmiDataId(3), + ISCSI_CONNECTION_STATE_TYPE_QUALIFIERS, + Description("**typedef** Indicates the current state of this connection"): amended, + cpp_quote("\n" + " //login - The TCP connection has been established, but a valid iSCSI\n" + " // login response with the final bit set has not been sent or received.\n" + " //full - A valid iSCSI login response with the final bit set \n" + " // has been sent or received.\n" + " //logout - A valid iSCSI logout command has been sent or received, but\n" + " // the TCP connection has not yet been closed.\n" + "\n" + ) + ] ISCSI_CONNECTION_STATE_TYPE State; + + + [read, + WmiDataId(4), + ISCSI_CONNECTION_PROTOCOL_TYPE_QUALIFIERS, + Description("**typedef** The transport protocol over which this connection instance is running."): amended + ] ISCSI_CONNECTION_PROTOCOL_TYPE Protocol; + + [read, + WmiDataId(5), + ISCSI_HEADER_INTEGRITY_TYPE_QUALIFIERS, + description("**typedef** The name of the iSCSI header digest scheme in use within this session."), + WmiVersion(1) + ] ISCSI_HEADER_INTEGRITY_TYPE HeaderIntegrity; + + [read, + WmiDataId(6), + ISCSI_DATA_INTEGRITY_TYPE_QUALIFIERS, + description("**typedef** The name of the iSCSI data digest scheme in use within this session."), + WmiVersion(1) + ] ISCSI_DATA_INTEGRITY_TYPE DataIntegrity; + + [read, + WmiDataId(7), + description("Must be zero") + ] uint16 Reserved; + + [read, + WmiDataId(8), + description("The maximum data payload size supported for command or data PDUs within this session."), + WmiVersion(1)] uint32 MaxRecvDataSegmentLength; + + [read, + WmiDataId(9), + ISCSI_AUTH_TYPES_QUALIFIERS, + description("**typedef** Authentication type used when establishing the connection.") + ] ISCSI_AUTH_TYPES AuthType; + + + [read, + WmiDataId(10), + Description("The local network address used for the connection"): amended + ] ISCSI_IP_Address LocalAddr; + + [read, + WmiDataId(11), + Description("The local port used for the connection"): amended + ] uint32 LocalPort; + + [read, + WmiDataId(12), + Description("The remote network address used for the connection"): amended + ] ISCSI_IP_Address RemoteAddr; + + [read, + WmiDataId(13), + Description("The remote port used for the connection"): amended + ] uint32 RemotePort; + + [read, + WmiDataId(14), + Description("Estimated throughput of the link in bytes per second"): amended + ] uint64 EstimatedThroughput; + + [read, + WmiDataId(15), + Description("Maximum Datagram size supported by the transport in bytes"): amended + ] uint32 MaxDatagramSize; +}; + + +[ + WMI, + Description ("iSCSI Static Sessions Statistics Information") : amended, + guid ("{B71D2538-57E2-4228-888B-1AF9B3BD01CD}") +] +class ISCSI_SessionStaticInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated session ID, it is the same id returned by the LoginToTarget method. Do not confuse this with ISID or SSID."): amended, + WmiVersion(1)] uint64 UniqueSessionId; + + [read, + WmiDataId(2), + WmiVersion(1), + description("Initiator node name used to establish the session"), + MaxLen(MAX_ISCSI_NAME_LEN)] string InitiatoriSCSIName; + + [read, + WmiDataId(3), + WmiVersion(1), + Description("iSCSI node name of the target"): amended, + MaxLen(MAX_ISCSI_NAME_LEN)] String TargetiSCSIName; + + [read, + WmiDataId(4), + Description("Target-defined portion of the iSCSI Session ID"): amended, + WmiVersion(1)] uint16 TSID; + + [read, + WmiDataId(5), + Description("Initiator-defined portion of the iSCSI Session ID"): amended, + WmiVersion(1)] uint8 ISID[6]; + + [read, + WmiDataId(6), + description("If TRUE, the initiator must wait for an R2T before sending data to the target. If FALSE, the initiator may send data immediately, within limits set by FirstBurstSize and the expected data transfer length of the request."), + WmiVersion(1)] boolean InitialR2t; + + [read, + WmiDataId(7), + description("If TRUE indicates whether the initiator and target have agreed to support immediate commands on this session."), + WmiVersion(1)] boolean ImmediateData; + + [read, + WmiDataId(8), + Description("**typedef** Type of iSCSI session") : amended, \ + ISCSI_SESSION_TYPE_QUALIFIERS, + cpp_quote("\n" + " // Type of iSCSI session\n" + " // discoverySession - session is being used only for discovery\n" + " // informationalSession - session is used for a limited number of scsi commands\n" + " // dataSession - session is being used as a full feature session\n" + " // bootSession - session is being used to boot an initiator\n" + "\n" + ), + WmiVersion(1)] ISCSI_SESSION_TYPE Type; + + [read, + WmiDataId(9), + description("If FALSE indicates that data PDU Sequences may be transferred in any order. If TRUE indicates that data PDU sequences must be transferred using continuously increasing offsets, except during error recovery."), + WmiVersion(1)] boolean DataSequenceInOrder; + + [read, + WmiDataId(10), + description("If FALSE indicates that data PDUs within sequences may be in any order. If TRUE indicates that data PDUs within sequences must be at continuously increasing addresses, with no gaps or overlay between PDUs."), + WmiVersion(1)] boolean DataPduInOrder; + + [read, + WmiDataId(11), + description("The level of error recovery negotiated between the initiator and the target."), + WmiVersion(1)] uint8 ErrorRecoveryLevel; + + [read, + WmiDataId(12), + description("The maximum number of outstanding request-to-transmit (R2T) per task within this session"), + WmiVersion(1)] uint32 MaxOutstandingR2t; + + [read, + WmiDataId(13), + description("The maximum length supported for unsolicited data sent within this session"), + WmiVersion(1)] uint32 FirstBurstLength; + + [read, + WmiDataId(14), + description("The maximum number of bytes which can be sent within a single sequence of Data-In or Data-Out PDUs"), + WmiVersion(1)] uint32 MaxBurstLength; + + [read, + WmiDataId(15), + description("The maximum number of connections that will be allowed within this session"), + WmiVersion(1)] uint32 MaxConnections; + + [read, + WmiDataId(16), + description("The number of connections that currently belong to this session"), + WmiVersion(1)] uint16 ConnectionCount; + + [WmiDataId(17), + read, + DisplayName("List of Connections") : amended, + Description("List of ISCSI_ConnectionStaticInfo. ConnectionCount specifies the number of elements in the array. NOTE: This is a variable length array.") : amended, + WmiSizeIs("ConnectionCount") + ] ISCSI_ConnectionStaticInfo ConnectionsList[]; +}; + + +[ + WMI, + Description ("iSCSI Portal Info") : amended, + guid ("{4FB9130E-1FEF-4ae6-9E48-77839204D413}") +] +class ISCSI_PortalInfo +{ + [read, + WmiDataId(1), + description("An integer used to uniquely identify a paticular port"), + WmiVersion(1)] uint32 Index; + + [read, + WmiDataId(2), + ISCSI_PORTAL_TYPE_QUALIFIERS, + description("**typedef** The type of portal (Initiator or Target) \n"), + WmiVersion(1)] ISCSI_PORTAL_TYPE PortalType; + + [read, + WmiDataId(3), + ISCSI_CONNECTION_PROTOCOL_TYPE_QUALIFIERS, + //Description("The portal's transport protocol"): amended, + description("The portal's transport protocol"), + WmiVersion(1)] ISCSI_CONNECTION_PROTOCOL_TYPE Protocol; + + [read, + WmiDataId(4), + WmiVersion(1)] uint8 Reserved1; + + [read, + WmiDataId(5), + WmiVersion(1)] uint8 Reserved2; + + [read, + WmiDataId(6), + description("The portal's network address"), + WmiVersion(1)] ISCSI_IP_Address IPAddr; + + [read, + WmiDataId(7), + description("The portal's socket number"), + WmiVersion(1)] uint32 Port; + + [read, + WmiDataId(8), + description("The portal's aggregation tag"), + WmiVersion(1)] uint16 PortalTag; +}; + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iScsi Portal Information Class") : amended, + guid ("{84CA6FD6-B152-4e6a-8869-FDE5E37B6157}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class exposes portal information.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_PortalInfoClass +{ + [read,key] String InstanceName; + [read] boolean Active; + + [WmiDataId(1), + read, + DisplayName("Count of Elements in iScsiPortalInfo array") : amended, + Description("Number of elements in iScsiPortalInfo array") : amended + ] uint32 PortalInfoCount; + + [WmiDataId(2), + read, + DisplayName("List Of Portals") : amended, + Description("Variable length array of iScsiPortalInfo. PortalInfoCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("PortalInfoCount") + ] ISCSI_PortalInfo PortalInformation[]; + +}; +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Static Initiator Session Information") : amended, + guid ("{D7931411-0376-4869-A491-8D679BFC004A}"), + cpp_quote( +"//\n" +"//\n" +"// This class is required. \n" +"//\n" +"// This class exposes session and connection information on the initiator.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorSessionInfo +{ + [read,key] String InstanceName; + + [read] boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique to each instance of each adapter. Using the address of the Adapter Extension is a good idea.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + read, + DisplayName("Count of Elements in SessionList array") : amended, + Description("Number of elements in SessionList array") : amended + ] uint32 SessionCount; + + [WmiDataId(3), + read, + DisplayName("List Of Sessions") : amended, + Description("Variable length array of sessions. SessionCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("SessionCount") + ] ISCSI_SessionStaticInfo SessionsList[]; + +}; + + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Initiator Node Failure Event") : amended, + guid ("{1221948A-6332-4ac2-AA04-268AABCECE4F}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class fires an event when a node failure occurs.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorNodeFailureEvent : __ExtrinsicEvent +{ + [read,key] String InstanceName; + [read] boolean Active; + + [read, + WmiDataId(1), + WmiTimeStamp, + Description("Timestamp denoting time failure occured"), + WmiVersion(1)] uint64 FailureTime; + + [read, + WmiDataId(2), + Description("**typedef** Types of initiator node failure") : amended, \ + ISCSI_INITIATOR_FAILURE_TYPE_QUALIFIERS, + WmiVersion(1)] ISCSI_INITIATOR_FAILURE_TYPE FailureType; + + [read, + WmiDataId(3), + description("Name of target involved in failure"), + WmiVersion(1), + MaxLen(MAX_ISCSI_NAME_LEN)] string TargetFailureName; + + [read, + WmiDataId(4), + description("Network address of target involved in failure"), + WmiVersion(1)] ISCSI_IP_Address TargetFailureAddr; +}; + +[ + Dynamic, Provider("WMIProv"), + WMI, + Description ("iSCSI Initiator Instance Failure Event") : amended, + guid ("{E67E1BDB-D130-4143-9EB2-8BEE1899FD52}"), + cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class fires an event when an initiator failure occurs.\n" +"//\n" +"// This class should use PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_InitiatorInstanceFailureEvent : __ExtrinsicEvent +{ + [read,key] String InstanceName; + [read] boolean Active; + + [read, + WmiDataId(1), + description("**typedef** Type of failure"), + ISCSI_INITIATOR_NODE_FAILURE_TYPE_QUALIFIERS, + WmiVersion(1)] ISCSI_INITIATOR_NODE_FAILURE_TYPE FailureType; + + [read, + WmiDataId(2), + description("Name of target involved in failure"), + WmiVersion(1), + MaxLen(MAX_ISCSI_NAME_LEN)] string RemoteNodeName; +}; + +// +// This class describes an iSCSI Path (A TCP Connection to the target) +// + +[ + WMI, + guid("{C8775641-5430-4220-BA25-7DA561CB64CE}"), + Description("This class describes an iSCSI Path (A TCP Connection to the target)") : amended +] +class ISCSI_Path +{ + [WmiDataId(1), + Description("iSCSI Unique connection id") : amended + ] + uint64 UniqueConnectionId; + + [WmiDataId(2), + Description("Estimated speed of the connection in MegaBits Per Second") : amended + ] + uint64 EstimatedLinkSpeed; + + [WmiDataId(3), + Description("Weight assigned to the path") : amended + ] + uint32 PathWeight; + + [WmiDataId(4), + Description("Flag set to 1 if the path is a primary path, 0 otherwise.") : amended + ] + uint32 PrimaryPath; + + [WmiDataId(5), + Description("Status of the path - connected, disconnected, reconnecting") : amended, + Values{"Connected", + "Disconnected", + "Reconnecting"} : amended, + DefineValues{"CONNECTION_STATE_CONNECTED", + "CONNECTION_STATE_DISCONNECTED", + "CONNECTION_STATE_RECONNECTING" + }, + ValueMap{"1", "2", "3"} + ] + uint32 ConnectionStatus; + + [WmiDataId(6), + Description("Flag set to 1 if TCP offload is supported for this connection, 0 otherwise.") : amended + ] + uint32 TCPOffLoadAvailable; +}; + +[WMI, + guid("{749AFE4D-804D-4662-A68B-DC696655C79A}"), + Description("iSCSI Initiator Load Balance Policies supported") : amended +] +class ISCSI_Supported_LB_Policies { + + [WmiDataId(1), + description("Id that is unique to this session within this adapter. ") : amended + ] + uint64 UniqueSessionId; + + [WmiDataId(2), + Description("Load Balance policy supported by the iSCSI Initiator") : amended, + Values{"Fail Over Only", + "Round Robin", + "Round Robin with Subset", + "Dynamic Least Queue Depth", + "Weighted Paths", + "Vendor Specific"} : amended, + DefineValues{"MSiSCSI_LB_FAILOVER", + "MSiSCSI_LB_ROUND_ROBIN", + "MSiSCSI_LB_ROUND_ROBIN_WITH_SUBSET", + "MSiSCSI_LB_DYN_LEAST_QUEUE_DEPTH", + "MSiSCSI_LB_WEIGHTED_PATHS", + "MSiSCSI_LB_VENDOR_SPECIFIC"}, + ValueMap{"1", "2", "3", "4", "5", "6"} + ] + uint32 LoadBalancePolicy; + + // + // If load balance policy is MSiSCSI_LB_VENDOR_SPECIFIC then + // the following properties are not used. Instead the caller would + // need to provide data for setting the vendor specific + // Load Balance policy. + // + [WmiDataId(3), + Description("Number of entries in MSiSCSI_Paths array") : amended + ] + + uint32 iSCSI_PathCount; + + [WmiDataId(4), + WmiSizeIs("iSCSI_PathCount"), + Description("Describes iSCSI Initiator Paths") : amended + ] + ISCSI_Path iSCSI_Paths[]; +}; + +[WMI, + Dynamic, + Provider("WmiProv"), + Description("Set iSCSI Initiator Load Balance Policies"), + guid("{A7DFE761-B6BC-4490-91B0-D9CF4A24D37C}") +] +class MSiSCSI_LB_Operations { + + [key, read] + string InstanceName; + + [read] + boolean Active; + + // + // Method to set load balance policy for the iSCSI Initiator + // + [WmiMethodId(10), + Implemented, + Description("Sets Load Balance Policy for the iSCSI Initiator") : amended, + cpp_quote( + "//\n" + "// SetLoadBalancePolicy instructs the iSCSI Initiator what Load Balance\n" + "// policy to use.\n" + "//\n" + ) + ] + void SetLoadBalancePolicy( + [in, + Description("New Load Balance policy to be set") + ] ISCSI_Supported_LB_Policies LoadBalancePolicies, + + [out, + Description("Status of the operation") + ] uint32 Status + ); +}; + +[ + WMI, + guid("{E0AECAEE-B311-426f-B67A-18D5E55D0996}"), + Dynamic, + DisplayName("iSCSI Initiator Query LoadBalance Policy") : amended, + Provider("wmiprov"), + description("Query Load Balance policy used by iSCSI Initiator") : amended, + cpp_quote( +"//\n" +"// MSiSCSI_QueryLBPolicy class is used to query the Initiator about\n" +"// the load balance policy that is currently used.\n" +"//\n" + ) +] +class MSiSCSI_QueryLBPolicy +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + Description("Id that is globally unique to each instance of each adapter. Using the address of the Adapter Extension is a good idea.") : amended + ] + uint64 UniqueAdapterId; + + [WmiDataId(2), + read, + DisplayName("Reserved field") : amended + ] uint32 Reserved; + + [WmiDataId(3), + read, + DisplayName("Count of Elements in LoadBalancePolicies array") : amended, + cpp_quote("\n // Number of elements in LoadBalancePolicies array\n"), + Description("Number of elements in LoadBalancePolicies array") : amended + ] uint32 SessionCount; + + [WmiDataId(4), + DisplayName("Load Balance Policy for each session") : amended, + description("Load Balance Policy that is currently being used by iSCSI Initiator - one element for each session on the adapter") : amended, + WmiSizeIs("SessionCount") + ] + ISCSI_Supported_LB_Policies LoadBalancePolicies[]; +}; + +// +// Define the qualifiers used for the Type property of the +// MSiSCSI_Eventlog class. The value of the property corresponds +// to the eventlog type as specified in iscsilog.h +// +#define EVENTLOG_MESSAGE_QUALIFIERS \ + Values{ \ + "ISCSI_ERR_TDI_CONNECT_FAILED", \ + "ISCSI_ERR_INSUFFICIENT_SESSION_RESOURCES", \ + "ISCSI_ERR_INVALID_COMMAND_SEQUENCE_NUMBER", \ + "ISCSI_ERR_INVALID_BURST_LENGTH", \ + "ISCSI_ERR_SETUP_NETWORK_NODE", \ + "ISCSI_ERR_INSUFFICIENT_CONNECTION_RESOURCES", \ + "ISCSI_ERR_SEND_FAILED", \ + "ISCSI_ERR_ISCSI_REQUEST_TIMEOUT", \ + "ISCSI_ERR_SCSI_REQUEST_TIMEOUT", \ + "ISCSI_ERR_LOGIN_FAILED", \ + "ISCSI_ERR_LOGIN_PDU_ERROR", \ + "ISCSI_ERR_INVALID_LOGIN_REDIRECT_DATA", \ + "ISCSI_ERR_INVALID_AUTHMETHOD", \ + "ISCSI_ERR_INVALID_CHAP_ALGORITHM", \ + "ISCSI_ERR_INVALID_CHAP_CHALLENGE", \ + "ISCSI_ERR_INVALID_KEY_DURING_CHAP", \ + "ISCSI_ERR_INVALID_CHAP_RESPONSE", \ + "ISCSI_ERR_HEADER_DIGEST_NEEDED", \ + "ISCSI_ERR_HEADER_DATA_NEEDED", \ + "ISCSI_ERR_CONNECTION_LOST", \ + "ISCSI_ERR_INVALID_DATA_SEGMENT_LENGTH", \ + "ISCSI_ERR_HEADER_DIGEST_ERROR", \ + "ISCSI_ERR_ISCSI_PDU_ERROR", \ + "ISCSI_ERR_UNKNOWN_ISCSI_OPCODE", \ + "ISCSI_ERR_DATA_DIGEST_ERROR", \ + "ISCSI_ERR_EXCESS_DATA_SENT", \ + "ISCSI_ERR_UNEXPECTED_PDU", \ + "ISCSI_ERR_INVALID_RTT_PDU", \ + "ISCSI_ERR_ISCSI_PDU_REJECTED", \ + "ISCSI_ERR_INSUFFICIENT_WORKITEM_RESOURCES", \ + "ISCSI_ERR_INSUFFICIENT_REQ_PACKET_RESOURCES", \ + "ISCSI_WRN_RECEIVED_ASYNC_LOGOUT", \ + "ISCSI_ERR_INVALID_CHAP_CHALLENGE_SIZE", \ + "ISCSI_INFO_RECONNECTED_TO_TARGET", \ + "ISCSI_ERR_INVALID_TARGET_CHAP_SECRET", \ + "ISCSI_ERR_INVALID_INITIATOR_CHAP_SECRET", \ + "ISCSI_ERR_FIPS_NOT_AVAILABLE", \ + "ISCSI_ERR_CHAP_NOT_OFFERED", \ + "ISCSI_ERR_DEVICE_RESET", \ + "ISCSI_ERR_CHAP_OFFERED", \ + "ISCSI_ERR_AUTH_METHOD_NOT_OFFERED", \ + "ISCSI_ERR_INVALID_STATUS_SEQ_NUM" \ + }, \ + ValueMap{ \ + "0xC0000001", \ + "0xC0000002", \ + "0xC0000003", \ + "0xC0000004", \ + "0xC0000005", \ + "0xC0000006", \ + "0xC0000007", \ + "0xC0000008", \ + "0xC0000009", \ + "0xC000000A", \ + "0xC000000B", \ + "0xC000000C", \ + "0xC000000D", \ + "0xC000000E", \ + "0xC000000F", \ + "0xC0000010", \ + "0xC0000011", \ + "0xC0000012", \ + "0xC0000013", \ + "0xC0000014", \ + "0xC0000015", \ + "0xC0000016", \ + "0xC0000017", \ + "0xC0000018", \ + "0xC0000019", \ + "0xC000001A", \ + "0xC000001B", \ + "0xC000001C", \ + "0xC000001D", \ + "0xC000001E", \ + "0xC000001F", \ + "0x80000020", \ + "0xC0000021", \ + "0x40000022", \ + "0xC0000023", \ + "0xC0000024", \ + "0xC0000025", \ + "0xC0000026", \ + "0xC0000027", \ + "0xC0000028", \ + "0xC0000029", \ + "0xC000002A" \ + }, \ + Description("Type of eventlog message") : amended + +#define ERROR_SEVERITY_QUALIFIERS \ + Values{"Recoverable", "Fatal", "Correctable"}, \ + ValueMap{ "0", "1", "2" }, \ + Description("Severity of the error record") : amended + +[WMI, + guid("{E6B8552B-7C62-4c6e-99EB-67CE6087894C}"), + description("iSCSI Eventlog generation event") : amended, + Dynamic, + Provider("wmiprov"), + cpp_quote( +"//\n" +"// Miniports can fire this event to cause eventlog entries to be\n" +"// included in the system eventlog. This is useful as the iscsilog.h\n" +"// header has many iSCSI specific eventlog messages that are useful for\n" +"// troubleshooting, but can't be fired directly by a miniport. By\n" +"// firing this WMI event appropriately a miniport can cause a useful\n" +"// eventlog entry to be included in the system eventlog\n" +"//\n") +] +class MSiSCSI_Eventlog : __ExtrinsicEvent +{ + [key] + string InstanceName; + + boolean Active; + + [WmiDataId(1), + EVENTLOG_MESSAGE_QUALIFIERS + ] + uint32 Type; + + [WmiDataId(2), + Description("If zero then this event is not logged to system eventlog") : amended + ] + uint32 LogToEventlog; + + [WmiDataId(3), + Description("Size of Additional Data") : amended + ] + uint32 Size; + + [WmiDataId(4), + WmiSizeIs("Size"), + Description("Additional data to include in eventlog message, typically iSCSI Header") : amended + ] + uint8 AdditionalData[]; +}; + +[ + WMI, + Description ("iSCSI Redirect Portal Info") : amended, + guid ("{F6004CE6-9507-4d86-AE1E-E9D64F166F2F}") +] +class ISCSI_RedirectPortalInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated connection ID. Do not confuse this with CID."): amended, + WmiVersion(1) + ] uint64 UniqueConnectionId; + + [read, + WmiDataId(2), + Description("Original Target IP Address given in the login"): amended, + WmiVersion(1)] ISCSI_IP_Address OriginalIPAddr; + + [read, + WmiDataId(3), + Description("Original Target portal's socket number given in the login"): amended, + WmiVersion(1)] uint32 OriginalPort; + + [read, + WmiDataId(4), + Description("Redirected Target IP Address"): amended, + WmiVersion(1)] ISCSI_IP_Address RedirectedIPAddr; + + [read, + WmiDataId(5), + Description("Redirected Target portal's socket number"): amended, + WmiVersion(1)] uint32 RedirectedPort; + + [read, + WmiDataId(6), + Description("TRUE if login was redirected. RedirectedIPAddr and RedirectedPort are valid then."): amended, + WmiVersion(1)] uint8 Redirected; + + [read, + WmiDataId(7), + Description("TRUE if the redirection is temporary. FALSE otherwise"): amended, + WmiVersion(1)] uint8 TemporaryRedirect; +}; + +[ + WMI, + Description ("iSCSI Redirect Session Info") : amended, + guid ("{ED60BC3F-3D56-42f0-B4D0-81DD16E28515}") +] +class ISCSI_RedirectSessionInfo +{ + [read, + WmiDataId(1), + Description("A uniquely generated session ID, it is the same id returned by the LoginToTarget method. Do not confuse this with ISID or SSID."): amended, + WmiVersion(1)] uint64 UniqueSessionId; + + [read, + WmiDataId(2), + Description("Target portal group tag for this Session "): amended, + WmiVersion(1)] uint32 TargetPortalGroupTag; + + [read, + WmiDataId(3), + DisplayName("Number of elements in RedirectPortalList array") : amended, + cpp_quote("\n // Number of elements in RedirectPortalList array\n"), + Description("Number of elements in RedirectPortalList array") : amended, + WmiVersion(1) + ] uint32 ConnectionCount; + + [read, + WmiDataId(4), + DisplayName("Redirect Portal info for each connection") : amended, + Description("Redirect portal info - one element for each connection in the session") : amended, + WmiSizeIs("ConnectionCount"), + WmiVersion(1) + ] ISCSI_RedirectPortalInfo RedirectPortalList[]; +}; + +[ + WMI, Dynamic, Provider("WMIProv"), + Description ("iScsi Redirect Portal Information Class") : amended, + guid ("{DAF7F63A-F9EA-4869-87E1-AE8A7C2261E2}"), +cpp_quote( +"//\n" +"//\n" +"// This class is recommended. \n" +"//\n" +"// This class exposes portal information. It provides the original and \n" +"// redirected target portal information for an iSCSI Connection.\n" +"//\n" +"// This class must be registered using PDO instance names with a single instance\n" +"//\n" + ) +] +class MSiSCSI_RedirectPortalInfoClass +{ + [read,key] String InstanceName; + + [read] boolean Active; + + [read, + WmiDataId(1), + DisplayName("Adapter Id") : amended, + DisplayInHex, + description("Id that is globally unique for all instances of iSCSI initiators.") : amended, + WmiVersion(1) + ] + uint64 UniqueAdapterId; + + [read, + WmiDataId(2), + DisplayName("Number of session on the adapter : Number of elements in RedirectSessionInfo array") : amended, + Description("Number of elements in RedirectSessionInfo array") : amended, + WmiVersion(1) + ] uint32 SessionCount; + + [read, + WmiDataId(3), + DisplayName("List Of ISCSI_RedirectSessionInfo ") : amended, + Description("Variable length array of ISCSI_RedirectSessionInfo. SessionCount specifies the number of elements in the array. NOTE: this is a variable length array.") : amended, + WmiSizeIs("SessionCount"), + WmiVersion(1) + ] ISCSI_RedirectSessionInfo RedirectSessionList[]; +}; + +[ + WMI, + guid("{B8D765F0-2D93-4da2-8186-A187622B4302}"), + Dynamic, + Provider("wmiprov"), + cpp_quote( +"\n" +"//\n" +"//\n" +"// This class is recommended.\n" +"//\n" +"// iSCSI management applications rely upon this\n" +"// class in order to interface with the adapter. Implement one instance\n" +"// per miniport instance (adapter). \n" +"//\n" +"// This class must be registered using PDO instance names with a single instance.\n" +"//\n" + ) +] +class MSiSCSI_ManagementOperations +{ + // + // This class must be registered using PDO instance names + // + [key] + string InstanceName; + + boolean Active; + + [WmiMethodId(10), + Implemented, + Description("Perform an ICMP ping") : amended, + cpp_quote( +"//\n" +"// This method is recommended.\n" +"//\n" +"// Ping will perform ICMP ping requests to the destination address \n" +"// and return the number of ping responses received. This is only supported\n" +"// by some HBA, use the ping command for the software initiator.\n" +"//\n" + ) + ] + void PingIPAddress( + [in, + Description("Number of requests to send") : amended + ] uint32 RequestCount, + + [in, + Description("Number of bytes in each request") : amended + ] uint32 RequestSize, + + [in, + Description("Number of ms to wait for response") : amended + ] uint32 Timeout, + + [in, + description("IP address to ping") : amended + ] ISCSI_IP_Address Address, + + [out, + ISCSI_STATUS_QUALIFIERS + ] ISCSI_STATUS Status, + + [out, + Description("Number of responses received") : amended + ] uint32 ResponsesReceived + + ); + + +}; diff --git a/storage/iscsi/src/readme.txt b/storage/iscsi/src/readme.txt new file mode 100644 index 00000000..40438312 --- /dev/null +++ b/storage/iscsi/src/readme.txt @@ -0,0 +1,49 @@ + + WMI implementation in a iSCSI miniport can be tested using the iscsicli.exe +application, device manager property pages, WBEMTEST.exe and scripts +generated by the wmimofck.exe tool. + +See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q252679 for more +information. + +Below is the list of classes and those that are required to be implemented +and those that are recommended. + +Core Functionality + - Must implement +MSiSCSI_TCPIPConfig +MSiSCSI_HBAInformation +MSiSCSI_InitiatorSessionInfo +MSiSCSI_Operations + (DeleteInitiatorNodeName and SetInitiatorNodeName method are optional) +MSiSCSI_PersistentLogins +MSiSCSI_TargetMappings +MSiSCSI_LUNMappingInformation +MSiSCSI_AdapterEvent +MSiSCSI_ConnectionStatistics (Windows 2003 Server only) +MSiSCSI_SessionStatistics (Windows 2003 Server only) +MSiSCSI_InitiatorLoginStatistics (Windows 2003 Server only) +MSiSCSI_InitiatorInstanceStatistics (Windows 2003 Server only) +MSiSCSI_NICPerformance (Windows 2003 Server only) + + + - May implement +MSiSCSI_NICConfig +MSiSCSI_BootConfiguration +MSiSCSI_HBASessionConfig +MSiSCSI_InitiatorNodeFailureEvent +MSiSCSI_InitiatorInstanceFailureEvent + +Discovery + - Must implement if discovery is supported. +MSiSCSI_DiscoveryConfig +MSiSCSI_DiscoveryOperations + +IPSEC/CHAP + - Must implement if ipsec and/or CHAP are supported +MSiSCSI_SecurityCapabilities +MSiSCSI_SecurityConfigOperations +MSiSCSI_MMIPSECStats (Windows 2003 Server only) +MSiSCSI_QMIPSECStats (Windows 2003 Server only) +MSiSCSI_RADIUSConfig + |
