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.
674 lines
20 KiB
674 lines
20 KiB
/*++
|
|
|
|
Copyright(c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
nlbwmi.c
|
|
|
|
Abstract:
|
|
|
|
Network Load Balancing (NLB)
|
|
Driver - WMI event generation
|
|
|
|
Author:
|
|
|
|
karthicn
|
|
|
|
--*/
|
|
|
|
|
|
#include "wlbsparm.h"
|
|
#include <wmistr.h>
|
|
#include <wmiguid.h>
|
|
#include <wmilib.h>
|
|
#include "main.h"
|
|
#include "univ.h"
|
|
#include "nlbwmimof.h"
|
|
#include "nlbwmi.h"
|
|
#include "nlbwmi.tmh"
|
|
|
|
//
|
|
// MOF Resource Name
|
|
//
|
|
WCHAR NLBMofResourceName[] = L"NLBMofResource";
|
|
|
|
//
|
|
// Base Instance Name
|
|
//
|
|
WCHAR NLBBaseInstanceName[] = L"NLB_Block";
|
|
|
|
|
|
// NLB Event Guids - the MicrosoftNLB* variables are autogenerated (in nlbwmimof.h)
|
|
GUID NodeControlEventGuid = MicrosoftNLB_NodeControlEventGuid;
|
|
GUID PortRuleControlEventGuid = MicrosoftNLB_PortControlEventGuid;
|
|
GUID ConvergingEventGuid = MicrosoftNLB_ConvergingEventGuid;
|
|
GUID ConvergedEventGuid = MicrosoftNLB_ConvergedEventGuid;
|
|
GUID StartupEventGuid = MicrosoftNLB_StartupEventGuid;
|
|
GUID ShutdownEventGuid = MicrosoftNLB_ShutdownEventGuid;
|
|
|
|
// NLB Event Guid Registration Information
|
|
WMIGUIDREGINFO NlbWmiGuidList[] =
|
|
{
|
|
{
|
|
&NodeControlEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
{
|
|
&PortRuleControlEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
{
|
|
&ConvergingEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
{
|
|
&ConvergedEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
{
|
|
&StartupEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
{
|
|
&ShutdownEventGuid,
|
|
1,
|
|
WMIREG_FLAG_EVENT_ONLY_GUID
|
|
},
|
|
// Add new event info here
|
|
};
|
|
|
|
#define NlbWmiGuidCount (ULONG)(sizeof(NlbWmiGuidList)/sizeof(WMIGUIDREGINFO))
|
|
|
|
|
|
// NLB Event Information
|
|
NLB_WMI_EVENT NlbWmiEvents[] =
|
|
{
|
|
{
|
|
&NodeControlEventGuid,
|
|
FALSE
|
|
},
|
|
{
|
|
&PortRuleControlEventGuid,
|
|
FALSE
|
|
},
|
|
{
|
|
&ConvergingEventGuid,
|
|
FALSE
|
|
},
|
|
{
|
|
&ConvergedEventGuid,
|
|
FALSE
|
|
},
|
|
{
|
|
&StartupEventGuid,
|
|
FALSE
|
|
},
|
|
{
|
|
&ShutdownEventGuid,
|
|
FALSE
|
|
},
|
|
// Add new event info here as well
|
|
};
|
|
|
|
//
|
|
// Prototype declarations
|
|
//
|
|
|
|
NTSTATUS
|
|
NlbWmi_Query_RegInfo(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
OUT ULONG *RegFlags,
|
|
OUT PUNICODE_STRING InstanceName,
|
|
OUT PUNICODE_STRING *RegistryPath,
|
|
OUT PUNICODE_STRING MofResourceName,
|
|
OUT PDEVICE_OBJECT *Pdo
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
NlbWmi_Query_DataBlock(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG InstanceCount,
|
|
IN OUT PULONG InstanceLengthArray,
|
|
IN ULONG BufferAvail,
|
|
OUT PUCHAR Buffer
|
|
);
|
|
|
|
NTSTATUS
|
|
NlbWmi_Function_Control(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN WMIENABLEDISABLECONTROL Function,
|
|
IN BOOLEAN Enable
|
|
);
|
|
|
|
//
|
|
// WMI Helper Library context
|
|
//
|
|
WMILIB_CONTEXT NlbWmiLibContext =
|
|
{
|
|
NlbWmiGuidCount,
|
|
NlbWmiGuidList,
|
|
NlbWmi_Query_RegInfo,
|
|
NlbWmi_Query_DataBlock,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NlbWmi_Function_Control
|
|
};
|
|
|
|
/*
|
|
Name : NlbWmi_Initialize
|
|
Description : This function initializes the data structures and registers the supported guids with the wmi system
|
|
Arguments : None
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS NlbWmi_Initialize()
|
|
{
|
|
ULONG idx;
|
|
NTSTATUS status;
|
|
|
|
TRACE_VERB("->%!FUNC!");
|
|
|
|
/* Disable event generation for all events */
|
|
for (idx = 0 ; idx < NlbWmiGuidCount ; idx++)
|
|
{
|
|
NlbWmiEvents[idx].Enable = FALSE;
|
|
}
|
|
|
|
if (univ_device_object != NULL)
|
|
{
|
|
/* Register with WMI */
|
|
status = IoWMIRegistrationControl(univ_device_object, WMIREG_ACTION_REGISTER);
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
TRACE_CRIT("%!FUNC! IoWMIRegistrationControl(DeviceObject : %p, REGISTER) returned Error : 0x%x",univ_device_object, status);
|
|
}
|
|
}
|
|
else // Device Object is NULL
|
|
{
|
|
status = STATUS_INVALID_DEVICE_OBJECT_PARAMETER;
|
|
TRACE_CRIT("%!FUNC! Device Object is NULL, Could not call IoWMIRegistrationControl() to register with WMI");
|
|
}
|
|
|
|
TRACE_VERB("<-%!FUNC! return : 0x%x", status);
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_Shutdown
|
|
Description : This function de-registers with the wmi system
|
|
Arguments : None
|
|
Return Value: void
|
|
*/
|
|
|
|
VOID NlbWmi_Shutdown()
|
|
{
|
|
NTSTATUS ntStatus;
|
|
|
|
TRACE_VERB("->%!FUNC!");
|
|
|
|
if (univ_device_object != NULL)
|
|
{
|
|
/* DeRegister with WMI */
|
|
ntStatus = IoWMIRegistrationControl(univ_device_object, WMIREG_ACTION_DEREGISTER);
|
|
if (ntStatus != STATUS_SUCCESS)
|
|
{
|
|
TRACE_CRIT("%!FUNC! IoWMIRegistrationControl(DeviceObject : %p, DEREGISTER) returned Error : 0x%x",univ_device_object, ntStatus);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE_CRIT("%!FUNC! Device Object is NULL, Could not call IoWMIRegistrationControl() to deregister with WMI");
|
|
}
|
|
|
|
TRACE_VERB("<-%!FUNC!");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_System_Control
|
|
Description : This function is responsible for handling the IRP_MJ_SYSTEM_CONTROL irps. It uses the wmi helper
|
|
library function to crack the irp to have the appropriate call back functions called
|
|
Arguments : Device Object, Irp
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS NlbWmi_System_Control (PVOID DeviceObject, PIRP pIrp)
|
|
{
|
|
NTSTATUS status;
|
|
SYSCTL_IRP_DISPOSITION disposition;
|
|
|
|
TRACE_VERB("->%!FUNC!");
|
|
|
|
//
|
|
// Call Wmilib helper function to crack the irp. If this is a wmi irp
|
|
// that is targetted for the supported guids, then WmiSystemControl will callback
|
|
// at the appropriate callback routine.
|
|
//
|
|
status = WmiSystemControl(
|
|
&NlbWmiLibContext,
|
|
DeviceObject,
|
|
pIrp,
|
|
&disposition
|
|
);
|
|
|
|
switch(disposition)
|
|
{
|
|
case IrpProcessed:
|
|
//
|
|
// This irp has been processed and may be completed or pending.
|
|
//
|
|
break;
|
|
|
|
case IrpNotCompleted:
|
|
//
|
|
// This irp has not been completed, but has been fully processed.
|
|
// so we need to complete it
|
|
// (Must be a IRP_MN_REG_INFO)
|
|
//
|
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
|
|
default:
|
|
case IrpNotWmi:
|
|
case IrpForward:
|
|
{
|
|
TRACE_CRIT("%!FUNC! WmiSystemControl returned disposition : 0x%x, Unexpected", disposition);
|
|
pIrp->IoStatus.Status = status;
|
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if( !NT_SUCCESS( status ))
|
|
{
|
|
TRACE_CRIT("%!FUNC! WmiSystemControl returned error : 0x%x", status);
|
|
}
|
|
|
|
TRACE_VERB("<-%!FUNC! return : 0x%x", status);
|
|
return status;
|
|
} // NlbWmi_System_Control
|
|
|
|
/*
|
|
Name : NlbWmi_Query_RegInfo
|
|
Description : This function is called back by the Wmi helper library to process a IRP_MN_REG_INFO irp. It
|
|
registers the Instance name, registry path & Mof resource name with wmi. For more information
|
|
about this function, please look in the DDK under "WMI library Callback Routines"->"DpWmiQueryReginfo"
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS
|
|
NlbWmi_Query_RegInfo(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
OUT ULONG *RegFlags,
|
|
OUT PUNICODE_STRING InstanceName,
|
|
OUT PUNICODE_STRING *RegistryPath,
|
|
OUT PUNICODE_STRING MofResourceName,
|
|
OUT PDEVICE_OBJECT *Pdo
|
|
)
|
|
{
|
|
PAGED_CODE();
|
|
|
|
TRACE_VERB("->%!FUNC!");
|
|
|
|
//
|
|
// Tell WMI to generate instance names off of a static base name
|
|
//
|
|
*RegFlags = WMIREG_FLAG_INSTANCE_BASENAME;
|
|
|
|
//
|
|
// Set our base instance name. WmiLib will call ExFreePool on the buffer
|
|
// of the string, so we need to allocate it from paged pool.
|
|
//
|
|
InstanceName->Length = wcslen( NLBBaseInstanceName ) * sizeof( WCHAR );
|
|
InstanceName->MaximumLength = InstanceName->Length + sizeof( UNICODE_NULL );
|
|
InstanceName->Buffer = ExAllocatePoolWithTag(
|
|
PagedPool,
|
|
InstanceName->MaximumLength,
|
|
UNIV_POOL_TAG
|
|
);
|
|
if( NULL != InstanceName->Buffer )
|
|
{
|
|
RtlCopyMemory(
|
|
InstanceName->Buffer,
|
|
NLBBaseInstanceName,
|
|
InstanceName->Length
|
|
);
|
|
InstanceName->Buffer[InstanceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
|
}
|
|
else
|
|
{
|
|
TRACE_CRIT("%!FUNC! Error allocating memory");
|
|
TRACE_VERB("<-%!FUNC! return status = STATUS_INSUFFICIENT_RESOURCES");
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Return the registry path for this driver. This is required so WMI
|
|
// can find your driver image and can attribute any eventlog messages to
|
|
// your driver.
|
|
//
|
|
*RegistryPath = &DriverEntryRegistryPath;
|
|
|
|
//
|
|
// Return the name specified in the .rc file of the resource which
|
|
// contains the binary mof data.
|
|
//
|
|
RtlInitUnicodeString(MofResourceName, NLBMofResourceName);
|
|
|
|
TRACE_VERB("<-%!FUNC! return=0x%x", STATUS_SUCCESS);
|
|
return STATUS_SUCCESS;
|
|
} // NlbWmi_Query_RegInfo
|
|
|
|
/*
|
|
Name : NlbWmi_Query_DataBlock
|
|
Description : This function is called back by the Wmi helper library to process IRP_MN_QUERY_ALL_DATA
|
|
& IRP_MN_QUERY_SINGLE_INSTANCE irps. We DO NOT SUPPORT these irps. However, this is a
|
|
required callback and hence we implement it. We DO NOT EXPECT THIS FUNCTION TO BE CALLED.
|
|
For more information about this function, please look in the DDK under
|
|
"WMI library Callback Routines"->"DpWmiQueryDataBlock"
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS
|
|
NlbWmi_Query_DataBlock(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG InstanceCount,
|
|
IN OUT PULONG InstanceLengthArray,
|
|
IN ULONG BufferAvail,
|
|
OUT PUCHAR Buffer
|
|
)
|
|
|
|
{
|
|
NTSTATUS status;
|
|
|
|
PAGED_CODE();
|
|
|
|
TRACE_VERB("->%!FUNC!");
|
|
|
|
status = WmiCompleteRequest(
|
|
DeviceObject,
|
|
Irp,
|
|
STATUS_WMI_GUID_NOT_FOUND,
|
|
0,
|
|
IO_NO_INCREMENT
|
|
);
|
|
|
|
TRACE_VERB("<-%!FUNC! return=0x%x", status);
|
|
return status;
|
|
} // NlbWmi_Query_DataBlock
|
|
|
|
|
|
/*
|
|
Name : NlbWmi_Function_Control
|
|
Description : This function is called back by the Wmi helper library to process IRP_MN_ENABLE_EVENTS,
|
|
IRP_MN_DISABLE_EVENTS, IRP_MN_ENABLE_COLLECTION & IRP_MN_DISABLE_COLLECTION irps. We only
|
|
support IRP_MN_ENABLE_EVENTS & IRP_MN_DISABLE_EVENTS irps. The function enables/disables
|
|
events generation. For more information about this function, please look in the DDK under
|
|
"WMI library Callback Routines"->"DpWmiQueryReginfo"
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS
|
|
NlbWmi_Function_Control(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN WMIENABLEDISABLECONTROL Function,
|
|
IN BOOLEAN Enable
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
PAGED_CODE();
|
|
|
|
TRACE_VERB("->%!FUNC! %ls Event Index : %d", Enable ? L"ENABLE" : L"DISABLE", GuidIndex);
|
|
|
|
if( WmiEventControl == Function )
|
|
{
|
|
// Verify that the guid index is in the range 0 - (NlbWmiGuidCount - 1)
|
|
// Also, verify that the guid has not been flagged as removed. Although
|
|
// we never flag a guid as being removed, do this check as part of
|
|
// following "best practices".
|
|
if( (GuidIndex < NlbWmiGuidCount)
|
|
&& !(NlbWmiGuidList[GuidIndex].Flags & WMIREG_FLAG_REMOVE_GUID))
|
|
{
|
|
NlbWmiEvents[GuidIndex].Enable = Enable;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Invalid guid index.
|
|
//
|
|
|
|
status = STATUS_WMI_GUID_NOT_FOUND;
|
|
|
|
TRACE_CRIT("%!FUNC! Invalid WMI guid or guid flagged as removed, guid index: %d", GuidIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We currently don't have any (expensive) data blocks
|
|
//
|
|
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
TRACE_CRIT("%!FUNC! Invalid Device Request");
|
|
}
|
|
|
|
status = WmiCompleteRequest(
|
|
DeviceObject,
|
|
Irp,
|
|
status,
|
|
0,
|
|
IO_NO_INCREMENT
|
|
);
|
|
|
|
TRACE_VERB("<-%!FUNC! return status = 0x%x", status);
|
|
return status;
|
|
} // NlbWmi_Function_Control
|
|
|
|
/*
|
|
Name : NlbWmi_Fire_Event
|
|
Description : This function fires wmi events. It allocates memory, fills it in with the
|
|
incoming event data and calls WmiFireEvent to fire the event.
|
|
Arguments : Event Id, Event Data (statically allocated)
|
|
Return Value: status
|
|
*/
|
|
|
|
NTSTATUS NlbWmi_Fire_Event(NlbWmiEventId EventId, PVOID pvInEventData, ULONG ulInEventDataSize)
|
|
{
|
|
NTSTATUS status;
|
|
PVOID pvOutEventData;
|
|
|
|
TRACE_VERB("->%!FUNC! Event : %d", EventId);
|
|
|
|
if (ulInEventDataSize > 0)
|
|
{
|
|
pvOutEventData = ExAllocatePoolWithTag(NonPagedPool, ulInEventDataSize, UNIV_POOL_TAG);
|
|
if (pvOutEventData == NULL)
|
|
{
|
|
TRACE_CRIT("%!FUNC! Error allocating memory");
|
|
TRACE_VERB("<-%!FUNC! return status = STATUS_INSUFFICIENT_RESOURCES");
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlCopyMemory(pvOutEventData, pvInEventData, ulInEventDataSize);
|
|
}
|
|
else
|
|
{
|
|
pvOutEventData = NULL;
|
|
}
|
|
|
|
status = WmiFireEvent(univ_device_object, NlbWmiEvents[EventId].pGuid, 0, ulInEventDataSize, pvOutEventData);
|
|
if( !NT_SUCCESS( status ))
|
|
{
|
|
TRACE_CRIT("%!FUNC! WmiFireEvent returned error : 0x%x", status);
|
|
}
|
|
|
|
TRACE_VERB("<-%!FUNC! return status = 0x%x", status);
|
|
return status;
|
|
} // NlbWmi_Fire_Event
|
|
|
|
|
|
// This macro fills in the common properties(Adapter Guid, IP Address, Host priority) of all events
|
|
#define FillCommonProperties() \
|
|
{ \
|
|
Event.AdapterGuid[0] = sizeof(Event.AdapterGuid) - sizeof(Event.AdapterGuid[0]); \
|
|
wcsncpy(&(Event.AdapterGuid[1]), univ_adapters[ctxtp->adapter_id].device_name + 8, Event.AdapterGuid[0]/sizeof(WCHAR)); \
|
|
Event.ClusterIPAddress[0] = sizeof(Event.ClusterIPAddress) - sizeof(Event.ClusterIPAddress[0]); \
|
|
wcsncpy(&(Event.ClusterIPAddress[1]), ctxtp->params.cl_ip_addr, Event.ClusterIPAddress[0]/sizeof(WCHAR)); \
|
|
Event.HostPriority = ctxtp->params.host_priority; \
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_Fire_NodeControlEvent
|
|
Description : This function fires Node Control events. It extracts the common event properties
|
|
(out of the given pointer to the MAIN_CTXT structure) and fills in a local
|
|
structure. It also fills in Node Control Event specific fields from the arguments
|
|
passed to it. It then fires the actual event by calling NlbWmi_Fire_Event.
|
|
Arguments : Pointer to MAIN_CTXT, NodeControlEventId
|
|
Return Value: void
|
|
*/
|
|
|
|
void NlbWmi_Fire_NodeControlEvent(PMAIN_CTXT ctxtp, NodeControlEventId Id)
|
|
{
|
|
MicrosoftNLB_NodeControlEvent Event;
|
|
|
|
TRACE_VERB("->%!FUNC! Event : %d", Id);
|
|
|
|
NdisZeroMemory(&Event, MicrosoftNLB_NodeControlEvent_SIZE);
|
|
|
|
// Fill in common properties - Adapter Guid, Cluster IP Address & Host Priority
|
|
FillCommonProperties()
|
|
|
|
// Fill event specific properties
|
|
Event.Id = Id;
|
|
|
|
// Fire the event
|
|
NlbWmi_Fire_Event(NodeControlEvent, &Event, MicrosoftNLB_NodeControlEvent_SIZE);
|
|
|
|
TRACE_VERB("<-%!FUNC!");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_Fire_PortControlEvent
|
|
Description : This function fires Port Control events. It extracts the common event properties
|
|
(out of the given pointer to the MAIN_CTXT structure) and fills in a local
|
|
structure. It also fills in Port Control Event specific fields (id, vip, port) from the arguments
|
|
passed to it. It then fires the actual event by calling NlbWmi_Fire_Event.
|
|
Arguments : Pointer to MAIN_CTXT, PortControlEventId, Vip, Port
|
|
Return Value: void
|
|
*/
|
|
|
|
void NlbWmi_Fire_PortControlEvent(PMAIN_CTXT ctxtp, PortControlEventId Id, WCHAR *pwcVip, ULONG ulPort)
|
|
{
|
|
MicrosoftNLB_PortControlEvent Event;
|
|
|
|
TRACE_VERB("->%!FUNC! Event : %d, Vip : %ls, Start Port : %d", Id, pwcVip, ulPort);
|
|
|
|
NdisZeroMemory(&Event, MicrosoftNLB_PortControlEvent_SIZE);
|
|
|
|
// Fill in common properties - Adapter Guid, Cluster IP Address & Host Priority
|
|
FillCommonProperties()
|
|
|
|
// Fill event specific properties
|
|
Event.Id = Id;
|
|
Event.VirtualIPAddress[0] = sizeof(Event.VirtualIPAddress) - sizeof(Event.VirtualIPAddress[0]);
|
|
wcsncpy(&(Event.VirtualIPAddress[1]), pwcVip, Event.VirtualIPAddress[0]/sizeof(WCHAR));
|
|
Event.Port = ulPort;
|
|
|
|
// Fire the event
|
|
NlbWmi_Fire_Event(PortRuleControlEvent, &Event, MicrosoftNLB_PortControlEvent_SIZE);
|
|
|
|
TRACE_VERB("<-%!FUNC!");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_Fire_ConvergingEvent
|
|
Description : This function fires Converging events. It extracts the common event properties
|
|
(out of the given pointer to the MAIN_CTXT structure) and fills in a local
|
|
structure. It also fills in Converging Event specific fields from the arguments
|
|
passed to it. It then fires the actual event by calling NlbWmi_Fire_Event.
|
|
Arguments : Pointer to MAIN_CTXT, NodeControlEventId, Initiator DIP, Initiator Host Priority
|
|
Return Value: void
|
|
*/
|
|
|
|
void NlbWmi_Fire_ConvergingEvent(
|
|
PMAIN_CTXT ctxtp,
|
|
ConvergingEventId Cause,
|
|
WCHAR *pwcInitiatorDip,
|
|
ULONG ulInitiatorHostPriority)
|
|
{
|
|
MicrosoftNLB_ConvergingEvent Event;
|
|
|
|
TRACE_VERB("->%!FUNC! Cause : %d, Initiator DIP : %ls, Initiator Host Priority : %d", Cause, pwcInitiatorDip, ulInitiatorHostPriority);
|
|
|
|
NdisZeroMemory(&Event, MicrosoftNLB_ConvergingEvent_SIZE);
|
|
|
|
// Fill in common properties - Adapter Guid, Cluster IP Address & Host Priority
|
|
FillCommonProperties()
|
|
|
|
// Fill event specific properties
|
|
Event.Cause = Cause;
|
|
Event.InitiatorDedicatedIP[0] = sizeof(Event.InitiatorDedicatedIP) - sizeof(Event.InitiatorDedicatedIP[0]);
|
|
wcsncpy(&(Event.InitiatorDedicatedIP[1]), pwcInitiatorDip, Event.InitiatorDedicatedIP[0]/sizeof(WCHAR));
|
|
Event.InitiatorHostPriority = ulInitiatorHostPriority;
|
|
|
|
// Fire the event
|
|
NlbWmi_Fire_Event(ConvergingEvent, &Event, MicrosoftNLB_ConvergingEvent_SIZE);
|
|
|
|
TRACE_VERB("<-%!FUNC!");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Name : NlbWmi_Fire_ConvergedEvent
|
|
Description : This function fires Converged events. It extracts the common event properties
|
|
(out of the given pointer to the MAIN_CTXT structure) and fills in a local
|
|
structure. It also fills in Converged Event specific fields from the arguments
|
|
passed to it. It then fires the actual event by calling NlbWmi_Fire_Event.
|
|
Arguments : Pointer to MAIN_CTXT, HostMap
|
|
Return Value: void
|
|
*/
|
|
|
|
void NlbWmi_Fire_ConvergedEvent(PMAIN_CTXT ctxtp, ULONG ulHostMap)
|
|
{
|
|
MicrosoftNLB_ConvergedEvent Event;
|
|
|
|
TRACE_VERB("->%!FUNC! Host Map : %d", ulHostMap);
|
|
|
|
NdisZeroMemory(&Event, MicrosoftNLB_ConvergedEvent_SIZE);
|
|
|
|
// Fill in common properties - Adapter Guid, Cluster IP Address & Host Priority
|
|
FillCommonProperties()
|
|
|
|
// Fill event specific properties
|
|
Event.HostMap = ulHostMap;
|
|
|
|
// Fire the event
|
|
NlbWmi_Fire_Event(ConvergedEvent, &Event, MicrosoftNLB_ConvergedEvent_SIZE);
|
|
|
|
TRACE_VERB("<-%!FUNC!");
|
|
return;
|
|
}
|
|
|
|
|