📄 wmisample.c
字号:
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 (iScsiSession != NULL)
{
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_bcount(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) {
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
//
#pragma prefast ( suppress: __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "BufferAvail is being checked against SizeNeeded above")
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) {
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;
}
}
return status;
}
VOID
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -