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.
588 lines
14 KiB
588 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wmi.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that handles the wmi IRPs for the
|
|
serial driver.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History :
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
// Prototypes
|
|
|
|
|
|
// -- CARD WMI Routines --
|
|
NTSTATUS
|
|
SpeedCard_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
|
|
OUT PUNICODE_STRING pInstanceName,
|
|
OUT PUNICODE_STRING *pRegistryPath,
|
|
OUT PUNICODE_STRING pMofResourceName,
|
|
OUT PDEVICE_OBJECT *pPdo);
|
|
NTSTATUS
|
|
SpeedCard_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
|
|
IN ULONG OutBufferSize, OUT PUCHAR pBuffer);
|
|
NTSTATUS
|
|
SpeedCard_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG BufferSize, IN PUCHAR pBuffer);
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG DataItemId, IN ULONG BufferSize,
|
|
IN PUCHAR pBuffer);
|
|
|
|
// End of prototypes.
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, SpeedCard_WmiInitializeWmilibContext)
|
|
#pragma alloc_text(PAGE, SpeedCard_WmiQueryRegInfo)
|
|
#pragma alloc_text(PAGE, SpeedCard_WmiQueryDataBlock)
|
|
#pragma alloc_text(PAGE, SpeedCard_WmiSetDataBlock)
|
|
#pragma alloc_text(PAGE, SpeedCard_WmiSetDataItem)
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define WMI_FAST_CARD_PROP 0
|
|
|
|
GUID FastCardWmiPropGuid = SPX_SPEED_WMI_FAST_CARD_PROP_GUID; // Fast Card Properties
|
|
|
|
|
|
WMIGUIDREGINFO SpeedCard_WmiGuidList[] =
|
|
{
|
|
{ &FastCardWmiPropGuid, 1, 0 },
|
|
};
|
|
|
|
|
|
#define SpeedCard_WmiGuidCount (sizeof(SpeedCard_WmiGuidList) / sizeof(WMIGUIDREGINFO))
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiInitializeWmilibContext(IN PWMILIB_CONTEXT WmilibContext)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will initialize the wmilib context structure with the
|
|
guid list and the pointers to the wmilib callback functions. This routine
|
|
should be called before calling IoWmiRegistrationControl to register
|
|
your device object.
|
|
|
|
Arguments:
|
|
|
|
WmilibContext is pointer to the wmilib context.
|
|
|
|
Return Value:
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PAGED_CODE();
|
|
|
|
RtlZeroMemory(WmilibContext, sizeof(WMILIB_CONTEXT));
|
|
|
|
WmilibContext->GuidCount = SpeedCard_WmiGuidCount;
|
|
WmilibContext->GuidList = SpeedCard_WmiGuidList;
|
|
|
|
WmilibContext->QueryWmiRegInfo = SpeedCard_WmiQueryRegInfo;
|
|
WmilibContext->QueryWmiDataBlock = SpeedCard_WmiQueryDataBlock;
|
|
WmilibContext->SetWmiDataBlock = SpeedCard_WmiSetDataBlock;
|
|
WmilibContext->SetWmiDataItem = SpeedCard_WmiSetDataItem;
|
|
WmilibContext->ExecuteWmiMethod = NULL; //SpeedCard_WmiExecuteMethod
|
|
WmilibContext->WmiFunctionControl = NULL; //SpeedCard_WmiFunctionControl;
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// WMI System Call back functions
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
|
|
OUT PUNICODE_STRING pInstanceName,
|
|
OUT PUNICODE_STRING *pRegistryPath,
|
|
OUT PUNICODE_STRING MofResourceName,
|
|
OUT PDEVICE_OBJECT *pPdo)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
|
|
|
|
PAGED_CODE();
|
|
|
|
*pRegFlags = WMIREG_FLAG_INSTANCE_PDO;
|
|
*pRegistryPath = &SavedRegistryPath;
|
|
*pPdo = pCard->PDO; // Card device object's PDO.
|
|
|
|
RtlInitUnicodeString(MofResourceName, L"MofResource");
|
|
|
|
return(status);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
|
|
IN ULONG OutBufferSize, OUT PUCHAR pBuffer)
|
|
{
|
|
PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
|
|
NTSTATUS status;
|
|
ULONG size = 0;
|
|
|
|
PAGED_CODE();
|
|
|
|
switch(GuidIndex)
|
|
{
|
|
case WMI_FAST_CARD_PROP:
|
|
{
|
|
size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP);
|
|
|
|
if(OutBufferSize < size)
|
|
{
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
|
|
*pInstanceLengthArray = size;
|
|
|
|
// Update items that may have changed.
|
|
|
|
if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
|
|
((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt = TRUE;
|
|
else
|
|
((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt = FALSE;
|
|
|
|
if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
|
|
((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR = TRUE;
|
|
else
|
|
((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR = FALSE;
|
|
|
|
status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
status = STATUS_WMI_GUID_NOT_FOUND;
|
|
break;
|
|
|
|
}
|
|
|
|
status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
|
|
|
|
return(status);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG BufferSize, IN PUCHAR pBuffer)
|
|
{
|
|
PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
|
|
NTSTATUS status;
|
|
ULONG size = 0;
|
|
|
|
PAGED_CODE();
|
|
|
|
switch(GuidIndex)
|
|
{
|
|
case WMI_FAST_CARD_PROP:
|
|
{
|
|
// Device stopping?, Device not powered?, Device not started?
|
|
if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pCard, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
|
|
|
|
size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP);
|
|
|
|
if(BufferSize < size)
|
|
{
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
|
|
// Currently these options are only settable on PCI-Fast 16 and PCI-Fast 16 FMC
|
|
if((pCard->CardType != Fast16_Pci) && (pCard->CardType != Fast16FMC_Pci))
|
|
{
|
|
status = STATUS_WMI_READ_ONLY;
|
|
break;
|
|
}
|
|
|
|
|
|
if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR)
|
|
{
|
|
// This option is not settable on PCI-Fast 16 FMC
|
|
if((pCard->CardType != Fast16_Pci))
|
|
{
|
|
status = STATUS_WMI_READ_ONLY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt)
|
|
{
|
|
if(!(pCard->CardOptions & DELAY_INTERRUPT_OPTION)) // If not already set then set the option
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardToDelayInterrupt, pCard))
|
|
{
|
|
pCard->CardOptions |= DELAY_INTERRUPT_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
if(pCard->CardOptions & DELAY_INTERRUPT_OPTION) // If set then unset the option.
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToDelayInterrupt, pCard))
|
|
{
|
|
pCard->CardOptions &= ~DELAY_INTERRUPT_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR)
|
|
{
|
|
if(!(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)) // If not already set then set the option
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardToUseDTRInsteadOfRTS, pCard))
|
|
{
|
|
pCard->CardOptions |= SWAP_RTS_FOR_DTR_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION) // If set then unset the option.
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToUseDTRInsteadOfRTS, pCard))
|
|
{
|
|
pCard->CardOptions &= ~SWAP_RTS_FOR_DTR_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
if(SPX_SUCCESS(status)) // If set was successful then save setting to registry.
|
|
{
|
|
HANDLE PnPKeyHandle;
|
|
|
|
// Open PnP Reg Key and save new setting to registry.
|
|
if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
|
|
{
|
|
ULONG TmpReg = 0;
|
|
|
|
if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
|
|
TmpReg = 0x1;
|
|
else
|
|
TmpReg = 0x0;
|
|
|
|
Spx_PutRegistryKeyValue( PnPKeyHandle, DELAY_INTERRUPT, wcslen(DELAY_INTERRUPT) * sizeof(WCHAR), REG_DWORD,
|
|
&TmpReg, sizeof(ULONG));
|
|
|
|
|
|
if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
|
|
TmpReg = 0x1;
|
|
else
|
|
TmpReg = 0x0;
|
|
|
|
|
|
Spx_PutRegistryKeyValue( PnPKeyHandle, SWAP_RTS_FOR_DTR, wcslen(SWAP_RTS_FOR_DTR) * sizeof(WCHAR), REG_DWORD,
|
|
&TmpReg, sizeof(ULONG));
|
|
|
|
ZwClose(PnPKeyHandle);
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
status = STATUS_WMI_GUID_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
|
|
|
|
return(status);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SpeedCard_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
|
|
IN ULONG GuidIndex, IN ULONG InstanceIndex,
|
|
IN ULONG DataItemId, IN ULONG BufferSize,
|
|
IN PUCHAR pBuffer)
|
|
{
|
|
PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
|
|
NTSTATUS status;
|
|
ULONG size = 0;
|
|
|
|
PAGED_CODE();
|
|
|
|
switch(GuidIndex)
|
|
{
|
|
case WMI_FAST_CARD_PROP:
|
|
{
|
|
HANDLE PnPKeyHandle;
|
|
|
|
// Device stopping?, Device not powered?, Device not started?
|
|
if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pCard, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
|
|
|
|
switch(DataItemId)
|
|
{
|
|
case SPX_SPEED_WMI_FAST_CARD_PROP_DelayCardIntrrupt_ID:
|
|
{
|
|
size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP_DelayCardIntrrupt_SIZE);
|
|
|
|
if(BufferSize < size)
|
|
{
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
|
|
if((pCard->CardType != Fast16_Pci) && (pCard->CardType != Fast16FMC_Pci))
|
|
{
|
|
status = STATUS_WMI_READ_ONLY;
|
|
break;
|
|
}
|
|
|
|
|
|
if(*pBuffer)
|
|
{
|
|
if(!(pCard->CardOptions & DELAY_INTERRUPT_OPTION)) // If not already set then set the option
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardToDelayInterrupt, pCard))
|
|
{
|
|
pCard->CardOptions |= DELAY_INTERRUPT_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
if(pCard->CardOptions & DELAY_INTERRUPT_OPTION) // If set then unset the option.
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToDelayInterrupt, pCard))
|
|
{
|
|
pCard->CardOptions &= ~DELAY_INTERRUPT_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
if(SPX_SUCCESS(status)) // If we set the option successfully then save the setting to the registry.
|
|
{
|
|
// Open PnP Reg Key and save new setting to registry.
|
|
if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
|
|
{
|
|
ULONG TmpReg = 0;
|
|
|
|
if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
|
|
TmpReg = 0x1;
|
|
else
|
|
TmpReg = 0x0;
|
|
|
|
Spx_PutRegistryKeyValue( PnPKeyHandle, DELAY_INTERRUPT, wcslen(DELAY_INTERRUPT) * sizeof(WCHAR), REG_DWORD,
|
|
&TmpReg, sizeof(ULONG));
|
|
|
|
ZwClose(PnPKeyHandle);
|
|
}
|
|
}
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
case SPX_SPEED_WMI_FAST_CARD_PROP_SwapRTSForDTR_ID:
|
|
{
|
|
size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP_SwapRTSForDTR_SIZE);
|
|
|
|
if(BufferSize < size)
|
|
{
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
|
|
if(pCard->CardType != Fast16_Pci)
|
|
{
|
|
status = STATUS_WMI_READ_ONLY;
|
|
break;
|
|
}
|
|
|
|
if(*pBuffer)
|
|
{
|
|
if(!(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)) // If not already set then set the option
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardToUseDTRInsteadOfRTS, pCard))
|
|
{
|
|
pCard->CardOptions |= SWAP_RTS_FOR_DTR_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION) // If set then unset the option.
|
|
{
|
|
if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToUseDTRInsteadOfRTS, pCard))
|
|
{
|
|
pCard->CardOptions &= ~SWAP_RTS_FOR_DTR_OPTION;
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_WMI_SET_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
if(SPX_SUCCESS(status)) // If we set the option successfully then save the setting to the registry.
|
|
{
|
|
// Open PnP Reg Key and save new setting to registry.
|
|
if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
|
|
{
|
|
ULONG TmpReg = 0;
|
|
|
|
if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
|
|
TmpReg = 0x1;
|
|
else
|
|
TmpReg = 0x0;
|
|
|
|
Spx_PutRegistryKeyValue( PnPKeyHandle, SWAP_RTS_FOR_DTR, wcslen(SWAP_RTS_FOR_DTR) * sizeof(WCHAR), REG_DWORD,
|
|
&TmpReg, sizeof(ULONG));
|
|
|
|
ZwClose(PnPKeyHandle);
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
{
|
|
status = STATUS_WMI_ITEMID_NOT_FOUND;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
status = STATUS_WMI_GUID_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
|
|
|
|
return(status);
|
|
}
|
|
|
|
|
|
|
|
|
|
|