Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2762
  • Last Modified:

WMI... Remote execution

HI, I want to execute an application on the remote machine using WMI in VC++ 6.0 !

can anybody help me please..
0
Dcom4CIT
Asked:
Dcom4CIT
  • 7
  • 6
1 Solution
 
grg99Commented:
Hmmm,  kinda hard I think.

WMI is yet another layer of glop layered onto the OS.  Glop would rather be called by other glop, so most of the interfaces to WMI are from gloppy languages like VB and ASP.     A 5-minute scan of the net shows lots of VB and ASP examples, one C# example, but not a single C or C++ example.


Here's how to do it in VB:
http://www.freevbcode.com/ShowCode.asp?ID=1861

0
 
waysideCommented:
What sort of application?

Programs started on remote machines through WMI are not allowed to open Windows.

I know I've got some code lying around somewhere do to this, let me dig it up...
0
 
waysideCommented:
Ok, I found my code. It is based on some sample code I found on the internet a long time ago.

It is a pain to do this in c++, you basically have to

- get a wbem locator
- connect to the other machine
- get a win32_process object
- get an object for the parameters of the create function
- fill in the parameters
- execute the create method

All this takes 100+ lines of c++ code to accomplish, where you can to this in VB in like 3 lines.

Rather than post my code, which I can't really do anyway since it is owned by my company, here is the link to the sample code I learned from. It includes a nice little MFC dialog app to demonstrate its use.

http://www.developer.com/net/cplus/article.php/640511

It might be easier to have your program write out a small vb script, and use CreateProcess to run cscript with it. :)

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Dcom4CITAuthor Commented:
i think the 100+ lines is too much as its too close to my project deadline - is it possible to give me sample vb script that will perform the same task..
0
 
waysideCommented:
I'm not much on VB, but it would be something like this. Subsitute in the appropriate strings for strComputer, strUser, and strPassword, and strProgram.

Set objWMILocator = CreateObject("WbemScripting.SWbemLocator")

Set objWMIService = objWMILocator.ConnectServer( strComputer, "\\root\\cimv2:Win32_Process",  strUser , strPassword  )

Set objProcess = objWMIService.Get("Win32_Process")

err = objProcess.Create(strProgram, null, null, intProcessID)
 

The link I posted has sample code which wraps all the gory details in a class. All you'd have to do is add the class to your project, and add one line of code to create the process.
0
 
Dcom4CITAuthor Commented:
Is there any chance of giving me sample code to create the process using the class in the link you posted...

Thanks in advance.
0
 
waysideCommented:
Sure, it's pretty easy.

#include "cprocess.h"

// create an object to run a process
CProcess      process;

// set up the arguments
CString            szMachineName = "mymachine";    // name of computer where to run
CString            szCommandLine = "cmd /C dir > out.txt";  // put your command here
CString            szUserID = "user"; // user to login to the remote computer
CString            szPassword "password";  // password for the remote computer

if(FAILED(process.CreateNewProcess(szMachineName.AllocSysString(),
                                                      szUserID.AllocSysString(),
                                                      szPassword.AllocSysString(),
                                                      szCommandLine.AllocSysString())))
{
  AfxMessageBox("Failed to create new process!");
}


Add these files into your project, these are from the link:

/******  cprocess.h ******/
#include "wbemcli.h"
#include "comdef.h"

class CProcess
{

private:
      
      IWbemLocator                  *pLocator;
      IWbemServices                  *pService;
      IWbemClassObject            *pInParameters;
      IWbemClassObject            *pMethodObject;
      STDMETHODIMP                  ConnectToWbem(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword);

public:

      CProcess();
      ~CProcess();
      STDMETHODIMP CreateNewProcess(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword, _variant_t      vCommandLine);

};
/****** end of cprocess.h ******/

/****** cprocess.cpp ******/
#include "cprocess.h"

CProcess::CProcess()
{
      pInParameters = NULL;
      pMethodObject = NULL;
      pLocator = NULL;
      pService = NULL;
      CoInitialize(NULL);
}

CProcess::~CProcess()
{
      if (pInParameters) pInParameters->Release();
      if (pMethodObject) pMethodObject->Release();
      if (pLocator) pLocator->Release();
      if (pService) pService->Release();
      CoUninitialize();
}

STDMETHODIMP CProcess::CreateNewProcess(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword, _variant_t vCommandLine)
{
HRESULT                        hRes = 0;
IWbemClassObject      *pProcess = NULL;
IWbemClassObject      *pOutInst = NULL;
      
      if(FAILED(ConnectToWbem(bstrMachine, bstrUserID, bstrPassword)))
      {
            return E_FAIL;
      }

      hRes = pService->GetObject(_bstr_t(L"Win32_Process"), 0, NULL, &pProcess, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL; // Program has failed.
      }

      hRes = pProcess->GetMethod(_bstr_t("Create"), 0, &pInParameters, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pInParameters->SpawnInstance(0, &pMethodObject);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pMethodObject->Put(_bstr_t(L"CommandLine"), 0, &vCommandLine, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pService->ExecMethod(_bstr_t(L"Win32_Process"), _bstr_t(L"Create"), 0, NULL, pMethodObject, &pOutInst, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }      

pProcess->Release();
pOutInst->Release();
return S_OK;

}

STDMETHODIMP CProcess::ConnectToWbem(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword)
{
HRESULT            hRes = 0;
_bstr_t            szConnectionPath;

      hRes = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator);
 
      if (FAILED(hRes))
      {
            return E_FAIL; // Program has failed.
      }

      if(SysStringLen(bstrMachine) == 0)
      {
            szConnectionPath += "root\\cimv2"; //connect to local machine
      }
      else
      {
            szConnectionPath += "\\\\";//set up connection string for remote machine
            szConnectionPath += bstrMachine;
            szConnectionPath += "\\root\\cimv2";
      }

      //if no UserName and PassWord supplied use NTLM to grab users access token
      if((SysStringLen(bstrUserID) == 0) && (SysStringLen(bstrPassword) == 0))
      {
            hRes = pLocator->ConnectServer(      szConnectionPath, NULL, NULL, 0, NULL,      0, 0, &pService);
            if FAILED(hRes)
            {
                  return E_FAIL;         // Program has failed.
            }

      }
      else
      {
            // Connect to the Root\Default namespace with the current user.
            hRes = pLocator->ConnectServer(      szConnectionPath, bstrUserID, bstrPassword, 0, NULL, 0, 0, &pService);
            if FAILED(hRes)
            {
                  return E_FAIL;         // Program has failed.
            }
      }
      // Set the proxy so that impersonation of the client occurs.

      hRes = CoSetProxyBlanket(pService, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
      if(FAILED(hRes))
      {
            //user impersonation has failed!
            return E_FAIL;         // Program has failed.
      }
      return S_OK;

}

/****** end of cprocess.cpp ******/
0
 
Dcom4CITAuthor Commented:
hi, thanks for the code.  it works perfect when i execute a program on the localhost
when i try to execute a program on a remote machine it  comes back with the following error - "failed to get GetObject"

thank in advance..

 hRes = pService->GetObject(_bstr_t(L"Win32_Process"),
                            0,
                            NULL,
                            &pProcess,
                            NULL);
 if(FAILED(hRes))
 {
       cout << "failed to get GetObject" << endl;
  return E_FAIL; // Program has failed
 }
0
 
waysideCommented:
What is the value of hRes after the call? This contains the error code for the call.

The GetObject call can return one of the following errors (according to MSDN):

WBEM_E_ACCESS_DENIED The current user does not have permission to access the object.
WBEM_E_FAILED This indicates other unspecified errors.
WBEM_E_INVALID_CLASS The specified class does not exist.
WBEM_E_INVALID_PARAMETER An invalid parameter was specified.
WBEM_E_INVALID_OBJECT_PATH The specified path was invalid.
WBEM_E_NOT_FOUND The requested object could not be found.
WBEM_E_OUT_OF_MEMORY There was not enough memory to complete the operation.
WBEM_E_SHUTTING_DOWN Windows Management service was probably stopped and restarted. A new call to ConnectServer is needed.
WBEM_E_TRANSPORT_FAILURE This indicates the failure of the remote procedure call (RPC) link between the current process and Windows Management.
WBEM_S_NO_ERROR The call succeeded.

Or you can get some other COM error.

These error codes are defined in WbemCli.h in the Include directory of the platform SDK. Here are the ones listed above:

      WBEM_E_ACCESS_DENIED      = 0x80041003,
      WBEM_E_FAILED      = 0x80041001,
      WBEM_E_INVALID_CLASS      = 0x80041010,
      WBEM_E_INVALID_PARAMETER      = 0x80041008,
      WBEM_E_INVALID_OBJECT_PATH      = 0x8004103a,
      WBEM_E_NOT_FOUND      = 0x80041002,
      WBEM_E_OUT_OF_MEMORY      = 0x80041006,
      WBEM_E_SHUTTING_DOWN      = 0x80041033,
      WBEM_E_TRANSPORT_FAILURE      = 0x80041015,
      WBEM_S_NO_ERROR      = 0,



0
 
Dcom4CITAuthor Commented:
It's returning the following error code   0x80041003 (access denied)
but i'm logging in as an administrator.. what do you think might be the problem

thanks.

0
 
waysideCommented:
Are the user name and password for the local machine this code is running on, or for the remote machine where you are are trying to start a process?
0
 
Dcom4CITAuthor Commented:
the username and password is correct for the remote machine that i'm trying to start the process..
0
 
waysideCommented:
This kind of thing can be really tough to debug. There can be domain issues, account issues, impersonation issues, security privilege issues, registry issues, dcom issues...

Maybe this link will help you:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_troubleshooting.asp

Microsoft also has newsgroups devoted to WMI, where there are MVP's hanging out that really know this stuff. For example, here is something that may be relevant:

http://www.tech-archive.net/Archive/WinXP/microsoft.public.windowsxp.wmi/2004-12/0033.html

I'm not too versed with this level of system administration, I don't know what else to tell you.
0
 
Dcom4CITAuthor Commented:
cheers thanks for your help..
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now