272 lines
7.7 KiB
C++
272 lines
7.7 KiB
C++
/*++
|
|
|
|
Copyright (C) 1999-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
BackupRestore.CPP
|
|
|
|
Abstract:
|
|
|
|
Backup Restore Interface.
|
|
|
|
History:
|
|
|
|
paulall 08-Feb-99 Implemented the call-outs to do the backup
|
|
and recovery. Stole lots of code from the core
|
|
to get this working!
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include <wbemint.h>
|
|
#include <cominit.h>
|
|
#include <genutils.h>
|
|
#include <reposit.h>
|
|
#include "wbemcomn.h"
|
|
#include "MRCIClass.h"
|
|
#include "CoreX.h"
|
|
#include "Reg.h"
|
|
#include "BackupRestore.h"
|
|
|
|
BOOL CheckSecurity(LPCTSTR pPriv)
|
|
{
|
|
WbemCoImpersonateClient();
|
|
HANDLE hToken;
|
|
BOOL bRet = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken);
|
|
WbemCoRevertToSelf();
|
|
if(!bRet)
|
|
return FALSE;
|
|
bRet = IsPrivilegePresent(hToken, pPriv);
|
|
CloseHandle(hToken);
|
|
return bRet;
|
|
}
|
|
|
|
CWbemBackupRestore::CWbemBackupRestore(HINSTANCE hInstance) : m_pDbDir(0),
|
|
m_pWorkDir(0), m_hInstance(hInstance)
|
|
{
|
|
m_cRef=0L;
|
|
};
|
|
|
|
|
|
TCHAR *CWbemBackupRestore::GetDbDir()
|
|
{
|
|
if (m_pDbDir == NULL)
|
|
{
|
|
if (m_pWorkDir == NULL)
|
|
{
|
|
Registry r1(WBEM_REG_WBEM);
|
|
if (r1.GetStr(__TEXT("Installation Directory"), &m_pWorkDir))
|
|
{
|
|
ERRORTRACE((LOG_WBEMCORE,"Unable to read 'Installation Directory' from registry\n"));
|
|
return NULL;
|
|
}
|
|
}
|
|
Registry r(WBEM_REG_WINMGMT);
|
|
if (r.GetStr(__TEXT("Repository Directory"), &m_pDbDir))
|
|
{
|
|
m_pDbDir = new TCHAR [lstrlen(m_pWorkDir) + lstrlen(__TEXT("\\Repository")) +1];
|
|
wsprintf(m_pDbDir, __TEXT("%s\\REPOSITORY"), m_pWorkDir);
|
|
|
|
r.SetStr(__TEXT("Repository Directory"), m_pDbDir);
|
|
}
|
|
}
|
|
return m_pDbDir;
|
|
}
|
|
|
|
TCHAR *CWbemBackupRestore::GetFullFilename(const TCHAR *pszFilename)
|
|
{
|
|
const TCHAR *pszDirectory = GetDbDir();
|
|
TCHAR *pszPathFilename = new TCHAR[lstrlen(pszDirectory) + lstrlen(pszFilename) + 2];
|
|
if (pszPathFilename == 0)
|
|
return 0;
|
|
lstrcpy(pszPathFilename, pszDirectory);
|
|
if ((lstrlen(pszPathFilename)) && (pszPathFilename[lstrlen(pszPathFilename)-1] != '\\'))
|
|
{
|
|
lstrcat(pszPathFilename, __TEXT("\\"));
|
|
}
|
|
lstrcat(pszPathFilename, pszFilename);
|
|
|
|
return pszPathFilename;
|
|
}
|
|
TCHAR *CWbemBackupRestore::GetExePath(const TCHAR *pszFilename)
|
|
{
|
|
TCHAR *pszPathFilename = new TCHAR[lstrlen(m_pWorkDir) + lstrlen(pszFilename) + 2];
|
|
if (pszPathFilename == 0)
|
|
return 0;
|
|
lstrcpy(pszPathFilename, m_pWorkDir);
|
|
lstrcat(pszPathFilename, __TEXT("\\"));
|
|
lstrcat(pszPathFilename, pszFilename);
|
|
|
|
return pszPathFilename;
|
|
}
|
|
|
|
HRESULT CWbemBackupRestore::GetDefaultRepDriverClsId(CLSID &clsid)
|
|
{
|
|
Registry r(WBEM_REG_WINMGMT);
|
|
TCHAR *pClsIdStr = 0;
|
|
TCHAR *pFSClsId = __TEXT("{7998dc37-d3fe-487c-a60a-7701fcc70cc6}");
|
|
HRESULT hRes;
|
|
wchar_t Buf[128];
|
|
|
|
if (r.GetStr(__TEXT("Default Repository Driver"), &pClsIdStr))
|
|
{
|
|
// If here, default to FS for now.
|
|
// =====================================
|
|
r.SetStr(__TEXT("Default Repository Driver"), pFSClsId);
|
|
swprintf(Buf, L"%S", pFSClsId);
|
|
hRes = CLSIDFromString(Buf, &clsid);
|
|
return hRes;
|
|
}
|
|
|
|
// If here, we actually retrieved one.
|
|
// ===================================
|
|
swprintf(Buf, L"%S", pClsIdStr);
|
|
hRes = CLSIDFromString(Buf, &clsid);
|
|
delete [] pClsIdStr;
|
|
return hRes;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWbemBackupRestore::Backup()
|
|
//
|
|
// Do the backup.
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CWbemBackupRestore::Backup(LPCWSTR strBackupToFile, long lFlags)
|
|
{
|
|
try
|
|
{
|
|
// !!!!! ***** temporarily disabled until SVCHOST changes are checked in ***** !!!!!
|
|
return WBEM_E_NOT_SUPPORTED;
|
|
|
|
|
|
|
|
// Check security
|
|
EnableAllPrivileges(TOKEN_PROCESS);
|
|
if(!CheckSecurity(SE_BACKUP_NAME))
|
|
return WBEM_E_ACCESS_DENIED;
|
|
|
|
// Check the params
|
|
if (NULL == strBackupToFile || (lFlags != 0))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
// Use GetFileAttributes to validate the path.
|
|
DWORD dwAttributes = GetFileAttributesW(strBackupToFile);
|
|
if (dwAttributes == 0xFFFFFFFF)
|
|
{
|
|
// It failed -- check for a no such file error (in which case, we're ok).
|
|
if (ERROR_FILE_NOT_FOUND != GetLastError())
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// The file already exists -- create mask of the attributes that would make an existing file invalid for use
|
|
DWORD dwMask = FILE_ATTRIBUTE_DEVICE |
|
|
FILE_ATTRIBUTE_DIRECTORY |
|
|
FILE_ATTRIBUTE_OFFLINE |
|
|
FILE_ATTRIBUTE_READONLY |
|
|
FILE_ATTRIBUTE_REPARSE_POINT |
|
|
FILE_ATTRIBUTE_SPARSE_FILE |
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
FILE_ATTRIBUTE_TEMPORARY;
|
|
|
|
if (dwAttributes & dwMask)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Retrieve the CLSID of the default repository driver
|
|
CLSID clsid;
|
|
HRESULT hRes = GetDefaultRepDriverClsId(clsid);
|
|
if (FAILED(hRes))
|
|
return hRes;
|
|
|
|
// Call IWmiDbController to do backup
|
|
IWmiDbController* pController = NULL;
|
|
_IWmiCoreServices *pCoreServices = NULL;
|
|
int nRet = WBEM_NO_ERROR;
|
|
IWbemServices *pServices = NULL;
|
|
|
|
//Make sure the core is initialized...
|
|
hRes = CoCreateInstance(CLSID_IWmiCoreServices, NULL,
|
|
CLSCTX_INPROC_SERVER, IID__IWmiCoreServices,
|
|
(void**)&pCoreServices);
|
|
CReleaseMe rm1(pCoreServices);
|
|
|
|
if (SUCCEEDED(hRes))
|
|
{
|
|
hRes = pCoreServices->GetServices(L"root", NULL,NULL,0, IID_IWbemServices, (LPVOID*)&pServices);
|
|
}
|
|
CReleaseMe rm2(pServices);
|
|
|
|
if (SUCCEEDED(hRes))
|
|
{
|
|
hRes = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IWmiDbController, (LPVOID *) &pController);
|
|
}
|
|
CReleaseMe rm3(pController);
|
|
|
|
if (SUCCEEDED(hRes))
|
|
{
|
|
hRes = pController->Backup(strBackupToFile, lFlags);
|
|
|
|
if (FAILED(hRes))
|
|
{
|
|
nRet = WBEM_E_FAILED;
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
catch (CX_MemoryException)
|
|
{
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
catch (...)
|
|
{
|
|
return WBEM_E_FAILED;
|
|
}
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWbemBackupRestore::Restore()
|
|
//
|
|
// Do the restore.
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CWbemBackupRestore::Restore(LPCWSTR strRestoreFromFile, long lFlags)
|
|
{
|
|
// !!!!! ***** temporarily disabled until SVCHOST changes are checked in ***** !!!!!
|
|
return WBEM_E_NOT_SUPPORTED;
|
|
|
|
|
|
// Check security
|
|
EnableAllPrivileges(TOKEN_PROCESS);
|
|
if(!CheckSecurity(SE_RESTORE_NAME))
|
|
return WBEM_E_ACCESS_DENIED;
|
|
|
|
if(strRestoreFromFile == NULL || (lFlags & ~WBEM_FLAG_BACKUP_RESTORE_FORCE_SHUTDOWN))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFOW si;
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
|
|
wchar_t wcBuff[MAX_PATH+1];
|
|
wsprintfW(wcBuff, L"WinMgmt.exe /restore \"%s\" %d",strRestoreFromFile, lFlags);
|
|
if (CreateProcessW(NULL, wcBuff, 0, 0, FALSE, CREATE_BREAKAWAY_FROM_JOB|DETACHED_PROCESS|CREATE_NO_WINDOW, 0, 0, &si, &pi) == 0)
|
|
{
|
|
return WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING;
|
|
}
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
return S_OK;
|
|
}
|
|
|
|
|