cardif_windows_wmi.c
来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 2,302 行 · 第 1/5 页
C
2,302 行
/**
* \brief Create an event handler to watch for card removal events.
*
* \retval 0 on success.
**/
int cardif_windows_wmi_event_setup_remove()
{
HRESULT hr;
hr = IWbemServices_ExecNotificationQuery(wmiEvents,
L"WQL",
L"SELECT * FROM MSNdis_NotifyAdapterRemoval" ,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pRemoveEvent);
if (FAILED(hr)) return -1;
return 0;
}
/**
* \brief Check an event handler to see if any removal events have happened.
*
* When an event is triggered here, this function will also take care of processing
* the event, and sending an IPC event..
*
* \retval 0 on success
**/
int cardif_windows_wmi_event_check_remove()
{
HRESULT hr;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn;
context *ctx = NULL;
wireless_ctx *wctx = NULL;
VARIANT vtProp;
char *intdesc = NULL;
if (pRemoveEvent == NULL) return -1;
hr = IEnumWbemClassObject_Next(pRemoveEvent, 0, 1, &pclsObj, &uReturn);
if (FAILED(hr)) return -1;
if (uReturn > 0)
{
// We have an event.
debug_printf(DEBUG_INT, "!!!!!!!!!!!!!!!!!!!! Card Removal Event !!!!!!!!!!!!!!!!!!!!!\n");
hr = IWbemClassObject_Get(pclsObj, L"InstanceName", 0, &vtProp, 0, 0);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Got a card removal event, but it didn't seem to have any "
"information in it.\n");
}
// Locate the context we want to work on.
debug_printf(DEBUG_INT, "Looking for interface with caption : %ws\n", vtProp.bstrVal);
intdesc = uni_to_ascii(vtProp.bstrVal);
if (intdesc != NULL)
{
// Try to delete the interface from the interface cache.
if (interfaces_delete(intdesc) == TRUE)
{
debug_printf(DEBUG_NORMAL, "Removed device '%s' from our live interfaces list.\n", intdesc);
}
}
ctx = event_core_locate_by_desc(intdesc);
VariantClear(&vtProp);
if (ctx == NULL)
{
debug_printf(DEBUG_INT, "Couldn't locate a context for removal event. (Perhaps "
"we aren't managing this interface?)\n");
FREE(intdesc);
return -1;
}
debug_printf(DEBUG_INT, "Interface is : %s\n", ctx->intName);
ipc_events_ui(ctx, IPC_EVENT_INTERFACE_REMOVED, ctx->desc);
debug_printf(DEBUG_NORMAL, "Interface '%s' was removed or disabled.\n", ctx->desc);
#ifdef HAVE_TNC
// If we are using a TNC enabled build, signal the IMC to clean up.
if(imc_disconnect_callback != NULL)
imc_disconnect_callback(ctx->tnc_connID);
#endif
ctx->flags |= INT_GONE;
if ((ctx != NULL) && (ctx->statemachine != NULL)) ctx->statemachine->portEnabled = FALSE;
if ((ctx != NULL) && (ctx->eap_state != NULL)) ctx->eap_state->portEnabled = FALSE;
event_core_deregister(((struct win_sock_data *)ctx->sockData)->devHandle);
FREE(intdesc);
}
return 0;
}
/**
* \brief Create an event handler to watch for media disconnect events.
*
* \retval 0 on success.
**/
int cardif_windows_wmi_event_setup_disconnect()
{
HRESULT hr;
hr = IWbemServices_ExecNotificationQuery(wmiEvents,
L"WQL",
L"SELECT * FROM MSNdis_StatusMediaDisconnect" ,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pDisconnectEvent);
if (FAILED(hr)) return -1;
return 0;
}
/**
* \brief Check an event handler to see if any media disconnect events have happened.
*
* When an event is triggered here, this function will also take care of processing
* the event, and changing the needed state options for interfaces.
*
* \retval 0 on success
**/
int cardif_windows_wmi_event_check_disconnect()
{
HRESULT hr;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn;
VARIANT vtProp;
context *ctx = NULL;
wireless_ctx *wctx = NULL;
char *intdesc = NULL;
char bssid_dest[6];
if (pDisconnectEvent == NULL) return -1;
hr = IEnumWbemClassObject_Next(pDisconnectEvent, 0, 1, &pclsObj, &uReturn);
if (FAILED(hr)) return -1;
if (uReturn > 0)
{
// We have an event.
debug_printf(DEBUG_INT, "!!!!!!!!!!!!!!!!!!!! Disconnect Event !!!!!!!!!!!!!!!!!!!!!\n");
hr = IWbemClassObject_Get(pclsObj, L"InstanceName", 0, &vtProp, 0, 0);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Got a disconnect event, but it didn't seem to have any "
"information in it.\n");
}
// Locate the context we want to work on.
debug_printf(DEBUG_INT, "Looking for interface with caption : %ws\n", vtProp.bstrVal);
ctx = event_core_locate_by_caption(vtProp.bstrVal, FALSE);
if (ctx == NULL)
{
intdesc = uni_to_ascii(vtProp.bstrVal);
debug_printf(DEBUG_INT, "Couldn't find by caption, looking by description.\n");
ctx = event_core_locate_by_desc_strstr(intdesc);
if (ctx == NULL)
{
debug_printf(DEBUG_INT, "Couldn't locate a context for disconnect event. (Perhaps "
"we aren't managing the interface?)\n");
VariantClear(&vtProp);
return -1;
}
}
VariantClear(&vtProp);
debug_printf(DEBUG_INT, "Interface is : %s\n", ctx->intName);
// Send event.
ipc_events_ui(NULL, IPC_EVENT_UI_LINK_DOWN, ctx->desc);
ctx->auths = 0; // Reset the number of authentications this interface has done.
if (ctx->intType == ETH_802_11_INT)
{
wctx = (wireless_ctx *)ctx->intTypeData;
if (wctx == NULL)
{
debug_printf(DEBUG_NORMAL, "Interface %s claims to be wireless, but doesn't "
"have a wireless context!?\n", ctx->intName);
return -1;
}
// Double check to make sure that we really are disconnected. Sometimes weird things
// can happen because the events aren't being received in real time.
if (cardif_windows_wireless_get_bssid(ctx, bssid_dest) != XENONE)
{
UNSET_FLAG(wctx->flags, WIRELESS_SM_ASSOCIATED); // We are now disassociated.
UNSET_FLAG(wctx->flags, WIRELESS_SM_STALE_ASSOCIATION);
}
if (TEST_FLAG(wctx->flags, WIRELESS_SM_DOING_PSK))
{
ipc_events_ui(ctx, IPC_EVENT_BAD_PSK, ctx->intName);
// We sent the error so unset the flag.
UNSET_FLAG(wctx->flags, WIRELESS_SM_DOING_PSK);
}
}
else
{
debug_printf(DEBUG_NORMAL, "Interface '%s' no longer has link.\n", ctx->desc);
ctx->eap_state->portEnabled = FALSE;
ctx->statemachine->initialize = TRUE;
}
}
return 0;
}
/**
* \brief Create an event handler to watch for media specific events.
*
* \retval 0 on success.
**/
int cardif_windows_wmi_event_setup_media_specific()
{
HRESULT hr;
hr = IWbemServices_ExecNotificationQuery(wmiEvents,
L"WQL",
L"SELECT * FROM MSNdis_StatusMediaSpecificIndication" ,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pMediaSpecificEvent);
if (FAILED(hr)) return -1;
return 0;
}
/**
* \brief Check an event handler to see if any media specific events have happened.
*
* When an event is triggered here, this function will also take care of processing
* the event, and changing any needed state options for interfaces.
*
* \retval 0 on success
**/
int cardif_windows_wmi_event_check_media_specific()
{
HRESULT hr;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn;
VARIANT vtProp;
context *ctx = NULL;
wireless_ctx *wctx = NULL;
LONG k;
BSTR *bstr = NULL;
char *data = NULL;
LONG lower, upper;
UCHAR ch;
if (pMediaSpecificEvent == NULL) return -1;
return 0; // Don't do the stuff below right now.
hr = IEnumWbemClassObject_Next(pMediaSpecificEvent, 0, 1, &pclsObj, &uReturn);
if (FAILED(hr)) return 0;
// printf("hr = %d\n", hr);
// while (uReturn > 0)
{
/*
debug_printf(DEBUG_NORMAL, "!!!!!!!!!!!!!!!!!!!!!!!!!!!! Media Specific Event !!!!!!!!!!!!!!!!!!!!!!!!!\n");
if (uReturn > 0)
{
hr = IWbemClassObject_Get(pclsObj, L"InstanceName", 0, &vtProp, 0, 0);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Got a media specific event, but it didn't seem to have any "
"information in it.\n");
}
/*
IWbemClassObject_BeginEnumeration(pclsObj, WBEM_FLAG_REFS_ONLY);
debug_printf(DEBUG_NORMAL, "------------- Properties ------------\n");
// bstr = Malloc(1024);
while (IWbemClassObject_Next(pclsObj, 0, bstr, NULL, NULL, NULL) != WBEM_S_NO_MORE_DATA)
{
data = uni_to_ascii(bstr);
debug_printf(DEBUG_NORMAL, "Property Name : %s\n", data);
wprintf("Property Name : %ws\n", bstr);
// printf("Property Name : %s\n", data);
if (bstr != NULL) SysFreeString(bstr);
free(data);
}
IWbemClassObject_EndEnumeration(pclsObj);
}
hr = IEnumWbemClassObject_Next(pMediaSpecificEvent, 0, 1, &pclsObj, &uReturn);
*/
if (uReturn > 0)
{
// We have an event.
debug_printf(DEBUG_INT, "!!!!!!!!!!!!!!!!!!!! Media Specific Event !!!!!!!!!!!!!!!!!!!!!\n");
hr = IWbemClassObject_Get(pclsObj, L"InstanceName", 0, &vtProp, 0, 0);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Got a media specific event, but it didn't seem to have any "
"information in it.\n");
}
// Locate the context we want to work on.
debug_printf(DEBUG_INT, "Looking for interface with caption : %ws\n", vtProp.bstrVal);
printf("Interface : %ws\n", vtProp.bstrVal);
ctx = event_core_locate_by_caption(vtProp.bstrVal, FALSE);
VariantClear(&vtProp);
hr = IWbemClassObject_Get(pclsObj, L"NdisStatusMediaSpecificIndication", 0, &vtProp, 0, 0);
SafeArrayGetLBound(V_ARRAY(&vtProp), 1, &lower);
SafeArrayGetUBound(V_ARRAY(&vtProp), 1, &upper);
for (k = lower; k < upper; k++)
{
SafeArrayGetElement(V_ARRAY(&vtProp), &k, &ch);
printf(" %02X ", ch);
}
if (ctx == NULL)
{
debug_printf(DEBUG_INT, "Couldn't locate a context for media specific event. (Perhaps "
"we aren't managing the interface?)\n");
return -1;
}
debug_printf(DEBUG_INT, "Interface is : %s\n", ctx->intName);
if (ctx->intType == ETH_802_11_INT)
{
wctx = (wireless_ctx *)ctx->intTypeData;
if (wctx == NULL)
{
debug_printf(DEBUG_NORMAL, "Interface %s claims to be wireless, but doesn't "
"have a wireless context!?\n", ctx->intName);
return -1;
}
}
else
{
debug_printf(DEBUG_INT, "Interface isn't wireless. Not doing anything with it for now.\n");
return -1;
}
}
}
return 0;
}
/**
* \brief Check to see if any events have triggered.
**/
void cardif_windows_wmi_check_events()
{
cardif_windows_wmi_event_check_media_specific();
cardif_windows_wmi_event_check_connect();
cardif_windows_wmi_event_check_disconnect();
cardif_windows_wmi_event_check_insert();
cardif_windows_wmi_event_check_remove();
// Check to see if any WMI method calls have completed.
cardif_windows_wmi_async_check();
cardif_windows_wmi_late_bind_insert_check(WMI_BIND_CHECK, NULL);
}
int ipupdatecallback(context *ctx, HANDLE myhandle)
{
LPOVERLAPPED ovr = NULL;
ipc_events_ui(ctx, IPC_EVENT_UI_IP_ADDRESS_SET, NULL);
ovr = event_core_get_ovr(myhandle);
// myhandle should NEVER change, so this is safe.
NotifyAddrChange(&myhandle, ovr);
return 0;
}
/**
* \brief This isn't really a WMI function, but WMI is inited only once, and we need to only init this once.
* The call above is the callback that is generated whenever an IP address is updated.
**/
void cardif_windows_wmi_ip_update()
{
DWORD ret;
LPOVERLAPPED ovr;
HANDLE hand = INVALID_HANDLE_VALUE;
ovr = Malloc(sizeof(OVERLAPPED));
if (ovr == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for overlapped structure!\n");
return;
}
ovr->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ret = NotifyAddrChange(&hand, ovr);
if ((ret != NO_ERROR) && (ret != 997))
{
debug_printf(DEBUG_NORMAL, "Can't establish IP address change notify handler. Error was : %d\n", WSAGetLastError());
return;
}
if (event_core_register(hand, NULL, &ipupdatecallback, 0, "IP address change event") != 0)
{
debug_printf(DEBUG_NORMAL, "Unable to register IP address change handler.\n");
return;
}
if (event_core_set_ovr(hand, ovr) != TRUE)
{
debug_printf(DEBUG_NORMAL, "Couldn't set ovr!\n");
return;
}
}
/**
* \brief Initialize WMI so that we can use it.
*
* \retval 0 on success.
**/
int cardif_windows_wmi_init()
{
HRESULT hr;
memset(checks, 0x00, sizeof(checks));
// Set up notifications to let us know when an address has updated.
cardif_windows_wmi_ip_update();
hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
if ((hr != S_OK) && (hr != S_FALSE))
{
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Failed to initialize COM library. Error code = 0x%02x\n", hr);
error_prequeue_add("Failed to initialize COM library.");
return -1;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?