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, &paramDispid, 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, &paramArgs, 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
{
}