programming4us
programming4us
ENTERPRISE

Windows 7 : Programming WMI Support (part 3) - Firing WMI Events

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

6. Firing WMI Events

In the Featured Toaster sample driver, the ToasterFireArrivalEvent function shows how to generate a WMI event that has a dynamic instance name. The WMI event contains the name of the device model, which WMI records to log the arrival of this device. The driver calls this function from its EvtDevicePrepareHardware callback to indicate that the device has been configured. Parts of this function are standard WMI tasks and have little to do with KMDF. This discussion focuses on the KMDF-specific code:

NTSTATUS
ToasterFireArrivalEvent(
IN WDFDEIVE Device
)
{
WDFMEMORY memory;
PWNODE_SINGLE_INSTANCE wnode;
ULONG wnodeSize;
ULONG wnodeDataBlockSize;
ULONG wnodeInstanceNameSize;
ULONG size;
ULONG length;
UNICODE_STRING deviceName;
UNICODE_STRING modelName;
NTSTATUS status;

//
// *NOTE*
// WdfWmiFireEvent only fires single instance events at
// the present, so continue to use this method of firing
// events
// *NOTE*
//

RtlInitUnicodeString(&modelName, L"Sonali\0\0");

//
// Get the device name.
//

status = GetDeviceFriendlyName(&Device, &memory);
if(!NT_SUCCESS(status)) {
return status;
}

RtlInitUnicodeString(&deviceName, (PWSTR)
WdfMemoryGetBuffer(memory, NULL));

//
//Determine the amount of wnode information we need.
//

wnodeSize = sizeof(WNODE_SINGLE_INSTANCE);
wnodeInstanceNameSize = deviceName.Length + sizeof(USHORT);
wnodeDataBlockSize = modelName.Length + sizeof(USHORT);

size = wnodeSize + wnodeInstanceNameSize +
wnodeDataBlockSize;


//
// Allocate memory for the WNODE from NonPagedPool
//

wnode = ExAllocatePoolWithTag(NoPagedPool, size,
TOASTER_POOL_TAG);

If(NULL != wnode) {
RtlZeroMemory(wnode, size);
wnode->WnodeHeader.BufferSize = size
wnode->WnodeHeader.ProviderId =
IoWMIDeviceObjectToProviderId(
WdfDeviceWdmGetDeviceObject(Device));
wnode->WnodeHeader.Version = 1;
KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);

RtlCopyMemory(&wnode->WnodeHeader.Guid,
&TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT,
Sizeof(GUID));

//
// Set flags to indicate that you are creating dynamic
// instance names. This driver supports dynamic
// instances because it can fire the events at any time.
// If it used static instance names instead, it could only
// fire events after WMI queries for IRP_MN_REGINFO,
// which happens after the device has been started.
// Note also that if you are firing an event after the
// device is started, you should
// check whether the event is enabled, because that
// indicates that someone is interested in receiving the
// event. Why waste system resources by firing an event
// when nobody is interested?
//

wnode->WnodeHeader.Flags = WNODE_FLAG_EVENT_ITEM |
WNODE_FLAG_SINGLE_INSTANCE;

wnode->OffsetInstanceName = wnodeSize;
wnode->DataBlockOffset= wnodeSize + wnodeInstanceNameSize;
wnode->SizeDataBlock = wnodeDataBlockSize;

//
// Write the instance name.
//

size -= wnodeSize;
status = WDF_WMI_BUFFER_APPEND_STRING(
WDF_PTR_ADD_OFFSET(wnode, wnod->OffsetInstance),
size,
&deviceName,
&length
);

//
// Size was precomputed, so this should never fail.
//

ASSERT(NT_SUCCESS(status));


//
// Write the data, which is the model name as a
string.
//

size = -= wnodeInstanceNameSize;
WDF_WMI_BUFFER_APPEND_STRING(
WDF_PTR_ADD_OFFSET(wnode, wnode->DataBlockOffset),
size,
&modelName,
&length
);

//
// Size was precomputed, so this should never fail.
//

ASSERT(NT_SUCCESS(status));

//
// Indicate the event to WMI. WMI will take care of
// freeing the WMI struct back to pool.
//

status = IoWMIWriteEvent(wnode);

if(!NT_SUCCESS(status)) {
KdPrint(("IoWMIWriteEvent failed %x\n", status));
ExFreePool(wnode);
}
}
else {
status = STATUS_INSUFFICIENT_RESOURCES;
}

//
// Free the memory allocated by GetDeviceFriendlyName
// function.
//

WdfObjectDelete(memory);
return status;
}


ToasterfireArrivalEvent first defines a model name for its device and then retrieves the friendly name for the device by calling the internal routine GetDeviceFriendlyName. GetDeviceFriendlyName takes a handle to the device object and returns a handle to a WDFMEMORY object that contains a buffer that holds the name.

The driver passes the returned WDFMEMORY object handle to WdfGetMemoryBuffer to retrieve a pointer to the buffer itself and calls RtlUnicodeString to copy the contents of the buffer into the Unicode string variable deviceName, as follows:

RtlInitUnicodeString(&deviceName,
(PWSTR)WdfMemoryGetBuffer(memory, NULL));

The driver now constructs the WMI event by using standard WMI structures and routines (defined in wmistr.h) along with standard Windows device driver interfaces (DDIs), which are defined in wdm.h and ntddk.h. The driver allocates memory from the nonpaged pool for the WNODE_SINGLE_INSTANCE structure (wnode) by calling ExAllocatePoolWithTag. If memory allocation succeeds, the driver zero-initializes the wnode structure and then fills it in the usual way for WMI. To supply the WMI provider ID, the driver calls IoWmiDeviceObjectToProviderId, passing as a parameter the WDM device object returned by WdfDeviceWdmGetDeviceObject.

After the wnode structure is filled, the driver calls the WDF_WMI_BUFFER_APPEND_STRING function once to append the instance name to the WNODE_SINGLE_INSTANCE structure and a second time to append the model name.

Finally, the driver fires the event by calling IoWMIWriteEvent. WMI records the data and frees the memory allocated for the WNODE_SINGLE_INSTANCE structure.

Other  
  •  Parallel Programming with Microsoft Visual Studio 2010 : PLINQ Operators and Methods (part 2)
  •  Parallel Programming with Microsoft Visual Studio 2010 : PLINQ Operators and Methods (part 1)
  •  Parallel Programming with Microsoft Visual Studio 2010 : Introduction to LINQ (part 2) - PLINQ
  •  Parallel Programming with Microsoft Visual Studio 2010 : Introduction to LINQ (part 1) - Execute a LINQ query and then iterate and display the results
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 7)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 6) - One-to-Many Joins - The join Operator
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 5) - One-to-One Join Performance Comparisons
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 4)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 3)
  •  LINQ to Objects : How to Join with Data in Another Sequence (part 2) - One-to-One Joins - The join Operator
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    - Messages forwarded by Outlook rule go nowhere
    - Create and Deploy Windows 7 Image
    - How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
    - Creating and using an unencrypted cookie in ASP.NET
    - Directories
    - Poor Performance on Sharepoint 2010 Server
    - SBS 2008 ~ The e-mail alias already exists...
    - Public to Private IP - DNS Changes
    - Send Email from Winform application
    - How to create a .mdb file from ms sql server database.......
    programming4us programming4us
    programming4us
     
     
    programming4us