mirror of
https://github.com/arehnman/yttrium-virtio-gpu.git
synced 2026-10-31 02:05:04 +00:00
Static analysis was failing with: coinstaller\netkvmnetsh.cpp(64): warning C6011: Dereferencing NULL pointer 'pguidDevClassPtr'. Signed-off-by: Ladi Prosek <[email protected]>
1250 lines
44 KiB
C++
1250 lines
44 KiB
C++
#include "stdafx.h"
|
|
#include "NetKVMnetsh.h"
|
|
#include "RegAccess.h"
|
|
#include "NetKVMAux.h"
|
|
#include "RegParam.h"
|
|
|
|
//This is NetSH Helper GUID {D9C599C4-8DCF-4a6a-93AA-A16FE6D5125C}
|
|
static const GUID NETKVM_HELPER_GUID =
|
|
{ 0xd9c599c4, 0x8dcf, 0x4a6a, { 0x93, 0xaa, 0xa1, 0x6f, 0xe6, 0xd5, 0x12, 0x5c } };
|
|
static const DWORD NETKVM_HELPER_VERSION = 1;
|
|
|
|
static const LPCTSTR NETKVM_HELPER_NAME = TEXT("NetKVM");
|
|
static const LPWSTR NETKVM_HELPER_NAME_W = L"NetKVM";
|
|
|
|
static const LPCTSTR NETKVM_DEVICES_CLASS = TEXT("net");
|
|
|
|
//TODO: put real device numbers here
|
|
static const LPCTSTR NETKVM_DEVICE_VENDOR_ID = TEXT("");
|
|
static const LPCTSTR NETKVM_DEVICE_HARDWARE_ID = TEXT("");
|
|
|
|
static const LPCWSTR NETKVM_IDX_PARAM_NAME = L"idx";
|
|
static const LPCTSTR NETKVM_IDX_PARAM_NAME_T = TEXT("idx");
|
|
static const LPCWSTR NETKVM_PARAM_PARAM_NAME = L"param";
|
|
static const LPCTSTR NETKVM_PARAM_PARAM_NAME_T = TEXT("param");
|
|
static const LPCWSTR NETKVM_VALUE_PARAM_NAME = L"value";
|
|
static const LPCTSTR NETKVM_VALUE_PARAM_NAME_T = TEXT("value");
|
|
|
|
static HINSTANCE g_hinstThisDLL = NULL;
|
|
|
|
static bool _NetKVMGetDeviceClassGuids(vector<GUID>& GUIDs)
|
|
{
|
|
GUID *pguidDevClassPtr = NULL;
|
|
DWORD dwNumGuids;
|
|
|
|
if(!SetupDiClassGuidsFromNameEx(NETKVM_DEVICES_CLASS, NULL, 0,
|
|
&dwNumGuids, NULL, NULL))
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
|
|
if(ERROR_INSUFFICIENT_BUFFER == dwErr)
|
|
{
|
|
/* On first attempt we pass NULL and 0 as GUID array and GUID array size respectively;
|
|
according to SetupDiClassGuidsFromNameEx, the function sets RequiredSize output formal parameter (&dwNumGuids)
|
|
to the desired GUID's array size. The static analyzer indicates an error when output parameter from
|
|
failed function is used, so the warning is suppressed */
|
|
#pragma warning(suppress: 6102)
|
|
pguidDevClassPtr = new GUID[dwNumGuids];
|
|
}
|
|
else
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiClassGuidsFromNameEx failed with code ") << dwErr);
|
|
return false;
|
|
}
|
|
|
|
if(!SetupDiClassGuidsFromNameEx(NETKVM_DEVICES_CLASS, pguidDevClassPtr, dwNumGuids,
|
|
&dwNumGuids, NULL, NULL))
|
|
{
|
|
delete [] pguidDevClassPtr;
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiClassGuidsFromNameEx failed with code ") << dwErr);
|
|
return false;
|
|
}
|
|
|
|
GUIDs.insert(GUIDs.end(), &pguidDevClassPtr[0], &pguidDevClassPtr[dwNumGuids]);
|
|
delete[] pguidDevClassPtr;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
tstring _NetKVMQueryDeviceString(HDEVINFO hDeviceSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD dwPropertyID)
|
|
{
|
|
LPTSTR szDeviceString = NULL;
|
|
DWORD dwSize = 0;
|
|
DWORD dwDataType;
|
|
|
|
while(!SetupDiGetDeviceRegistryProperty(hDeviceSet, DeviceInfoData, dwPropertyID,
|
|
&dwDataType, (PBYTE)szDeviceString, dwSize, &dwSize))
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
|
|
if(ERROR_INSUFFICIENT_BUFFER != dwErr)
|
|
{
|
|
delete [] szDeviceString;
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetDeviceRegistryProperty failed with code ") << dwErr);
|
|
return tstring();
|
|
}
|
|
/* According to SetupDiGetDeviceRegistryProperty, the RequiredSize output parameter (&dwSize) is set
|
|
to the required size of PropertyBuffer (szDeviceString) parameter. The static analyzer indicates
|
|
error when the output parameter from failed function, so the warning is suppressed */
|
|
#pragma warning(suppress: 6102)
|
|
szDeviceString = new TCHAR[(dwSize/sizeof(TCHAR))+1];
|
|
}
|
|
if (REG_SZ != dwDataType)
|
|
{
|
|
#pragma warning(suppress: 6102)
|
|
delete[] szDeviceString;
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetDeviceRegistryProperty(string) returned incorrect data type ") << dwDataType);
|
|
return tstring();
|
|
}
|
|
|
|
#pragma warning(suppress: 6102)
|
|
#pragma warning(suppress: 6011)
|
|
szDeviceString[dwSize/sizeof(TCHAR)] = TEXT('\0');
|
|
return tstring(szDeviceString);
|
|
}
|
|
|
|
DWORD _NetKVMQueryDeviceDWORD(HDEVINFO hDeviceSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD dwPropertyID)
|
|
{
|
|
DWORD dwDeviceDword;
|
|
DWORD dwDataType;
|
|
|
|
if(!SetupDiGetDeviceRegistryProperty(hDeviceSet, DeviceInfoData, dwPropertyID,
|
|
&dwDataType, (PBYTE)&dwDeviceDword, sizeof(dwDeviceDword), NULL))
|
|
{
|
|
return 0;
|
|
}
|
|
if (REG_DWORD != dwDataType)
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetDeviceRegistryProperty(DWORD) returned incorrect data type ") << REG_DWORD);
|
|
return 0;
|
|
}
|
|
#pragma warning(suppress: 6102)
|
|
return dwDeviceDword;
|
|
}
|
|
|
|
static HKEY _NetKVMOpenDeviceSwRegKey(HDEVINFO hDeviceSet, PSP_DEVINFO_DATA DeviceInfoData)
|
|
{
|
|
HKEY hRes = SetupDiOpenDevRegKey(hDeviceSet, DeviceInfoData, DICS_FLAG_GLOBAL,
|
|
0, DIREG_DRV, KEY_READ);
|
|
|
|
if(INVALID_HANDLE_VALUE == hRes)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_CANNOTOPENKEY);
|
|
tcout << TEXT("Error: ") << GetLastError() << endl;
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
typedef struct tag_NetKVMDeviceInfo
|
|
{
|
|
tstring strDeviceID;
|
|
tstring strDeviceDescription;
|
|
tstring strDeviceFriendlyName;
|
|
tstring strLocationInfo;
|
|
tstring strRegPathName;
|
|
DWORD dwDeviceNumber;
|
|
SP_DEVINFO_DATA DevInfoData;
|
|
} _NetKVMDeviceInfo, *_PNetKVMDeviceInfo;
|
|
|
|
bool _NetKVMIsKnownDevice(const tstring &strDeviceID)
|
|
{
|
|
return (tstring::npos != strDeviceID.find(tstring(TEXT("VEN_")) + NETKVM_DEVICE_VENDOR_ID)) &&
|
|
(tstring::npos != strDeviceID.find(tstring(TEXT("DEV_")) + NETKVM_DEVICE_HARDWARE_ID));
|
|
}
|
|
|
|
tstring _NetKVMKeyPathFromDeviceSwHKEY(HKEY hKey)
|
|
{
|
|
tstring strNativePath = wstring2tstring(NetKVMGetKeyPathFromKKEY(hKey));
|
|
tstring strNativePrefix = TEXT("\\REGISTRY\\MACHINE\\");
|
|
if(strNativePath.substr(0, strNativePrefix.length()) == strNativePrefix)
|
|
{
|
|
return strNativePath.substr(strNativePrefix.length());
|
|
}
|
|
else return tstring();
|
|
}
|
|
|
|
|
|
static bool _NetKVMGetKnownDevices(GUID *pguidDevClassPtr, vector<_NetKVMDeviceInfo>& Devices, HDEVINFO *phDeviceInfo)
|
|
{
|
|
*phDeviceInfo = SetupDiGetClassDevsEx(pguidDevClassPtr, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
|
if(INVALID_HANDLE_VALUE == *phDeviceInfo)
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
UNREFERENCED_PARAMETER(dwErr);
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetClassDevsEx failed with code ") << dwErr);
|
|
return false;
|
|
}
|
|
|
|
SP_DEVINFO_LIST_DETAIL_DATA DevListInfo;
|
|
DevListInfo.cbSize = sizeof(DevListInfo);
|
|
if(!SetupDiGetDeviceInfoListDetail(*phDeviceInfo, &DevListInfo))
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
UNREFERENCED_PARAMETER(dwErr);
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetDeviceInfoListDetail failed with code ") << dwErr);
|
|
SetupDiDestroyDeviceInfoList(*phDeviceInfo);
|
|
return false;
|
|
}
|
|
|
|
SP_DEVINFO_DATA CurrDeviceInfo;
|
|
CurrDeviceInfo.cbSize = sizeof(CurrDeviceInfo);
|
|
for(DWORD dwDevIndex = 0; SetupDiEnumDeviceInfo(*phDeviceInfo, dwDevIndex, &CurrDeviceInfo); dwDevIndex++)
|
|
{
|
|
TCHAR szDeviceId[MAX_DEVICE_ID_LEN];
|
|
CONFIGRET err = CM_Get_Device_ID_Ex(CurrDeviceInfo.DevInst,
|
|
szDeviceId, MAX_DEVICE_ID_LEN,
|
|
0, DevListInfo.RemoteMachineHandle);
|
|
if(CR_SUCCESS == err)
|
|
{
|
|
if(_NetKVMIsKnownDevice(szDeviceId))
|
|
{
|
|
_NetKVMDeviceInfo ResDevInfo;
|
|
ResDevInfo.strDeviceID = szDeviceId;
|
|
ResDevInfo.strDeviceDescription = _NetKVMQueryDeviceString(*phDeviceInfo, &CurrDeviceInfo, SPDRP_DEVICEDESC);
|
|
ResDevInfo.strDeviceFriendlyName = _NetKVMQueryDeviceString(*phDeviceInfo, &CurrDeviceInfo, SPDRP_FRIENDLYNAME);
|
|
if (ResDevInfo.strDeviceFriendlyName.length() == 0)
|
|
{
|
|
ResDevInfo.strDeviceFriendlyName = ResDevInfo.strDeviceDescription;
|
|
}
|
|
ResDevInfo.strLocationInfo = _NetKVMQueryDeviceString(*phDeviceInfo, &CurrDeviceInfo, SPDRP_LOCATION_INFORMATION);
|
|
ResDevInfo.dwDeviceNumber = _NetKVMQueryDeviceDWORD(*phDeviceInfo, &CurrDeviceInfo, SPDRP_UI_NUMBER);
|
|
ResDevInfo.DevInfoData = CurrDeviceInfo;
|
|
HKEY hSoftwareRegKey = _NetKVMOpenDeviceSwRegKey(*phDeviceInfo, &CurrDeviceInfo);
|
|
if(INVALID_HANDLE_VALUE != hSoftwareRegKey)
|
|
{
|
|
ResDevInfo.strRegPathName = _NetKVMKeyPathFromDeviceSwHKEY(hSoftwareRegKey);
|
|
CloseHandle(hSoftwareRegKey);
|
|
if(!ResDevInfo.strRegPathName.empty())
|
|
Devices.push_back(ResDevInfo);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("CM_Get_Device_ID_Ex failed with code ") << err);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
DWORD dwErr = GetLastError();
|
|
if(ERROR_NO_MORE_ITEMS != dwErr)
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("SetupDiGetDeviceInfoListDetail failed with code ") << dwErr);
|
|
SetupDiDestroyDeviceInfoList(*phDeviceInfo);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static pair< HDEVINFO, vector<_NetKVMDeviceInfo> > _NetKVMGetDevicesOfInterest()
|
|
{
|
|
vector<GUID> GUIDs;
|
|
pair< HDEVINFO, vector<_NetKVMDeviceInfo> > Devices;
|
|
|
|
_NetKVMGetDeviceClassGuids(GUIDs);
|
|
if(GUIDs.empty())
|
|
return Devices;
|
|
|
|
_NetKVMGetKnownDevices(&GUIDs[0], Devices.second, &Devices.first);
|
|
return Devices;
|
|
}
|
|
|
|
void _NetKVMDumpDeviceInfo(DWORD dwIndex, const _NetKVMDeviceInfo &DeviceInfo)
|
|
{
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICEID);
|
|
tcout << TEXT(": ") << DeviceInfo.strDeviceID << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICEIDX);
|
|
tcout << TEXT(": ") << dwIndex << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICEDESC);
|
|
tcout << TEXT(": ") << DeviceInfo.strDeviceDescription << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICEFRNAME);
|
|
tcout << TEXT(": ") << DeviceInfo.strDeviceFriendlyName << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICELOCINFO);
|
|
tcout << TEXT(": ") << DeviceInfo.strLocationInfo << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICENUM);
|
|
tcout << TEXT(": ") << DeviceInfo.dwDeviceNumber << endl;
|
|
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DEVICEREGKEY);
|
|
tcout << TEXT(": ") << DeviceInfo.strRegPathName << endl << endl;
|
|
}
|
|
|
|
HDEVINFO g_hDeviceInfoList = INVALID_HANDLE_VALUE;
|
|
static vector<_NetKVMDeviceInfo> g_DevicesOfInterest;
|
|
|
|
static DWORD _NetKVMRestartDevice(DWORD dwIndex)
|
|
{
|
|
SP_PROPCHANGE_PARAMS Params;
|
|
Params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
|
|
Params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
|
|
Params.StateChange = DICS_PROPCHANGE;
|
|
Params.Scope = DICS_FLAG_CONFIGSPECIFIC;
|
|
Params.HwProfile = 0;
|
|
|
|
if(!SetupDiSetClassInstallParams(g_hDeviceInfoList,
|
|
&g_DevicesOfInterest[dwIndex].DevInfoData,
|
|
&Params.ClassInstallHeader,
|
|
sizeof(Params)))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
|
|
g_hDeviceInfoList,
|
|
&g_DevicesOfInterest[dwIndex].DevInfoData))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
SP_DEVINSTALL_PARAMS DeviceInstallParams;
|
|
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
|
|
|
|
if(!SetupDiGetDeviceInstallParams(g_hDeviceInfoList,
|
|
&g_DevicesOfInterest[dwIndex].DevInfoData,
|
|
&DeviceInstallParams))
|
|
{
|
|
return ERROR_SUCCESS_REBOOT_REQUIRED;
|
|
}
|
|
|
|
if(DeviceInstallParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
|
|
{
|
|
return ERROR_SUCCESS_REBOOT_REQUIRED;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
static DWORD __NetKVMwsz2DWORD(PWSTR wszInput)
|
|
{
|
|
wstringstream wstrmConverter;
|
|
wstrmConverter << wszInput;
|
|
DWORD dwIndex;
|
|
wstrmConverter >> dwIndex;
|
|
return dwIndex;
|
|
}
|
|
|
|
static BOOL __NetKVMConvertDeviceIndex(PWSTR wszIndex, PDWORD pdwIndex)
|
|
{
|
|
*pdwIndex = __NetKVMwsz2DWORD(wszIndex);
|
|
if(*pdwIndex >= g_DevicesOfInterest.size())
|
|
{
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_INDEXOUTOFRANGE);
|
|
tcout << endl;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
typedef pair<tstring, tstring> ParamDescrT;
|
|
typedef list< ParamDescrT > ParamDescrListT;
|
|
|
|
static void _NetKVMFillDeviceParamsList(DWORD dwDeviceIndex, ParamDescrListT& List)
|
|
{
|
|
auto_ptr<neTKVMRegParam> pParam;
|
|
DWORD dwParamIndex = 0;
|
|
neTKVMRegAccess DeviceRegKey(HKEY_LOCAL_MACHINE, g_DevicesOfInterest[dwDeviceIndex].strRegPathName.c_str());
|
|
|
|
while(NULL != (pParam = auto_ptr<neTKVMRegParam>(neTKVMRegParam::GetParam(DeviceRegKey, dwParamIndex++))).get())
|
|
{
|
|
ParamDescrT ParamDescr;
|
|
ParamDescr.first = pParam->GetName();
|
|
ParamDescr.second = pParam->GetDescription();
|
|
List.push_back(ParamDescr);
|
|
}
|
|
}
|
|
|
|
typedef pair<tstring, tstring> ParamValueT;
|
|
typedef list< ParamValueT > ParamValueListT;
|
|
|
|
static void _NetKVMFillDeviceValuesList(DWORD dwDeviceIndex, ParamValueListT& List)
|
|
{
|
|
auto_ptr<neTKVMRegParam> pParam;
|
|
DWORD dwParamIndex = 0;
|
|
neTKVMRegAccess DeviceRegKey(HKEY_LOCAL_MACHINE, g_DevicesOfInterest[dwDeviceIndex].strRegPathName.c_str());
|
|
|
|
while(NULL != (pParam = auto_ptr<neTKVMRegParam>(neTKVMRegParam::GetParam(DeviceRegKey, dwParamIndex++))).get())
|
|
{
|
|
ParamValueT ParamValue;
|
|
ParamValue.first = pParam->GetName();
|
|
ParamValue.second = pParam->GetValue();
|
|
List.push_back(ParamValue);
|
|
}
|
|
}
|
|
|
|
static bool _NetKVMQueryDetailedParamInfo(DWORD dwDeviceIndex,
|
|
const tstring &strParamName,
|
|
neTKVMRegParamType &ParamType,
|
|
neTKVMRegParamExInfoList &ParamInfo)
|
|
{
|
|
neTKVMRegAccess DeviceRegKey(HKEY_LOCAL_MACHINE, g_DevicesOfInterest[dwDeviceIndex].strRegPathName.c_str());
|
|
|
|
auto_ptr<neTKVMRegParam> pParam(neTKVMRegParam::GetParam(DeviceRegKey, strParamName.c_str()));
|
|
|
|
ParamType = neTKVMRegParam::GetType(DeviceRegKey, strParamName.c_str());
|
|
if(NETKVM_RTT_UNKNOWN == ParamType)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(NULL == pParam.get())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pParam->FillExInfo(ParamInfo);
|
|
return true;
|
|
}
|
|
|
|
static bool _NetKVMQueryParamValue(DWORD dwDeviceIndex,
|
|
const tstring &strParamName,
|
|
tstring &strParamValue)
|
|
{
|
|
neTKVMRegAccess DeviceRegKey(HKEY_LOCAL_MACHINE, g_DevicesOfInterest[dwDeviceIndex].strRegPathName.c_str());
|
|
|
|
auto_ptr<neTKVMRegParam> pParam(neTKVMRegParam::GetParam(DeviceRegKey, strParamName.c_str()));
|
|
if(NULL == pParam.get())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
strParamValue = pParam->GetValue();
|
|
return true;
|
|
}
|
|
|
|
static bool _NetKVMSetParamValue(DWORD dwDeviceIndex,
|
|
const tstring &strParamName,
|
|
const tstring &strParamValue)
|
|
{
|
|
neTKVMRegAccess DeviceRegKey(HKEY_LOCAL_MACHINE, g_DevicesOfInterest[dwDeviceIndex].strRegPathName.c_str());
|
|
|
|
auto_ptr<neTKVMRegParam> pParam(neTKVMRegParam::GetParam(DeviceRegKey, strParamName.c_str()));
|
|
if(NULL == pParam.get())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(!pParam->ValidateAndSetValue(strParamValue.c_str()))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return pParam->Save();
|
|
}
|
|
|
|
//
|
|
// Usage: show devices
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Lists all NetKVM devices currently present in the system.
|
|
// Each device is assigned unique index.
|
|
// The index is used to identify the device for all other NetKVM commands.
|
|
//
|
|
DWORD WINAPI _NetKVMShowDevicesCmdHandler(__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* /*ppwcArguments*/,
|
|
__in DWORD /*dwCurrentIndex*/,
|
|
__in DWORD /*dwArgCount*/,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMShowDevicesCmdHandler called"));
|
|
int i = 0;
|
|
for(vector<_NetKVMDeviceInfo>::const_iterator it = g_DevicesOfInterest.begin();
|
|
it != g_DevicesOfInterest.end();
|
|
++it, ++i)
|
|
{
|
|
_NetKVMDumpDeviceInfo(i, *it);
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Usage: show paraminfo [idx=]0-N [param=]name
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IDX - Specifies the device index as it is shown in "show devices" output.
|
|
// PARAM - Specifies name of the parameter.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Shows detailed information about specified parameter of specified device.
|
|
//
|
|
// Examples:
|
|
//
|
|
// show paraminfo idx=0 param=window
|
|
// show paraminfo 2 rx_buffers
|
|
//
|
|
DWORD WINAPI _NetKVMShowParamInfoCmdHandler (__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* ppwcArguments,
|
|
__in DWORD dwCurrentIndex,
|
|
__in DWORD dwArgCount,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMShowParamInfoCmdHandler called"));
|
|
TAG_TYPE TagsList[] =
|
|
{ {NETKVM_IDX_PARAM_NAME, NS_REQ_PRESENT},
|
|
{NETKVM_PARAM_PARAM_NAME, NS_REQ_PRESENT} };
|
|
|
|
auto_ptr<DWORD> pdwTagMatchResults(new DWORD[dwArgCount - dwCurrentIndex]);
|
|
DWORD dwPreprocessResult = PreprocessCommand(NULL, ppwcArguments,
|
|
dwCurrentIndex, dwArgCount,
|
|
TagsList, ARRAY_SIZE(TagsList),
|
|
ARRAY_SIZE(TagsList), ARRAY_SIZE(TagsList),
|
|
pdwTagMatchResults.get());
|
|
|
|
switch (dwPreprocessResult)
|
|
{
|
|
case NO_ERROR:
|
|
{
|
|
DWORD dwIndex;
|
|
if(__NetKVMConvertDeviceIndex(ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[0]], &dwIndex))
|
|
{
|
|
wstring wstrParamName = ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[1]];
|
|
neTKVMRegParamExInfoList ParamInfo;
|
|
neTKVMRegParamType ParamType;
|
|
|
|
if(!_NetKVMQueryDetailedParamInfo(dwIndex, wstring2tstring(wstrParamName),ParamType, ParamInfo))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMTYPE);
|
|
tcout << TEXT(": ");
|
|
switch(ParamType)
|
|
{
|
|
case NETKVM_RTT_ENUM:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMENUM);
|
|
break;
|
|
case NETKVM_RTT_INT:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMINT);
|
|
break;
|
|
case NETKVM_RTT_LONG:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMLONG);
|
|
break;
|
|
case NETKVM_RTT_EDIT:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMTEXT);
|
|
break;
|
|
default:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMUNKNOWN);
|
|
break;
|
|
}
|
|
tcout << endl;
|
|
|
|
for(neTKVMRegParamExInfoList::const_iterator it = ParamInfo.begin();
|
|
it != ParamInfo.end(); ++it)
|
|
{
|
|
switch(it->first)
|
|
{
|
|
case NETKVM_RPIID_ENUM_VALUE:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMENUMVALUE);
|
|
tcout << TEXT(" \"") << it->second << TEXT("\" - ");
|
|
break;
|
|
case NETKVM_RPIID_ENUM_VALUE_DESC:
|
|
tcout << it->second << endl;
|
|
break;
|
|
case NETKVM_RPIID_NUM_MIN:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMNUMMIN);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
case NETKVM_RPIID_NUM_MAX:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMNUMMAX);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
case NETKVM_RPIID_NUM_STEP:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMNUMSTEP);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
case NETKVM_RPIID_EDIT_TEXT_LIMIT:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMTEXTLIMIT);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
case NETKVM_RPIID_EDIT_UPPER_CASE:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMUPPERCASE);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
default:
|
|
tcout << TEXT("\t");
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_PARAMUNKNOWNPROP);
|
|
tcout << TEXT(": ") << it->second << endl;
|
|
break;
|
|
}
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
__fallthrough;
|
|
default:
|
|
NETCO_DEBUG_PRINT(TEXT("PreprocessCommand returned: ") << dwPreprocessResult);
|
|
return dwPreprocessResult;
|
|
}
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Usage: getparam [idx=]0-N [param=]name
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IDX - Specifies the device index as it is shown in "show devices" output.
|
|
// PARAM - Specifies name of the parameter.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Retrieves given parameter value.
|
|
//
|
|
// Examples:
|
|
//
|
|
// getparam idx=0 param=window
|
|
// getparam 2 rx_buffers
|
|
//
|
|
DWORD WINAPI _NetKVMGetParamCmdHandler (__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* ppwcArguments,
|
|
__in DWORD dwCurrentIndex,
|
|
__in DWORD dwArgCount,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMGetParamCmdHandler called"));
|
|
TAG_TYPE TagsList[] =
|
|
{ {NETKVM_IDX_PARAM_NAME, NS_REQ_PRESENT},
|
|
{NETKVM_PARAM_PARAM_NAME, NS_REQ_PRESENT} };
|
|
|
|
auto_ptr<DWORD> pdwTagMatchResults(new DWORD[dwArgCount - dwCurrentIndex]);
|
|
DWORD dwPreprocessResult = PreprocessCommand(NULL, ppwcArguments,
|
|
dwCurrentIndex, dwArgCount,
|
|
TagsList, ARRAY_SIZE(TagsList),
|
|
ARRAY_SIZE(TagsList), ARRAY_SIZE(TagsList),
|
|
pdwTagMatchResults.get());
|
|
|
|
switch (dwPreprocessResult)
|
|
{
|
|
case NO_ERROR:
|
|
{
|
|
DWORD dwIndex;
|
|
if(__NetKVMConvertDeviceIndex(ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[0]], &dwIndex))
|
|
{
|
|
wstring wstrParamName = ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[1]];
|
|
tstring strParamName = wstring2tstring(wstrParamName);
|
|
tstring strParamValue;
|
|
|
|
if(!_NetKVMQueryParamValue(dwIndex, strParamName, strParamValue))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
tcout << strParamName << TEXT(" = ") << strParamValue << endl;
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
__fallthrough;
|
|
default:
|
|
NETCO_DEBUG_PRINT(TEXT("PreprocessCommand returned: ") << dwPreprocessResult);
|
|
return dwPreprocessResult;
|
|
}
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Usage: setparam [idx=]0-N [param=]name [value=]value
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IDX - Specifies the device index as it is shown in "show devices" output.
|
|
// PARAM - Specifies name of the parameter.
|
|
// VALUE - Specifies the value of the parameter.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Set given parameter value.
|
|
//
|
|
// Examples:
|
|
//
|
|
// setparam idx=0 param=window value=10
|
|
// setparam 2 rx_buffers 45
|
|
//
|
|
DWORD WINAPI _NetKVMSetParamCmdHandler (__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* ppwcArguments,
|
|
__in DWORD dwCurrentIndex,
|
|
__in DWORD dwArgCount,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMSetParamCmdHandler called"));
|
|
TAG_TYPE TagsList[] =
|
|
{ {NETKVM_IDX_PARAM_NAME, NS_REQ_PRESENT},
|
|
{NETKVM_PARAM_PARAM_NAME, NS_REQ_PRESENT},
|
|
{NETKVM_VALUE_PARAM_NAME, NS_REQ_PRESENT} };
|
|
|
|
auto_ptr<DWORD> pdwTagMatchResults(new DWORD[dwArgCount - dwCurrentIndex]);
|
|
DWORD dwPreprocessResult = PreprocessCommand(NULL, ppwcArguments,
|
|
dwCurrentIndex, dwArgCount,
|
|
TagsList, ARRAY_SIZE(TagsList),
|
|
ARRAY_SIZE(TagsList), ARRAY_SIZE(TagsList),
|
|
pdwTagMatchResults.get());
|
|
|
|
switch (dwPreprocessResult)
|
|
{
|
|
case NO_ERROR:
|
|
{
|
|
DWORD dwIndex;
|
|
if(__NetKVMConvertDeviceIndex(ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[0]], &dwIndex))
|
|
{
|
|
wstring wstrParamName = ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[1]];
|
|
wstring wstrParamValue = ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[2]];
|
|
|
|
if(!_NetKVMSetParamValue(dwIndex, wstring2tstring(wstrParamName), wstring2tstring(wstrParamValue)))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
__fallthrough;
|
|
default:
|
|
NETCO_DEBUG_PRINT(TEXT("PreprocessCommand returned: ") << dwPreprocessResult);
|
|
return dwPreprocessResult;
|
|
}
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
//
|
|
// Usage: show parameters [idx=]0-N
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IDX - Specifies the device index as it is shown in "show devices" output.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Shows parameters of device specified by index.
|
|
//
|
|
// Examples:
|
|
//
|
|
// show parameters idx=0
|
|
// show parameters 2
|
|
//
|
|
DWORD WINAPI _NetKVMShowParamsCmdHandler(__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* ppwcArguments,
|
|
__in DWORD dwCurrentIndex,
|
|
__in DWORD dwArgCount,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMShowParamsCmdHandler called"));
|
|
TAG_TYPE TagsList[] =
|
|
{ {NETKVM_IDX_PARAM_NAME, NS_REQ_PRESENT} };
|
|
|
|
auto_ptr<DWORD> pdwTagMatchResults(new DWORD[dwArgCount - dwCurrentIndex]);
|
|
DWORD dwPreprocessResult = PreprocessCommand(NULL, ppwcArguments,
|
|
dwCurrentIndex, dwArgCount,
|
|
TagsList, ARRAY_SIZE(TagsList),
|
|
ARRAY_SIZE(TagsList), ARRAY_SIZE(TagsList),
|
|
pdwTagMatchResults.get());
|
|
|
|
switch (dwPreprocessResult)
|
|
{
|
|
case NO_ERROR:
|
|
{
|
|
DWORD dwIndex;
|
|
if(__NetKVMConvertDeviceIndex(ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[0]], &dwIndex))
|
|
{
|
|
ParamDescrListT Params;
|
|
|
|
_NetKVMFillDeviceParamsList(dwIndex, Params);
|
|
for(ParamDescrListT::const_iterator it = Params.begin();
|
|
it != Params.end(); ++it)
|
|
{
|
|
tcout << it->first << endl<< TEXT("\t") << it->second << endl;
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
__fallthrough;
|
|
default:
|
|
NETCO_DEBUG_PRINT(TEXT("PreprocessCommand returned: ") << dwPreprocessResult);
|
|
return dwPreprocessResult;
|
|
}
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Usage: restart [idx=]0-N
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IDX - Specifies the device index as it is shown in "show devices" output.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Restarts device specified by index.
|
|
//
|
|
// Examples:
|
|
//
|
|
// restart idx=0
|
|
// restart 2
|
|
//
|
|
DWORD WINAPI _NetKVMRestartDeviceCmdHandler(__in PWCHAR /*pwszMachine*/,
|
|
__in PWCHAR* ppwcArguments,
|
|
__in DWORD dwCurrentIndex,
|
|
__in DWORD dwArgCount,
|
|
__in DWORD /*dwFlags*/,
|
|
__in PVOID /*pvData*/,
|
|
__out BOOL* pbDone)
|
|
{
|
|
*pbDone = FALSE; /* Just to make static analyzer happy */
|
|
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMRestartDeviceCmdHandler called"));
|
|
TAG_TYPE TagsList[] =
|
|
{ {NETKVM_IDX_PARAM_NAME, NS_REQ_PRESENT} };
|
|
|
|
auto_ptr<DWORD> pdwTagMatchResults(new DWORD[dwArgCount - dwCurrentIndex]);
|
|
DWORD dwPreprocessResult = PreprocessCommand(NULL, ppwcArguments,
|
|
dwCurrentIndex, dwArgCount,
|
|
TagsList, ARRAY_SIZE(TagsList),
|
|
ARRAY_SIZE(TagsList), ARRAY_SIZE(TagsList),
|
|
pdwTagMatchResults.get());
|
|
|
|
switch (dwPreprocessResult)
|
|
{
|
|
case NO_ERROR:
|
|
{
|
|
DWORD dwIndex;
|
|
if(__NetKVMConvertDeviceIndex(ppwcArguments[dwCurrentIndex + pdwTagMatchResults.get()[0]], &dwIndex))
|
|
{
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_RESTARTINGDEVICE);
|
|
tcout << TEXT(" ") << dwIndex << TEXT("... ");
|
|
DWORD dwError = _NetKVMRestartDevice(dwIndex);
|
|
switch(dwError)
|
|
{
|
|
case NO_ERROR:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_DONE);
|
|
break;
|
|
case ERROR_SUCCESS_REBOOT_REQUIRED:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_REBOOTREQUIRED);
|
|
break;
|
|
default:
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_FAIL);
|
|
break;
|
|
}
|
|
tcout << endl;
|
|
return dwError;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
__fallthrough;
|
|
default:
|
|
NETCO_DEBUG_PRINT(TEXT("PreprocessCommand returned: ") << dwPreprocessResult);
|
|
return dwPreprocessResult;
|
|
}
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
#define CMD_NETKVM_SHOW_DEVICES L"devices"
|
|
#define HLP_NETKVM_SHOW_DEVICES IDS_SHOWDEVICESSHORT
|
|
#define HLP_NETKVM_SHOW_DEVICES_EX IDS_SHOWDEVICESLONG
|
|
#define CMD_NETKVM_SHOW_PARAMS L"parameters"
|
|
#define HLP_NETKVM_SHOW_PARAMS IDS_SHOWPARAMSSHORT
|
|
#define HLP_NETKVM_SHOW_PARAMS_EX IDS_SHOWPARAMSLONG
|
|
#define CMD_NETKVM_SHOW_PARAMINFO L"paraminfo"
|
|
#define HLP_NETKVM_SHOW_PARAMINFO IDS_SHOWPARAMINFOSHORT
|
|
#define HLP_NETKVM_SHOW_PARAMINFO_EX IDS_SHOWPARAMINFOLONG
|
|
|
|
CMD_ENTRY g_ShowCmdTable[] =
|
|
{
|
|
CREATE_CMD_ENTRY_EX(NETKVM_SHOW_DEVICES,
|
|
(PFN_HANDLE_CMD) _NetKVMShowDevicesCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL),
|
|
CREATE_CMD_ENTRY_EX(NETKVM_SHOW_PARAMS,
|
|
(PFN_HANDLE_CMD) _NetKVMShowParamsCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL),
|
|
CREATE_CMD_ENTRY_EX(NETKVM_SHOW_PARAMINFO,
|
|
(PFN_HANDLE_CMD) _NetKVMShowParamInfoCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL)
|
|
|
|
};
|
|
|
|
#define CMD_NETKVM_RESTART_DEVICE L"restart"
|
|
#define CMD_NETKVM_RESTART_DEVICE_T TEXT("restart")
|
|
#define HLP_NETKVM_RESTART_DEVICE IDS_RESTARTDEVICE
|
|
#define HLP_NETKVM_RESTART_DEVICE_EX IDS_RESTARTDEVICELONG
|
|
#define CMD_NETKVM_GET_PARAM L"getparam"
|
|
#define HLP_NETKVM_GET_PARAM IDS_GETPARAM
|
|
#define HLP_NETKVM_GET_PARAM_EX IDS_GETPARAMLONG
|
|
#define CMD_NETKVM_SET_PARAM L"setparam"
|
|
#define CMD_NETKVM_SET_PARAM_T TEXT("setparam")
|
|
#define HLP_NETKVM_SET_PARAM IDS_SETPARAM
|
|
#define HLP_NETKVM_SET_PARAM_EX IDS_SETPARAMLONG
|
|
|
|
CMD_ENTRY g_TopLevelCommands[] =
|
|
{
|
|
CREATE_CMD_ENTRY_EX(NETKVM_RESTART_DEVICE,
|
|
(PFN_HANDLE_CMD) _NetKVMRestartDeviceCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL),
|
|
CREATE_CMD_ENTRY_EX(NETKVM_GET_PARAM,
|
|
(PFN_HANDLE_CMD) _NetKVMGetParamCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL),
|
|
CREATE_CMD_ENTRY_EX(NETKVM_SET_PARAM,
|
|
(PFN_HANDLE_CMD) _NetKVMSetParamCmdHandler,
|
|
CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL)
|
|
};
|
|
|
|
|
|
#define HLP_GROUP_SHOW IDS_SHOWCMDHELP
|
|
#define CMD_GROUP_SHOW L"show"
|
|
|
|
static CMD_GROUP_ENTRY g_TopLevelGroups[] =
|
|
{
|
|
CREATE_CMD_GROUP_ENTRY_EX(GROUP_SHOW, g_ShowCmdTable, CMD_FLAG_PRIVATE | CMD_FLAG_LOCAL)
|
|
};
|
|
|
|
DWORD WINAPI _NetKVMDumpCdmHandler(__in PWCHAR pwszRouter,
|
|
__in WCHAR ** /* ppwcArguments */,
|
|
__in DWORD /* dwArgCount */,
|
|
__in PVOID /* pvData */)
|
|
{
|
|
try
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMDumpCdmHandler called"));
|
|
|
|
if(NULL != pwszRouter)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOCALONLY);
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
tcout << endl<< TEXT("pushd ") << NETKVM_HELPER_NAME << endl << endl;
|
|
|
|
for(DWORD i = 0; i < g_DevicesOfInterest.size(); i++)
|
|
{
|
|
ParamValueListT ValuesList;
|
|
_NetKVMFillDeviceValuesList(i, ValuesList);
|
|
|
|
for(ParamValueListT::const_iterator it = ValuesList.begin();
|
|
it != ValuesList.end(); ++it)
|
|
{
|
|
tcout << CMD_NETKVM_SET_PARAM_T << TEXT(" ")
|
|
<< NETKVM_IDX_PARAM_NAME_T << TEXT("=") << i << TEXT(" ")
|
|
<< NETKVM_PARAM_PARAM_NAME_T << TEXT("=") << it->first << TEXT(" ")
|
|
<< NETKVM_VALUE_PARAM_NAME_T << TEXT("=") << it->second << endl;
|
|
}
|
|
|
|
tcout << CMD_NETKVM_RESTART_DEVICE_T << TEXT(" ")
|
|
<< NETKVM_IDX_PARAM_NAME_T << TEXT("=") << i << TEXT(" ")
|
|
<< endl << endl;
|
|
}
|
|
|
|
tcout << TEXT("popd") << endl;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
DWORD WINAPI _NetKVMNetshStartHelper(__in const GUID *pguidParent,
|
|
__in DWORD dwVersion)
|
|
{
|
|
try
|
|
{
|
|
UNREFERENCED_PARAMETER(pguidParent);
|
|
UNREFERENCED_PARAMETER(dwVersion);
|
|
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMNetshStartHelper called"));
|
|
|
|
pair< HDEVINFO, vector<_NetKVMDeviceInfo> > Devices = _NetKVMGetDevicesOfInterest();
|
|
g_hDeviceInfoList = Devices.first;
|
|
g_DevicesOfInterest = Devices.second;
|
|
|
|
if(g_DevicesOfInterest.empty())
|
|
{
|
|
PrintMessageFromModule(g_hinstThisDLL, IDS_NODEVICESFOUND);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
NS_CONTEXT_ATTRIBUTES attr;
|
|
ZeroMemory(&attr, sizeof(attr));
|
|
attr.dwVersion = NETKVM_HELPER_VERSION;
|
|
attr.dwReserved = 0;
|
|
attr.pwszContext = NETKVM_HELPER_NAME_W;
|
|
attr.guidHelper = NETKVM_HELPER_GUID;
|
|
attr.dwFlags = CMD_FLAG_LOCAL;
|
|
attr.ulPriority = DEFAULT_CONTEXT_PRIORITY;
|
|
attr.ulNumTopCmds = ARRAYSIZE(g_TopLevelCommands);
|
|
attr.pTopCmds = (CMD_ENTRY (*)[])g_TopLevelCommands;
|
|
attr.ulNumGroups = ARRAYSIZE(g_TopLevelGroups);
|
|
attr.pCmdGroups = (CMD_GROUP_ENTRY (*)[])g_TopLevelGroups;
|
|
attr.pfnCommitFn = NULL;
|
|
attr.pfnDumpFn = (PNS_CONTEXT_DUMP_FN) _NetKVMDumpCdmHandler;
|
|
attr.pfnConnectFn = NULL;
|
|
attr.pReserved = NULL;
|
|
RegisterContext(&attr);
|
|
}
|
|
catch(const exception& ex)
|
|
{
|
|
PrintError(g_hinstThisDLL, IDS_LOGICEXCEPTION);
|
|
tcout << TEXT(": ") << string2tstring(string(ex.what())) << endl;
|
|
return ERROR_EXCEPTION_IN_SERVICE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return ERROR_UNKNOWN_EXCEPTION;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD WINAPI _NetKVMNetshStopHelper(__in DWORD dwReserved)
|
|
{
|
|
UNREFERENCED_PARAMETER(dwReserved);
|
|
|
|
NETCO_DEBUG_PRINT(TEXT("_NetKVMNetshStopHelper called"));
|
|
|
|
return SetupDiDestroyDeviceInfoList(g_hDeviceInfoList) ? NO_ERROR
|
|
: GetLastError();
|
|
}
|
|
|
|
DWORD NETCO_API InitHelperDll(__in DWORD dwNetshVersion,
|
|
PVOID pReserved)
|
|
{
|
|
UNREFERENCED_PARAMETER(dwNetshVersion);
|
|
UNREFERENCED_PARAMETER(pReserved);
|
|
|
|
NS_HELPER_ATTRIBUTES attr;
|
|
|
|
ZeroMemory(&attr, sizeof(attr));
|
|
attr.guidHelper = NETKVM_HELPER_GUID;
|
|
attr.dwVersion = NETKVM_HELPER_VERSION;
|
|
attr.pfnStart = _NetKVMNetshStartHelper;
|
|
attr.pfnStop = _NetKVMNetshStopHelper;
|
|
RegisterHelper( NULL, &attr );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
static DWORD _GetThisDLLPathName(LPTSTR szPathName, DWORD *pdwLength)
|
|
{
|
|
DWORD dwPathLength = GetModuleFileName(g_hinstThisDLL, szPathName, *pdwLength);
|
|
DWORD dwErr = GetLastError();
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("GetModuleFileName failed. Error code: ") << dwErr);
|
|
return dwErr;
|
|
}
|
|
else if(dwPathLength == *pdwLength)
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("Buffer provided to GetModuleFileName is too small"));
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
else
|
|
{
|
|
NETCO_DEBUG_PRINT(TEXT("DLL pathname: ") << szPathName);
|
|
*pdwLength = dwPathLength;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
static const LPCTSTR NETSH_HELPERS_LIST_PATH = TEXT("SOFTWARE\\Microsoft\\NetSh");
|
|
static const HKEY NETSH_HELPERS_LIST_HIVE = HKEY_LOCAL_MACHINE;
|
|
|
|
DWORD NETCO_API RegisterNetKVMNetShHelper(void)
|
|
{
|
|
try
|
|
{
|
|
TCHAR szDllPathName[MAX_PATH];
|
|
DWORD dwPathNameLength = TBUF_SIZEOF(szDllPathName);
|
|
|
|
DWORD dwErr = _GetThisDLLPathName(szDllPathName, &dwPathNameLength);
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
tstringstream strmError;
|
|
strmError << TEXT("_GetThisDLLPathName failed with code ") << dwErr;
|
|
OutputDebugString(strmError.str().c_str());
|
|
return dwErr;
|
|
}
|
|
|
|
neTKVMRegAccess regAccess(NETSH_HELPERS_LIST_HIVE, NETSH_HELPERS_LIST_PATH);
|
|
if(!regAccess.WriteString(NETKVM_HELPER_NAME, szDllPathName))
|
|
{
|
|
dwErr = GetLastError();
|
|
tstringstream strmError;
|
|
strmError << TEXT("Registry operation failed with code ") << dwErr;
|
|
OutputDebugString(strmError.str().c_str());
|
|
return dwErr;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
catch (const exception& ex)
|
|
{
|
|
OutputDebugStringA(ex.what());
|
|
return ERROR_INSTALL_FAILURE;
|
|
}
|
|
}
|
|
DWORD NETCO_API UnregisterNetKVMNetShHelper(void)
|
|
{
|
|
try
|
|
{
|
|
neTKVMRegAccess regAccess(NETSH_HELPERS_LIST_HIVE, NETSH_HELPERS_LIST_PATH);
|
|
regAccess.DeleteValue(NETKVM_HELPER_NAME);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
catch (const exception& ex)
|
|
{
|
|
OutputDebugStringA(ex.what());
|
|
return ERROR_INSTALL_FAILURE;
|
|
}
|
|
}
|
|
|
|
BOOL NETCO_API __stdcall DllMain(__in HINSTANCE hinstDLL,
|
|
__in DWORD fdwReason,
|
|
__in LPVOID lpvReserved)
|
|
{
|
|
UNREFERENCED_PARAMETER(lpvReserved);
|
|
|
|
NETCO_DEBUG_PRINT(TEXT("DllMain(") << fdwReason << TEXT(") called"));
|
|
|
|
//Obtain DLL path name and store it for future use
|
|
if(DLL_PROCESS_ATTACH == fdwReason)
|
|
{
|
|
g_hinstThisDLL = hinstDLL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|