//////////////////////////////////////////////////////////////////////// // // regcode.cpp // // Module: // // History: // ivanbrug 17-09-2000 Create // // // Copyright (c) 1997-2001 Microsoft Corporation, All rights reserved // //////////////////////////////////////////////////////////////////////// #include "precomp.h" #include #include // for LoadString #include #include #include #include #include #define SVCHOST_HOME _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost") #define SERVICE_PATH _T("System\\CurrentControlSet\\Services\\") #define DLL_PATH _T("%SystemRoot%\\system32\\wbem\\WMIsvc.dll") #define ENTRY_POINT _T("ServiceMain") #define COM_APPID _T("Software\\classes\\AppID\\{8BC3F05E-D86B-11D0-A075-00C04FB68820}") //= Windows Management Instrumentation //LocalService = WinMgmt #define COM_APPID_NAME _T("Software\\classes\\AppID\\winmgmt") //AppID = {8BC3F05E-D86B-11D0-A075-00C04FB68820} #define SERVICE_CLSID _T("{8BC3F05E-D86B-11D0-A075-00C04FB68820}") #define SERVICE_NAME_GROUP_ALONE _T("winmgmt") #define SERVICE_NAME_GROUP _T("netsvcs") #define SERVICE_NAME_GROUP_TOGETHER _T("netsvcs") // see winmgmt.h //#define SERVICE_NAME _T("winmgmt") #define VALUE_AUTH _T("AuthenticationCapabilities") #define VALUE_COINIT _T("CoInitializeSecurityParam") #define VALUE_AUTZN _T("AuthenticationLevel") #define VALUE_IMPER _T("ImpersonationLevel") #define ACCOUNT_NAME _T("LocalService") // unused, for now #define DISPLAY_CLSID _T("Windows Management and Instrumentation") #define DISPLAY_BACKUP_CLSID _T("Windows Management Instrumentation Backup and Recovery") // // how verbose can PMs be ? // #define MAX_BUFF 2048 // // // this is the rundll32 interface // // ////////////////////////////////////////////////////////////////// void CALLBACK MoveToAlone(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //RPC_C_AUTHN_LEVEL_CONNECT { BOOL bRet = TRUE; LONG lRet; HKEY hKey; DWORD dwLevel = RPC_C_AUTHN_LEVEL_CONNECT; if (lpszCmdLine) { dwLevel = atoi(lpszCmdLine); if (0 == dwLevel) // in case of error { dwLevel = RPC_C_AUTHN_LEVEL_CONNECT; } } // create the new group key under svchost if (bRet) { lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_HOME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { // add the group LONG lRet2; DWORD dwCurrSize; DWORD dwType; lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,NULL,&dwCurrSize); if (ERROR_SUCCESS == lRet2) { // the key is there, append to the multistring BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)]; wmilib::auto_buffer rm_(pMulti); if (pMulti) { lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize); if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check { TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR)); // verify the multisz TCHAR *pEnd = (TCHAR *)pMulti; BOOL bIsThere = FALSE; while (*pEnd) { if (0 == _tcsicmp(pEnd,SERVICE_NAME)) { bIsThere = TRUE; } while (*pEnd){ pEnd++; } pEnd++; // past the zero who terminates the string } if (!bIsThere) { if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint) { _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1); DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME); RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,dwNowSize); } else { bRet = FALSE; } } } } } else if (ERROR_FILE_NOT_FOUND == lRet2) { BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_ALONE _T("\0"); RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T(""))); } else { // what to do ? } HKEY hKey2; DWORD dwDisposistion; lRet = RegCreateKeyEx(hKey, SERVICE_NAME_GROUP_ALONE, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisposistion); if (ERROR_SUCCESS == lRet) { // any value non NULL will work DWORD dwVal = 1; RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); // from packet to connect dwVal = dwLevel; //RPC_C_AUTHN_LEVEL_CONNECT; RegSetValueEx(hKey2,VALUE_AUTZN,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); dwVal = RPC_C_IMP_LEVEL_IDENTIFY; RegSetValueEx(hKey2,VALUE_IMPER,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ; RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); RegCloseKey(hKey2); bRet = TRUE; } } } if (bRet) { SC_HANDLE scHandle; scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS); if (scHandle) { SC_HANDLE scService; scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS); if (scService) { DWORD dwNeeded = 0; bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded); if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError())) { BYTE * pByte = new BYTE[dwNeeded]; wmilib::auto_buffer rm_(pByte); QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte; if (pConfig) { bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded); if (bRet) { TCHAR BinPath[MAX_PATH]; wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP_ALONE); bRet = ChangeServiceConfig(scService, pConfig->dwServiceType, pConfig->dwStartType, pConfig->dwErrorControl, BinPath, pConfig->lpLoadOrderGroup, NULL, //&pConfig->dwTagId, pConfig->lpDependencies, pConfig->lpServiceStartName, NULL, pConfig->lpDisplayName); if (!bRet) { DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError())); } } } else { bRet = FALSE; } } CloseServiceHandle(scService); } else { // the service was not there or other error DBG_PRINTFA((pBuff,"MoveToStandalone OpenService %d\n",GetLastError())); bRet = FALSE; } CloseServiceHandle(scHandle); } else { DBG_PRINTFA((pBuff,"MoveToStandalone OpenSCManager %d\n",GetLastError())); bRet = FALSE; } } if (bRet) { // // remove the winmgmt string from the multi-sz of winmgmt // lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_HOME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { // add the group LONG lRet2; DWORD dwCurrSize; DWORD dwType; lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,NULL,&dwCurrSize); if (ERROR_SUCCESS == lRet2) { // the key is there, append to the multistring BYTE * pMulti = new BYTE[dwCurrSize+4]; wmilib::auto_buffer rm1_(pMulti); BYTE * pMultiNew = new BYTE[dwCurrSize+4]; wmilib::auto_buffer rm2_(pMultiNew); TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew; if (pMulti && pMultiNew) { lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize); if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check { // verify the multisz TCHAR *pEnd = (TCHAR *)pMulti; BOOL bIsThere = FALSE; while (*pEnd) { if (0 == _tcsicmp(pEnd,SERVICE_NAME)) { bIsThere = TRUE; while (*pEnd){ pEnd++; } pEnd++; // past the zero who terminates the string } else // copy { while (*pEnd){ *pMultiNewCopy++ = *pEnd++; } pEnd++; // past the zero who terminates the string *pMultiNewCopy++ = 0; } } *pMultiNewCopy++ = 0; // put the double terminator if (bIsThere) { DWORD dwNowSize = dwCurrSize-sizeof(SERVICE_NAME); RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMultiNew,dwNowSize); } } } else { bRet = FALSE; } } else { // // the netsvcs multi sz MUST be there !!!! // bRet = TRUE; } } else { bRet = FALSE; } } return; } // // // this is the rundll32 interface // // ////////////////////////////////////////////////////////////////// void CALLBACK MoveToShared(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //RPC_C_AUTHN_LEVEL_CONNECT { // BOOL bRet = TRUE; LONG lRet; HKEY hKey; DWORD dwLevel = RPC_C_PROTECT_LEVEL_PKT; if (lpszCmdLine) { dwLevel = atoi(lpszCmdLine); if (0 == dwLevel) // in case of error { dwLevel = RPC_C_PROTECT_LEVEL_PKT; } } // create the new group key under svchost if (bRet) { lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_HOME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { // add the group LONG lRet2; DWORD dwCurrSize; DWORD dwType; lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,NULL,&dwCurrSize); if (ERROR_SUCCESS == lRet2) { // the key is there, append to the multistring BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)]; wmilib::auto_buffer rm_(pMulti); if (pMulti) { lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize); if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check { TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR)); // verify the multisz TCHAR *pEnd = (TCHAR *)pMulti; BOOL bIsThere = FALSE; while (*pEnd) { if (0 == _tcsicmp(pEnd,SERVICE_NAME)) { bIsThere = TRUE; } while (*pEnd){ pEnd++; } pEnd++; // past the zero who terminates the string } if (!bIsThere) { if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint) { _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1); DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME); RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMulti,dwNowSize); } else { bRet = FALSE; DebugBreak(); } } } } else { bRet = FALSE; } } else if (ERROR_FILE_NOT_FOUND == lRet2) { BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_TOGETHER _T("\0"); RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T(""))); } else { // what to do ? } HKEY hKey2; DWORD dwDisposistion; lRet = RegCreateKeyEx(hKey, SERVICE_NAME_GROUP_TOGETHER, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisposistion); if (ERROR_SUCCESS == lRet) { // any value non NULL will work DWORD dwVal = 1; RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); // from packet to connect dwVal = dwLevel; //RPC_C_AUTHN_LEVEL_CONNECT; RegSetValueEx(hKey2,VALUE_AUTZN,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); dwVal = RPC_C_IMP_LEVEL_IDENTIFY; RegSetValueEx(hKey2,VALUE_IMPER,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ; RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); RegCloseKey(hKey2); bRet = TRUE; } else { DebugBreak(); } } } // // changes the SCM database // if (bRet) { SC_HANDLE scHandle; scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS); if (scHandle) { SC_HANDLE scService; scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS); if (scService) { DWORD dwNeeded = 0; bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded); if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError())) { BYTE * pByte = new BYTE[dwNeeded]; wmilib::auto_buffer rm1_(pByte); QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte; if (pConfig) { bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded); if (bRet) { TCHAR BinPath[MAX_PATH]; wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP_TOGETHER); bRet = ChangeServiceConfig(scService, pConfig->dwServiceType, pConfig->dwStartType, pConfig->dwErrorControl, BinPath, pConfig->lpLoadOrderGroup, NULL, //&pConfig->dwTagId, pConfig->lpDependencies, pConfig->lpServiceStartName, NULL, pConfig->lpDisplayName); if (!bRet) { DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError())); } } } else { bRet = FALSE; } } CloseServiceHandle(scService); } else { // the service was not there or other error DBG_PRINTFA((pBuff,"MoveToShared OpenService %d\n",GetLastError())); bRet = FALSE; } CloseServiceHandle(scHandle); } else { DBG_PRINTFA((pBuff,"MoveToStandalone OpenSCManager %d\n",GetLastError())); bRet = FALSE; } } if (bRet) { // // remove the winmgmt string from the multi-sz of winmgmt // lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_HOME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { // add the group LONG lRet2; DWORD dwCurrSize; DWORD dwType; lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,NULL,&dwCurrSize); if (ERROR_SUCCESS == lRet2) { // the key is there, append to the multistring BYTE * pMulti = new BYTE[dwCurrSize+4]; wmilib::auto_buffer rm2_(pMulti); BYTE * pMultiNew = new BYTE[dwCurrSize+4]; wmilib::auto_buffer rm3_(pMultiNew); TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew; if (pMulti && pMultiNew) { lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize); if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check { // verify the multisz TCHAR *pEnd = (TCHAR *)pMulti; BOOL bIsThere = FALSE; while (*pEnd) { if (0 == _tcsicmp(pEnd,SERVICE_NAME)) { bIsThere = TRUE; while (*pEnd){ pEnd++; } pEnd++; // past the zero who terminates the string } else // copy { while (*pEnd){ *pMultiNewCopy++ = *pEnd++; } pEnd++; // past the zero who terminates the string *pMultiNewCopy++ = 0; } } *pMultiNewCopy++ = 0; // put the double terminator if (bIsThere) { DWORD dwNowSize = dwCurrSize-sizeof(SERVICE_NAME); RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMultiNew,dwNowSize); } } } else { bRet = FALSE; } } else { // // the netsvcs multi sz MUST be there !!!! // bRet = TRUE; } } else { bRet = FALSE; } } } //*************************************************************************** // // void InitializeLaunchPermissions() // // DESCRIPTION: // // Sets the DCOM Launch permissions. // //*************************************************************************** void InitializeLaunchPermissions() { Registry reg(__TEXT("SOFTWARE\\CLASSES\\APPID\\{8bc3f05e-d86b-11d0-a075-00c04fb68820}")); if(reg.GetLastError() != 0) return; // If there already is a SD, then dont overwrite BYTE * pData = NULL; DWORD dwDataSize = 0; int iRet = reg.GetBinary(__TEXT("LaunchPermission"), &pData, &dwDataSize); if(iRet == 0) { delete [] pData; return; // it's already there } PSID pEveryoneSid; SID_IDENTIFIER_AUTHORITY id_World = SECURITY_WORLD_SID_AUTHORITY; if(!AllocateAndInitializeSid( &id_World, 1, SECURITY_WORLD_RID, 0,0,0,0,0,0,0, &pEveryoneSid)) return; OnDelete freeSid1(pEveryoneSid); SID_IDENTIFIER_AUTHORITY id_NT = SECURITY_NT_AUTHORITY; PSID pAdministratorsSid = NULL; if (!AllocateAndInitializeSid(&id_NT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsSid)) return; OnDelete freeSid2(pAdministratorsSid); // Create the class sids for everyone and administrators CNtSid SidEveryone(pEveryoneSid); CNtSid SidAdmins(pAdministratorsSid); if(SidEveryone.GetStatus() != 0 || SidAdmins.GetStatus() != 0) return; // Create a single ACE, and add it to the ACL CNtAcl DestAcl; CNtAce Users(1, ACCESS_ALLOWED_ACE_TYPE, 0, SidEveryone); if(Users.GetStatus() != 0) return; DestAcl.AddAce(&Users); if(DestAcl.GetStatus() != 0) return; // Set the descresionary acl, and the owner and group sids // Create a sd with a single entry for launch permissions. CNtSecurityDescriptor LaunchPermSD; LaunchPermSD.SetDacl(&DestAcl); LaunchPermSD.SetOwner(&SidAdmins); LaunchPermSD.SetGroup(&SidAdmins); if(LaunchPermSD.GetStatus() != 0) return; // Write it out reg.SetBinary(__TEXT("LaunchPermission"), (BYTE *)LaunchPermSD.GetPtr(), LaunchPermSD.GetSize()); } //*************************************************************************** // // DllRegisterServer // // Standard OLE entry point for registering the server. // // RETURN VALUES: // // S_OK Registration was successful // E_FAIL Registration failed. // //*************************************************************************** STDAPI DllRegisterServer(void) { // set the group HKEY hKey; LONG lRet; BOOL bRet = TRUE; if (bRet) { lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_HOME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { // add the group LONG lRet2; DWORD dwCurrSize; DWORD dwType; lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP,0,&dwType,NULL,&dwCurrSize); if (ERROR_SUCCESS == lRet2) { // the key is there, append to the multistring BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)]; wmilib::auto_buffer rm4_(pMulti); if (pMulti) { lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP,0,&dwType,pMulti,&dwCurrSize); if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check { TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR)); // verify the multisz TCHAR *pEnd = (TCHAR *)pMulti; BOOL bIsThere = FALSE; while (*pEnd) { if (0 == _tcsicmp(pEnd,SERVICE_NAME)) { bIsThere = TRUE; } while (*pEnd){ pEnd++; } pEnd++; // past the zero who terminates the string } if (!bIsThere) { if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint) { _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1); DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME); RegSetValueEx(hKey,SERVICE_NAME_GROUP,0,REG_MULTI_SZ,pMulti,dwNowSize); } else { DebugBreak(); } } } } else { bRet = FALSE; } } else if (ERROR_FILE_NOT_FOUND == lRet2) { BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP _T("\0"); RegSetValueEx(hKey,SERVICE_NAME_GROUP,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T(""))); } else { // what to do ? } HKEY hKey2; DWORD dwDisposistion; lRet = RegCreateKeyEx(hKey, SERVICE_NAME_GROUP, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisposistion); if (ERROR_SUCCESS == lRet) { // any value non NULL will work DWORD dwVal = 1; RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); // servicehost default + static cloaking dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ; RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD)); RegCloseKey(hKey2); bRet = TRUE; } } } BOOL bCreated = FALSE; if (bRet) { SC_HANDLE hSCM = NULL; hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (hSCM) { DWORD dwTag; TCHAR BinPath[MAX_PATH]; wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP); TCHAR * pServiceDisplay = new TCHAR[MAX_BUFF]; if (pServiceDisplay) { int nRet = LoadString(g_hInstance,ID_WINMGMT_SERVICE,pServiceDisplay,MAX_BUFF); } else { bRet = FALSE; } SC_HANDLE hService = NULL; if (bRet) { hService = OpenService(hSCM,SERVICE_NAME,SERVICE_ALL_ACCESS ); } SC_ACTION ac[2]; ac[0].Type = SC_ACTION_RESTART; ac[0].Delay = 60000; ac[1].Type = SC_ACTION_RESTART; ac[1].Delay = 60000; SERVICE_FAILURE_ACTIONS sf; sf.dwResetPeriod = 86400; sf.lpRebootMsg = NULL; sf.lpCommand = NULL; sf.cActions = 2; sf.lpsaActions = ac; if (hService) { bRet = ChangeServiceConfig(hService, SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START, //SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, BinPath, NULL, NULL, _T("RPCSS\0Eventlog\0\0\0"), NULL, //ACCOUNT_NAME, NULL, pServiceDisplay); if (bRet) { ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sf); // // insert code for description here TCHAR * pBuff = new TCHAR[MAX_BUFF]; if (pBuff) { int nRet = LoadString(g_hInstance,ID_WINMGMT_DESCRIPTION,pBuff,MAX_BUFF); if (nRet) { SERVICE_DESCRIPTION sd; sd.lpDescription = pBuff; ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,&sd); } delete [] pBuff; } // // } else { DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError())); } CloseServiceHandle(hService); } else { // Create it hService = CreateService(hSCM, SERVICE_NAME, pServiceDisplay, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START, //SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, BinPath, NULL, NULL, _T("RPCSS\0Eventlog\0\0\0"), NULL, //ACCOUNT_NAME, NULL); if (hService) { ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sf); // // insert code for description here TCHAR * pBuff = new TCHAR[MAX_BUFF]; if (pBuff) { int nRet = LoadString(g_hInstance,ID_WINMGMT_DESCRIPTION,pBuff,MAX_BUFF); if (nRet) { SERVICE_DESCRIPTION sd; sd.lpDescription = pBuff; ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,&sd); } delete [] pBuff; } // // CloseServiceHandle(hService); bRet = TRUE; }; } if (pServiceDisplay) { delete [] pServiceDisplay; } CloseServiceHandle(hSCM); } } if (bRet) { lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SERVICE_PATH SERVICE_NAME, 0, KEY_ALL_ACCESS, &hKey); if (ERROR_SUCCESS == lRet) { HKEY hKey3; DWORD dwDisposistion; lRet = RegCreateKeyEx(hKey, _T("Parameters"), 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey3, &dwDisposistion); if (ERROR_SUCCESS == lRet) { RegSetValueEx(hKey3,_T("ServiceDll"),0,REG_EXPAND_SZ,(BYTE *)DLL_PATH,sizeof(DLL_PATH)-sizeof(TCHAR)); RegSetValueEx(hKey3,_T("ServiceMain"),0,REG_SZ,(BYTE *)ENTRY_POINT,sizeof(ENTRY_POINT)-sizeof(TCHAR)); RegCloseKey(hKey3); bRet = TRUE; }; RegCloseKey(hKey); } } if (bRet) { HKEY hKey4; DWORD dwDisposistion; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, COM_APPID, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey4, &dwDisposistion); if (ERROR_SUCCESS == lRet) { RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_CLSID,sizeof(DISPLAY_CLSID)-sizeof(TCHAR)); RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR)); RegCloseKey(hKey4); } lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, COM_APPID_NAME, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey4, &dwDisposistion); if (ERROR_SUCCESS == lRet) { RegSetValueEx(hKey4,_T("AppID"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR)); RegCloseKey(hKey4); } InitializeLaunchPermissions(); OLECHAR ClsidBuff[40]; TCHAR * ClsidBuff2; TCHAR ClsidPath[MAX_PATH]; StringFromGUID2(CLSID_WbemLevel1Login,ClsidBuff,40); #ifdef UNICODE ClsidBuff2 = ClsidBuff; #else TCHAR pTmp_[40]; ClsidPath2 = pTmp_; WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL); #endif wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff2); lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, ClsidPath, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey4, &dwDisposistion); if (ERROR_SUCCESS == lRet) { RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_CLSID,sizeof(DISPLAY_CLSID)-sizeof(TCHAR)); RegSetValueEx(hKey4,_T("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR)); RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR)); RegCloseKey(hKey4); } StringFromGUID2(CLSID_WbemBackupRestore,ClsidBuff,40); #ifdef UNICODE ClsidBuff2 = ClsidBuff; #else // already _alloca-ted at this point //ClsidPath2 = (TCHAR *)_alloca(40*sizeof(TCHAR)); WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL); #endif wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff); lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, ClsidPath, 0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey4, &dwDisposistion); if (ERROR_SUCCESS == lRet) { RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_BACKUP_CLSID,sizeof(DISPLAY_BACKUP_CLSID)-sizeof(TCHAR)); RegSetValueEx(hKey4,_T("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR)); RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR)); RegCloseKey(hKey4); } } return S_OK; } //*************************************************************************** // // DllUnregisterServer // // Standard OLE entry point for unregistering the server. // // RETURN VALUES: // // S_OK Unregistration was successful // E_FAIL Unregistration failed. // //*************************************************************************** STDAPI DllUnregisterServer(void) { HKEY hKey; LONG lRet; BOOL bRet = TRUE; if (bRet) { TCHAR ClsidBuff[40]; TCHAR ClsidPath[MAX_PATH]; #ifdef UNICODE StringFromCLSID(CLSID_WbemLevel1Login,(LPOLESTR *)ClsidBuff); #else WCHAR ClsidPath2[40]; StringFromCLSID(CLSID_WbemLevel1Login,(LPOLESTR *)ClsidBuff2); MultiByteToWideChar(CP_ACP,0,ClsidBuff2,-1,ClsidBuff,40); #endif wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff); lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath); #ifdef UNICODE StringFromCLSID(CLSID_WbemBackupRestore,(LPOLESTR *)ClsidBuff); #else WCHAR ClsidPath2[40]; StringFromCLSID(CLSID_WbemBackupRestore,(LPOLESTR *)ClsidBuff2); MultiByteToWideChar(CP_ACP,0,ClsidBuff2,-1,ClsidBuff,40); #endif wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff); lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath); lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID); lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID_NAME); } return S_OK; }