You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1245 lines
46 KiB
1245 lines
46 KiB
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All rights reserved
|
|
//
|
|
// Module: regcode.cpp
|
|
//
|
|
// Implements the Service registration routines
|
|
//
|
|
// History:
|
|
//
|
|
// ivanbrug 17-09-2000 CreateF
|
|
//
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precomp.h"
|
|
#include <winmgmt.h>
|
|
#include <strings.h> // for LoadString
|
|
#include <malloc.h>
|
|
#include <winntsec.h>
|
|
#include <autoptr.h>
|
|
#include <strutils.h>
|
|
|
|
#define SVCHOST_HOME TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost")
|
|
#define SERVICE_PATH TEXT("System\\CurrentControlSet\\Services\\")
|
|
#define DLL_PATH TEXT("%SystemRoot%\\system32\\wbem\\WMIsvc.dll")
|
|
#define ENTRY_POINT TEXT("ServiceMain")
|
|
|
|
#define COM_APPID TEXT("Software\\classes\\AppID\\{8BC3F05E-D86B-11D0-A075-00C04FB68820}")
|
|
//= Windows Management Instrumentation
|
|
//LocalService = WinMgmt
|
|
|
|
#define COM_APPID_NAME TEXT("Software\\classes\\AppID\\winmgmt")
|
|
//AppID = {8BC3F05E-D86B-11D0-A075-00C04FB68820}
|
|
|
|
#define SERVICE_CLSID TEXT("{8BC3F05E-D86B-11D0-A075-00C04FB68820}")
|
|
|
|
|
|
#define SERVICE_NAME_GROUP_ALONE TEXT("winmgmt")
|
|
#define SERVICE_NAME_GROUP TEXT("netsvcs")
|
|
#define SERVICE_NAME_GROUP_TOGETHER TEXT("netsvcs")
|
|
|
|
|
|
// see winmgmt.h
|
|
//#define SERVICE_NAME TEXT("winmgmt")
|
|
|
|
#define VALUE_AUTH TEXT("AuthenticationCapabilities")
|
|
#define VALUE_COINIT TEXT("CoInitializeSecurityParam")
|
|
#define VALUE_AUTZN TEXT("AuthenticationLevel")
|
|
#define VALUE_IMPER TEXT("ImpersonationLevel")
|
|
|
|
#define ACCOUNT_NAME TEXT("LocalService") // unused, for now
|
|
#define DISPLAY_CLSID TEXT("Windows Management and Instrumentation")
|
|
#define DISPLAY_BACKUP_CLSID TEXT("Windows Management Instrumentation Backup and Recovery")
|
|
|
|
//
|
|
// for the Description string
|
|
//
|
|
#define MAX_BUFF 2048
|
|
|
|
//
|
|
// this is the rundll32 interface
|
|
// usage is
|
|
// C:\>rundll32 %windir%\system32\wbem\wmisvc.dll,MoveToAlone X
|
|
// where X is the AuthenticationLevel
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
void CALLBACK
|
|
MoveToAlone(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //RPC_C_AUTHN_LEVEL_CONNECT
|
|
{
|
|
BOOL bRet = TRUE;
|
|
LONG lRet;
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
if (bRet)
|
|
{
|
|
// create the new group key under svchost
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SVCHOST_HOME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm(hKey);
|
|
// add the group
|
|
|
|
LONG lRet2;
|
|
DWORD dwCurrSize = 0;
|
|
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<BYTE> rm_(pMulti);
|
|
if (pMulti)
|
|
{
|
|
lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize);
|
|
if (ERROR_SUCCESS == lRet2 && REG_MULTI_SZ == dwType)
|
|
{
|
|
TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
|
|
// verify the multisz
|
|
TCHAR *pEnd = (TCHAR *)pMulti;
|
|
BOOL bIsThere = FALSE;
|
|
|
|
while (*pEnd)
|
|
{
|
|
if (0 == wbem_wcsicmp(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)
|
|
{
|
|
wcsncpy(pEnd,SERVICE_NAME TEXT("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1);
|
|
DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME);
|
|
if (ERROR_SUCCESS == RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,dwNowSize))
|
|
bRet = TRUE;
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ERROR_FILE_NOT_FOUND == lRet2)
|
|
{
|
|
BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_ALONE TEXT("\0");
|
|
LONG lResInner = RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(TEXT("")));
|
|
bRet = (ERROR_SUCCESS == lResInner)?TRUE:FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
// create the key with the COM init Param
|
|
if (bRet)
|
|
{
|
|
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)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm2(hKey2);
|
|
|
|
// 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));
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no svchost key
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
SC_HANDLE scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS);
|
|
if (scHandle)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm1(scHandle);
|
|
|
|
SC_HANDLE scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS);
|
|
if (scService)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm2(scService);
|
|
|
|
DWORD dwNeeded = 0;
|
|
bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded);
|
|
|
|
if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
|
|
{
|
|
BYTE * pByte = new BYTE[dwNeeded];
|
|
wmilib::auto_buffer<BYTE> rm_(pByte);
|
|
QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte;
|
|
if (pConfig)
|
|
{
|
|
bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded);
|
|
if (bRet)
|
|
{
|
|
TCHAR BinPath[MAX_PATH];
|
|
StringCchPrintf(BinPath,MAX_PATH,TEXT("%%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;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the service was not there or other error
|
|
DBG_PRINTFA((pBuff,"MoveToStandalone OpenService %d\n",GetLastError()));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_PRINTFA((pBuff,"MoveToStandalone OpenSCManager %d\n",GetLastError()));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
//
|
|
// remove the winmgmt string from the multi-sz of netsvcs
|
|
//
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SVCHOST_HOME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm3(hKey);
|
|
// add the group
|
|
|
|
LONG lRet2;
|
|
DWORD dwCurrSize = 0;
|
|
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<BYTE> rm1_(pMulti);
|
|
BYTE * pMultiNew = new BYTE[dwCurrSize+4];
|
|
wmilib::auto_buffer<BYTE> rm2_(pMultiNew);
|
|
TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew;
|
|
|
|
if (pMulti && pMultiNew)
|
|
{
|
|
lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize);
|
|
|
|
if (ERROR_SUCCESS == lRet2 && REG_MULTI_SZ == dwType)
|
|
{
|
|
|
|
// verify the multisz
|
|
TCHAR *pEnd = (TCHAR *)pMulti;
|
|
BOOL bIsThere = FALSE;
|
|
|
|
while (*pEnd)
|
|
{
|
|
if (0 == wbem_wcsicmp(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
|
|
{
|
|
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;
|
|
|
|
|
|
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)
|
|
{
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SVCHOST_HOME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm(hKey);
|
|
// add the group
|
|
|
|
LONG lRet2;
|
|
DWORD dwCurrSize = 0;
|
|
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<BYTE> rm_(pMulti);
|
|
if (pMulti)
|
|
{
|
|
lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize);
|
|
|
|
if (ERROR_SUCCESS == lRet2 && REG_MULTI_SZ == dwType)
|
|
{
|
|
TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
|
|
// verify the multisz
|
|
TCHAR *pEnd = (TCHAR *)pMulti;
|
|
BOOL bIsThere = FALSE;
|
|
|
|
while (*pEnd)
|
|
{
|
|
if (0 == wbem_wcsicmp(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)
|
|
{
|
|
wcsncpy(pEnd,SERVICE_NAME TEXT("\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;
|
|
DBG_PRINTFA((pBuff,"Malformed REG_MULTI_SZ under %S\n",SERVICE_NAME_GROUP_TOGETHER));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// invalid type in reg_multi_sz
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else if (ERROR_FILE_NOT_FOUND == lRet2)
|
|
{
|
|
BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_TOGETHER TEXT("\0");
|
|
RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(TEXT("")));
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm2(hKey2);
|
|
|
|
// 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));
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DBG_PRINTFA((pBuff,"Could not create %S\n",SERVICE_NAME_GROUP_TOGETHER));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// changes the SCM database
|
|
//
|
|
if (bRet)
|
|
{
|
|
SC_HANDLE scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (scHandle)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm1(scHandle);
|
|
|
|
SC_HANDLE scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS);
|
|
|
|
if (scService)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm2(scService);
|
|
|
|
DWORD dwNeeded = 0;
|
|
bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded);
|
|
|
|
if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
|
|
{
|
|
BYTE * pByte = new BYTE[dwNeeded];
|
|
wmilib::auto_buffer<BYTE> rm1_(pByte);
|
|
QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte;
|
|
if (pConfig)
|
|
{
|
|
bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded);
|
|
if (bRet)
|
|
{
|
|
TCHAR BinPath[MAX_PATH];
|
|
StringCchPrintf(BinPath,MAX_PATH,TEXT("%%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;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the service was not there or other error
|
|
DBG_PRINTFA((pBuff,"MoveToShared OpenService %d\n",GetLastError()));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_PRINTFA((pBuff,"MoveToShared OpenSCManager %d\n",GetLastError()));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
if (bRet)
|
|
{
|
|
//
|
|
// remove the winmgmt string from the multi-sz of winmgmt
|
|
//
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SVCHOST_HOME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm3(hKey);
|
|
// 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<BYTE> rm2_(pMulti);
|
|
BYTE * pMultiNew = new BYTE[dwCurrSize+4];
|
|
wmilib::auto_buffer<BYTE> rm3_(pMultiNew);
|
|
TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew;
|
|
|
|
if (pMulti && pMultiNew)
|
|
{
|
|
lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize);
|
|
|
|
if (ERROR_SUCCESS == lRet2 && REG_MULTI_SZ == dwType)
|
|
{
|
|
|
|
// verify the multisz
|
|
TCHAR *pEnd = (TCHAR *)pMulti;
|
|
BOOL bIsThere = FALSE;
|
|
|
|
while (*pEnd)
|
|
{
|
|
if (0 == wbem_wcsicmp(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
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// the winmgmt multi sz MUST can be NOT 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<PSID,PVOID(*)(PSID),FreeSid> 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<PSID,PVOID(*)(PSID),FreeSid> 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 COM server.
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// S_OK Registration was successful
|
|
// E_FAIL Registration failed.
|
|
//
|
|
//***************************************************************************
|
|
//
|
|
// Phase 1 : Create the MULTI_SZ under the svchost key (AKA, create a group of services)
|
|
// If the key is there, check if the WinMgmt service is already there, otherwise add it
|
|
// Phase 2 : Use the SCM Api in order to create the service if not there
|
|
// otherwise change the service configuration to some known value
|
|
// Phase 3 : Creates specific keys under the Services\WinMgmt key.
|
|
// cannot be done before, if the service is not already there
|
|
// Phase 4 : Expose this service as a COM server, creates CLSID, APPID and misc keys
|
|
//
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
LONG lRet;
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Phase 1
|
|
//
|
|
if (bRet)
|
|
{
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SVCHOST_HOME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm(hKey);
|
|
// add the group
|
|
|
|
LONG lRet2;
|
|
DWORD dwCurrSize = 0;
|
|
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<BYTE> rm4_(pMulti);
|
|
if (pMulti)
|
|
{
|
|
lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP,0,&dwType,pMulti,&dwCurrSize);
|
|
|
|
if (ERROR_SUCCESS == lRet2 && REG_MULTI_SZ == dwType )
|
|
{
|
|
TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
|
|
// verify the multisz
|
|
TCHAR *pEnd = (TCHAR *)pMulti;
|
|
BOOL bIsThere = FALSE;
|
|
|
|
while (*pEnd)
|
|
{
|
|
if (0 == wbem_wcsicmp(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)
|
|
{
|
|
wcsncpy(pEnd,SERVICE_NAME TEXT("\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
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else if (ERROR_FILE_NOT_FOUND == lRet2)
|
|
{
|
|
BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP TEXT("\0");
|
|
lRet = RegSetValueEx(hKey,SERVICE_NAME_GROUP,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(TEXT("")));
|
|
bRet = (ERROR_SUCCESS == lRet)?TRUE:FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm2(hKey2);
|
|
|
|
// 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));
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Phase 2
|
|
//
|
|
if (bRet)
|
|
{
|
|
SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
|
|
if (hSCM)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm1(hSCM);
|
|
|
|
DWORD dwTag;
|
|
TCHAR BinPath[MAX_PATH];
|
|
|
|
StringCchPrintf(BinPath,MAX_PATH,TEXT("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP);
|
|
|
|
TCHAR * pServiceDisplay = new TCHAR[MAX_BUFF];
|
|
wmilib::auto_buffer<TCHAR> rm(pServiceDisplay);
|
|
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)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm2(hService);
|
|
|
|
bRet = ChangeServiceConfig(hService,
|
|
SERVICE_WIN32_SHARE_PROCESS,
|
|
SERVICE_AUTO_START, //SERVICE_DEMAND_START,
|
|
SERVICE_ERROR_IGNORE,
|
|
BinPath,
|
|
NULL,
|
|
NULL,
|
|
TEXT("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()));
|
|
}
|
|
}
|
|
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,
|
|
TEXT("RPCSS\0Eventlog\0\0\0"),
|
|
NULL, //ACCOUNT_NAME,
|
|
NULL);
|
|
if (hService)
|
|
{
|
|
OnDelete<SC_HANDLE,BOOL(*)(SC_HANDLE),CloseServiceHandle> cm3(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;
|
|
}
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Phase 3
|
|
//
|
|
if (bRet)
|
|
{
|
|
HKEY hKey;
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SERVICE_PATH SERVICE_NAME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm3(hKey);
|
|
|
|
HKEY hKey3;
|
|
DWORD dwDisposistion;
|
|
lRet = RegCreateKeyEx(hKey,
|
|
TEXT("Parameters"),
|
|
0,NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey3,
|
|
&dwDisposistion);
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
|
|
|
|
RegSetValueEx(hKey3,TEXT("ServiceDll"),0,REG_EXPAND_SZ,(BYTE *)DLL_PATH,sizeof(DLL_PATH)-sizeof(TCHAR));
|
|
|
|
RegSetValueEx(hKey3,TEXT("ServiceMain"),0,REG_SZ,(BYTE *)ENTRY_POINT,sizeof(ENTRY_POINT)-sizeof(TCHAR));
|
|
|
|
RegCloseKey(hKey3);
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Phase 4
|
|
//
|
|
|
|
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,TEXT("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,TEXT("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];
|
|
ClsidBuff2 = pTmp_;
|
|
WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL);
|
|
#endif
|
|
|
|
StringCchPrintf(ClsidPath,MAX_PATH,TEXT("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,TEXT("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR));
|
|
RegSetValueEx(hKey4,TEXT("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR));
|
|
RegCloseKey(hKey4);
|
|
}
|
|
|
|
StringFromGUID2(CLSID_WbemBackupRestore,ClsidBuff,40);
|
|
#ifdef UNICODE
|
|
ClsidBuff2 = ClsidBuff;
|
|
#else
|
|
WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL);
|
|
#endif
|
|
|
|
StringCchPrintf(ClsidPath,MAX_PATH,TEXT("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,TEXT("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR));
|
|
RegSetValueEx(hKey4,TEXT("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 COM server.
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// S_OK Unregistration was successful
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
LONG lRet;
|
|
|
|
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
|
|
|
|
StringCchPrintf(ClsidPath,MAX_PATH,TEXT("software\\classes\\CLSID\\%s"),ClsidBuff);
|
|
|
|
lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath);
|
|
if (ERROR_SUCCESS != lRet) return E_FAIL;
|
|
|
|
#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
|
|
|
|
StringCchPrintf(ClsidPath,MAX_PATH,TEXT("software\\classes\\CLSID\\%s"),ClsidBuff);
|
|
|
|
lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath);
|
|
if (ERROR_SUCCESS != lRet) return E_FAIL;
|
|
|
|
lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID);
|
|
if (ERROR_SUCCESS != lRet) return E_FAIL;
|
|
|
|
lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID_NAME);
|
|
if (ERROR_SUCCESS != lRet) return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|