利用WMI实现远程登录、文件拷贝、建立进程、启动服务

来源:互联网 发布:晒照片的软件 编辑:程序博客网 时间:2024/06/04 17:55

#ifndef __SW_FACE_CONNON_WMI__
#define __SW_FACE_CONNON_WMI__

#include "swftype.h"

namespace SWFWMI
{
 class WMICtr;
 class SWFWmi
 {
 public:
  
  SWFWmi();
  /*
  描述:
   初始化SWFWmi对象
  参数:
   无
  返回值:
   无
  */

  ~SWFWmi();
  /*
  描述:
   析构SWFWmi对象
  参数:
   无
  返回值:
   无
  */
  
  SWFRESULT RemoteLogin(const char *pDomain, const char *pName, const char *pPwd);
  /*
  描述:
   登录远程主机
  参数:
   pDomain:           主机IP地址
   pName:            账户名称
   pPwd:            账户密码
  返回值:
   SWF_S_OK       0x00000000  成功

   SWF_E_NOINIT      0x79120426  初始化COM库失败
   E_POINTER       0x80004003  无效指针
   E_INVALIDARG      0x80070057  参数错误
   WBEM_E_FAILED      0x80041001  Generic failure
   WBEM_E_ACCESS_DENIED    0x80041003  Access denied
   WBEM_E_OUT_OF_MEMORY    0x80041006  Out of memory
   WBEM_E_INVALID_PARAMETER   0x80041008  Invalid parameter
   WBEM_E_TRANSPORT_FAILURE   0x80041015  Transport failure
   WBEM_E_LOCAL_CREDENTIALS   0x80041064  User credentials cannot be used for local connections 
  */

  SWFRESULT CreateProcessRemote(const char *pPath);
  /*
  描述:
   在已登录远程主机上创建指定的进程
  参数:
   pPath:            创建进程的路径
  返回值:
   SWF_S_OK       0x00000000  成功

            0x00000002  Access Denied
            0x00000003  Insufficient Privilege
            0x00000008  Unknown failure
            0x00000009  Path Not Found
            0x00000015  Invalid Parameter
   SWF_E_NOINIT      0x79120426  初始化COM库失败
   SWF_E_NOTREADY      0x7912042f  没有登录到远程主机
   WBEM_E_FAILED      0x80041001  Generic failure
   WBEM_E_ACCESS_DENIED    0x80041003  Access denied
   WBEM_E_OUT_OF_MEMORY    0x80041006  Out of memory
   WBEM_E_INVALID_PARAMETER   0x80041008  Invalid parameter
   WBEM_E_TRANSPORT_FAILURE   0x80041015  Transport failure
   WBEM_E_INVALID_METHOD_PARAMETERS 0x8004102f   Invalid method Parameter(s)
   WBEM_E_SHUTTING_DOWN    0x80041033  Shutting down
   WBEM_E_INVALID_OBJECT_PATH   0x8004103a  Invalid object path
  */

  SWFRESULT StartServiceRemote(const char *pService);
  /*
  描述:
   在已登录远程主机上启动指定的服务
  参数:
   pService         启动服务的名称
  返回值:
   SWF_S_OK     0x00000000  成功
   SWF_S_FALSE     0xFFFFFFFF  没有查询到对应的服务

          0x00000001  Not Supported
          0x00000002  Access Denied
          0x00000003  Dependent Services Running
          0x00000004  Invalid Service Control
          0x00000005  Service Cannot Accept Control
          0x00000006  Service Not Active
          0x00000007  Service Request Timeout
          0x00000008  Unknown Failure
          0x00000009  Path Not Found
          0x0000000a  Service Already Running
          0x0000000b  Service Database Locked
          0x0000000c  Service Dependency Deleted
          0x0000000d  Service Dependency Failure
          0x0000000e  Service Disabled
          0x0000000f  Service Logon Failure
          0x00000010  Service Marked For Deletion
          0x00000011  Service No Thread
          0x00000012  Status Circular Dependency  
          0x00000013  Status Duplicate Name
          0x00000014  Status Invalid Name
          0x00000015  Status Invalid Parameter
          0x00000016  Status Invalid Service Account
          0x00000017  Status Service Exists
          0x00000018  Service Already Paused
   SWF_E_NOINIT    0x79120426  初始化COM库失败
   SWF_E_NOTREADY    0x7912042f  没有登录到远程主机
   E_INVALIDARG    0x80070057  参数错误
   WBEM_E_FAILED    0x80041001  Generic failure
   WBEM_E_ACCESS_DENIED  0x80041003  Access denied
   WBEM_E_OUT_OF_MEMORY  0x80041006  Out of memory
   WBEM_E_INVALID_PARAMETER 0x80041008  Invalid parameter  
   WBEM_E_TRANSPORT_FAILURE 0x80041015  Transport failure
   WBEM_E_SHUTTING_DOWN  0x80041033  Shutting down
  */

  SWFRESULT CopyAllFile(const char *pSrcPath, const char *pDstPath, const char *pDomain, const char *pName, const char *pPwd);
  /*
  描述:
   将本机上指定的目录拷贝到已登录远程主机上指定的目录
  参数:
   pSrcPath:           本机源目录完整路径
   pDstPath           远程主机目的目录完整路径
   pDomain:           主机IP地址
   pName:            账户名称
   pPwd:            账户密码
  返回值:
   SWF_S_OK       0x00000000  成功
   SWF_S_FAIL       0x79120427  失败 

   ERROR_ACCESS_DENIED     0x00000005  拒绝访问
   ERROR_BAD_NETPATH     0x00000035   找不到网络路径
   ERROR_BAD_DEV_TYPE     0x00000042  网络资源类型不对
   ERROR_BAD_NET_NAME     0x00000043  找不到网络名
   ERROR_ALREADY_ASSIGNED    0x00000055  本地设备名已在使用中
   ERROR_INVALID_PASSWORD    0x00000056  指定的网络密码不正确
   ERROR_INVALID_PARAMETER    0x00000057  参数错误
   ERROR_BUSY       0x000000aa  请求的资源在使用中
   ERROR_INVALID_ADDRESS    0x000001e7  试图访问无效的地址
   ERROR_BAD_DEVICE     0x000004b0  指定的设备名无效
   ERROR_DEVICE_ALREADY_REMEMBERED  0x000004b2  本地设备名称已有到另一网络资源的记录连接
   ERROR_NO_NET_OR_BAD_PATH   0x000004b3  网络路径键入不正确、不存在或者网络提供程序当前不可用。请尝试重新键入路径或者与网络管理员联系
   ERROR_BAD_PROVIDER     0x000004b4  指定的网络提供程序名称无效
   ERROR_CANNOT_OPEN_PROFILE   0x000004b5  无法打开网络连接配置文件
   ERROR_BAD_PROFILE     0x000004b6  网络连接配置文件损坏
   ERROR_EXTENDED_ERROR    0x000004b8  出现了扩展错误
   ERROR_NO_NETWORK     0x000004c6  网络不存在或尚未启动
   ERROR_CANCELLED      0x000004c7  操作已被用户取消
   ERROR_LOGON_FAILURE     0x0000052e  登录失败: 未知的用户名或错误密码
   ERROR_BAD_USERNAME     0x0000089a  指定的用户名无效
   ...
  */

  unsigned int GetErrorMsg(char *str, unsigned int length);
  /*
  描述:
   获取操作结果描述信息
  参数:
   str    指向接收错误描述的缓冲区
   length   空间的最大长度
  返回值:  
   参数length为0时,返回需要的空间
   参数length不为0时,返回实际拷贝的错误信息的长度
  */

 protected:
  WMICtr *pWmiCtr;
 };
}
#endif

 

//#include "stdafx.h"
#include "swfwmi.h"

#define _WIN32_DCOM//使用函数 CoInitializeEx的代码的前面需要包含于处理标志
#include <comdef.h>//使用COM库需要包含此头文件

#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")//有关wmi的api

#include <comutil.h>//_bstr_t类

#pragma comment(lib, "mpr.lib")//网络api

#include <stdio.h>
#include <fstream>
#include <locale>

#include<io.h>   //定义了结构体struct _finddata64i32_t(该结构体包含文件的相关属性,如文件名,文件的属性等

namespace SWFWMI
{
 class WMICtr
 {
 public:
  WMICtr();
  ~WMICtr();
  SWFRESULT RemoteLogin(const char *pDomain, const char *pName, const char *pPwd);
  SWFRESULT CreateProcessRemote(const char *pPath);
  SWFRESULT StartServiceRemote(const char *pService);
  SWFRESULT CopyAllFile(const char *pSrcPath, const char *pDstPath, const char *pDomain, const char *pName, const char *pPwd);
  unsigned int GetErrorMsg(char *str, unsigned int length);
 private:
  SWFRESULT SelectInfo(const wchar_t *wql, IEnumWbemClassObject *&pEnumerator);//根据wql查询计算机相关信息 
  SWFRESULT NetAddConnect();//建立共享连接
  SWFRESULT NetCancelConnect();//取消共享连接
  SWFRESULT CreatePath(const char *pPath);//创建目录
  SWFRESULT CopyDictroy(const char *pSrcPath, const char *pDstPath);//目录拷贝
  void GetMsgBuffer(HRESULT &hres);//保存错误藐视信息

  BSTR bMsgBuffer;//错误描述信息
  bool bComFlag;//COM库初始标志
  IWbemLocator *pLoc;//访问wmi时的IWbemLocator对象
  IWbemServices *pSvc;//访问wmi时的IWbemServices对象

  static const int maxsizedef=50;
  wchar_t pszRemotename[maxsizedef];//远程主机名(ipc$命令管道)
  wchar_t pszUsername[maxsizedef];//账户
  wchar_t pszPassword[maxsizedef];//密码

  wchar_t pszDomain[maxsizedef];//远程主机域(ip地址)
  wchar_t pszName[maxsizedef];//账户
  wchar_t pszPwd[maxsizedef];//密码
  COAUTHIDENTITY authIdent;//用户凭证
 };

 WMICtr::WMICtr() : bComFlag(true), bMsgBuffer(NULL), pLoc(NULL), pSvc(NULL)
 { 
  HRESULT hres;
  // Step 1: --------------------------------------------------
  // Initialize COM. ------------------------------------------
  // S_OK      初始化成功
  // S_FALSE     已经初始化
  // RPC_E_CHANGED_MODE  无法在设置线程模式后对其加以更改
  hres = CoInitializeEx(0, COINIT_MULTITHREADED);
  if (  FAILED(hres) )//只需要设置一次即可,多次调用返回S_FALSE,模式不同返回RPC_E_CHANGED_MODE
  {
   //GetMsgBuffer(hres);
   bComFlag = false;    // Program has failed.
   return;
  }

  // Step 2: --------------------------------------------------
  // Set general COM security levels --------------------------
  // S_OK        初始化成功
  // RPC_E_TOO_LATE     在整理或打乱任何接口之前,必须初始化安全机制。一旦初始化,不能再作更改
  // RPC_E_NO_GOOD_SECURITY_PACKAGES 消息筛选器显示应用程序正在使用中。
  // E_OUTOFMEMORY     存储空间不足,无法完成此操作。
  hres = CoInitializeSecurity(
   NULL,
   -1,                          // COM authentication
   NULL,                        // Authentication services
   NULL,                        // Reserved
   RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
   RPC_C_IMP_LEVEL_IDENTIFY,    // Default Impersonation 
   NULL,                        // Authentication info
   EOAC_NONE,                   // Additional capabilities
   NULL                         // Reserved
   );
  if ( hres != RPC_E_TOO_LATE && FAILED(hres) )//只需要设置一次即可,多次调用返回RPC_E_TOO_LATE
  {
   //GetMsgBuffer(hres);
   CoUninitialize();
   bComFlag = false;    // Program has failed.
   return;
  }
 }

 WMICtr::~WMICtr()
 {
  if(pSvc)
  {
   pSvc->Release();
   pSvc = NULL;
  }
  if(pLoc)
  {
   pLoc->Release();
   pLoc = NULL;
  }
  if(bComFlag)
  {
   CoUninitialize();
  }
  if(bMsgBuffer)
  {
   LocalFree(bMsgBuffer);
   bMsgBuffer = NULL;
  }
 }

 /*
 描述:
  登录远程主机
 参数:
  pDomain:           主机IP地址
  pName:            账户名称
  pPwd:            账户密码
 返回值:
  SWF_S_OK       0x00000000  成功

  SWF_E_NOINIT      0x79120426  初始化COM库失败
  E_POINTER       0x80004003  无效指针
  E_INVALIDARG      0x80070057  参数错误
  WBEM_E_FAILED      0x80041001  Generic failure
  WBEM_E_ACCESS_DENIED    0x80041003  Access denied
  WBEM_E_OUT_OF_MEMORY    0x80041006  Out of memory
  WBEM_E_INVALID_PARAMETER   0x80041008  Invalid parameter
  WBEM_E_TRANSPORT_FAILURE   0x80041015  Transport failure
  WBEM_E_LOCAL_CREDENTIALS   0x80041064  User credentials cannot be used for local connections 
 */
 SWFRESULT WMICtr::RemoteLogin(const char *pDomain, const char *pName, const char *pPwd)
 {
  HRESULT hres;

  if(!bComFlag)
  {
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer = SysAllocString(L"COM库初始化失败!");
   }
   return SWF_E_NOINIT;
  }

  if(pSvc)
  {
   pSvc->Release();
   pSvc = NULL;
  }
  if(pLoc)
  {
   pLoc->Release();
   pLoc = NULL;
  }

  // Step 3: ---------------------------------------------------
  // Obtain the initial locator to WMI -------------------------
  hres = CoCreateInstance(
   CLSID_WbemLocator,            
   0,
   CLSCTX_INPROC_SERVER,
   IID_IWbemLocator,
   (LPVOID *)&pLoc);
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);

   return (SWFRESULT)hres;                 // Program has failed.
  }

  // Step 4: -----------------------------------------------------
  // Connect to WMI through the IWbemLocator::ConnectServer method
  // Connect to the remote root\cimv2 namespace
  // and obtain pointer pSvc to make IWbemServices calls.
  //---------------------------------------------------------
  memset(pszDomain, 0, sizeof(pszDomain));
  memset(pszName, 0, sizeof(pszName));
  memset(pszPwd, 0, sizeof(pszPwd));
  

  setlocale(LC_CTYPE, "");
  swprintf_s(pszDomain, maxsizedef, L"\\\\%S\\root\\cimv2", pDomain);
  swprintf_s(pszName, maxsizedef, L"%S", pName);
  swprintf_s(pszPwd, maxsizedef, L"%S", pPwd);
  setlocale(LC_CTYPE, "C");

  hres = pLoc->ConnectServer(
   _bstr_t(pszDomain),        // Domain
   _bstr_t(wcslen(pszName) == 0 ? NULL : pszName),  // User name
   _bstr_t(wcslen(pszPwd) == 0 ? NULL : pszPwd),   // User password
   NULL,           // Locale            
   NULL,           // Security flags
   NULL,           // Authority       
   NULL,           // Context object
   &pSvc           // IWbemServices proxy
   );
  if (FAILED(hres))
  { 
   GetMsgBuffer(hres);

   pLoc->Release();
   pLoc = NULL;
   return (SWFRESULT)hres;                // Program has failed.
  }

  // step 5: --------------------------------------------------
  // Create COAUTHIDENTITY that can be used for setting security on proxy
  //COAUTHIDENTITY init
  memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
  authIdent.Domain = (USHORT*)pszDomain;
  authIdent.DomainLength = (ULONG)wcslen(pszDomain);
  authIdent.User = (USHORT*)pszName;
  authIdent.UserLength = (ULONG)wcslen(pszName);
  authIdent.Password = (USHORT*)pszPwd;
  authIdent.PasswordLength = (ULONG)wcslen(pszPwd);
  authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

  // Step 6: --------------------------------------------------
  // Set security levels on a WMI connection ------------------
  hres = CoSetProxyBlanket(
   pSvc,          // Indicates the proxy to set
   RPC_C_AUTHN_DEFAULT,      // RPC_C_AUTHN_xxx
   RPC_C_AUTHZ_DEFAULT,      // RPC_C_AUTHZ_xxx
   COLE_DEFAULT_PRINCIPAL,      // Server principal name
   RPC_C_AUTHN_LEVEL_PKT_PRIVACY,    // RPC_C_AUTHN_LEVEL_xxx
   RPC_C_IMP_LEVEL_IMPERSONATE,    // RPC_C_IMP_LEVEL_xxx
   wcslen(pszName) == 0 ? NULL : &authIdent, // client identity
   EOAC_NONE          // proxy capabilities
   );
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);

   pSvc->Release();
   pSvc = NULL;
   pLoc->Release();
   pLoc = NULL;
   return (SWFRESULT)hres;
  }

  return (SWFRESULT)hres; 
 }

 /*
 描述:
  在已登录远程主机上创建指定的进程
 参数:
  pPath:            创建进程的路径
 返回值:
  SWF_S_OK       0x00000000  成功

           0x00000002  Access Denied
           0x00000003  Insufficient Privilege
           0x00000008  Unknown failure
           0x00000009  Path Not Found
           0x00000015  Invalid Parameter
  SWF_E_NOINIT      0x79120426  初始化COM库失败
  SWF_E_NOTREADY      0x7912042f  没有登录到远程主机
  WBEM_E_FAILED      0x80041001  Generic failure
  WBEM_E_ACCESS_DENIED    0x80041003  Access denied
  WBEM_E_OUT_OF_MEMORY    0x80041006  Out of memory
  WBEM_E_INVALID_PARAMETER   0x80041008  Invalid parameter
  WBEM_E_TRANSPORT_FAILURE   0x80041015  Transport failure
  WBEM_E_INVALID_METHOD_PARAMETERS 0x8004102f   Invalid method Parameter(s)
  WBEM_E_SHUTTING_DOWN    0x80041033  Shutting down
  WBEM_E_INVALID_OBJECT_PATH   0x8004103a  Invalid object path
 */ 
 SWFRESULT WMICtr::CreateProcessRemote(const char *pPath)
 {
  HRESULT hres;

  if(!bComFlag)
  {
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer= NULL ;
    bMsgBuffer = SysAllocString(L"COM库初始化失败!");
   }
   return SWF_E_NOINIT;
  }

  if(pLoc == NULL || pSvc == NULL)
  {  
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer = NULL;
   }
   bMsgBuffer = SysAllocString(L"没有登录到远程主机!");
   return SWF_E_NOTREADY;                 
  }

  //配置Win32_Process
  _bstr_t MethodName(L"Create");
  _bstr_t ClassName(L"Win32_Process");
  IWbemClassObject *pClass = NULL;
  IWbemClassObject *pInParamsDefinition = NULL;
  IWbemClassObject *pClassInstance = NULL;
  IWbemClassObject *pOutParams = NULL;

  hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);
   return (SWFRESULT)hres;
  }

  hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL);
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);

   if( pClass ) pClass->Release();
   return (SWFRESULT)hres;
  }
  pInParamsDefinition->SpawnInstance(0, &pClassInstance);

  //配置Win32_Process参数
  VARIANT varCommand;
  VariantInit(&varCommand);
  _bstr_t bCommand(pPath);
  varCommand.vt = VT_BSTR;
  varCommand.bstrVal = bCommand;
  pClassInstance->Put(L"CommandLine", 0, &varCommand, 0);

  //执行
  hres = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);

   if( pClass ) pClass->Release();
   if( pInParamsDefinition ) pInParamsDefinition->Release();
   if( pClassInstance ) pClassInstance->Release(); 
   return (SWFRESULT)hres;
  }

  VARIANT vtProp;
  VariantInit(&vtProp);  
  hres=pOutParams->Get(L"ReturnValue", 0, &vtProp, 0, 0);
  if (FAILED(hres)) GetMsgBuffer(hres);
  else
  {
   hres = vtProp.iVal;
   VariantClear(&vtProp);

   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer = NULL;
   }
   switch(hres)
   {
   case 0: //Success
    bMsgBuffer = SysAllocString(L"Success!");
    break;
   case 2: //Access denied
    bMsgBuffer = SysAllocString(L"Access denied !");
    break;
   case 3: //Insufficient Privilege
    bMsgBuffer = SysAllocString(L"Insufficient Privilege!");
    break;
   case 8: //Unknown failure
    bMsgBuffer = SysAllocString(L"Unknown failure !");
    break;
   case 9: //Path Not Found
    bMsgBuffer = SysAllocString(L"Path Not Found!");
    break;
   case 21: //Invalid parameter
   default:
    bMsgBuffer = SysAllocString(L"Invalid parameter !");
    break;
   }
  }

  if( pClass ) pClass->Release();
  if( pInParamsDefinition ) pInParamsDefinition->Release();
  if( pClassInstance ) pClassInstance->Release();
  if( pOutParams ) pOutParams->Release();
  return (SWFRESULT)hres;
 }

 /*
 描述:
  在已登录远程主机上启动指定的服务
 参数:
  pService         启动服务的名称
 返回值:
  SWF_S_OK     0x00000000  成功
  SWF_S_FALSE     0xFFFFFFFF  没有查询到对应的服务

         0x00000001  Not Supported
         0x00000002  Access Denied
         0x00000003  Dependent Services Running
         0x00000004  Invalid Service Control
         0x00000005  Service Cannot Accept Control
         0x00000006  Service Not Active
         0x00000007  Service Request Timeout
         0x00000008  Unknown Failure
         0x00000009  Path Not Found
         0x0000000a  Service Already Running
         0x0000000b  Service Database Locked
         0x0000000c  Service Dependency Deleted
         0x0000000d  Service Dependency Failure
         0x0000000e  Service Disabled
         0x0000000f  Service Logon Failure
         0x00000010  Service Marked For Deletion
         0x00000011  Service No Thread
         0x00000012  Status Circular Dependency  
         0x00000013  Status Duplicate Name
         0x00000014  Status Invalid Name
         0x00000015  Status Invalid Parameter
         0x00000016  Status Invalid Service Account
         0x00000017  Status Service Exists
         0x00000018  Service Already Paused
  SWF_E_NOINIT    0x79120426  初始化COM库失败
  SWF_E_NOTREADY    0x7912042f  没有登录到远程主机
  E_INVALIDARG    0x80070057  参数错误
  WBEM_E_FAILED    0x80041001  Generic failure
  WBEM_E_ACCESS_DENIED  0x80041003  Access denied
  WBEM_E_OUT_OF_MEMORY  0x80041006  Out of memory
  WBEM_E_INVALID_PARAMETER 0x80041008  Invalid parameter  
  WBEM_E_TRANSPORT_FAILURE 0x80041015  Transport failure
  WBEM_E_SHUTTING_DOWN  0x80041033  Shutting down
 */
 SWFRESULT WMICtr::StartServiceRemote(const char *pService)
 {
  HRESULT hres;
   
  if(!bComFlag)
  {
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer= NULL ;
    bMsgBuffer = SysAllocString(L"COM库初始化失败!");
   }
   return SWF_E_NOINIT;
  }

  if(pLoc == NULL || pSvc == NULL)
  {  
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer = NULL;
   }
   bMsgBuffer = SysAllocString(L"没有登录到远程主机!");
   return SWF_E_NOTREADY;                 
  }

  IEnumWbemClassObject *pEnumerator = NULL;
  wchar_t pWql[256];
  swprintf(pWql, 256, L"SELECT * FROM Win32_Service where Name='%S'", pService);

  hres = SelectInfo(pWql,pEnumerator);
  if( FAILED(hres) ) return (SWFRESULT)hres;     
  if (pEnumerator)
  { 
   IWbemClassObject *pclsObj = NULL;
   unsigned long uReturn;
   pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
   if(0 == uReturn)
   {
    if(bMsgBuffer)
    {
     SysFreeString(bMsgBuffer);
     bMsgBuffer = NULL;
    }
    bMsgBuffer = SysAllocString(L"没有查询到服务!");
    hres = SWF_S_FALSE;
   }
   else
   {
    // Get the context for non-static method
    CIMTYPE pType;
    LONG pFlavor;
    VARIANT varPath;
    pclsObj->Get(L"__PATH", 0, &varPath, &pType, &pFlavor);
    if(pclsObj) pclsObj->Release();

    // Execute Method
    IWbemClassObject *pOut = NULL;
    hres = pSvc->ExecMethod(varPath.bstrVal, L"StartService", 0, NULL, NULL, &pOut, NULL);
    VariantClear(&varPath);
    if (FAILED(hres)) GetMsgBuffer(hres);
    else
    {
     VARIANT vtRet;  
     hres = pOut->Get(L"ReturnValue", 0, &vtRet, 0, 0);
     if( pOut ) pOut->Release();
     if (FAILED(hres)) GetMsgBuffer(hres);
     else
     {
      hres = vtRet.iVal;
      VariantClear(&vtRet);
      
      if(bMsgBuffer)
      {
       SysFreeString(bMsgBuffer);
       bMsgBuffer = NULL;
      }
      switch(hres)
      {
      case 0:
       bMsgBuffer = SysAllocString(L"Success!");
       break;
      case 1:
       bMsgBuffer = SysAllocString(L"Not Supported!");
       break;
      case 2:
       bMsgBuffer = SysAllocString(L"Access Denied!");
       break; 
      case 3:
       bMsgBuffer = SysAllocString(L"Dependent Services Running!");
       break;
      case 4:
       bMsgBuffer = SysAllocString(L"Invalid Service Control!");
       break;
      case 5:
       bMsgBuffer = SysAllocString(L"Service Cannot Accept Control!");
       break;
      case 6:
       bMsgBuffer = SysAllocString(L"Service Not Active!");
       break;
      case 7:
       bMsgBuffer = SysAllocString(L"Service Request Timeout!");
       break;
      case 8:
       bMsgBuffer = SysAllocString(L"Unknown Failure!");
       break;
      case 9:
       bMsgBuffer = SysAllocString(L"Path Not Found!");
       break;
      case 10:
       bMsgBuffer = SysAllocString(L"Service Already Running!");
       break;
      case 11:
       bMsgBuffer = SysAllocString(L"Service Database Locked!");
       break;
      case 12:
       bMsgBuffer = SysAllocString(L"Service Dependency Deleted!");
       break;
      case 13:
       bMsgBuffer = SysAllocString(L"Service Dependency Failure!");
       break;
      case 14:
       bMsgBuffer = SysAllocString(L"Service Disabled!");
       break;
      case 15:
       bMsgBuffer = SysAllocString(L"Service Logon Failure!");
       break;
      case 16:
       bMsgBuffer = SysAllocString(L"Service Marked For Deletion!");
       break;
      case 17:
       bMsgBuffer = SysAllocString(L"Service No Thread!");
       break;
      case 18:
       bMsgBuffer = SysAllocString(L"Status Circular Dependency!");
       break;
      case 19:
       bMsgBuffer = SysAllocString(L"Status Duplicate Name!");
       break;
      case 20:
       bMsgBuffer = SysAllocString(L"Status Invalid Name!");
       break;
      case 21:
       bMsgBuffer = SysAllocString(L"Status Invalid Parameter!");
       break;
      case 22:
       bMsgBuffer = SysAllocString(L"Status Invalid Service Account!");
       break;
      case 23:
       bMsgBuffer = SysAllocString(L"Status Service Exists!");
       break;
      case 24:
      default:
       bMsgBuffer = SysAllocString(L"Service Already Paused!");
       break;
      }
     }
    }
   }
   if(pEnumerator) pEnumerator->Release();
  }
  else
  {
   if(bMsgBuffer)
   {
    SysFreeString(bMsgBuffer);
    bMsgBuffer = NULL;
   }
   bMsgBuffer = SysAllocString(L"没有查询到服务!");
   hres = SWF_S_FALSE;
  }

  return (SWFRESULT)hres;
 }

 /*
 描述:
  查询已登录远程主机上的计算机信息
 参数:
  wql:          wql语句
  pEnumerator         返回结果集
 返回值:
  SWF_S_OK     0x00000000  成功

  E_INVALIDARG    0x80070057  参数错误
  WBEM_E_FAILED    0x80041001  Generic failure
  WBEM_E_ACCESS_DENIED  0x80041003  Access denied
  WBEM_E_OUT_OF_MEMORY  0x80041006  Out of memory
  WBEM_E_INVALID_PARAMETER 0x80041008  Invalid parameter  
  WBEM_E_TRANSPORT_FAILURE 0x80041015  Transport failure
  WBEM_E_SHUTTING_DOWN  0x80041033  Shutting down
 */
 SWFRESULT  WMICtr::SelectInfo(const wchar_t*wql, IEnumWbemClassObject *&pEnumerator)
 {
  HRESULT hres;
  // Step 7: --------------------------------------------------
  // Use the IWbemServices pointer to make requests of WMI ----;
  hres = pSvc->ExecQuery(
   bstr_t("WQL"),
   bstr_t(wql),
   WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
   NULL,
   &pEnumerator);
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);
   return (SWFRESULT)hres;   // Program has failed.
  }

  // Step 8: -------------------------------------------------
  // Secure the enumerator proxy
  hres = CoSetProxyBlanket(
   pEnumerator,        // Indicates the proxy to set
   RPC_C_AUTHN_DEFAULT,      // RPC_C_AUTHN_xxx
   RPC_C_AUTHZ_DEFAULT,      // RPC_C_AUTHZ_xxx
   COLE_DEFAULT_PRINCIPAL,      // Server principal name
   RPC_C_AUTHN_LEVEL_PKT_PRIVACY,    // RPC_C_AUTHN_LEVEL_xxx
   RPC_C_IMP_LEVEL_IMPERSONATE,    // RPC_C_IMP_LEVEL_xxx
   wcslen(pszName) == 0 ? NULL : &authIdent,   // client identity
   EOAC_NONE         // proxy capabilities
   );
  if (FAILED(hres))
  {
   GetMsgBuffer(hres);
   return (SWFRESULT)hres;   // Program has failed.
  }

  return (SWFRESULT)hres;
 }

 /*
 描述:
  将本机上指定的目录拷贝到已登录远程主机上指定的目录
 参数:
  pSrcPath:           本机源目录完整路径
  pDstPath           远程主机目的目录完整路径
  pDomain:           主机IP地址
  pName:            账户名称
  pPwd:            账户密码
 返回值:
  SWF_S_OK       0x00000000  成功
  SWF_S_FAIL       0x79120427  失败 

  ERROR_ACCESS_DENIED     0x00000005  拒绝访问
  ERROR_BAD_NETPATH     0x00000035   找不到网络路径
  ERROR_BAD_DEV_TYPE     0x00000042  网络资源类型不对
  ERROR_BAD_NET_NAME     0x00000043  找不到网络名
  ERROR_ALREADY_ASSIGNED    0x00000055  本地设备名已在使用中
  ERROR_INVALID_PASSWORD    0x00000056  指定的网络密码不正确
  ERROR_INVALID_PARAMETER    0x00000057  参数错误
  ERROR_BUSY       0x000000aa  请求的资源在使用中
  ERROR_INVALID_ADDRESS    0x000001e7  试图访问无效的地址
  ERROR_BAD_DEVICE     0x000004b0  指定的设备名无效
  ERROR_DEVICE_ALREADY_REMEMBERED  0x000004b2  本地设备名称已有到另一网络资源的记录连接
  ERROR_NO_NET_OR_BAD_PATH   0x000004b3  网络路径键入不正确、不存在或者网络提供程序当前不可用。请尝试重新键入路径或者与网络管理员联系
  ERROR_BAD_PROVIDER     0x000004b4  指定的网络提供程序名称无效
  ERROR_CANNOT_OPEN_PROFILE   0x000004b5  无法打开网络连接配置文件
  ERROR_BAD_PROFILE     0x000004b6  网络连接配置文件损坏
  ERROR_EXTENDED_ERROR    0x000004b8  出现了扩展错误
  ERROR_NO_NETWORK     0x000004c6  网络不存在或尚未启动
  ERROR_CANCELLED      0x000004c7  操作已被用户取消
  ERROR_LOGON_FAILURE     0x0000052e  登录失败: 未知的用户名或错误密码
  ERROR_BAD_USERNAME     0x0000089a  指定的用户名无效
  ...
 */
 SWFRESULT WMICtr::CopyAllFile(const char *pSrcPath, const char *pDstPath, const char *pDomain, const char *pName, const char *pPwd)
 {
  HRESULT hres;
  char pDst[MAXLOGICALLOGNAMESIZE];

  sprintf_s(pDst, MAXLOGICALLOGNAMESIZE, "\\\\%s\\%s", pDomain, pDstPath);
  size_t length=strlen(pDst);
  for(size_t ii = 0; ii < length; ++ii)
  {
   if(pDst[ii] == ':')
   {
    pDst[ii] = '$';
   }
  }

  memset(pszRemotename, 0, sizeof(pszRemotename));
  memset(pszUsername, 0, sizeof(pszUsername));
  memset(pszPassword, 0, sizeof(pszPassword));

  setlocale(LC_CTYPE, "");
  swprintf_s(pszRemotename, maxsizedef, L"\\\\%S\\ipc$", pDomain);
  swprintf_s(pszUsername, maxsizedef, L"%S", pName);
  swprintf_s(pszPassword, maxsizedef, L"%S", pPwd);
  setlocale(LC_CTYPE, "C");

  hres=NetAddConnect();//建立共享连接
  if(hres!=SWF_S_OK)  return (SWFRESULT)hres;

  hres=CopyDictroy(pSrcPath,pDst);//拷贝目录
  NetCancelConnect();//断开网络共享连接

  return (SWFRESULT)hres;
 }

 /*
 描述:
  建立共享连接
 参数:
  无
 返回值:
  SWF_S_OK       0x00000000   成功
 
  ERROR_ACCESS_DENIED     0x00000005  拒绝访问
  ERROR_BAD_NETPATH     0x00000035   找不到网络路径
  ERROR_BAD_DEV_TYPE     0x00000042  网络资源类型不对
  ERROR_BAD_NET_NAME     0x00000043  找不到网络名
  ERROR_ALREADY_ASSIGNED    0x00000055  本地设备名已在使用中
  ERROR_INVALID_PASSWORD    0x00000056  指定的网络密码不正确
  ERROR_INVALID_PARAMETER    0x00000057  参数错误
  ERROR_BUSY       0x000000aa  请求的资源在使用中
  ERROR_INVALID_ADDRESS    0x000001e7  试图访问无效的地址
  ERROR_BAD_DEVICE     0x000004b0  指定的设备名无效
  ERROR_DEVICE_ALREADY_REMEMBERED  0x000004b2  本地设备名称已有到另一网络资源的记录连接
  ERROR_NO_NET_OR_BAD_PATH   0x000004b3  网络路径键入不正确、不存在或者网络提供程序当前不可用。请尝试重新键入路径或者与网络管理员联系
  ERROR_BAD_PROVIDER     0x000004b4  指定的网络提供程序名称无效
  ERROR_CANNOT_OPEN_PROFILE   0x000004b5  无法打开网络连接配置文件
  ERROR_BAD_PROFILE     0x000004b6  网络连接配置文件损坏
  ERROR_EXTENDED_ERROR    0x000004b8  出现了扩展错误
  ERROR_NO_NETWORK     0x000004c6  网络不存在或尚未启动
  ERROR_CANCELLED      0x000004c7  操作已被用户取消
  ERROR_LOGON_FAILURE     0x0000052e  登录失败: 未知的用户名或错误密码
  ERROR_BAD_USERNAME     0x0000089a  指定的用户名无效
  ...
 */
 SWFRESULT WMICtr::NetAddConnect()
 {
  HRESULT hres;
  NETRESOURCE nr;

  nr.dwType = RESOURCETYPE_DISK;
  nr.lpLocalName = NULL;
  nr.lpRemoteName = pszRemotename;
  nr.lpProvider = NULL;

  hres = WNetAddConnection2(&nr, pszPassword, pszUsername, CONNECT_UPDATE_PROFILE);//创建共享连接
  GetMsgBuffer(hres);

  return (SWFRESULT)hres;
 }

 /*
 描述:
  取消共享连接
 参数:
  无
 返回值:
  SWF_S_OK  0x00000000  成功
 */
 SWFRESULT WMICtr::NetCancelConnect()
 {
  WNetCancelConnection2(pszRemotename, CONNECT_UPDATE_PROFILE, true);
  return SWF_S_OK;
 }

   /*
 描述:
  创建文件夹
 参数:
  pPath       创建的文件夹路径
 返回值:
  SWF_S_OK  0x00000000  成功
  SWF_S_FAIL  0x79120427  失败    
 */
 SWFRESULT WMICtr::CreatePath(const char *pPath)
 {
  HRESULT hres;

  WIN32_FIND_DATA  wfd;//检查某个文件夹是否存在
  HANDLE hFind;
  wchar_t pszPath[MAXLOGICALLOGNAMESIZE];

  setlocale(LC_CTYPE, "");
  swprintf_s(pszPath, MAXLOGICALLOGNAMESIZE ,L"%S", pPath);
  setlocale(LC_CTYPE, "C");

  hFind=FindFirstFile(pszPath, &wfd);
  if (hFind != INVALID_HANDLE_VALUE) hres = 0;
  else  hres = 1;
  FindClose(hFind);
  if(hres == 1)//不存在创建
  {
   long pathLen,endIndex;
   char UpPath[MAXLOGICALLOGNAMESIZE];

   pathLen = (long)strlen(pPath);
   endIndex = pathLen;
   for(int ii = 0; ii < pathLen; ++ii)
   {
    UpPath[ii] = pPath[ii];
   }

   while(endIndex >= 0)
   {
    if(UpPath[endIndex] == '\\')
    {
     UpPath[endIndex] = 0;
     break;
    }
    else
     --endIndex;
   }
   if(endIndex >= 0)
   {
    if(CreatePath(UpPath) == SWF_S_OK)
    {
     hres = CreateDirectory(pszPath, NULL);
     if(hres == 0)
     {
      if(bMsgBuffer)
      {
       SysFreeString(bMsgBuffer);
       bMsgBuffer=NULL;
      }
      wchar_t log[256];
      swprintf_s(log, 256, L"%s目录创建失败!", pszPath);
      bMsgBuffer = SysAllocString(log);
      return SWF_E_FAIL;
     }
     else
     {
      if(bMsgBuffer)
      {
       SysFreeString(bMsgBuffer);
       bMsgBuffer = NULL;
      }
      wchar_t log[256];
      swprintf_s(log, 256, L"%s目录创建成功!", pszPath);
      bMsgBuffer = SysAllocString(log);
      return SWF_S_OK;
     }
    }
    else//上级目录创建失败
    {
     return SWF_E_FAIL;
    }
   }
   else//目录不正确
   {
    if(bMsgBuffer)
    {
     SysFreeString(bMsgBuffer);
     bMsgBuffer = NULL;
    }
    wchar_t log[256];
    swprintf_s(log, 256, L"%s目录不正确,创建失败!", pszPath);
    bMsgBuffer = SysAllocString(log);
    return SWF_E_FAIL;
   }
  }
  
  if(bMsgBuffer)
  {
   SysFreeString(bMsgBuffer);
   bMsgBuffer = NULL;
  }
  wchar_t log[256];
  swprintf_s(log, 256, L"%s目录存在!", pszPath);
  bMsgBuffer = SysAllocString(log);
  return SWF_S_OK;
 }

 /*
 描述:
  拷贝目录
 参数:
  pSrcPath      源目录路径
  pDstPath      目的目录路径
 返回值:
  SWF_S_OK  0x00000000  成功
  SWF_S_FAIL  0x79120427  失败 
 */
 SWFRESULT WMICtr::CopyDictroy(const char *pSrcPath, const char *pDstPath)
 {
  HRESULT hres;
  struct _finddata_t fileInfo;//保存文件信息的结构体
  intptr_t handle;//句柄
  int done;//查找nextfile是否成功

  char srcDict[MAXLOGICALLOGNAMESIZE];
  sprintf_s(srcDict, MAXLOGICALLOGNAMESIZE, "%s\\*.*", pSrcPath);

  //在目的主机创建目标文件夹
  hres=CreatePath(pDstPath);
  if(hres != SWF_S_OK) return (SWFRESULT)hres;
  
  //查找第一个文件,返回句柄
  handle=_findfirst(srcDict, &fileInfo);
  if(handle != -1)
  {
   do
   {
    if((strcmp(fileInfo.name, ".") == 0) | (strcmp(fileInfo.name, "..") == 0)) continue;//如果是文件夹".",或者"..",则进行判断下一个文件
    else if((fileInfo.attrib & _A_SUBDIR) == _A_SUBDIR)//文件夹,递归调用
    {
     char srcDir[MAXLOGICALLOGNAMESIZE],dstDir[MAXLOGICALLOGNAMESIZE];
     sprintf_s(srcDir, MAXLOGICALLOGNAMESIZE, "%s\\%s", pSrcPath, fileInfo.name);
     sprintf_s(dstDir, MAXLOGICALLOGNAMESIZE, "%s\\%s", pDstPath, fileInfo.name);

     hres=CopyDictroy(srcDir, dstDir);//递归调用,拷贝文件
     if(hres != SWF_S_OK)
     {
      _findclose(handle);
      return (SWFRESULT)hres;
     }
    }
    else//文件拷贝
    {
     wchar_t srcFile[MAXLOGICALLOGNAMESIZE],dstFile[MAXLOGICALLOGNAMESIZE];
     setlocale(LC_CTYPE, "");
     swprintf_s(srcFile, MAXLOGICALLOGNAMESIZE, L"%S\\%S", pSrcPath, fileInfo.name);
     swprintf_s(dstFile, MAXLOGICALLOGNAMESIZE, L"%S\\%S", pDstPath, fileInfo.name);
     setlocale(LC_CTYPE, "C");

     hres=CopyFile(srcFile, dstFile, false);//true不覆盖 false覆盖
     if(hres == 0)
     {
      _findclose(handle);
      if(bMsgBuffer)
      {
       SysFreeString(bMsgBuffer);
       bMsgBuffer = NULL;
      }
      wchar_t log[256];
      swprintf_s(log, 256, L"%s文件拷贝失败!", srcFile);
      bMsgBuffer = SysAllocString(log);
      return SWF_E_FAIL;
     }
    }
   }while(!(done = _findnext(handle, &fileInfo)));
   _findclose(handle);
  }
  
  if(bMsgBuffer)
  {
   SysFreeString(bMsgBuffer);
   bMsgBuffer = NULL;
  }
  wchar_t log[256];
  swprintf_s(log, 256, L"%S目录拷贝成功!", pSrcPath);
  bMsgBuffer = SysAllocString(log);
  return SWF_S_OK;
 }

 /*
 描述:
  获取操作结果描述信息
 参数:
  str    指向接收错误描述的缓冲区
  length   空间的最大长度
 返回值:  
  参数length为0时,返回需要的空间
  参数length不为0时,返回实际拷贝的错误信息的长度
 */ 
 unsigned int WMICtr::GetErrorMsg(char *str, unsigned int length)
 {
  if(bMsgBuffer)
  {
   _bstr_t bstr = bMsgBuffer;
   char *temp = bstr;
   unsigned int len = (unsigned int)strlen(temp) + 1;
   
   if(length == 0) return len;
   else
   {
    if(!str) return 0;
    unsigned int itemp = length > len ? len : length;
    memcpy(str, temp, itemp);
    return itemp;
   }
  }
  else
  {
   if(length == 0) return 1;
   else
   {
    if(!str) return 0;
    str[0] = 0;
    return 0;
   }
  }
 }

 /*
 描述:
  保存错误描述信息
 参数:
  hres  错误码
 返回值:
  无
 */
 void  WMICtr::GetMsgBuffer(HRESULT &hres)
 {
  if(bMsgBuffer)
  {
   SysFreeString(bMsgBuffer);
   bMsgBuffer = NULL;
  }

  IWbemStatusCodeText *pStatus = NULL;
  SCODE sc = CoCreateInstance(
   CLSID_WbemStatusCodeText,
   0,
   CLSCTX_INPROC_SERVER,
   IID_IWbemStatusCodeText,
   (LPVOID *)&pStatus);
  if(sc == S_OK)
  {
   pStatus->GetErrorCodeText(hres, 0, 0, &bMsgBuffer);
   pStatus->Release();
   pStatus = NULL;
  }

  if(pStatus)
  {
   pStatus->Release();
   pStatus = NULL;
  }
 }

 SWFWmi::SWFWmi(){pWmiCtr=new WMICtr();};
 SWFWmi::~SWFWmi(){if(pWmiCtr){delete pWmiCtr;pWmiCtr = NULL;}};
 SWFRESULT SWFWmi::RemoteLogin(const char *pDomain, const char *pName, const char *pPwd) {return pWmiCtr->RemoteLogin(pDomain, pName, pPwd);}
 SWFRESULT SWFWmi::CreateProcessRemote(const char *pPath) {return pWmiCtr->CreateProcessRemote(pPath);}
 SWFRESULT SWFWmi::StartServiceRemote(const char *pService) {return pWmiCtr->StartServiceRemote(pService);}
 SWFRESULT SWFWmi::CopyAllFile(const char *pSrcPath, const char *pDstPath, const char *pDomain, const char *pName, const char *pPwd) {return pWmiCtr->CopyAllFile(pSrcPath, pDstPath, pDomain, pName, pPwd);}
 unsigned int SWFWmi::GetErrorMsg(char *str,unsigned int length) {return pWmiCtr->GetErrorMsg(str, length);}
}