cardif_windows_wmi.c
来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 2,302 行 · 第 1/5 页
C
2,302 行
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Couldn't determine array data via WMI query!\n");
IWbemClassObject_Release(pEnumerator);
VariantClear(&vtProp);
IWbemClassObject_Release(pclsObj);
return NULL;
}
if (vtProp.parray == NULL) return NULL;
// Whew! After all that, we should have an IP address now.
hr = SafeArrayAccessData(vtProp.parray, (void HUGEP**)&pbstr);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Get variant array data failed!\n");
IWbemClassObject_Release(pEnumerator);
VariantClear(&vtProp);
IWbemClassObject_Release(pclsObj);
return NULL;
}
debug_printf(DEBUG_INT, "Data : %ws\n", pbstr[0]);
retval = _wcsdup(pbstr[0]);
SafeArrayUnaccessData(vtProp.parray);
// Clean up.
IWbemClassObject_Release(pEnumerator);
VariantClear(&vtProp);
IWbemClassObject_Release(pclsObj);
return retval;
}
/**
* \brief Convert a unicode string to a UTF-8 string.
*
* @param[in] instr A pointer to a wchar_t string that needs to be converted.
*
* \retval NULL on error
* \retval ptr instr converted to UTF-8.
**/
char *convert_unicode_to_chars(wchar_t *instr)
{
char *utf8result = NULL;
utf8result = Malloc(wcslen(instr)+2);
if (utf8result == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store UTF-8 result at %s()!\n",
__FUNCTION__);
return NULL;
}
sprintf(utf8result, "%ws", instr);
return utf8result;
}
/**
* \brief Get the IP address for a given device.
*
* If this is the first time we have requested information about this interface,
* we will need to call cardif_windows_wmi_get_idx() to populate it's index number.
* Once we have cached the index number, we shouldn't need to query for the index
* again.
*
* @param[in] ctx A pointer to the context for this interface.
*
* \retval NULL on error
* \retval ptr A pointer to a unicode string that identifies the IP address. You should
* use the cardif_windows_wmi_get_ip_utf8() call to get a utf8 string.
**/
wchar_t *cardif_windows_wmi_get_ip(context *ctx)
{
return cardif_windows_wmi_get_array_idx0(ctx, L"IPAddress");
}
/**
* \brief Get the IP address for a given device in UTF-8 format.
*
* This function will call cardif_windows_wmi_get_ip(), and convert the
* resulting wide characater string in to UTF-8.
*
* \warning This function assumes that the resulting interface name will
* not contain characters with values > 0xff. If they do, the
* resulting string will be invalid.
*
* \retval NULL on failure
* \retval ptr A pointer to a string that identifies the IP address.
**/
char *cardif_windows_wmi_get_ip_utf8(context *ctx)
{
wchar_t *wresult = NULL;
char *utf8result = NULL;
wresult = cardif_windows_wmi_get_ip(ctx);
if (wresult == NULL) return NULL;
utf8result = convert_unicode_to_chars(wresult);
FREE(wresult);
return utf8result;
}
/**
* \brief Get the IP network mask for a given device.
*
* If this is the first time we have requested information about this interface,
* we will need to call cardif_windows_wmi_get_idx() to populate it's index number.
* Once we have cached the index number, we shouldn't need to query for the index
* again.
*
* @param[in] ctx A pointer to the context for this interface.
*
* \retval NULL on failure
* \retval ptr A pointer to a unicode string that identifies the IP network mask. You should
* use the cardif_windows_wmi_get_netmask_utf8() call to get a utf8 string.
**/
wchar_t *cardif_windows_wmi_get_netmask(context *ctx)
{
return cardif_windows_wmi_get_array_idx0(ctx, L"IPSubnet");
}
/**
* \brief Get the IP network mask for a given device in UTF-8 format.
*
* This function will call cardif_windows_wmi_get_netmask(), and convert the
* resulting wide characater string in to UTF-8.
*
* \warning This function assumes that the resulting interface name will
* not contain characters with values > 0xff. If they do, the
* resulting string will be invalid.
*
* \retval NULL on failure
* \retval ptr A pointer to a string that identifies the IP network mask.
**/
char *cardif_windows_wmi_get_netmask_utf8(context *ctx)
{
wchar_t *wresult = NULL;
char *utf8result = NULL;
wresult = cardif_windows_wmi_get_netmask(ctx);
if (wresult == NULL) return NULL;
utf8result = convert_unicode_to_chars(wresult);
FREE(wresult);
return utf8result;
}
/**
* \brief Get the IP default gateway for a given device.
*
* If this is the first time we have requested information about this interface,
* we will need to call cardif_windows_wmi_get_idx() to populate it's index number.
* Once we have cached the index number, we shouldn't need to query for the index
* again.
*
* @param[in] ctx A pointer to the context for this interface.
*
* \todo Fix!
*
* \retval NULL on failure
* \retval ptr A pointer to a unicode string that identifies the IP default gateway. You should
* use the cardif_windows_wmi_get_gw_utf8() call to get a utf8 string.
**/
wchar_t *cardif_windows_wmi_get_gw(context *ctx)
{
return NULL;
return cardif_windows_wmi_get_array_idx0(ctx, L"DefaultIPGateway");
}
/**
* \brief Get the IP default gateway address for a given device in UTF-8 format.
*
* This function will call cardif_windows_wmi_get_gw(), and convert the
* resulting wide characater string in to UTF-8.
*
* \warning This function assumes that the resulting interface name will
* not contain characters with values > 0xff. If they do, the
* resulting string will be invalid.
*
* \retval NULL on failure
* \retval ptr A pointer to a string that identifies the IP default gateway.
**/
char *cardif_windows_wmi_get_gw_utf8(context *ctx)
{
wchar_t *wresult = NULL;
char *utf8result = NULL;
wresult = cardif_windows_wmi_get_gw(ctx);
if (wresult == NULL) return NULL;
utf8result = convert_unicode_to_chars(wresult);
FREE(wresult);
return utf8result;
}
/**
* \brief Free all memory used in an allocated 'SAFEARRAY'.
*
* @param[in] myarray The SAFEARRAY we want to destroy.
*
**/
void cardif_windows_wmi_destroy_safearray(SAFEARRAY **myarray)
{
SafeArrayDestroyData((*myarray));
SafeArrayDestroyDescriptor((*myarray));
(*myarray) = NULL;
}
/**
* \brief Set the value of element 0 in the 'SAFEARRAY' to be the string
* passed in.
*
* \todo Do we need to free mybstr?
*
* @param[in] psa A pointer to an allocated 'SAFEARRAY' that we want
* to populate.
* @param[in] mystr The string to put in element 0 of the 'SAFEARRAY'.
*
* \retval HRESULT An HRESULT value for the calls.
**/
HRESULT cardif_windows_wmi_set_safearray_str(SAFEARRAY *psa, char *mystr)
{
wchar_t *pbstr = NULL;
LONG index[] = {0};
BSTR mybstr = NULL;
pbstr = malloc(strlen(mystr)*4); // Should be big enough, and then some.
if (pbstr == NULL)
{
// This is a garbage error, but it will cause the right thing to
// happen.
return MAKE_HRESULT(1, FACILITY_CONFIGURATION, 0);
}
memset(pbstr, 0x00, (strlen(mystr) * 4));
mbstowcs(pbstr, mystr, (strlen(mystr)*4));
mybstr = SysAllocString(pbstr);
if (mybstr == NULL)
{
// This is a garbage error, but it will cause the right thing to
// happen.
return MAKE_HRESULT(1, FACILITY_CONFIGURATION, 0);
}
free(pbstr);
return SafeArrayPutElement(psa, index, mybstr);
}
/**
* \brief Make a WMI call that doesn't require any parameters. (Semisync version)
*
* @param[in] ctx The context to execute the command against.
* @param[in] cmdname The WMI command name to execute.
* @param[in] callname The name of the call for debugging and logging purposes.
* @param[in] callback The callback that will be called when this call finishes.
*
* \retval <0 an error occurred
* \retval >=0 value returned from WMI call.
**/
static int cardif_windows_wmi_call_async(context *ctx, char *cmdname, char *callname, void *callback)
{
struct win_sock_data *sockData = NULL;
HRESULT hr;
char lcmdname[200];
BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
BSTR MethodName = NULL;
IWbemClassObject* pClass = NULL;
IWbemClassObject* pOutParams = NULL;
IWbemCallResult *pResult = NULL;
LPVOID lpMsgBuf = NULL;
VARIANT varReturnValue;
BSTR IntPath = NULL;
char apath[100];
char lpath[200];
int retval = 0;
if (ctx == NULL)
{
retval = -1;
goto done;
}
if (!xsup_assert((cmdname != NULL), "cmdname != NULL", FALSE))
{
retval = -1;
goto done;
}
sockData = (struct win_sock_data *)ctx->sockData;
if (sockData == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't get socket data for context '%s'!?\n",
ctx->intName);
return -1;
}
if (sockData->wmiIntIdx == INVALID_WMI_IDX)
{
// We don't know the index, so locate it.
if (cardif_windows_wmi_get_idx(ctx, NULL) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Couldn't determine WMI interface index in %s()!\n",
__FUNCTION__);
retval = -1;
goto done;
}
}
sprintf(&apath, "Win32_NetworkAdapterConfiguration.Index='%d'", sockData->wmiIntIdx);
mbstowcs((wchar_t *)&lpath, apath, strlen(apath)+1);
IntPath = SysAllocString((OLECHAR *)&lpath);
if (IntPath == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't create interface path!\n");
retval = -1;
goto done;
}
mbstowcs((wchar_t *)&lcmdname, cmdname, strlen(cmdname)+1);
MethodName = SysAllocString((OLECHAR *)&lcmdname);
if (MethodName == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't create long command name!\n");
retval = -1;
goto done;
}
hr = IWbemServices_GetObject(wmiSvc, ClassName, 0, NULL, &pClass, NULL);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Failed to get object for 'Win32_NetworkAdapterConfiguration'"
" class!\n");
debug_printf(DEBUG_NORMAL, "Error #%x\n", hr);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Error was : %s", lpMsgBuf);
LocalFree(lpMsgBuf);
retval = -1;
goto done;
}
hr = IWbemServices_ExecMethod(wmiSvc, IntPath, MethodName, WBEM_FLAG_RETURN_IMMEDIATELY, // | WBEM_FLAG_FORWARD_ONLY,
NULL, pClass, NULL, &pResult);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Could not execute method. Error code = 0x%x\n", hr);
lpMsgBuf = GetLastErrorStr(GetLastError());
debug_printf(DEBUG_NORMAL, "Error : %s\n", lpMsgBuf);
LocalFree(lpMsgBuf);
retval = -1;
goto done;
}
done:
// Clean up.
if (pOutParams) IWbemClassObject_Release(pOutParams);
if (pClass) IWbemClassObject_Release(pClass);
if (MethodName) SysFreeString(MethodName);
if (IntPath) SysFreeString(IntPath);
if (ClassName) SysFreeString(ClassName);
if (retval != 0) return retval;
return cardif_windows_wmi_async(callname, ctx, pResult, callback);
}
/**
* \brief Make a WMI call that doesn't require any parameters.
*
* @param[in] ctx The context to execute the command against.
* @param[in] cmdname The WMI command name to execute.
*
* \retval <0 an error occurred
* \retval >=0 value returned from WMI call.
**/
static int cardif_windows_wmi_call(context *ctx, char *cmdname)
{
struct win_sock_data *sockData = NULL;
HRESULT hr;
char lcmdname[200];
BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
BSTR MethodName = NULL;
IWbemClassObject* pClass = NULL;
IWbemClassObject* pOutParams = NULL;
LPVOID lpMsgBuf = NULL;
VARIANT varReturnValue;
BSTR IntPath = NULL;
char apath[100];
char lpath[200];
int retval = 0;
if (ctx == NULL)
{
retval = -1;
goto done;
}
if (!xsup_assert((cmdname != NULL), "cmdname != NULL", FALSE))
{
retval = -1;
goto done;
}
sockData = (struct win_sock_data *)ctx->sockData;
if (sockData == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't get socket data for context '%s'!?\n",
ctx->intName);
retval = -1;
goto done;
}
if (sockData->wmiIntIdx == INVALID_WMI_IDX)
{
// We don't know the index, so locate it.
if (cardif_windows_wmi_get_idx(ctx, NULL) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Couldn't determine WMI interface index in %s()!\n",
__FUNCTION__);
retval = -1;
goto done;
}
}
sprintf(&apath, "Win32_NetworkAdapterConfiguration.Index='%d'", sockData->wmiIntIdx);
mbstowcs((wchar_t *)&lpath, apath, strlen(apath)+1);
IntPath = SysAllocString((OLECHAR *)&lpath);
if (IntPath == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't create interface path!\n");
retval = -1;
goto done;
}
mbstowcs((wchar_t *)&lcmdname, cmdname, strlen(cmdname)+1);
MethodName = SysAllocString((OLECHAR *)&lcmdname);
if (MethodName == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't create long command name!\n");
retval = -1;
goto done;
}
hr = IWbemServices_GetObject(wmiSvc, ClassName, 0, NULL, &pClass, NULL);
if (FAILED(hr))
{
debug_printf(DEBUG_NORMAL, "Failed to get object for 'Win32_NetworkAdapterConfiguration'"
" class!\n");
debug_printf(DEBUG_NORMAL, "Error #%x\n", hr);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?