785 lines
22 KiB
C++
785 lines
22 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2007 Intel Corporation
|
|
//
|
|
// File: WRMWsmanClient.cpp
|
|
//
|
|
// Contents: An implementation of the WsmanClient interface using Microsoft WinRM
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "WRMWsmanClient.h"
|
|
#include <atlbase.h>
|
|
#include <atlconv.h>
|
|
#include <sstream>
|
|
|
|
using namespace WsmanClientNamespace;
|
|
|
|
WRMWsmanClient::WRMWsmanClient(const string& endp,
|
|
const string& username,
|
|
const string& password,
|
|
const bool krb)
|
|
:endpoint(endp), user(username), pwd(password), kerb(krb)
|
|
{
|
|
_pWsmanSessionDispatch = NULL;
|
|
_pWsmanDispatch = NULL;
|
|
_pWsmanConnectionOptions = NULL;
|
|
_getDispid = 0;
|
|
_putDispid = 0;
|
|
_createDispid = 0;
|
|
_enumerateDispid = 0;
|
|
_invokeDispid = 0;
|
|
_deleteDispid = 0;
|
|
_createSessionDispid = 0;
|
|
_createConnectionOptionsDispid = 0;
|
|
_createResourceLocatorDispid = 0;
|
|
_dispPropertyPut = DISPID_PROPERTYPUT;
|
|
_connectionFlags = 0;
|
|
|
|
if(!Init())
|
|
{
|
|
ReleaseDisps();
|
|
throw WsmanClientException(
|
|
"ERROR: Failed to create Microsoft WinRM client.\n"
|
|
"Make Sure your system supports WS-MAN COM development and that CoInitialize() was called.");
|
|
}
|
|
}
|
|
|
|
WRMWsmanClient::~WRMWsmanClient()
|
|
{
|
|
ReleaseDisps();
|
|
}
|
|
|
|
bool WRMWsmanClient::Init()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// get wsman.automation object
|
|
hr = CLSIDFromProgID(L"wsman.automation", &_wsmanOleClsid);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
hr = CoCreateInstance(_wsmanOleClsid, 0, CLSCTX_INPROC_SERVER, IID_IDispatch, (LPVOID *)&_pWsmanDispatch);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// create connection
|
|
return CreateSession() && GetFunctionIds() && GetDispId(_pWsmanDispatch, &_createResourceLocatorDispid, L"createresourcelocator");
|
|
}
|
|
|
|
bool WRMWsmanClient::GetFunctionIds()
|
|
{
|
|
return GetDispId(_pWsmanSessionDispatch, &_getDispid, L"get") &&
|
|
GetDispId(_pWsmanSessionDispatch, &_putDispid, L"put") &&
|
|
GetDispId(_pWsmanSessionDispatch, &_createDispid, L"create") &&
|
|
GetDispId(_pWsmanSessionDispatch, &_invokeDispid, L"invoke") &&
|
|
GetDispId(_pWsmanSessionDispatch, &_deleteDispid, L"delete") &&
|
|
GetDispId(_pWsmanSessionDispatch, &_enumerateDispid, L"enumerate");
|
|
}
|
|
|
|
bool WRMWsmanClient::GetDispId(IDispatch* disp, DISPID* id, wchar_t* name)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
OLECHAR FAR* idName = name;
|
|
hr = disp->GetIDsOfNames(IID_NULL, &idName, 1, LOCALE_USER_DEFAULT, id);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void WRMWsmanClient::ReleaseDisps()
|
|
{
|
|
if (_pWsmanSessionDispatch)
|
|
{
|
|
_pWsmanSessionDispatch->Release();
|
|
_pWsmanSessionDispatch = NULL;
|
|
}
|
|
if (_pWsmanConnectionOptions)
|
|
{
|
|
_pWsmanConnectionOptions->Release();
|
|
_pWsmanConnectionOptions = NULL;
|
|
}
|
|
if(_pWsmanDispatch)
|
|
{
|
|
_pWsmanDispatch->Release();
|
|
_pWsmanDispatch = NULL;
|
|
}
|
|
}
|
|
|
|
bool WRMWsmanClient::SetConnectionOptions(wchar_t* fieldName, const string& fieldValue)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// set password
|
|
DISPID paramDispid;
|
|
if(!GetDispId(_pWsmanConnectionOptions, ¶mDispid, fieldName))
|
|
{
|
|
return false;
|
|
}
|
|
DISPPARAMS paramArgs = {0};
|
|
paramArgs.cArgs = 1;
|
|
paramArgs.rgvarg = new VARIANTARG[paramArgs.cArgs]; // parameters are passed in reverse order
|
|
paramArgs.cNamedArgs = 1;
|
|
paramArgs.rgdispidNamedArgs = &_dispPropertyPut;
|
|
paramArgs.rgvarg[0].vt = VT_BSTR;
|
|
|
|
int len = MultiByteToWideChar(CP_ACP, 0, fieldValue.c_str(), fieldValue.length()+1,0,0);
|
|
wchar_t* tmp = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, fieldValue.c_str(), fieldValue.length()+1, tmp, len);
|
|
paramArgs.rgvarg[0].bstrVal = SysAllocString(tmp);
|
|
delete[] tmp;
|
|
|
|
hr = _pWsmanConnectionOptions->Invoke(paramDispid, IID_NULL,
|
|
LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶mArgs, NULL, NULL, NULL);
|
|
VariantClear(&(paramArgs.rgvarg[0]));
|
|
delete [] paramArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::CreateConnectionOptions()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// create connection parameters
|
|
// get dispid for createconnectionoptions
|
|
if(!GetDispId(_pWsmanDispatch, &_createConnectionOptionsDispid, L"createconnectionoptions"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DISPPARAMS connectionOptionsArgs = {0};
|
|
connectionOptionsArgs.cArgs = 0;
|
|
connectionOptionsArgs.rgvarg = 0; // parameters are passed in reverse order
|
|
|
|
VARIANT opt;
|
|
VariantInit(&opt);
|
|
hr = _pWsmanDispatch->Invoke(_createConnectionOptionsDispid, IID_NULL,
|
|
LOCALE_USER_DEFAULT, DISPATCH_METHOD, &connectionOptionsArgs, &opt, NULL, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
hr = opt.punkVal->QueryInterface(IID_IDispatch, (LPVOID *)&_pWsmanConnectionOptions);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
VariantClear(&opt);
|
|
return false;
|
|
}
|
|
|
|
return SetConnectionOptions(L"password", pwd) && SetConnectionOptions(L"username", user);
|
|
|
|
}
|
|
|
|
bool WRMWsmanClient::AddSessionFlag(wchar_t* fName)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
long flag = 0;
|
|
DISPID flagDisp = 0;
|
|
if(!GetDispId(_pWsmanDispatch, &flagDisp, fName))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DISPPARAMS dispArgs = {0};
|
|
dispArgs.cArgs = 0;
|
|
dispArgs.rgvarg = 0; // parameters are passed in reverse order
|
|
|
|
VARIANT opt;
|
|
VariantInit(&opt);
|
|
hr = _pWsmanDispatch->Invoke(flagDisp, IID_NULL,
|
|
LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispArgs, &opt, NULL, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
flag = opt.lVal;
|
|
VariantClear(&opt);
|
|
_connectionFlags |= flag;
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::CreateSessionFlags()
|
|
{
|
|
// set SessionFlagUTF8
|
|
return AddSessionFlag(L"sessionflagcredusernamepassword") &&
|
|
AddSessionFlag(L"sessionflagutf8") &&
|
|
AddSessionFlag(kerb ? L"sessionflagusenegotiate" : L"sessionflagusedigest");
|
|
}
|
|
|
|
bool WRMWsmanClient::CreateSession()
|
|
{
|
|
if(!CreateConnectionOptions() || !CreateSessionFlags())
|
|
{
|
|
return false;
|
|
}
|
|
// get dispid for createsession
|
|
if(!GetDispId(_pWsmanDispatch, &_createSessionDispid, L"createsession"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
DISPPARAMS connectArgs = {0};
|
|
connectArgs.cArgs = 3;
|
|
connectArgs.rgvarg = new VARIANTARG[connectArgs.cArgs]; // parameters are passed in reverse order
|
|
|
|
int len = MultiByteToWideChar(CP_ACP, 0, endpoint.c_str(), endpoint.length()+1,0,0);
|
|
wchar_t* tmp = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, endpoint.c_str(), endpoint.length()+1, tmp, len);
|
|
connectArgs.rgvarg[0].vt = VT_DISPATCH;
|
|
connectArgs.rgvarg[0].pdispVal = _pWsmanConnectionOptions;
|
|
connectArgs.rgvarg[1].vt = VT_I4;
|
|
connectArgs.rgvarg[1].lVal = _connectionFlags;
|
|
connectArgs.rgvarg[2].vt = VT_BSTR;
|
|
connectArgs.rgvarg[2].bstrVal = SysAllocString(tmp);
|
|
delete[] tmp;
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
hr = _pWsmanDispatch->Invoke(_createSessionDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &connectArgs, &var, NULL, NULL);
|
|
VariantClear(&(connectArgs.rgvarg[2]));
|
|
delete [] connectArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
hr = var.punkVal->QueryInterface(IID_IDispatch, (LPVOID *)&_pWsmanSessionDispatch);
|
|
if (FAILED(hr))
|
|
{
|
|
VariantClear(&var);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::AddSelectors(IDispatch* disp, const NameValuePairs *selectors) const
|
|
{
|
|
DISPID addsel = 0;
|
|
HRESULT hr = E_FAIL;
|
|
OLECHAR FAR* idName = L"addselector";
|
|
hr = disp->GetIDsOfNames(IID_NULL, &idName, 1, LOCALE_USER_DEFAULT, &addsel);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (PairsIterator p = selectors->begin(); p != selectors->end(); ++p)
|
|
{
|
|
if(!p->second.empty())
|
|
{
|
|
if(!AddSelector(disp, addsel, p->first, p->second))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::AddSelector(IDispatch* disp, DISPID& selID, const string& name, const string& value) const
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
DISPPARAMS selArgs = {0};
|
|
selArgs.cArgs = 2;
|
|
selArgs.rgvarg = new VARIANTARG[selArgs.cArgs];
|
|
VARIANT val;
|
|
VariantInit(&val);
|
|
val.vt = VT_BSTR;
|
|
int len0 = MultiByteToWideChar(CP_ACP, 0, value.c_str(), value.length()+1,0,0);
|
|
wchar_t* tmp0 = new wchar_t[len0];
|
|
MultiByteToWideChar(CP_ACP, 0, value.c_str(), value.length()+1, tmp0, len0);
|
|
val.bstrVal = SysAllocString(tmp0);
|
|
selArgs.rgvarg[0].vt = VT_VARIANT | VT_BYREF;
|
|
selArgs.rgvarg[0].pvarVal = &val;
|
|
delete[] tmp0;
|
|
int len1 = MultiByteToWideChar(CP_ACP, 0, name.c_str(), name.length()+1,0,0);
|
|
wchar_t* tmp1 = new wchar_t[len1];
|
|
MultiByteToWideChar(CP_ACP, 0, name.c_str(), name.length()+1, tmp1, len1);
|
|
selArgs.rgvarg[1].vt = VT_BSTR;
|
|
selArgs.rgvarg[1].bstrVal = SysAllocString(tmp1);
|
|
delete[] tmp1;
|
|
hr = disp->Invoke(selID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &selArgs, NULL, NULL, NULL);
|
|
/// clean up
|
|
VariantClear(&(selArgs.rgvarg[1]));
|
|
VariantClear(&val);
|
|
delete [] selArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::CreateResourceLocator(IDispatch **disp, const string& uri, const NameValuePairs *s) const
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
DISPPARAMS uriArgs = {0};
|
|
uriArgs.cArgs = 1;
|
|
uriArgs.rgvarg = new VARIANTARG[uriArgs.cArgs]; // parameters are passed in reverse order
|
|
|
|
int len = MultiByteToWideChar(CP_ACP, 0, uri.c_str(), uri.length()+1,0,0);
|
|
wchar_t* tmp = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, uri.c_str(), uri.length()+1, tmp, len);
|
|
uriArgs.rgvarg[0].vt = VT_BSTR;
|
|
uriArgs.rgvarg[0].bstrVal = SysAllocString(tmp);
|
|
delete[] tmp;
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
hr = _pWsmanDispatch->Invoke(_createResourceLocatorDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &uriArgs, &var, NULL, NULL);
|
|
VariantClear(&(uriArgs.rgvarg[0]));
|
|
delete [] uriArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
hr = var.punkVal->QueryInterface(IID_IDispatch, (LPVOID *)disp);
|
|
if (FAILED(hr))
|
|
{
|
|
VariantClear(&var);
|
|
return false;
|
|
}
|
|
if(!s)
|
|
{
|
|
return true;
|
|
}
|
|
return AddSelectors(*disp, s);
|
|
}
|
|
|
|
|
|
string WRMWsmanClient::Create(const string &resourceUri, const string &data) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, NULL))
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Create function.");
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS createArgs = {0};
|
|
createArgs.cArgs = 3;
|
|
createArgs.rgvarg = new VARIANTARG[createArgs.cArgs]; // parameters are passed in reverse order
|
|
createArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
createArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
createArgs.rgvarg[1].vt = VT_BSTR;
|
|
int len = MultiByteToWideChar(CP_ACP, 0, data.c_str(), data.length()+1,0,0);
|
|
wchar_t* resource = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, data.c_str(), data.length()+1, resource, len);
|
|
createArgs.rgvarg[1].bstrVal = SysAllocString(resource);
|
|
delete[] resource;
|
|
createArgs.rgvarg[2].vt = VT_VARIANT | VT_BYREF;
|
|
createArgs.rgvarg[2].pvarVal = &uri;
|
|
|
|
unsigned int argNum = 0;
|
|
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_createDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &createArgs, &var, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
VariantClear(&(createArgs.rgvarg[1]));
|
|
delete [] createArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Create function. Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
|
|
string ret = W2CA(SysAllocString(var.bstrVal));
|
|
VariantClear(&var);
|
|
return ret;
|
|
}
|
|
|
|
void WRMWsmanClient::Delete(const string &resourceUri, const NameValuePairs *s) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, s))
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Delete function.");
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS deleteArgs = {0};
|
|
deleteArgs.cArgs = 2;
|
|
deleteArgs.rgvarg = new VARIANTARG[deleteArgs.cArgs]; // parameters are passed in reverse order
|
|
deleteArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
deleteArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
deleteArgs.rgvarg[1].vt = VT_VARIANT | VT_BYREF;
|
|
deleteArgs.rgvarg[1].pvarVal = &uri;
|
|
|
|
unsigned int argNum = 0;
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_deleteDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &deleteArgs, NULL, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
delete [] deleteArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Delete function. Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
}
|
|
|
|
bool WRMWsmanClient::CheckForMoreItems(IDispatch* disp, DISPID& id, bool& hasItems) const
|
|
{
|
|
DISPPARAMS dispArgs = {0};
|
|
dispArgs.cArgs = 0;
|
|
dispArgs.rgvarg = 0;
|
|
EXCEPINFO excepinfo = {0};
|
|
unsigned int argNum = 0;
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
HRESULT hr = disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispArgs, &var, NULL, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
hasItems = !var.boolVal;
|
|
VariantClear(&var);
|
|
return true;
|
|
}
|
|
|
|
bool WRMWsmanClient::GetEnumerationItems(IDispatch* disp, vector<string> &enumRes) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
DISPID getItemId = 0;
|
|
DISPID eosId = 0;
|
|
OLECHAR FAR* getItemName = L"readitem";
|
|
OLECHAR FAR* eosName = L"atendofstream";
|
|
hr = disp->GetIDsOfNames(IID_NULL, &getItemName, 1, LOCALE_USER_DEFAULT, &getItemId);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
hr = disp->GetIDsOfNames(IID_NULL, &eosName, 1, LOCALE_USER_DEFAULT, &eosId);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
bool hasItem = false;
|
|
if(!CheckForMoreItems(disp, eosId, hasItem))
|
|
{
|
|
return false;
|
|
}
|
|
DISPPARAMS dispArgs = {0};
|
|
dispArgs.cArgs = 0;
|
|
dispArgs.rgvarg = 0;
|
|
EXCEPINFO excepinfo = {0};
|
|
unsigned int argNum = 0;
|
|
while(hasItem)
|
|
{
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
hr = disp->Invoke(getItemId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispArgs, &var, &excepinfo, &argNum);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
string item = W2CA(SysAllocString(var.bstrVal));
|
|
VariantClear(&var);
|
|
enumRes.push_back(item);
|
|
if(!CheckForMoreItems(disp, eosId, hasItem))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
void WRMWsmanClient::Enumerate(const string &resourceUri, vector<string> &enumRes, const NameValuePairs *s) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, s))
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Enumerate function.");
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS enumArgs = {0};
|
|
enumArgs.cArgs = 4;
|
|
enumArgs.rgvarg = new VARIANTARG[enumArgs.cArgs]; // parameters are passed in reverse order
|
|
|
|
enumArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
enumArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
enumArgs.rgvarg[1].vt = VT_ERROR; // skip optional param
|
|
enumArgs.rgvarg[1].scode = DISP_E_PARAMNOTFOUND;
|
|
enumArgs.rgvarg[2].vt = VT_ERROR; // skip optional param
|
|
enumArgs.rgvarg[2].scode = DISP_E_PARAMNOTFOUND;
|
|
enumArgs.rgvarg[3].vt = VT_VARIANT | VT_BYREF;
|
|
enumArgs.rgvarg[3].pvarVal = &uri;
|
|
|
|
unsigned int argNum = 0;
|
|
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_enumerateDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &enumArgs, &var, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
delete [] enumArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Enumerate function. Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
IDispatch* enumerator = NULL;
|
|
hr = var.punkVal->QueryInterface(IID_IDispatch, (LPVOID *)&enumerator);
|
|
if (FAILED(hr))
|
|
{
|
|
VariantClear(&var);
|
|
throw WsmanClientException("ERROR: Failed to perform Enumerate function.");
|
|
}
|
|
bool ret = GetEnumerationItems(enumerator, enumRes);
|
|
enumerator->Release();
|
|
if(!ret)
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Enumerate function.");
|
|
}
|
|
}
|
|
|
|
string WRMWsmanClient::Get(const string &resourceUri, const NameValuePairs *s) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, s))
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Get function.");
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS getArgs = {0};
|
|
getArgs.cArgs = 2;
|
|
getArgs.rgvarg = new VARIANTARG[getArgs.cArgs]; // parameters are passed in reverse order
|
|
|
|
getArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
getArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
getArgs.rgvarg[1].vt = VT_VARIANT | VT_BYREF;
|
|
getArgs.rgvarg[1].pvarVal = &uri;
|
|
|
|
unsigned int argNum = 0;
|
|
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_getDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &getArgs, &var, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
delete [] getArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Get function. Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
|
|
string ret = W2CA(SysAllocString(var.bstrVal));
|
|
VariantClear(&var);
|
|
return ret;
|
|
}
|
|
|
|
string WRMWsmanClient::Put(const string &resourceUri, const string &content, const NameValuePairs *s) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, s))
|
|
{
|
|
throw WsmanClientException("ERROR: Failed to perform Get function.");
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS putArgs = {0};
|
|
putArgs.cArgs = 3;
|
|
putArgs.rgvarg = new VARIANTARG[putArgs.cArgs]; // parameters are passed in reverse order
|
|
putArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
putArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
putArgs.rgvarg[1].vt = VT_BSTR;
|
|
int len = MultiByteToWideChar(CP_ACP, 0, content.c_str(), content.length()+1,0,0);
|
|
wchar_t* resource = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, content.c_str(), content.length()+1, resource, len);
|
|
putArgs.rgvarg[1].bstrVal = SysAllocString(resource);
|
|
delete[] resource;
|
|
putArgs.rgvarg[2].vt = VT_VARIANT | VT_BYREF;
|
|
putArgs.rgvarg[2].pvarVal = &uri;
|
|
|
|
unsigned int argNum = 0;
|
|
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_putDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &putArgs, &var, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
VariantClear(&(putArgs.rgvarg[1]));
|
|
delete [] putArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Put function. Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
|
|
string ret = W2CA(SysAllocString(var.bstrVal));
|
|
VariantClear(&var);
|
|
return ret;
|
|
}
|
|
|
|
string WRMWsmanClient::Invoke(const string &resourceUri, const string &methodName, const string &content, const NameValuePairs *s) const
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
IDispatch* resourceLocator = 0;
|
|
if(!CreateResourceLocator(&resourceLocator, resourceUri, s))
|
|
{
|
|
string msg = "ERROR: Failed to perform Invoke " + methodName + " function.";
|
|
throw WsmanClientException(msg.c_str());
|
|
}
|
|
|
|
VARIANT uri;
|
|
VariantInit(&uri);
|
|
uri.vt = VT_DISPATCH;
|
|
uri.pdispVal = resourceLocator;
|
|
|
|
DISPPARAMS invokeArgs = {0};
|
|
invokeArgs.cArgs = 4;
|
|
invokeArgs.rgvarg = new VARIANTARG[invokeArgs.cArgs]; // parameters are passed in reverse order
|
|
invokeArgs.rgvarg[0].vt = VT_ERROR; // skip optional param
|
|
invokeArgs.rgvarg[0].scode = DISP_E_PARAMNOTFOUND;
|
|
invokeArgs.rgvarg[1].vt = VT_BSTR;
|
|
int len = MultiByteToWideChar(CP_ACP, 0, content.c_str(), content.length()+1,0,0);
|
|
wchar_t* resource = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, content.c_str(), content.length()+1, resource, len);
|
|
invokeArgs.rgvarg[1].bstrVal = SysAllocString(resource);
|
|
delete[] resource;
|
|
invokeArgs.rgvarg[2].vt = VT_VARIANT | VT_BYREF;
|
|
invokeArgs.rgvarg[2].pvarVal = &uri;
|
|
invokeArgs.rgvarg[3].vt = VT_BSTR;
|
|
len = MultiByteToWideChar(CP_ACP, 0, methodName.c_str(), methodName.length()+1,0,0);
|
|
wchar_t* meth = new wchar_t[len];
|
|
MultiByteToWideChar(CP_ACP, 0, methodName.c_str(), methodName.length()+1, meth, len);
|
|
invokeArgs.rgvarg[3].bstrVal = SysAllocString(meth);
|
|
delete[] meth;
|
|
|
|
unsigned int argNum = 0;
|
|
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
EXCEPINFO excepinfo = {0};
|
|
hr = _pWsmanSessionDispatch->Invoke(_invokeDispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &invokeArgs, &var, &excepinfo, &argNum);
|
|
resourceLocator->Release();
|
|
VariantClear(&uri);
|
|
VariantClear(&(invokeArgs.rgvarg[1]));
|
|
VariantClear(&(invokeArgs.rgvarg[3]));
|
|
delete [] invokeArgs.rgvarg;
|
|
if (FAILED(hr))
|
|
{
|
|
stringstream msg;
|
|
msg << "ERROR: Failed to perform Invoke " << methodName.c_str() << " function." << endl;
|
|
msg << "Dispatch function returned " << hr << endl;
|
|
msg << "Winrm returned error code: " << argNum;
|
|
if(excepinfo.bstrDescription)
|
|
{
|
|
msg << endl << "\nError Description: " << W2CA(excepinfo.bstrDescription);
|
|
}
|
|
throw WsmanClientException(msg.str().c_str());
|
|
}
|
|
|
|
string ret = W2CA(SysAllocString(var.bstrVal));
|
|
VariantClear(&var);
|
|
return ret;
|
|
}
|
|
|
|
// Submit a subscription
|
|
string WRMWsmanClient::Subscribe(const string &resourceUri, const SubscribeInfo &info, string &identifier) const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Renew a subscription
|
|
string WRMWsmanClient::Renew(const string &identifier, float expire) const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Terminate a subscription
|
|
void WRMWsmanClient::Unsubscribe(const string &identifier) const
|
|
{
|
|
}
|
|
|