You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1431 lines
39 KiB
1431 lines
39 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft, Inc
|
|
|
|
Module Name:
|
|
|
|
wmi.c
|
|
|
|
Abstract:
|
|
|
|
This is the common source code for WMI debugging support within a NT
|
|
SCSI miniport. This code implements the WMI specific functionality that
|
|
needed and is independent of the miniport that includes it. To include
|
|
the wmi debugging code in a miniport, the miniport must do the following:
|
|
|
|
1. Create a file (say wmi.c) that includes any headers needed by the
|
|
the miniport and #define PHWDEVEXT to the name for its hardware device
|
|
extension. One of the headers needs to #define WMI_TEST_CODE to include
|
|
wmi debug code in the build.
|
|
|
|
2. Include the following before the hardware device extension structure:
|
|
|
|
#ifdef WMI_TEST_CODE
|
|
|
|
#define MAX_STRING 255
|
|
|
|
typedef struct
|
|
{
|
|
BOOLEAN boolean;
|
|
UCHAR uchar;
|
|
USHORT ushort;
|
|
ULONG ulong;
|
|
ULONGLONG ulonglong;
|
|
CHAR achar;
|
|
SHORT ashort;
|
|
LONG along;
|
|
LONGLONG longlong;
|
|
WCHAR datetime[25];
|
|
USHORT stringlen;
|
|
WCHAR string[MAX_STRING];
|
|
} EC1, *PEC1;
|
|
|
|
typedef struct
|
|
{
|
|
BOOLEAN boolean[8];
|
|
UCHAR uchar[8];
|
|
USHORT ushort[4];
|
|
ULONG ulong[2];
|
|
ULONGLONG ulonglong;
|
|
CHAR achar[8];
|
|
SHORT ashort[4];
|
|
LONG along[2];
|
|
LONGLONG longlong;
|
|
WCHAR datetime[25];
|
|
USHORT stringlen;
|
|
WCHAR string[MAX_STRING];
|
|
} EC2, *PEC2;
|
|
|
|
#define WMI_EVENT_BUFFER_SIZE (sizeof(EC2) + 0x40)
|
|
#endif
|
|
|
|
|
|
3. Include the following within the hardware device extension structure:
|
|
|
|
#ifdef WMI_TEST_CODE
|
|
SCSI_WMILIB_CONTEXT WmiLibContext;
|
|
|
|
ULONG Ec1Count;
|
|
ULONG Ec1Length[4];
|
|
ULONG Ec1ActualLength[4];
|
|
EC1 Ec1[4];
|
|
|
|
ULONG Ec2Count;
|
|
ULONG Ec2Length[4];
|
|
ULONG Ec2ActualLength[4];
|
|
EC2 Ec2[4];
|
|
|
|
UCHAR EventBuffer[WMI_EVENT_BUFFER_SIZE];
|
|
#endif
|
|
|
|
4. Include the following in the HwDetect routine
|
|
#ifdef WMI_TEST_CODE
|
|
//
|
|
// Enable and initialize WMI
|
|
ConfigInfo->WmiDataProvider = TRUE;
|
|
WmiInitialize(CardPtr);
|
|
#endif
|
|
|
|
5. Dispatch wmi srbs to WmiSrb().
|
|
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifdef WMI_TEST_CODE
|
|
|
|
|
|
BOOLEAN WmiSampSetEc1(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Length,
|
|
ULONG Index
|
|
);
|
|
|
|
BOOLEAN WmiSampSetEc2(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Length,
|
|
ULONG Index
|
|
);
|
|
|
|
|
|
|
|
#define WmiSampDateTime L"19940525133015.000000-300"
|
|
|
|
#define Wmi_MofResourceName L"MofResource"
|
|
|
|
#define WmiSampleClass1 0
|
|
#define WmiSampleClass2 1
|
|
#define WmiSampleClass3 2
|
|
#define WmiSampleClass4 3
|
|
#define WmiSampleClass5 4
|
|
#define WmiSampleClass6 5
|
|
#define WmiSampleClass7 6
|
|
#define WmiGetSetData 7
|
|
#define WmiFireEvent 8
|
|
#define WmiEventClass1 9
|
|
#define WmiEventClass2 10
|
|
#define WmiEventClass3 11
|
|
#define WmiEventClass4 12
|
|
#define WmiEventClass5 13
|
|
#define WmiEventClass6 14
|
|
#define WmiEventClass7 15
|
|
|
|
GUID WmiSampleClass1Guid = { 0x15d851f1, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass2Guid = { 0x15d851f2, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass3Guid = { 0x15d851f3, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass4Guid = { 0x15d851f4, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass5Guid = { 0x15d851f5, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass6Guid = { 0x15d851f6, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiSampleClass7Guid = { 0x15d851f7, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiGetSetDataGuid = { 0x15d851f8, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiFireEventGuid = { 0x15d851f9, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass1Guid = { 0x15d851e1, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass2Guid = { 0x15d851e2, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass3Guid = { 0x15d851e3, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass4Guid = { 0x15d851e4, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass5Guid = { 0x15d851e5, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass6Guid = { 0x15d851e6, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
GUID WmiEventClass7Guid = { 0x15d851e7, 0x6539, 0x11d1, 0xa5, 0x29, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 };
|
|
|
|
SCSIWMIGUIDREGINFO GuidList[] =
|
|
{
|
|
{
|
|
&WmiSampleClass1Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass2Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass3Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass4Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass5Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass6Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiSampleClass7Guid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiGetSetDataGuid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiFireEventGuid,
|
|
1,
|
|
0
|
|
},
|
|
|
|
{
|
|
&WmiEventClass1Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass2Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass3Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass4Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass5Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass6Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
{
|
|
&WmiEventClass7Guid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
|
|
};
|
|
|
|
#define WmiGuidCount (sizeof(GuidList) / sizeof(SCSIWMIGUIDREGINFO))
|
|
|
|
UCHAR
|
|
QueryWmiDataBlock(
|
|
IN PVOID Context,
|
|
IN PVOID DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG InstanceCount,
|
|
IN OUT PULONG InstanceLengthArray,
|
|
IN ULONG OutBufferSize,
|
|
OUT PUCHAR Buffer
|
|
);
|
|
|
|
UCHAR
|
|
QueryWmiRegInfo(
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
OUT PWCHAR *MofResourceName
|
|
);
|
|
|
|
UCHAR
|
|
WmiFunctionControl (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN SCSIWMI_ENABLE_DISABLE_CONTROL Function,
|
|
IN BOOLEAN Enable
|
|
);
|
|
|
|
UCHAR
|
|
WmiExecuteMethod (
|
|
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
|
|
);
|
|
|
|
UCHAR
|
|
WmiSetDataItem (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG DataItemId,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
UCHAR
|
|
WmiSetDataBlock (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
void WmiInitialize(
|
|
IN PHWDEVEXT CardPtr
|
|
)
|
|
{
|
|
PSCSI_WMILIB_CONTEXT WmiLibContext;
|
|
UCHAR Ec[sizeof(EC2) + 11*sizeof(WCHAR)];
|
|
PEC1 Ec1;
|
|
PEC2 Ec2;
|
|
ULONG i;
|
|
|
|
WmiLibContext = &CardPtr->WmiLibContext;
|
|
|
|
WmiLibContext->GuidList = GuidList;
|
|
WmiLibContext->GuidCount = WmiGuidCount;
|
|
WmiLibContext->QueryWmiRegInfo = QueryWmiRegInfo;
|
|
WmiLibContext->QueryWmiDataBlock = QueryWmiDataBlock;
|
|
WmiLibContext->WmiFunctionControl = WmiFunctionControl;
|
|
WmiLibContext->SetWmiDataBlock = WmiSetDataBlock;
|
|
WmiLibContext->SetWmiDataItem = WmiSetDataItem;
|
|
WmiLibContext->ExecuteWmiMethod = WmiExecuteMethod;
|
|
|
|
CardPtr->Ec1Count = 3;
|
|
CardPtr->Ec2Count = 3;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
Ec1 = (PEC1)Ec;
|
|
memset(Ec1, i, sizeof(EC1));
|
|
ScsiPortMoveMemory(Ec1->string, L"EC1-0", 5*sizeof(WCHAR));
|
|
Ec1->stringlen = 10;
|
|
Ec1->string[4] += (USHORT)i;
|
|
ScsiPortMoveMemory(Ec1->datetime, WmiSampDateTime, 25*sizeof(WCHAR));
|
|
|
|
WmiSampSetEc1(CardPtr,
|
|
(PUCHAR)Ec1,
|
|
FIELD_OFFSET(EC1, string) + 10,
|
|
i);
|
|
|
|
|
|
Ec2 = (PEC2)Ec;
|
|
memset(Ec2, i, sizeof(EC2));
|
|
ScsiPortMoveMemory(Ec2->string, L"EC2-0", 5*sizeof(WCHAR));
|
|
Ec2->stringlen = 10;
|
|
Ec2->string[4] += (USHORT)i;
|
|
ScsiPortMoveMemory(Ec2->datetime, WmiSampDateTime, 25*sizeof(WCHAR));
|
|
|
|
WmiSampSetEc2(CardPtr,
|
|
(PUCHAR)Ec2,
|
|
FIELD_OFFSET(EC2, string) + 10,
|
|
i);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
WmiSrb(
|
|
IN PHWDEVEXT CardPtr,
|
|
IN OUT PSCSI_WMI_REQUEST_BLOCK Srb
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Process an SRB_FUNCTION_WMI request packet.
|
|
|
|
This routine is called from the SCSI port driver synchronized with the
|
|
kernel via StartIo. On completion of WMI processing, the SCSI
|
|
port driver is notified that the adapter can take another request, if
|
|
any are available.
|
|
|
|
Arguments:
|
|
|
|
HwCardPtr - HBA miniport driver's adapter data storage.
|
|
|
|
Srb - IO request packet.
|
|
|
|
Return Value:
|
|
|
|
Value to return to Aha154xStartIo caller. Always TRUE.
|
|
|
|
--*/
|
|
{
|
|
UCHAR status;
|
|
SCSIWMI_REQUEST_CONTEXT dc;
|
|
PSCSIWMI_REQUEST_CONTEXT dispatchContext = &dc;
|
|
ULONG retSize;
|
|
BOOLEAN pending;
|
|
|
|
//
|
|
// Validate our assumptions.
|
|
//
|
|
|
|
ASSERT(Srb->Function == SRB_FUNCTION_WMI);
|
|
ASSERT(Srb->Length == sizeof(SCSI_WMI_REQUEST_BLOCK));
|
|
ASSERT(Srb->DataTransferLength >= sizeof(ULONG));
|
|
ASSERT(Srb->DataBuffer);
|
|
|
|
//
|
|
// Only support wmi for the adapter and not disks
|
|
if (!(Srb->WMIFlags & SRB_WMI_FLAGS_ADAPTER_REQUEST)) {
|
|
Srb->DataTransferLength = 0;
|
|
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
|
return SRB_STATUS_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Process the incoming WMI request.
|
|
//
|
|
dispatchContext->UserContext = Srb;
|
|
|
|
DebugPrint((1, "ScsiPortWmiDispatchFunction(%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x)\n",
|
|
&CardPtr->WmiLibContext,
|
|
Srb->WMISubFunction,
|
|
CardPtr,
|
|
dispatchContext,
|
|
Srb->DataPath,
|
|
Srb->DataTransferLength,
|
|
Srb->DataBuffer));
|
|
|
|
pending = ScsiPortWmiDispatchFunction(&CardPtr->WmiLibContext,
|
|
Srb->WMISubFunction,
|
|
CardPtr,
|
|
dispatchContext,
|
|
Srb->DataPath,
|
|
Srb->DataTransferLength,
|
|
Srb->DataBuffer);
|
|
|
|
ASSERT(pending == FALSE);
|
|
|
|
// We can do this since we assume it is done synchronously
|
|
retSize = ScsiPortWmiGetReturnSize(dispatchContext);
|
|
status = ScsiPortWmiGetReturnStatus(dispatchContext);
|
|
|
|
DebugPrint((1,"WmiSrb %x completed %d, retsize 0x%x\n", Srb, status, retSize));
|
|
|
|
Srb->DataTransferLength = retSize;
|
|
|
|
//
|
|
// Adapter ready for next request.
|
|
//
|
|
|
|
Srb->SrbStatus = status;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
ULONG WmiSampGetEc1(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Index
|
|
)
|
|
{
|
|
ScsiPortMoveMemory(Buffer,
|
|
&CardPtr->Ec1[Index],
|
|
CardPtr->Ec1Length[Index]);
|
|
|
|
return(CardPtr->Ec1Length[Index]);
|
|
}
|
|
|
|
ULONG WmiSampGetActualEc1(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Index
|
|
)
|
|
{
|
|
ScsiPortMoveMemory(Buffer,
|
|
&CardPtr->Ec1[Index],
|
|
CardPtr->Ec1ActualLength[Index]);
|
|
|
|
return(CardPtr->Ec1ActualLength[Index]);
|
|
}
|
|
|
|
BOOLEAN WmiSampSetEc1(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Length,
|
|
ULONG Index
|
|
)
|
|
{
|
|
PEC1 New;
|
|
ULONG NewLength;
|
|
|
|
NewLength = (Length + 7) & ~7;
|
|
|
|
if (NewLength > sizeof(EC1))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
CardPtr->Ec1Length[Index] = NewLength;
|
|
CardPtr->Ec1ActualLength[Index] = Length;
|
|
ScsiPortMoveMemory(&CardPtr->Ec1[Index],
|
|
Buffer,
|
|
Length);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
ULONG WmiSampGetEc2(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Index
|
|
)
|
|
{
|
|
ScsiPortMoveMemory(Buffer,
|
|
&CardPtr->Ec2[Index],
|
|
CardPtr->Ec2Length[Index]);
|
|
|
|
return(CardPtr->Ec2Length[Index]);
|
|
}
|
|
|
|
ULONG WmiSampGetActualEc2(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Index
|
|
)
|
|
{
|
|
ScsiPortMoveMemory(Buffer,
|
|
&CardPtr->Ec2[Index],
|
|
CardPtr->Ec2ActualLength[Index]);
|
|
|
|
return(CardPtr->Ec2ActualLength[Index]);
|
|
}
|
|
|
|
BOOLEAN WmiSampSetEc2(
|
|
PHWDEVEXT CardPtr,
|
|
PUCHAR Buffer,
|
|
ULONG Length,
|
|
ULONG Index
|
|
)
|
|
{
|
|
PEC2 New;
|
|
ULONG NewLength;
|
|
|
|
NewLength = (Length + 7) & ~7;
|
|
|
|
if (NewLength > sizeof(EC2))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
CardPtr->Ec2Length[Index] = NewLength;
|
|
CardPtr->Ec2ActualLength[Index] = Length;
|
|
ScsiPortMoveMemory(&CardPtr->Ec2[Index],
|
|
Buffer,
|
|
Length);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
QueryWmiDataBlock(
|
|
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
|
|
)
|
|
{
|
|
PHWDEVEXT CardPtr = (PHWDEVEXT)Context;
|
|
UCHAR status;
|
|
ULONG i;
|
|
ULONG sizeNeeded;
|
|
ULONG sizeUsed;
|
|
ULONG vlSize;
|
|
|
|
//
|
|
// Only ever registers 1 instance per guid
|
|
ASSERT((InstanceIndex == 0) &&
|
|
(InstanceCount == 1));
|
|
|
|
DebugPrint((1, "QueryWmiDataBlock (%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n",
|
|
Context,
|
|
DispatchContext,
|
|
GuidIndex,
|
|
InstanceIndex,
|
|
InstanceCount,
|
|
InstanceLengthArray,
|
|
BufferAvail,
|
|
Buffer));
|
|
|
|
switch(GuidIndex)
|
|
{
|
|
case WmiSampleClass1:
|
|
case WmiSampleClass2:
|
|
case WmiEventClass1:
|
|
case WmiEventClass2:
|
|
{
|
|
// plain EC1
|
|
sizeNeeded = CardPtr->Ec1Length[0];
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
WmiSampGetEc1(CardPtr, Buffer, 0);
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass3:
|
|
case WmiEventClass3:
|
|
{
|
|
// fixed array of EC1
|
|
sizeNeeded = 0;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
//
|
|
// Embedded classes must be naturally aligned, but we
|
|
// maintain naturally aligned lengths not acttual lengths
|
|
sizeNeeded += CardPtr->Ec1Length[i];
|
|
}
|
|
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
sizeUsed = WmiSampGetEc1(CardPtr, Buffer, i);
|
|
Buffer += sizeUsed;
|
|
}
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass4:
|
|
case WmiEventClass4:
|
|
{
|
|
// variable array of EC1
|
|
sizeNeeded = (sizeof(ULONG) + 7) & ~7;
|
|
vlSize = CardPtr->Ec1Count;
|
|
ASSERT(vlSize <= 4);
|
|
for (i = 0; i < vlSize; i++)
|
|
{
|
|
sizeNeeded += CardPtr->Ec1Length[i];
|
|
}
|
|
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
*((PULONG)Buffer) = vlSize;
|
|
Buffer += (sizeof(ULONG) + 7) & ~7;
|
|
for (i = 0; i < vlSize; i++)
|
|
{
|
|
sizeUsed = WmiSampGetEc1(CardPtr, Buffer, i);
|
|
Buffer += sizeUsed;
|
|
}
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass5:
|
|
case WmiEventClass5:
|
|
{
|
|
// plain EC2
|
|
sizeNeeded = CardPtr->Ec2Length[0];
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
WmiSampGetEc2(CardPtr, Buffer, 0);
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass6:
|
|
case WmiEventClass6:
|
|
{
|
|
// fixed array EC2
|
|
sizeNeeded = 0;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
sizeNeeded += CardPtr->Ec2Length[i];
|
|
}
|
|
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
sizeUsed = WmiSampGetEc2(CardPtr, Buffer, i);
|
|
Buffer += sizeUsed;
|
|
}
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass7:
|
|
case WmiEventClass7:
|
|
{
|
|
// VL array EC2
|
|
sizeNeeded = (sizeof(ULONG) + 7) & ~7;
|
|
vlSize = CardPtr->Ec2Count;
|
|
for (i = 0; i < vlSize; i++)
|
|
{
|
|
sizeNeeded += CardPtr->Ec2Length[i];
|
|
}
|
|
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
*((PULONG)Buffer) = vlSize;
|
|
Buffer += (sizeof(ULONG)+7) & ~7;
|
|
for (i = 0; i < vlSize; i++)
|
|
{
|
|
sizeUsed = WmiSampGetEc2(CardPtr, Buffer, i);
|
|
Buffer += sizeUsed;
|
|
}
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiFireEvent:
|
|
case WmiGetSetData:
|
|
{
|
|
// return no data
|
|
sizeNeeded = sizeof(USHORT);
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
*InstanceLengthArray = sizeNeeded;
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ScsiPortWmiPostProcess(
|
|
DispatchContext,
|
|
status,
|
|
sizeNeeded);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
UCHAR
|
|
QueryWmiRegInfo(
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
OUT PWCHAR *MofResourceName
|
|
)
|
|
{
|
|
*MofResourceName = Wmi_MofResourceName;
|
|
return SRB_STATUS_SUCCESS;
|
|
}
|
|
|
|
UCHAR WmiSampSetEc1Worker(
|
|
PHWDEVEXT CardPtr,
|
|
ULONG BufferSize,
|
|
ULONG Index,
|
|
PUCHAR Buffer,
|
|
PULONG BufferUsed
|
|
)
|
|
{
|
|
ULONG blockLen;
|
|
UCHAR status;
|
|
PEC1 Ec1;
|
|
|
|
Ec1 = (PEC1)Buffer;
|
|
if (BufferSize >= FIELD_OFFSET(EC1, string))
|
|
{
|
|
blockLen = FIELD_OFFSET(EC1, string) + Ec1->stringlen;
|
|
|
|
if (blockLen <= BufferSize)
|
|
{
|
|
if (! WmiSampSetEc1(CardPtr,
|
|
Buffer,
|
|
blockLen,
|
|
Index))
|
|
{
|
|
return(SRB_STATUS_ERROR);
|
|
}
|
|
*BufferUsed = (blockLen+7) & ~7;
|
|
status = SRB_STATUS_SUCCESS;
|
|
} else {
|
|
DebugPrint((1,"Set EC1 buffer too small\n"));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"Set EC1 buffer size wrong %d\n", BufferSize));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
return(status);
|
|
}
|
|
|
|
UCHAR WmiSampSetEc2Worker(
|
|
PHWDEVEXT CardPtr,
|
|
ULONG BufferSize,
|
|
ULONG Index,
|
|
PUCHAR Buffer,
|
|
PULONG BufferUsed
|
|
)
|
|
{
|
|
ULONG blockLen;
|
|
UCHAR status;
|
|
PUSHORT wPtr;
|
|
PEC2 Ec2;
|
|
|
|
Ec2 = (PEC2)Buffer;
|
|
if (BufferSize >= FIELD_OFFSET(EC2, string))
|
|
{
|
|
blockLen = FIELD_OFFSET(EC2, string) + Ec2->stringlen;
|
|
|
|
if (blockLen <= BufferSize)
|
|
{
|
|
if (! WmiSampSetEc2(CardPtr,
|
|
Buffer,
|
|
blockLen,
|
|
Index))
|
|
{
|
|
return(SRB_STATUS_ERROR);
|
|
}
|
|
*BufferUsed = (blockLen+7) & ~7;
|
|
status = SRB_STATUS_SUCCESS;
|
|
} else {
|
|
DebugPrint((1,"Set EC2 buffer too small\n"));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"Set EC2 buffer size wrong %d\n", BufferSize));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
return(status);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
WmiSetDataBlock (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
)
|
|
{
|
|
PHWDEVEXT CardPtr = (PHWDEVEXT)Context;
|
|
UCHAR status;
|
|
ULONG bufferUsed;
|
|
ULONG i;
|
|
ULONG vlSize;
|
|
|
|
DebugPrint((1, "WmiSetDataBlock(%x,\n%x,\n%x,\n%x,\n%x,\n%x)\n",
|
|
Context,
|
|
DispatchContext,
|
|
GuidIndex,
|
|
InstanceIndex,
|
|
BufferSize,
|
|
Buffer));
|
|
|
|
|
|
switch(GuidIndex)
|
|
{
|
|
case WmiSampleClass1:
|
|
case WmiSampleClass2:
|
|
{
|
|
// plain EC1
|
|
status = WmiSampSetEc1Worker(CardPtr,
|
|
BufferSize,
|
|
0,
|
|
Buffer,
|
|
&bufferUsed);
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass3:
|
|
{
|
|
// fixed array of EC1
|
|
|
|
for (i = 0, status = SRB_STATUS_SUCCESS;
|
|
(i < 4) && (status == SRB_STATUS_SUCCESS); i++)
|
|
{
|
|
status = WmiSampSetEc1Worker(CardPtr,
|
|
BufferSize,
|
|
i,
|
|
Buffer,
|
|
&bufferUsed);
|
|
Buffer += bufferUsed;
|
|
BufferSize -= bufferUsed;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass4:
|
|
{
|
|
// variable array of EC1
|
|
|
|
if (BufferSize >= ((sizeof(ULONG) +7) & ~7))
|
|
{
|
|
vlSize = *((PULONG)Buffer);
|
|
Buffer += ((sizeof(ULONG) +7) & ~7);
|
|
|
|
if ((vlSize >= 1) && (vlSize <= 4))
|
|
{
|
|
for (i = 0, status = SRB_STATUS_SUCCESS;
|
|
(i < vlSize) && (status == SRB_STATUS_SUCCESS); i++)
|
|
{
|
|
status = WmiSampSetEc1Worker(CardPtr,
|
|
BufferSize,
|
|
i,
|
|
Buffer,
|
|
&bufferUsed);
|
|
Buffer += bufferUsed;
|
|
BufferSize -= bufferUsed;
|
|
}
|
|
if (status == SRB_STATUS_SUCCESS)
|
|
{
|
|
CardPtr->Ec1Count = vlSize;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"SetEc1 only up to [4] allowed, not %d\n",
|
|
vlSize));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"SetEc1 size too small\n"));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass5:
|
|
{
|
|
// plain EC2
|
|
status = WmiSampSetEc2Worker(CardPtr,
|
|
BufferSize,
|
|
0,
|
|
Buffer,
|
|
&bufferUsed);
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass6:
|
|
{
|
|
// fixed array EC2
|
|
for (i = 0, status = SRB_STATUS_SUCCESS;
|
|
(i < 4) && (status == SRB_STATUS_SUCCESS); i++)
|
|
{
|
|
status = WmiSampSetEc2Worker(CardPtr,
|
|
BufferSize,
|
|
i,
|
|
Buffer,
|
|
&bufferUsed);
|
|
Buffer += bufferUsed;
|
|
BufferSize -= bufferUsed;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WmiSampleClass7:
|
|
{
|
|
// VL array EC2
|
|
if (BufferSize >= sizeof(ULONG))
|
|
{
|
|
vlSize = *((PULONG)Buffer);
|
|
Buffer += (sizeof(ULONG) +7) & ~7;
|
|
if ((vlSize >= 1) && (vlSize <= 4))
|
|
{
|
|
for (i = 0, status = SRB_STATUS_SUCCESS;
|
|
(i < vlSize) && (status == SRB_STATUS_SUCCESS); i++)
|
|
{
|
|
status = WmiSampSetEc2Worker(CardPtr,
|
|
BufferSize,
|
|
i,
|
|
Buffer,
|
|
&bufferUsed);
|
|
Buffer += bufferUsed;
|
|
BufferSize -= bufferUsed;
|
|
}
|
|
if (status == SRB_STATUS_SUCCESS)
|
|
{
|
|
CardPtr->Ec1Count = vlSize;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"SetEc2 only up to [4] allowed, not %d\n",
|
|
vlSize));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
DebugPrint((1,"SetEc2 size too small\n"));
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
ScsiPortWmiPostProcess(
|
|
DispatchContext,
|
|
status,
|
|
0);
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOLEAN
|
|
WmiSetDataItem (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG DataItemId,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
)
|
|
{
|
|
UCHAR status;
|
|
|
|
DebugPrint((1, "WmiSetDataItem(%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x)\n",
|
|
Context,
|
|
DispatchContext,
|
|
GuidIndex,
|
|
InstanceIndex,
|
|
DataItemId,
|
|
BufferSize,
|
|
Buffer));
|
|
switch(GuidIndex)
|
|
{
|
|
case WmiSampleClass1:
|
|
case WmiSampleClass2:
|
|
case WmiSampleClass3:
|
|
case WmiSampleClass4:
|
|
case WmiSampleClass5:
|
|
case WmiSampleClass6:
|
|
case WmiSampleClass7:
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ScsiPortWmiPostProcess(
|
|
DispatchContext,
|
|
status,
|
|
0);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
UCHAR WmiSampFireEvent(
|
|
PHWDEVEXT CardPtr,
|
|
ULONG WnodeType, // 0 - AllData, 1 - Single Instance
|
|
ULONG DataType, // 1 - 7 is guid id
|
|
ULONG BlockIndex // 0 - 3 is block index containing data
|
|
)
|
|
{
|
|
PWNODE_HEADER Wnode;
|
|
PWNODE_EVENT_REFERENCE WnodeER;
|
|
ULONG dataSize;
|
|
LPGUID Guid;
|
|
UCHAR status;
|
|
ULONG sizeNeeded;
|
|
|
|
|
|
if (BlockIndex > 3)
|
|
{
|
|
return(SRB_STATUS_ERROR);
|
|
}
|
|
|
|
switch(DataType)
|
|
{
|
|
case 1:
|
|
{
|
|
// EC1
|
|
dataSize = CardPtr->Ec1Length[BlockIndex];
|
|
Guid = &WmiEventClass1Guid;
|
|
break;
|
|
}
|
|
|
|
case 2:
|
|
{
|
|
// EC1 (embedded)
|
|
dataSize = CardPtr->Ec1Length[BlockIndex];
|
|
Guid = &WmiEventClass2Guid;
|
|
break;
|
|
}
|
|
|
|
case 5:
|
|
{
|
|
// EC2 (embedded)
|
|
dataSize = CardPtr->Ec2Length[BlockIndex];
|
|
Guid = &WmiEventClass5Guid;
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
{
|
|
return(SRB_STATUS_ERROR);
|
|
}
|
|
}
|
|
|
|
Wnode = (PWNODE_HEADER)CardPtr->EventBuffer;
|
|
|
|
sizeNeeded = sizeof(WNODE_EVENT_REFERENCE);
|
|
|
|
if (sizeNeeded > WMI_EVENT_BUFFER_SIZE)
|
|
{
|
|
ASSERT(FALSE);
|
|
return(SRB_STATUS_ERROR);
|
|
}
|
|
|
|
Wnode->Flags = WNODE_FLAG_EVENT_ITEM |
|
|
WNODE_FLAG_EVENT_REFERENCE |
|
|
WNODE_FLAG_STATIC_INSTANCE_NAMES;
|
|
WnodeER = (PWNODE_EVENT_REFERENCE)Wnode;
|
|
WnodeER->TargetGuid = *Guid;
|
|
WnodeER->TargetDataBlockSize = dataSize + sizeof(WNODE_SINGLE_INSTANCE);
|
|
WnodeER->TargetInstanceIndex = 0;
|
|
|
|
Wnode->Guid = *Guid;
|
|
Wnode->BufferSize = sizeNeeded;
|
|
|
|
ScsiPortNotification(WMIEvent,
|
|
CardPtr,
|
|
Wnode,
|
|
0xff);
|
|
|
|
return(SRB_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
WmiExecuteMethod (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG MethodId,
|
|
IN ULONG InBufferSize,
|
|
IN ULONG BufferAvail,
|
|
IN OUT PUCHAR Buffer
|
|
)
|
|
{
|
|
PHWDEVEXT CardPtr = (PHWDEVEXT)Context;
|
|
ULONG sizeNeeded = 0;
|
|
UCHAR status;
|
|
PSCSI_REQUEST_BLOCK srb = (PSCSI_REQUEST_BLOCK)(DispatchContext->UserContext);
|
|
ULONG bufferUsed;
|
|
ULONG blockIndex;
|
|
ULONG UlongPadSize = (sizeof(ULONG) + 7) & ~7;
|
|
|
|
DebugPrint((1, "WmiExecuteMethod(%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x,\n%x)\n",
|
|
Context,
|
|
DispatchContext,
|
|
GuidIndex,
|
|
InstanceIndex,
|
|
MethodId,
|
|
InBufferSize,
|
|
BufferAvail,
|
|
Buffer));
|
|
|
|
|
|
if (GuidIndex == WmiGetSetData)
|
|
{
|
|
switch(MethodId)
|
|
{
|
|
case 1:
|
|
case 7:
|
|
{
|
|
// SetEc1
|
|
|
|
if (InBufferSize < UlongPadSize)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
sizeNeeded = 0;
|
|
break;
|
|
} else {
|
|
blockIndex = *((PULONG)Buffer);
|
|
if (blockIndex > 3)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
Buffer += UlongPadSize;
|
|
InBufferSize -= UlongPadSize;
|
|
}
|
|
|
|
status = WmiSampSetEc1Worker(CardPtr,
|
|
InBufferSize,
|
|
blockIndex,
|
|
Buffer,
|
|
&bufferUsed);
|
|
sizeNeeded = 0;
|
|
break;
|
|
}
|
|
|
|
case 2:
|
|
case 8:
|
|
{
|
|
// SetEc2
|
|
|
|
if (InBufferSize < UlongPadSize)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
sizeNeeded = 0;
|
|
break;
|
|
} else {
|
|
blockIndex = *((PULONG)Buffer);
|
|
if (blockIndex > 3)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
Buffer += UlongPadSize;
|
|
InBufferSize -= UlongPadSize;
|
|
}
|
|
|
|
status = WmiSampSetEc2Worker(CardPtr,
|
|
InBufferSize,
|
|
blockIndex,
|
|
Buffer,
|
|
&bufferUsed);
|
|
sizeNeeded = 0;
|
|
break;
|
|
}
|
|
|
|
case 3:
|
|
case 9:
|
|
{
|
|
// GetEc1
|
|
|
|
if (InBufferSize != sizeof(ULONG))
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
sizeNeeded = 0;
|
|
break;
|
|
} else {
|
|
blockIndex = *((PULONG)Buffer);
|
|
if (blockIndex > 3)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sizeNeeded = CardPtr->Ec1ActualLength[blockIndex];
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
WmiSampGetActualEc1(CardPtr, Buffer, blockIndex);
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 4:
|
|
case 10:
|
|
{
|
|
// GetEc2
|
|
if (InBufferSize != sizeof(ULONG))
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
sizeNeeded = 0;
|
|
break;
|
|
} else {
|
|
blockIndex = *((PULONG)Buffer);
|
|
if (blockIndex > 3)
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sizeNeeded = CardPtr->Ec2ActualLength[blockIndex];
|
|
if (BufferAvail < sizeNeeded)
|
|
{
|
|
status = SRB_STATUS_DATA_OVERRUN;
|
|
} else {
|
|
WmiSampGetActualEc2(CardPtr, Buffer, blockIndex);
|
|
status = SRB_STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
case 13:
|
|
{
|
|
ScsiPortNotification(WMIReregister,
|
|
CardPtr,
|
|
0xff);
|
|
status = SRB_STATUS_SUCCESS;
|
|
sizeNeeded = 0;
|
|
break;
|
|
}
|
|
|
|
case 5:
|
|
case 11:
|
|
case 6:
|
|
case 12:
|
|
default:
|
|
{
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
}
|
|
} else if (GuidIndex == WmiFireEvent) {
|
|
if (MethodId == 1)
|
|
{
|
|
if (InBufferSize == 3*sizeof(ULONG))
|
|
{
|
|
ULONG wnodeType;
|
|
ULONG dataType;
|
|
ULONG blockIndex;
|
|
|
|
wnodeType = *(PULONG)Buffer;
|
|
Buffer += sizeof(ULONG);
|
|
|
|
dataType = *(PULONG)Buffer;
|
|
Buffer += sizeof(ULONG);
|
|
|
|
blockIndex = *(PULONG)Buffer;
|
|
Buffer += sizeof(ULONG);
|
|
|
|
status = WmiSampFireEvent(CardPtr,
|
|
wnodeType,
|
|
dataType,
|
|
blockIndex);
|
|
|
|
sizeNeeded = 0;
|
|
|
|
} else {
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
} else {
|
|
status = SRB_STATUS_ERROR;
|
|
}
|
|
|
|
ScsiPortWmiPostProcess(
|
|
DispatchContext,
|
|
status,
|
|
sizeNeeded);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOLEAN
|
|
WmiFunctionControl (
|
|
IN PVOID Context,
|
|
IN PSCSIWMI_REQUEST_CONTEXT DispatchContext,
|
|
IN ULONG GuidIndex,
|
|
IN SCSIWMI_ENABLE_DISABLE_CONTROL Function,
|
|
IN BOOLEAN Enable
|
|
)
|
|
{
|
|
UCHAR status = SRB_STATUS_SUCCESS;
|
|
|
|
//
|
|
// TODO: Verify that expensive guids are being enbled and inexpensive ones
|
|
// are not, same with events
|
|
DebugPrint((1, "WmiFunctionControl(%x,\n%x,\n%x,\n%x,\n%x)\n\n",
|
|
Context,
|
|
DispatchContext,
|
|
GuidIndex,
|
|
Function,
|
|
Enable));
|
|
|
|
|
|
ScsiPortWmiPostProcess(
|
|
DispatchContext,
|
|
status,
|
|
0);
|
|
|
|
return(FALSE);
|
|
}
|
|
#endif
|