头文件
// W3SvcAgent.h: interface for the CW3SvcAgent class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_W3SVCAGENT_H__D10CF1B7_10C9_45DC_95A7_3AAEA1CFE558__INCLUDED_) #define AFX_W3SVCAGENT_H__D10CF1B7_10C9_45DC_95A7_3AAEA1CFE558__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <Accctrl.h>
const ERRORCODE_CHECKSERVICEERROR = 1; const ERRORCODE_CANNTSTARTSERVICE = 2; const ERRORCODE_NOSERVICE = 3; const ERRORCODE_SUCCESS = 0; class CW3SvcAgent { public: CW3SvcAgent(); virtual ~CW3SvcAgent(); public: int CheckW3SvcExist(); bool DeleteWebServer(LPCTSTR lpszServerComment); bool CreateWebServer(LPCTSTR lpszServerComment, LPCTSTR lpszBindAddress,LPCTSTR lpszDomain,LPCTSTR lpszPathName);
bool DeleteVirtualDirectry(LPCTSTR lpszVirtualDirName); bool CreateVirtualDirectry(LPCTSTR lpszVirtualDirName,LPCTSTR lpszDiskPath); bool AddAclToDir(LPTSTR pszDir,LPTSTR pszUserName,DWORD dwAccessRights);
protected: DWORD AddAceToObjectsSecurityDescriptor ( LPTSTR pszObjName, // name of object SE_OBJECT_TYPE ObjectType, // type of object LPTSTR pszTrustee, // trustee for new ACE TRUSTEE_FORM TrusteeForm, // format of trustee structure DWORD dwAccessRights, // access mask for new ACE ACCESS_MODE AccessMode, // type of ACE DWORD dwInheritance // inheritance flags for new ACE ); //Sample //DWORD dwResult = AddAceToObjectsSecurityDescriptor( // szDirectory[i], // SE_FILE_OBJECT, // szUser, // TRUSTEE_IS_NAME, // dwPermission[i], // GRANT_ACCESS , // SUB_CONTAINERS_AND_OBJECTS_INHERIT); };
#endif // !defined(AFX_W3SVCAGENT_H__D10CF1B7_10C9_45DC_95A7_3AAEA1CFE558__INCLUDED_)
实现文件
// W3SvcAgent.cpp: implementation of the CW3SvcAgent class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "setup.h" #include "W3SvcAgent.h"
#include <comutil.h> #include <windows.h> #include <Winsvc.h> #include <Iads.h> #include <comdef.h> #include <tchar.h> //#include <stdio.h> #include <Adshlp.h> #include <Oleauto.h>
#include <aclapi.h> #pragma comment(lib,"comsupp.lib") #pragma comment(lib,"ActiveDS.lib") #pragma comment(lib,"adsiid.lib")
#pragma comment(lib, "WS2_32.lib")
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CW3SvcAgent::CW3SvcAgent() { CoInitialize(NULL); }
CW3SvcAgent::~CW3SvcAgent() { CoUninitialize(); }
int CW3SvcAgent::CheckW3SvcExist() { int iErrCode = ERRORCODE_SUCCESS; SC_HANDLE hHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); SC_HANDLE hService; if (hHandle ==NULL ) //创建句柄失败 { iErrCode = ERRORCODE_CHECKSERVICEERROR; return iErrCode; } ENUM_SERVICE_STATUS service; DWORD dwBytesNeeded = 0; DWORD dwServicesReturned = 0; DWORD dwResumedHandle = 0; DWORD dwServiceType = SERVICE_WIN32;//只读取WIN32的服务 | SERVICE_DRIVER; char* chServiceName; char* chFind; bool bResult; bool bHasService=false;
chFind="W3SVC"; chFind=_strupr(_strdup(chFind)); //_strdup The _strdup function calls malloc to allocate storage space //for a copy of strSource and then copies strSource to the allocated space. //所以要释放
// 查找服务列表 bResult = EnumServicesStatus(hHandle, dwServiceType, SERVICE_STATE_ALL, &service, sizeof(ENUM_SERVICE_STATUS), &dwBytesNeeded, &dwServicesReturned, &dwResumedHandle ); if (!bResult) { // 获取应需要的内存空间 if (GetLastError() == ERROR_MORE_DATA) { DWORD dwBytes = sizeof(ENUM_SERVICE_STATUS) + dwBytesNeeded; ENUM_SERVICE_STATUS* pServices = NULL; pServices = new ENUM_SERVICE_STATUS [dwBytes]; // 获取服务列表 EnumServicesStatus(hHandle, dwServiceType, SERVICE_STATE_ALL, pServices, dwBytes, &dwBytesNeeded, &dwServicesReturned, &dwResumedHandle ); // 提取每个列表 for (unsigned iIndex = 0; iIndex < dwServicesReturned; iIndex++) { //chServiceName=(pServices+iIndex)->lpDisplayName; chServiceName=_strupr(_strdup((pServices+iIndex)->lpServiceName)); if(strcmp(chFind,chServiceName)==0) { switch((pServices+iIndex)->ServiceStatus.dwCurrentState) { case SERVICE_STOPPED: hService= OpenService(hHandle,chServiceName,SERVICE_ALL_ACCESS); if(hService==0) { iErrCode=ERRORCODE_CANNTSTARTSERVICE; } else { bResult=StartService(hService,0,NULL); if(!bResult) { iErrCode=ERRORCODE_CANNTSTARTSERVICE; } CloseServiceHandle(hService); } break; case SERVICE_RUNNING: iErrCode=ERRORCODE_SUCCESS; break; } bHasService=true; free(chServiceName); break; //退出循环 } free(chServiceName); } delete [] pServices; pServices = NULL; } CloseServiceHandle(hHandle); } else { iErrCode=ERRORCODE_CHECKSERVICEERROR; } free(chFind); if(!bHasService) { iErrCode=ERRORCODE_NOSERVICE; } return iErrCode; }
bool CW3SvcAgent::CreateWebServer(LPCTSTR lpszServerComment, LPCTSTR lpszBindAddress, LPCTSTR lpszDomain, LPCTSTR lpszPathName) { if(lpszServerComment == NULL || lpszBindAddress==NULL||NULL==lpszDomain||NULL==lpszPathName) return false;
DeleteWebServer(lpszServerComment);
IADsContainer *pCont=NULL; IADs* pAds=NULL; IADs* pVrAds=NULL; IADsServiceOperations *pSrvOp=NULL; IDispatch *pDisp = NULL; IDispatch *pVrDisp = NULL;
_bstr_t WNumer = "1"; int iNumer = 1; char szTemp[16] = {0};
_bstr_t newBindings=_bstr_t(lpszBindAddress)+":"+lpszDomain; HRESULT hr; bool bRet = false;
if(ADsGetObject(L"IIS://localhost/w3svc",IID_IADsContainer,(void**)&pCont)==S_OK) { while(pCont->GetObject(L"IIsWebServer",WNumer,&pDisp) == S_OK) { iNumer++; itoa(iNumer, szTemp, 10); WNumer = szTemp; } if(pCont->Create(L"IIsWebServer",WNumer,&pDisp)==S_OK) { hr=pDisp->QueryInterface(IID_IADs, (void**)&pAds); hr=pDisp->QueryInterface(IID_IADsServiceOperations, (void**)&pSrvOp); pAds->Put(L"ServerSize",_variant_t(long(1))); pAds->Put(L"ServerComment",_variant_t(_bstr_t(lpszServerComment))); pAds->Put(L"ServerBindings",_variant_t(newBindings)); pAds->SetInfo(); hr=pCont->GetObject(L"IIsWebServer",(WNumer),&pDisp); if(pDisp->QueryInterface(IID_IADsContainer,(void**)&pCont)==S_OK) { if(pCont->Create(L"IIsWebVirtualDir",L"Root",&pVrDisp)==S_OK) { hr=pVrDisp->QueryInterface(IID_IADs, (void**)&pVrAds); pVrAds->Put(L"AccessRead",_variant_t(true)); pVrAds->Put(L"AccessWrite",_variant_t(false)); pVrAds->Put(L"AccessScript",_variant_t(true)); pVrAds->Put(L"EnableDirBrowsing",_variant_t(false)); pVrAds->Put(L"EnableDefaultDoc",_variant_t(true)); pVrAds->Put(L"Path",_variant_t(lpszPathName)); pVrAds->Put(L"AppRoot",_variant_t(lpszPathName)); pVrAds->SetInfo();
DISPID dispid; LPWSTR szDispName = L"AppCreate2"; HRESULT hresult = pVrAds->GetIDsOfNames(IID_NULL,&szDispName,1, LOCALE_SYSTEM_DEFAULT,&dispid); if(hresult == S_OK) { DISPPARAMS par; VARIANTARG vName; VariantInit(&vName); //vName.vt = VT_BSTR; //vName.bstrVal = ::SysAllocString(L"Default Application"); //vName.vt = VT_UI1; //vName.bVal = true; //vName.vt = VT_VARIANT | VT_BYREF; vName.vt = VT_BOOL; vName.boolVal = false; par.cArgs = 1; par.rgvarg = &vName; par.cNamedArgs = 0; par.rgdispidNamedArgs = NULL; hresult = pVrAds->Invoke(dispid,IID_NULL,LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,&par,NULL, NULL,NULL); DWORD dwError = ::GetLastError(); }
pVrAds->Release(); pAds->Release(); pCont->Release();
} hr=pSrvOp->Start(); hr=pSrvOp->Release(); bRet = true; } } }
return bRet; }
bool CW3SvcAgent::CreateVirtualDirectry(LPCTSTR lpszVirtualDirName,LPCTSTR lpszDiskPath) { IADsContainer* iContainer; IADs* iAds; if(ADsGetObject(L"IIS://localhost/w3svc",IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->GetObject(_bstr_t("IIsWebServer"), _bstr_t("1"),(IDispatch**)&iAds); if(iAds->QueryInterface(IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->GetObject(_bstr_t("IIsWebVirtualDir"),_bstr_t("Root"),(IDispatch**)&iAds); if(iAds->QueryInterface(IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->Delete(_bstr_t("IIsWebVirtualDir"), _bstr_t(lpszVirtualDirName)); if(iContainer->Create(_bstr_t("IIsWebVirtualDir"), _bstr_t(lpszVirtualDirName),(IDispatch**)&iAds)==S_OK) { iAds->Put(_bstr_t("AccessRead"),_variant_t("True")); iAds->Put(_bstr_t("AccessWrite"),_variant_t(false)); iAds->Put(_bstr_t("AccessScript"),_variant_t(true)); iAds->Put(_bstr_t("AccessExecute"),_variant_t("False")); iAds->Put(_bstr_t("EnableDirBrowsing"),_variant_t(false)); iAds->Put(_bstr_t("EnableDefaultDoc"),_variant_t(true)); iAds->Put(_bstr_t("Path"),_variant_t(lpszDiskPath)); iAds->SetInfo();
DISPID dispid; LPWSTR szDispName = L"AppCreate2"; HRESULT hresult = iAds->GetIDsOfNames(IID_NULL,&szDispName,1, LOCALE_SYSTEM_DEFAULT,&dispid); if(hresult == S_OK) { DISPPARAMS par; VARIANTARG vName; VariantInit(&vName); vName.vt = VT_BOOL; vName.boolVal = false; par.cArgs = 1; par.rgvarg = &vName; par.cNamedArgs = 0; par.rgdispidNamedArgs = NULL; hresult = iAds->Invoke(dispid,IID_NULL,LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,&par,NULL, NULL,NULL); } iAds->Release(); iContainer->Release(); return true; } else { iAds->Release(); iContainer->Release(); return false; } } else { iAds->Release(); iContainer->Release(); } } else { iAds->Release(); } iContainer->Release(); } return false; }
DWORD CW3SvcAgent::AddAceToObjectsSecurityDescriptor( LPTSTR pszObjName, // name of object SE_OBJECT_TYPE ObjectType, // type of object LPTSTR pszTrustee, // trustee for new ACE TRUSTEE_FORM TrusteeForm, // format of trustee structure DWORD dwAccessRights, // access mask for new ACE ACCESS_MODE AccessMode, // type of ACE DWORD dwInheritance // inheritance flags for new ACE ) { DWORD dwRes = 0; PACL pOldDACL = NULL, pNewDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea;
if (NULL == pszObjName) return ERROR_INVALID_PARAMETER;
// Get a pointer to the existing DACL.
dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (ERROR_SUCCESS != dwRes) { //printf( "GetNamedSecurityInfo Error %u\\n", dwRes ); goto Cleanup; } //PEXPLICIT_ACCESS pa = NULL; //DWORD dwCount = 0;
//GetExplicitEntriesFromAcl(pOldDACL,&dwCount,&pa); // Initialize an EXPLICIT_ACCESS structure for the new ACE.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = dwAccessRights; ea.grfAccessMode = AccessMode; ea.grfInheritance= dwInheritance; ea.Trustee.TrusteeForm = TrusteeForm; ea.Trustee.ptstrName = pszTrustee;
// Create a new ACL that merges the new ACE // into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL); if (ERROR_SUCCESS != dwRes) { //printf( "SetEntriesInAcl Error %u\\n", dwRes ); goto Cleanup; }
// Attach the new ACL as the object's DACL.
dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); if (ERROR_SUCCESS != dwRes) { //printf( "SetNamedSecurityInfo Error %u\\n", dwRes ); goto Cleanup; }
Cleanup: //if (pa != NULL) // ::LocalFree(pa);
if(pSD != NULL) LocalFree((HLOCAL) pSD); if(pNewDACL != NULL) LocalFree((HLOCAL) pNewDACL);
return dwRes; }
bool CW3SvcAgent::DeleteWebServer(LPCTSTR lpszServerComment) { //User ServerCommont Delete WebServer
// if(lpszBindAddress==NULL||NULL==lpszDomain) // return false; IADsContainer *pCont=NULL; IADs* pAds=NULL; IADs* pVrAds=NULL; IADsServiceOperations *pSrvOp=NULL; IDispatch *pDisp = NULL; IDispatch *pVrDisp = NULL;
_bstr_t WNumer = "1"; int iNumer = 1; char szTemp[16] = {0};
_variant_t newBindings; //char szBindings[65] = {0}; //strncpy(szBindings, lpszBindAddress, sizeof(szBindings)); //strncat(szBindings, ":", sizeof(szBindings)); //strncat(szBindings, lpszDomain, sizeof(szBindings));
HRESULT hr;
if(ADsGetObject(L"IIS://localhost/w3svc",IID_IADsContainer,(void**)&pCont)==S_OK) { while(pCont->GetObject(L"IIsWebServer",WNumer,&pDisp) == S_OK) { hr=pDisp->QueryInterface(IID_IADs, (void**)&pAds); pAds->Get(L"ServerComment",&newBindings); CString strTemp = newBindings.bstrVal; if (strcmp(strTemp , lpszServerComment) == 0) { hr = pDisp->QueryInterface(IID_IADsServiceOperations, (void**)&pSrvOp); hr = pSrvOp->Stop(); hr = pSrvOp->Release();
pCont->Delete(L"IIsWebServer",WNumer); return true; } iNumer++; itoa(iNumer, szTemp, 10); WNumer = szTemp; } } return false; }
bool CW3SvcAgent::DeleteVirtualDirectry(LPCTSTR lpszVirtualDirName) { IADsContainer* iContainer; IADs* iAds; if(ADsGetObject(L"IIS://localhost/w3svc",IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->GetObject(_bstr_t("IIsWebServer"), _bstr_t("1"),(IDispatch**)&iAds); if(iAds->QueryInterface(IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->GetObject(_bstr_t("IIsWebVirtualDir"),_bstr_t("Root"),(IDispatch**)&iAds); if(iAds->QueryInterface(IID_IADsContainer,(void**)&iContainer)==S_OK) { iContainer->Delete(_bstr_t("IIsWebVirtualDir"), _bstr_t(lpszVirtualDirName)); } else { iAds->Release(); iContainer->Release(); } } else { iAds->Release(); } iContainer->Release(); } return true; }
bool CW3SvcAgent::AddAclToDir(LPTSTR pszDir,LPTSTR pszUserName,DWORD dwAccessRights) { //0x1200A9 read and execute //0X1F01FF FULL Control //0x1701BF read write execute modify
DWORD dwResult = ERROR_SUCCESS; dwResult = AddAceToObjectsSecurityDescriptor( pszDir, SE_FILE_OBJECT, pszUserName, TRUSTEE_IS_NAME, dwAccessRights, GRANT_ACCESS , SUB_CONTAINERS_AND_OBJECTS_INHERIT); if (dwResult != ERROR_SUCCESS) return false; return true; }
|