Leaked source code of windows server 2003
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.

1326 lines
45 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. BackupRestore.CPP
  5. Abstract:
  6. Backup Restore Interface.
  7. History:
  8. paulall 08-Feb-99 Implemented the call-outs to do the backup
  9. and recovery. Stole lots of code from the core
  10. to get this working!
  11. --*/
  12. #include "precomp.h"
  13. #include <wbemint.h>
  14. #include <reg.h>
  15. #include <cominit.h> // for WbemCoImpersonate
  16. #include <genutils.h> // for IsPrivilegePresent
  17. #include <arrtempl.h> // for CReleaseMe
  18. #include <CoreX.h> // for CX_MemoryException
  19. #include <reposit.h>
  20. #include "BackupRestore.h"
  21. #include "winmgmt.h"
  22. #include <malloc.h>
  23. #include <helper.h>
  24. #include <aclapi.h>
  25. #define RESTORE_FILE L"repdrvfs.rec"
  26. #define DEFAULT_TIMEOUT_BACKUP (15*60*1000)
  27. HRESULT GetRepositoryDirectory(wchar_t wszRepositoryDirectory[MAX_PATH+1]);
  28. HRESULT DeleteRepository();
  29. HRESULT DeleteSavedRepository(const wchar_t *wszBackupDirectory);
  30. HRESULT DoDeleteContentsOfDirectory(const wchar_t *wszExcludeFile, const wchar_t *wszRepositoryDirectory);
  31. HRESULT DoDeleteDirectory(const wchar_t *wszExcludeFile, const wchar_t *wszParentDirectory, wchar_t *wszSubDirectory);
  32. HRESULT GetRepPath(wchar_t wcsPath[MAX_PATH+1], wchar_t * wcsName);
  33. HRESULT WbemPauseService();
  34. HRESULT WbemContinueService();
  35. HRESULT SaveRepository(wchar_t *wszBackupDirectory);
  36. HRESULT RestoreSavedRepository(const wchar_t *wszBackupDirectory);
  37. HRESULT MoveRepositoryFiles(const wchar_t *wszSourceDirectory, const wchar_t *wszDestinationDirectory, bool bMoveForwards);
  38. BOOL CheckSecurity(LPCTSTR pPriv,HANDLE * phToken = NULL)
  39. {
  40. HRESULT hres = WbemCoImpersonateClient();
  41. if (FAILED(hres))
  42. return FALSE;
  43. HANDLE hToken;
  44. BOOL bRet = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken);
  45. WbemCoRevertToSelf();
  46. if(!bRet)
  47. return FALSE;
  48. bRet = IsPrivilegePresent(hToken, pPriv);
  49. if (phToken)
  50. *phToken = hToken;
  51. else
  52. CloseHandle(hToken);
  53. return bRet;
  54. }
  55. //
  56. //
  57. // Static Initialization
  58. //
  59. //////////////////////////////////////////////////////////////////////
  60. LIST_ENTRY CWbemBackupRestore::s_ListHead = { &CWbemBackupRestore::s_ListHead, &CWbemBackupRestore::s_ListHead };
  61. CStaticCritSec CWbemBackupRestore::s_CritSec;
  62. CWbemBackupRestore::CWbemBackupRestore(HINSTANCE hInstance):
  63. m_cRef(0),
  64. m_pDbDir(0),
  65. m_pWorkDir(0),
  66. m_hInstance(hInstance),
  67. m_pController(0),
  68. m_PauseCalled(0),
  69. m_lResumeCalled(0),
  70. m_Method(0),
  71. m_hTimer(NULL),
  72. m_dwDueTime(DEFAULT_TIMEOUT_BACKUP)
  73. {
  74. DWORD dwTemp;
  75. if (ERROR_SUCCESS == RegGetDWORD(HKEY_LOCAL_MACHINE,
  76. HOME_REG_PATH,
  77. TEXT("PauseResumeTimeOut"),
  78. &dwTemp))
  79. {
  80. m_dwDueTime = dwTemp;
  81. }
  82. CInCritSec ics(&s_CritSec);
  83. InsertTailList(&s_ListHead,&m_ListEntry);
  84. //DBG_PRINTFA((pBuff,"+ (%p)\n",this));
  85. };
  86. CWbemBackupRestore::~CWbemBackupRestore(void)
  87. {
  88. if (m_PauseCalled)
  89. {
  90. Resume(); // Resume will release the IDbController
  91. }
  92. delete [] m_pDbDir;
  93. delete [] m_pWorkDir;
  94. CInCritSec ics(&s_CritSec);
  95. RemoveEntryList(&m_ListEntry);
  96. //DBG_PRINTFA((pBuff,"- (%p)\n",this));
  97. }
  98. TCHAR *CWbemBackupRestore::GetDbDir()
  99. {
  100. if (m_pDbDir == NULL)
  101. {
  102. Registry r(WBEM_REG_WINMGMT);
  103. if (m_pWorkDir == NULL)
  104. {
  105. if (r.GetStr(__TEXT("Working Directory"), &m_pWorkDir))
  106. {
  107. ERRORTRACE((LOG_WINMGMT,"Unable to read 'Installation Directory' from registry\n"));
  108. return NULL;
  109. }
  110. }
  111. if (r.GetStr(__TEXT("Repository Directory"), &m_pDbDir))
  112. {
  113. size_t cchSizeTmp = lstrlen(m_pWorkDir) + lstrlen(__TEXT("\\Repository")) +1;
  114. m_pDbDir = new TCHAR [cchSizeTmp];
  115. if (m_pDbDir)
  116. {
  117. StringCchPrintf(m_pDbDir,cchSizeTmp, __TEXT("%s\\REPOSITORY"), m_pWorkDir);
  118. r.SetStr(__TEXT("Repository Directory"), m_pDbDir);
  119. }
  120. }
  121. }
  122. return m_pDbDir;
  123. }
  124. TCHAR *CWbemBackupRestore::GetFullFilename(const TCHAR *pszFilename)
  125. {
  126. const TCHAR *pszDirectory = GetDbDir();
  127. if (NULL == pszDirectory) return 0;
  128. size_t cchSizeTmp = lstrlen(pszDirectory) + lstrlen(pszFilename) + 2;
  129. TCHAR *pszPathFilename = new TCHAR[cchSizeTmp];
  130. if (pszPathFilename == 0)
  131. return 0;
  132. StringCchCopy(pszPathFilename,cchSizeTmp, pszDirectory);
  133. if ((lstrlen(pszPathFilename)) && (pszPathFilename[lstrlen(pszPathFilename)-1] != '\\'))
  134. {
  135. StringCchCat(pszPathFilename,cchSizeTmp, __TEXT("\\"));
  136. }
  137. StringCchCat(pszPathFilename,cchSizeTmp, pszFilename);
  138. return pszPathFilename;
  139. }
  140. TCHAR *CWbemBackupRestore::GetExePath(const TCHAR *pszFilename)
  141. {
  142. size_t cchSizeTmp = lstrlen(m_pWorkDir) + lstrlen(pszFilename) + 2;
  143. TCHAR *pszPathFilename = new TCHAR[cchSizeTmp];
  144. if (pszPathFilename == 0)
  145. return 0;
  146. StringCchCopy(pszPathFilename,cchSizeTmp, m_pWorkDir);
  147. StringCchCat(pszPathFilename,cchSizeTmp, __TEXT("\\"));
  148. StringCchCat(pszPathFilename,cchSizeTmp, pszFilename);
  149. return pszPathFilename;
  150. }
  151. HRESULT CWbemBackupRestore::GetDefaultRepDriverClsId(CLSID &clsid)
  152. {
  153. Registry r(WBEM_REG_WINMGMT);
  154. TCHAR *pClsIdStr = 0;
  155. TCHAR *pFSClsId = __TEXT("{7998dc37-d3fe-487c-a60a-7701fcc70cc6}");
  156. HRESULT hRes;
  157. TCHAR Buf[128];
  158. if (r.GetStr(__TEXT("Default Repository Driver"), &pClsIdStr))
  159. {
  160. // If here, default to FS for now.
  161. // =====================================
  162. r.SetStr(__TEXT("Default Repository Driver"), pFSClsId);
  163. StringCchPrintf(Buf,128, __TEXT("%s"), pFSClsId);
  164. hRes = CLSIDFromString(Buf, &clsid);
  165. return hRes;
  166. }
  167. // If here, we actually retrieved one.
  168. // ===================================
  169. StringCchPrintf(Buf,128, __TEXT("%s"), pClsIdStr);
  170. hRes = CLSIDFromString(Buf, &clsid);
  171. delete [] pClsIdStr;
  172. return hRes;
  173. }
  174. //
  175. //
  176. //
  177. /////////////////////////////////////////////////////
  178. DWORD CheckTokenForFileAccess(HANDLE hToken,
  179. LPCWSTR pBackupFile)
  180. {
  181. DWORD dwRes;
  182. SECURITY_INFORMATION SecInfo = DACL_SECURITY_INFORMATION |
  183. SACL_SECURITY_INFORMATION |
  184. OWNER_SECURITY_INFORMATION |
  185. GROUP_SECURITY_INFORMATION;
  186. PSECURITY_DESCRIPTOR pSecDes = NULL;
  187. if (ERROR_SUCCESS != (dwRes = GetNamedSecurityInfo((LPWSTR)pBackupFile,
  188. SE_FILE_OBJECT,
  189. SecInfo,
  190. NULL,NULL,NULL,NULL,
  191. &pSecDes))) return dwRes;
  192. OnDelete<HLOCAL,HLOCAL(*)(HLOCAL),LocalFree> fm(pSecDes);
  193. BOOL bCheckRes = FALSE;
  194. DWORD DesiredMask = FILE_GENERIC_WRITE;
  195. DWORD ReturnedMask = 0;
  196. GENERIC_MAPPING Mapping= {0,0,0,0};
  197. struct tagPrivSet : PRIVILEGE_SET {
  198. LUID_AND_ATTRIBUTES m_[SE_MAX_WELL_KNOWN_PRIVILEGE];
  199. } PrivSec;
  200. DWORD dwPrivSecLen = sizeof(PrivSec);
  201. if (FALSE == AccessCheck(pSecDes,
  202. hToken,
  203. DesiredMask,
  204. &Mapping,
  205. &PrivSec,
  206. &dwPrivSecLen,
  207. &ReturnedMask,
  208. &bCheckRes)) return GetLastError();
  209. if (FALSE == bCheckRes)
  210. return ERROR_ACCESS_DENIED;
  211. return ERROR_SUCCESS;
  212. }
  213. //
  214. // to debug Volume Snapshot failure in IOStress we introduced
  215. // some self instrumentation that did relay on RtlCaptureStackBacktrace
  216. // that function works only if there is a proper stack frame
  217. // the general trick to force stack frames on i386 is the usage of _alloca
  218. //
  219. //#ifdef _X86_
  220. // DWORD * pDW = (DWORD *)_alloca(sizeof(DWORD));
  221. //#endif
  222. // enable generation of stack frames here
  223. #pragma optimize( "y", off )
  224. //***************************************************************************
  225. //
  226. // CWbemBackupRestore::Backup()
  227. //
  228. // Do the backup.
  229. //
  230. //***************************************************************************
  231. HRESULT CWbemBackupRestore::Backup(LPCWSTR strBackupToFile, long lFlags)
  232. {
  233. //DBG_PRINTFA((pBuff,"(%p)->Backup\n",this));
  234. m_Method |= mBackup;
  235. m_CallerId = GetCurrentThreadId();
  236. ULONG Hash;
  237. RtlCaptureStackBackTrace(0,MaxTraceSize,m_Trace,&Hash);
  238. if (m_PauseCalled)
  239. {
  240. // invalid state machine
  241. return WBEM_E_INVALID_OPERATION;
  242. }
  243. else
  244. {
  245. try
  246. {
  247. // Check security
  248. EnableAllPrivileges(TOKEN_PROCESS);
  249. HANDLE hToken = NULL;
  250. BOOL bCheck = CheckSecurity(SE_BACKUP_NAME,&hToken);
  251. if(!bCheck)
  252. {
  253. if (hToken) CloseHandle(hToken);
  254. return WBEM_E_ACCESS_DENIED;
  255. }
  256. OnDelete<HANDLE,BOOL(*)(HANDLE),CloseHandle> cm(hToken);
  257. // Check the params
  258. if (NULL == strBackupToFile || (lFlags != 0))
  259. return WBEM_E_INVALID_PARAMETER;
  260. // Use GetFileAttributes to validate the path.
  261. DWORD dwAttributes = GetFileAttributesW(strBackupToFile);
  262. if (dwAttributes == 0xFFFFFFFF)
  263. {
  264. // It failed -- check for a no such file error (in which case, we're ok).
  265. if ((ERROR_FILE_NOT_FOUND != GetLastError()) && (ERROR_PATH_NOT_FOUND != GetLastError()))
  266. {
  267. return WBEM_E_INVALID_PARAMETER;
  268. }
  269. }
  270. else
  271. {
  272. // The file already exists -- create mask of the attributes that would make an existing file invalid for use
  273. DWORD dwMask = FILE_ATTRIBUTE_DEVICE |
  274. FILE_ATTRIBUTE_DIRECTORY |
  275. FILE_ATTRIBUTE_OFFLINE |
  276. FILE_ATTRIBUTE_READONLY |
  277. FILE_ATTRIBUTE_REPARSE_POINT |
  278. FILE_ATTRIBUTE_SPARSE_FILE |
  279. FILE_ATTRIBUTE_SYSTEM |
  280. FILE_ATTRIBUTE_TEMPORARY;
  281. if (dwAttributes & dwMask)
  282. return WBEM_E_INVALID_PARAMETER;
  283. //
  284. // we are doing backup on behaf of clients
  285. // from localsystem, so attempt to do accesscheck here
  286. // if the file already exists
  287. //
  288. if (ERROR_SUCCESS != CheckTokenForFileAccess(hToken,strBackupToFile))
  289. return WBEM_E_ACCESS_DENIED;
  290. }
  291. //Now we need to determine if we are a disk file or not
  292. {
  293. HANDLE hFile = CreateFileW(strBackupToFile, 0, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL);
  294. if (hFile != INVALID_HANDLE_VALUE)
  295. {
  296. DWORD dwType = GetFileType(hFile);
  297. CloseHandle(hFile);
  298. if (dwType != FILE_TYPE_DISK)
  299. return WBEM_E_INVALID_PARAMETER;
  300. }
  301. }
  302. // Retrieve the CLSID of the default repository driver
  303. CLSID clsid;
  304. HRESULT hRes = GetDefaultRepDriverClsId(clsid);
  305. if (FAILED(hRes))
  306. return hRes;
  307. // Call IWmiDbController to do backup
  308. IWmiDbController* pController = NULL;
  309. _IWmiCoreServices *pCoreServices = NULL;
  310. IWbemServices *pServices = NULL;
  311. //Make sure the core is initialized...
  312. hRes = CoCreateInstance(CLSID_IWmiCoreServices, NULL,
  313. CLSCTX_INPROC_SERVER, IID__IWmiCoreServices,
  314. (void**)&pCoreServices);
  315. CReleaseMe rm1(pCoreServices);
  316. if (SUCCEEDED(hRes))
  317. {
  318. hRes = pCoreServices->GetServices(L"root", NULL,NULL,0, IID_IWbemServices, (LPVOID*)&pServices);
  319. }
  320. CReleaseMe rm2(pServices);
  321. if (SUCCEEDED(hRes))
  322. {
  323. hRes = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IWmiDbController, (LPVOID *) &pController);
  324. }
  325. CReleaseMe rm3(pController);
  326. if (SUCCEEDED(hRes))
  327. {
  328. //DBG_PRINTFA((pBuff,"(%p)->RealBackup\n",this));
  329. hRes = pController->Backup(strBackupToFile, lFlags);
  330. }
  331. return hRes;
  332. }
  333. catch (CX_MemoryException)
  334. {
  335. return WBEM_E_OUT_OF_MEMORY;
  336. }
  337. catch (...)
  338. {
  339. return WBEM_E_CRITICAL_ERROR;
  340. }
  341. }
  342. }
  343. //***************************************************************************
  344. //
  345. // CWbemBackupRestore::Restore()
  346. //
  347. // Do the restore.
  348. //
  349. //***************************************************************************
  350. HRESULT CWbemBackupRestore::Restore(LPCWSTR strRestoreFromFile, long lFlags)
  351. {
  352. //DBG_PRINTFA((pBuff,"(%p)->Restore\n",this));
  353. m_Method |= mRestore;
  354. m_CallerId = GetCurrentThreadId();
  355. ULONG Hash;
  356. RtlCaptureStackBackTrace(0,MaxTraceSize,m_Trace,&Hash);
  357. if (m_PauseCalled)
  358. {
  359. // invalid state machine
  360. return WBEM_E_INVALID_OPERATION;
  361. }
  362. else
  363. {
  364. try
  365. {
  366. HRESULT hr = WBEM_S_NO_ERROR;
  367. // Check security
  368. EnableAllPrivileges(TOKEN_PROCESS);
  369. if(!CheckSecurity(SE_RESTORE_NAME))
  370. hr = WBEM_E_ACCESS_DENIED;
  371. // Check the params
  372. if (SUCCEEDED(hr) && ((NULL == strRestoreFromFile) || (lFlags & ~WBEM_FLAG_BACKUP_RESTORE_FORCE_SHUTDOWN)))
  373. hr = WBEM_E_INVALID_PARAMETER;
  374. // Use GetFileAttributes to validate the path.
  375. if (SUCCEEDED(hr))
  376. {
  377. DWORD dwAttributes = GetFileAttributesW(strRestoreFromFile);
  378. if (dwAttributes == 0xFFFFFFFF)
  379. {
  380. hr = WBEM_E_INVALID_PARAMETER;
  381. }
  382. else
  383. {
  384. // The file exists -- create mask of the attributes that would make an existing file invalid for use
  385. DWORD dwMask = FILE_ATTRIBUTE_DEVICE |
  386. FILE_ATTRIBUTE_DIRECTORY |
  387. FILE_ATTRIBUTE_OFFLINE |
  388. FILE_ATTRIBUTE_REPARSE_POINT |
  389. FILE_ATTRIBUTE_SPARSE_FILE;
  390. if (dwAttributes & dwMask)
  391. hr = WBEM_E_INVALID_PARAMETER;
  392. }
  393. }
  394. //Now we need to determine if we are a disk file or not
  395. if (SUCCEEDED(hr))
  396. {
  397. HANDLE hFile = CreateFileW(strRestoreFromFile, 0, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL);
  398. if (hFile == INVALID_HANDLE_VALUE)
  399. {
  400. return WBEM_E_INVALID_PARAMETER;
  401. }
  402. else
  403. {
  404. DWORD dwType = GetFileType(hFile);
  405. CloseHandle(hFile);
  406. if (dwType != FILE_TYPE_DISK)
  407. return WBEM_E_INVALID_PARAMETER;
  408. }
  409. }
  410. //**************************************************
  411. // Shutdown the core if it is running
  412. // and make sure it does not start up while we are
  413. // preparing to restore...
  414. //**************************************************
  415. bool bPaused = false;
  416. if (SUCCEEDED(hr))
  417. {
  418. hr = WbemPauseService();
  419. if (SUCCEEDED(hr))
  420. bPaused=true;
  421. }
  422. //**************************************************
  423. // Now we need to copy over the <restore file> into
  424. // the repository directory
  425. // This must be done before the repository rename
  426. // because we don't know if the rename will affect
  427. // the location of the file, thus making
  428. // strRestoreFromFile invalid.
  429. //**************************************************
  430. wchar_t szRecoveryActual[MAX_PATH+1] = { 0 };
  431. if (SUCCEEDED(hr))
  432. hr = GetRepPath(szRecoveryActual, RESTORE_FILE);
  433. bool bRestoreFileCopied = false;
  434. if (SUCCEEDED(hr))
  435. {
  436. if(wbem_wcsicmp(szRecoveryActual, strRestoreFromFile))
  437. {
  438. DeleteFileW(szRecoveryActual);
  439. if (!CopyFileW(strRestoreFromFile, szRecoveryActual, FALSE))
  440. hr = WBEM_E_FAILED;
  441. else
  442. bRestoreFileCopied = true;
  443. }
  444. }
  445. //**************************************************
  446. // Now we need to rename the existing repository so
  447. // that we can restore it in the event of a failure.
  448. // We also need to create a new empty repository
  449. // directory and recopy the <restore file> into it
  450. // from the now renamed original repository directory.
  451. //**************************************************
  452. wchar_t wszRepositoryOrg[MAX_PATH+1] = { 0 };
  453. wchar_t wszRepositoryBackup[MAX_PATH+1] = { 0 };
  454. if (SUCCEEDED(hr))
  455. {
  456. hr = SaveRepository(wszRepositoryBackup); //Moves the files into the backup directory!
  457. }
  458. //******************************************************************
  459. // Regardless of whether we succeeded or failed the calls above,
  460. // we need to restart the core or we leave WMI in an unusable state.
  461. // However, we don't want to lose knowledge of any prior failure,
  462. // so we use a different HRESULT variable
  463. //******************************************************************
  464. HRESULT hrContinue = 0;
  465. if (bPaused)
  466. hrContinue = WbemContinueService();
  467. if (SUCCEEDED(hr) && SUCCEEDED(hrContinue))
  468. {
  469. //**************************************************
  470. //Connecting to winmgmt will now result in this
  471. //backup file getting loaded
  472. //**************************************************
  473. { //Scoping for destruction of COM objects before CoUninitialize!
  474. IWbemLocator *pLocator = NULL;
  475. hr = CoCreateInstance(CLSID_WbemLocator,NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator,(void**)&pLocator);
  476. CReleaseMe relMe(pLocator);
  477. if (SUCCEEDED(hr))
  478. {
  479. IWbemServices *pNamespace = NULL;
  480. BSTR tmpStr = SysAllocString(L"root");
  481. CSysFreeMe sysFreeMe(tmpStr);
  482. if (tmpStr == NULL)
  483. hr = WBEM_E_OUT_OF_MEMORY;
  484. if (SUCCEEDED(hr))
  485. {
  486. HKEY hKeyLoc;
  487. LONG lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,WBEM_REG_WINMGMT,0,KEY_SET_VALUE,&hKeyLoc);
  488. if (ERROR_SUCCESS != lRes) hr = HRESULT_FROM_WIN32(lRes);
  489. if (SUCCEEDED(hr))
  490. {
  491. RegDeleteValue(hKeyLoc,L"LocaleUpgrade");
  492. RegCloseKey(hKeyLoc);
  493. hr = pLocator->ConnectServer(tmpStr, NULL, NULL, NULL, NULL, NULL, NULL, &pNamespace);
  494. CReleaseMe relMe4(pNamespace);
  495. //If connect server failed, then we want a generic failure error code!
  496. if (hr == WBEM_E_INITIALIZATION_FAILURE)
  497. hr = WBEM_E_FAILED;
  498. }
  499. }
  500. }
  501. }
  502. if (FAILED(hr))
  503. {
  504. // something failed, so we need to put back the original repository
  505. // - pause service
  506. // - delete failed repository
  507. // - rename the backed up repository
  508. // - restart the service
  509. HRESULT hres = WbemPauseService();
  510. if (SUCCEEDED(hres))
  511. hres = DeleteRepository();
  512. if (SUCCEEDED(hres))
  513. {
  514. hres = RestoreSavedRepository(wszRepositoryBackup);
  515. }
  516. if (SUCCEEDED(hres))
  517. hres = WbemContinueService();
  518. }
  519. else
  520. {
  521. // restore succeeded, so delete the saved original repository
  522. DeleteSavedRepository(wszRepositoryBackup);
  523. }
  524. }
  525. //Delete our copy of the restore file if we made one
  526. if (bRestoreFileCopied)
  527. {
  528. if (*szRecoveryActual)
  529. DeleteFileW(szRecoveryActual);
  530. }
  531. //**************************************************
  532. // All done!
  533. // Return the more interesting of the two HRESULTs
  534. //**************************************************
  535. if (SUCCEEDED(hr))
  536. return hrContinue;
  537. else
  538. return hr;
  539. }
  540. catch (CX_MemoryException)
  541. {
  542. return WBEM_E_OUT_OF_MEMORY;
  543. }
  544. catch (...)
  545. {
  546. return WBEM_E_CRITICAL_ERROR;
  547. }
  548. }
  549. }
  550. //***************************************************************************
  551. //
  552. // EXTENDED Interface
  553. //
  554. //***************************************************************************
  555. HRESULT CWbemBackupRestore::Pause()
  556. {
  557. //DBG_PRINTFA((pBuff,"(%p)->Pause\n",this));
  558. m_Method |= mPause;
  559. m_CallerId = GetCurrentThreadId();
  560. ULONG Hash;
  561. RtlCaptureStackBackTrace(0,MaxTraceSize,m_Trace,&Hash);
  562. if (InterlockedCompareExchange(&m_PauseCalled,1,0))
  563. return WBEM_E_INVALID_OPERATION;
  564. try
  565. {
  566. HRESULT hRes = WBEM_NO_ERROR;
  567. // determine if we are already paused
  568. // Check security
  569. if (SUCCEEDED(hRes))
  570. {
  571. EnableAllPrivileges(TOKEN_PROCESS);
  572. if(!CheckSecurity(SE_BACKUP_NAME))
  573. hRes = WBEM_E_ACCESS_DENIED;
  574. }
  575. // Retrieve the CLSID of the default repository driver
  576. CLSID clsid;
  577. if (SUCCEEDED(hRes))
  578. {
  579. hRes = GetDefaultRepDriverClsId(clsid);
  580. }
  581. //Make sure the core is initialized...
  582. _IWmiCoreServices *pCoreServices = NULL;
  583. if (SUCCEEDED(hRes))
  584. {
  585. hRes = CoCreateInstance(CLSID_IWmiCoreServices, NULL, CLSCTX_INPROC_SERVER, IID__IWmiCoreServices, (void**)&pCoreServices);
  586. }
  587. CReleaseMe rm1(pCoreServices);
  588. IWbemServices *pServices = NULL;
  589. if (SUCCEEDED(hRes))
  590. {
  591. hRes = pCoreServices->GetServices(L"root", NULL,NULL,0, IID_IWbemServices, (LPVOID*)&pServices);
  592. }
  593. CReleaseMe rm2(pServices);
  594. // Call IWmiDbController to do UnlockRepository
  595. if (SUCCEEDED(hRes))
  596. {
  597. hRes = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IWmiDbController, (LPVOID *) &m_pController);
  598. }
  599. if (SUCCEEDED(hRes))
  600. {
  601. hRes = m_pController->LockRepository();
  602. //DBG_PRINTFA((pBuff,"(%p)->Pause : LockRepository %08x\n",this,hRes));
  603. if (FAILED(hRes))
  604. {
  605. m_pController->Release();
  606. m_pController = reinterpret_cast<IWmiDbController*>(-1); // For debug
  607. }
  608. else
  609. {
  610. this->AddRef();
  611. if (CreateTimerQueueTimer(&m_hTimer,NULL,
  612. CWbemBackupRestore::TimeOutCallback,
  613. this,
  614. m_dwDueTime,
  615. 0,
  616. WT_EXECUTEINTIMERTHREAD|WT_EXECUTEONLYONCE))
  617. {
  618. // we are OK here, we have a timer that will save the repository lock
  619. //DBG_PRINTFA((pBuff,"+ (%p)->m_hTimer = %p\n",this,m_hTimer));
  620. }
  621. else
  622. {
  623. this->Release();
  624. // we are going to be left locked in case a bad client exists
  625. }
  626. }
  627. }
  628. if (FAILED(hRes))
  629. {
  630. InterlockedDecrement(&m_PauseCalled);
  631. }
  632. return hRes;
  633. }
  634. catch (CX_MemoryException)
  635. {
  636. InterlockedDecrement(&m_PauseCalled);
  637. return WBEM_E_OUT_OF_MEMORY;
  638. }
  639. catch (...)
  640. {
  641. InterlockedDecrement(&m_PauseCalled);
  642. return WBEM_E_CRITICAL_ERROR;
  643. }
  644. }
  645. HRESULT CWbemBackupRestore::pResume()
  646. {
  647. //DBG_PRINTFA((pBuff,"(%p)->pResume\n",this));
  648. if (0 == m_pController ||
  649. -1 == (LONG_PTR)m_pController )
  650. return WBEM_E_INVALID_OPERATION;
  651. HRESULT hRes = m_pController->UnlockRepository();
  652. m_pController->Release();
  653. m_pController = 0;
  654. // clean the state machine
  655. InterlockedDecrement(&m_PauseCalled);
  656. m_lResumeCalled = 0; // Resume is completed here
  657. return hRes;
  658. }
  659. HRESULT CWbemBackupRestore::Resume()
  660. {
  661. //DBG_PRINTFA((pBuff,"(%p)->Resume\n",this));
  662. m_Method |= mResume;
  663. m_CallerId = GetCurrentThreadId();
  664. ULONG Hash;
  665. RtlCaptureStackBackTrace(0,MaxTraceSize,m_Trace,&Hash);
  666. if (!m_PauseCalled)
  667. {
  668. // invalid state machine pause without resume
  669. return WBEM_E_INVALID_OPERATION;
  670. }
  671. if (InterlockedCompareExchange(&m_lResumeCalled,1,0))
  672. {
  673. // the time-out-thread beat us
  674. return WBEM_E_TIMED_OUT;
  675. }
  676. else
  677. {
  678. HANDLE hTimer = m_hTimer;
  679. m_hTimer = NULL;
  680. //DBG_PRINTFA((pBuff,"- (%p)->m_hTimer = %p\n",this,hTimer));
  681. DeleteTimerQueueTimer(NULL,hTimer,INVALID_HANDLE_VALUE);
  682. this->Release(); //compensate the Addref in the Pause
  683. return pResume();
  684. }
  685. }
  686. VOID CALLBACK
  687. CWbemBackupRestore::TimeOutCallback(PVOID lpParameter,
  688. BOOLEAN TimerOrWaitFired)
  689. {
  690. //DBG_PRINTFA((pBuff,"(%p)->TimeOutCallback\n",lpParameter));
  691. CWbemBackupRestore * pBackupRes= (CWbemBackupRestore *)lpParameter;
  692. if (InterlockedCompareExchange(&pBackupRes->m_lResumeCalled,1,0))
  693. {
  694. // the Resume call beat us
  695. // the Resume will DelteTimer and Release us
  696. return;
  697. }
  698. else
  699. {
  700. HANDLE hTimer = pBackupRes->m_hTimer;
  701. pBackupRes->m_hTimer = NULL;
  702. DeleteTimerQueueTimer(NULL,hTimer,NULL);
  703. HRESULT hrLog = pBackupRes->pResume();
  704. ERRORTRACE((LOG_WINMGMT,"Forcing a IWbemBackupRestoreEx::Resume after %x ms hr = %08x\n",pBackupRes->m_dwDueTime,hrLog));
  705. pBackupRes->Release(); //compensate the Addref in the Pause
  706. //DBG_PRINTFA((pBuff,"- (%p)->m_hTimer = %p\n",lpParameter,hTimer));
  707. }
  708. }
  709. #pragma optimize( "", on )
  710. /******************************************************************************
  711. *
  712. * GetRepositoryDirectory
  713. *
  714. * Description:
  715. * Retrieves the location of the repository directory from the registry.
  716. *
  717. * Parameters:
  718. * wszRepositoryDirectory: Array to store location in.
  719. *
  720. * Return:
  721. * HRESULT: WBEM_S_NO_ERROR If successful
  722. * WBEM_E_OUT_OF_MEMORY If out of memory
  723. * WBEM_E_FAILED If anything else failed
  724. *
  725. ******************************************************************************
  726. */
  727. HRESULT GetRepositoryDirectory(wchar_t wszRepositoryDirectory[MAX_PATH+1])
  728. {
  729. HKEY hKey;
  730. long lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  731. L"SOFTWARE\\Microsoft\\WBEM\\CIMOM",
  732. 0,
  733. KEY_READ,
  734. &hKey);
  735. if (ERROR_SUCCESS != lRes) return WBEM_E_FAILED;
  736. OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm(hKey);
  737. wchar_t wszTmp[MAX_PATH + 1];
  738. DWORD dwType;
  739. DWORD dwLen = sizeof(wchar_t) * (MAX_PATH + 1);
  740. lRes = RegQueryValueExW(hKey,
  741. L"Repository Directory",
  742. NULL,
  743. &dwType,
  744. (LPBYTE)wszTmp,
  745. &dwLen);
  746. if (ERROR_SUCCESS != lRes) return WBEM_E_FAILED;
  747. if (REG_EXPAND_SZ != dwType) return WBEM_E_FAILED;
  748. if (ExpandEnvironmentStringsW(wszTmp,wszRepositoryDirectory, MAX_PATH + 1) == 0)
  749. return WBEM_E_FAILED;
  750. DWORD dwOutLen = wcslen(wszRepositoryDirectory);
  751. if (dwOutLen < 2) return WBEM_E_FAILED; // at least 'c:'
  752. if (wszRepositoryDirectory[dwOutLen-1] == L'\\')
  753. wszRepositoryDirectory[dwOutLen-1] = L'\0';
  754. return WBEM_S_NO_ERROR;
  755. }
  756. /******************************************************************************
  757. *
  758. * CRepositoryPackager::DeleteRepository
  759. *
  760. * Description:
  761. * Delete all the files associated with the repository
  762. *
  763. * Parameters:
  764. * <none>
  765. *
  766. * Return:
  767. * HRESULT: WBEM_S_NO_ERROR If successful
  768. * WBEM_E_OUT_OF_MEMORY If out of memory
  769. * WBEM_E_FAILED If anything else failed
  770. *
  771. ******************************************************************************
  772. */
  773. HRESULT DeleteRepository()
  774. {
  775. HRESULT hr = WBEM_S_NO_ERROR;
  776. wchar_t *wszRepositoryOrg = new wchar_t[MAX_PATH+1];
  777. CVectorDeleteMe<wchar_t> vdm1(wszRepositoryOrg);
  778. if (!wszRepositoryOrg)
  779. hr = WBEM_E_OUT_OF_MEMORY;
  780. if (SUCCEEDED(hr))
  781. hr = GetRepositoryDirectory(wszRepositoryOrg);
  782. //MOVE EACH OF THE FILES, ONE BY ONE
  783. for (int i = 0; SUCCEEDED(hr) && (i != 6); i++)
  784. {
  785. static wchar_t *filename[] = { L"\\$winmgmt.cfg", L"\\index.btr", L"\\objects.data", L"\\Mapping1.map", L"\\Mapping2.map", L"Mapping.Ver"};
  786. wchar_t *wszDestinationFile = new wchar_t[MAX_PATH+1];
  787. CVectorDeleteMe<wchar_t> vdm2(wszDestinationFile);
  788. if (!wszDestinationFile)
  789. hr = WBEM_E_OUT_OF_MEMORY;
  790. else
  791. {
  792. StringCchCopy(wszDestinationFile,MAX_PATH+1, wszRepositoryOrg);
  793. if (i != 0)
  794. {
  795. StringCchCat(wszDestinationFile,MAX_PATH+1, L"\\fs");
  796. }
  797. StringCchCat(wszDestinationFile,MAX_PATH+1, filename[i]);
  798. if (!DeleteFileW(wszDestinationFile))
  799. {
  800. if ((GetLastError() != ERROR_FILE_NOT_FOUND) && (GetLastError() != ERROR_PATH_NOT_FOUND))
  801. {
  802. hr = WBEM_E_FAILED;
  803. break;
  804. }
  805. }
  806. }
  807. }
  808. return hr;
  809. }
  810. /******************************************************************************
  811. *
  812. * DoDeleteContentsOfDirectory
  813. *
  814. * Description:
  815. * Given a directory, iterates through all files and directories and
  816. * calls into the function to delete it.
  817. *
  818. * Parameters:
  819. * wszRepositoryDirectory: Directory to process
  820. *
  821. * Return:
  822. * HRESULT: WBEM_S_NO_ERROR If successful
  823. * WBEM_E_OUT_OF_MEMORY If out of memory
  824. * WBEM_E_FAILED If anything else failed
  825. *
  826. ******************************************************************************
  827. */
  828. HRESULT DoDeleteContentsOfDirectory(const wchar_t *wszExcludeFile, const wchar_t *wszRepositoryDirectory)
  829. {
  830. HRESULT hres = WBEM_S_NO_ERROR;
  831. wchar_t *wszFullFileName = new wchar_t[MAX_PATH+1];
  832. if (wszFullFileName == NULL)
  833. return WBEM_E_OUT_OF_MEMORY;
  834. CVectorDeleteMe<wchar_t> dm_(wszFullFileName);
  835. //create file search pattern...
  836. wchar_t *wszSearchPattern = new wchar_t[MAX_PATH+1];
  837. if (wszSearchPattern == NULL)
  838. return WBEM_E_OUT_OF_MEMORY;
  839. CVectorDeleteMe<wchar_t> dm1_(wszSearchPattern);
  840. StringCchCopy(wszSearchPattern,MAX_PATH+1, wszRepositoryDirectory);
  841. StringCchCat(wszSearchPattern,MAX_PATH+1, L"\\*");
  842. WIN32_FIND_DATAW findFileData;
  843. HANDLE hff = INVALID_HANDLE_VALUE;
  844. //Start the file iteration in this directory...
  845. hff = FindFirstFileW(wszSearchPattern, &findFileData);
  846. if (hff == INVALID_HANDLE_VALUE)
  847. {
  848. hres = WBEM_E_FAILED;
  849. }
  850. if (SUCCEEDED(hres))
  851. {
  852. do
  853. {
  854. //If we have a filename of '.' or '..' we ignore it...
  855. if ((wcscmp(findFileData.cFileName, L".") == 0) ||
  856. (wcscmp(findFileData.cFileName, L"..") == 0))
  857. {
  858. //Do nothing with these...
  859. }
  860. else if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  861. {
  862. //This is a directory, so we need to deal with that...
  863. hres = DoDeleteDirectory(wszExcludeFile, wszRepositoryDirectory, findFileData.cFileName);
  864. if (FAILED(hres))
  865. break;
  866. }
  867. else
  868. {
  869. //This is a file, so we need to deal with that...
  870. StringCchCopy(wszFullFileName,MAX_PATH+1, wszRepositoryDirectory);
  871. StringCchCat(wszFullFileName,MAX_PATH+1, L"\\");
  872. StringCchCat(wszFullFileName,MAX_PATH+1, findFileData.cFileName);
  873. //Make sure this is not the excluded filename...
  874. if (wbem_wcsicmp(wszFullFileName, wszExcludeFile) != 0)
  875. {
  876. if (!DeleteFileW(wszFullFileName))
  877. {
  878. hres = WBEM_E_FAILED;
  879. break;
  880. }
  881. }
  882. }
  883. } while (FindNextFileW(hff, &findFileData));
  884. }
  885. DWORD dwLastErrBeforeFindClose = GetLastError();
  886. if (hff != INVALID_HANDLE_VALUE)
  887. FindClose(hff);
  888. if (ERROR_SUCCESS != dwLastErrBeforeFindClose &&
  889. ERROR_NO_MORE_FILES != dwLastErrBeforeFindClose)
  890. {
  891. hres = WBEM_E_FAILED;
  892. }
  893. return hres;
  894. }
  895. /******************************************************************************
  896. *
  897. * DoDeleteDirectory
  898. *
  899. * Description:
  900. * This is the code which processes a directory. It iterates through
  901. * all files and directories in that directory.
  902. *
  903. * Parameters:
  904. * wszParentDirectory: Full path of parent directory
  905. * eszSubDirectory: Name of sub-directory to process
  906. *
  907. * Return:
  908. * HRESULT: WBEM_S_NO_ERROR If successful
  909. * WBEM_E_OUT_OF_MEMORY If out of memory
  910. * WBEM_E_FAILED If anything else failed
  911. *
  912. ******************************************************************************
  913. */
  914. HRESULT DoDeleteDirectory(const wchar_t *wszExcludeFile,
  915. const wchar_t *wszParentDirectory,
  916. wchar_t *wszSubDirectory)
  917. {
  918. HRESULT hres = WBEM_S_NO_ERROR;
  919. //Get full path of new directory...
  920. wchar_t *wszFullDirectoryName = new wchar_t[MAX_PATH+1];
  921. if (wszFullDirectoryName == NULL)
  922. return WBEM_E_OUT_OF_MEMORY;
  923. CVectorDeleteMe<wchar_t> dm_(wszFullDirectoryName);
  924. StringCchCopy(wszFullDirectoryName,MAX_PATH+1, wszParentDirectory);
  925. StringCchCat(wszFullDirectoryName,MAX_PATH+1, L"\\");
  926. StringCchCat(wszFullDirectoryName,MAX_PATH+1, wszSubDirectory);
  927. //delete the contents of that directory...
  928. hres = DoDeleteContentsOfDirectory(wszExcludeFile, wszFullDirectoryName);
  929. // now that the directory is empty, remove it
  930. if (!RemoveDirectoryW(wszFullDirectoryName))
  931. { //If a remove directory fails, it may be because our excluded file is in it!
  932. }
  933. return hres;
  934. }
  935. /******************************************************************************
  936. *
  937. * GetRepPath
  938. *
  939. * Description:
  940. * Gets the repository path and appends the filename to the end
  941. *
  942. * Parameters:
  943. * wcsPath: repository path with filename appended
  944. * wcsName: name of file to append
  945. *
  946. * Return:
  947. * HRESULT: WBEM_S_NO_ERROR If successful
  948. * WBEM_E_FAILED If anything failed
  949. *
  950. ******************************************************************************
  951. */
  952. HRESULT GetRepPath(wchar_t wcsPath[MAX_PATH+1], wchar_t * wcsName)
  953. {
  954. HKEY hKey;
  955. long lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  956. L"SOFTWARE\\Microsoft\\WBEM\\CIMOM",
  957. 0, KEY_READ, &hKey);
  958. if (ERROR_SUCCESS != lRes) return WBEM_E_FAILED;
  959. OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cm(hKey);
  960. wchar_t wszTmp[MAX_PATH+1];
  961. DWORD dwLen = sizeof(wchar_t) * (MAX_PATH+1);
  962. DWORD dwType;
  963. lRes = RegQueryValueExW(hKey,
  964. L"Repository Directory",
  965. NULL,&dwType,
  966. (LPBYTE)(wchar_t*)wszTmp,
  967. &dwLen);
  968. if (ERROR_SUCCESS != lRes) return WBEM_E_FAILED;
  969. if(REG_EXPAND_SZ != dwType) return WBEM_E_FAILED;
  970. if (ExpandEnvironmentStringsW(wszTmp, wcsPath, MAX_PATH+1) == 0)
  971. return WBEM_E_FAILED;
  972. DWORD dwOutLen = wcslen(wcsPath);
  973. if (dwOutLen < 2 ) return WBEM_E_FAILED; // at least 'c:'
  974. if (wcsPath[dwOutLen-1] != L'\\')
  975. StringCchCat(wcsPath,MAX_PATH+1, L"\\");
  976. StringCchCat(wcsPath,MAX_PATH+1, wcsName);
  977. return WBEM_S_NO_ERROR;
  978. }
  979. DWORD g_DirSD[] = {
  980. 0x90040001, 0x00000000, 0x00000000, 0x00000000,
  981. 0x00000014,
  982. 0x004c0002, 0x00000003, 0x00180300, 0x001f01ff,
  983. 0x00000201, 0x05000000, 0x00000020, 0x00000220,
  984. 0x00180300, 0x001f01ff, 0x00000201, 0x05000000,
  985. 0x00000020, 0x00000227, 0x00140300, 0x001f01ff,
  986. 0x00000101, 0x05000000, 0x00000012
  987. };
  988. /******************************************************************************
  989. *
  990. * SaveRepository
  991. *
  992. * Description:
  993. * Moves the existing repository to a safe location so that it may be
  994. * put back in the event of restore failure. A new empty repository
  995. * directory is then created, and our copy of the restore file is then
  996. * recopied into it.
  997. *
  998. * Parameters:
  999. *
  1000. * Return:
  1001. * HRESULT: WBEM_S_NO_ERROR If successful
  1002. * WBEM_E_OUT_OF_MEMORY If out of memory
  1003. * WBEM_E_FAILED If anything else failed
  1004. *
  1005. ******************************************************************************
  1006. */
  1007. HRESULT SaveRepository(wchar_t* wszRepositoryBackup)
  1008. {
  1009. wchar_t* wszRepositoryOrg = new wchar_t[MAX_PATH+1];
  1010. if (NULL == wszRepositoryOrg) return WBEM_E_OUT_OF_MEMORY;
  1011. CVectorDeleteMe<wchar_t> vdm1(wszRepositoryOrg);
  1012. HRESULT hr = GetRepositoryDirectory(wszRepositoryOrg);
  1013. if (SUCCEEDED(hr))
  1014. {
  1015. unsigned long i = 0;
  1016. DWORD dwAttributes = INVALID_FILE_ATTRIBUTES;
  1017. do
  1018. {
  1019. StringCchPrintfW(wszRepositoryBackup, MAX_PATH+1, L"%sTempBackup.%lu", wszRepositoryOrg, i++);
  1020. dwAttributes = GetFileAttributesW(wszRepositoryBackup);
  1021. } while (dwAttributes != INVALID_FILE_ATTRIBUTES) ;
  1022. DWORD dwLastError = GetLastError();
  1023. if (dwLastError != ERROR_FILE_NOT_FOUND)
  1024. hr = WBEM_E_FAILED;
  1025. //Create the backup directory where we copy the current repository files to
  1026. SECURITY_ATTRIBUTES sa = { sizeof(sa),g_DirSD,FALSE};
  1027. if (SUCCEEDED(hr) && !CreateDirectoryW(wszRepositoryBackup, &sa))
  1028. hr = WBEM_E_FAILED;
  1029. }
  1030. if (SUCCEEDED(hr))
  1031. hr = MoveRepositoryFiles(wszRepositoryOrg, wszRepositoryBackup, true);
  1032. return hr;
  1033. }
  1034. HRESULT RestoreSavedRepository(const wchar_t* wszRepositoryBackup)
  1035. {
  1036. wchar_t* wszRepositoryOrg = new wchar_t[MAX_PATH+1];
  1037. if (NULL == wszRepositoryOrg) return WBEM_E_OUT_OF_MEMORY;
  1038. CVectorDeleteMe<wchar_t> vdm1(wszRepositoryOrg);
  1039. HRESULT hr = GetRepositoryDirectory(wszRepositoryOrg);
  1040. if (SUCCEEDED(hr))
  1041. hr = MoveRepositoryFiles(wszRepositoryOrg, wszRepositoryBackup, false);
  1042. if (SUCCEEDED(hr))
  1043. RemoveDirectoryW(wszRepositoryBackup);
  1044. return hr;
  1045. }
  1046. HRESULT MoveRepositoryFiles(const wchar_t *wszSourceDirectory, const wchar_t *wszDestinationDirectory, bool bMoveForwards)
  1047. {
  1048. static wchar_t *filename[] =
  1049. {
  1050. L"\\$winmgmt.cfg",
  1051. L"\\index.btr",
  1052. L"\\objects.data",
  1053. L"\\Mapping1.map" ,
  1054. L"\\Mapping2.map",
  1055. L"\\Mapping.ver"
  1056. };
  1057. wchar_t *wszSourceFile = new wchar_t[MAX_PATH+1];
  1058. if (NULL == wszSourceFile) return WBEM_E_OUT_OF_MEMORY;
  1059. CVectorDeleteMe<wchar_t> vdm2(wszSourceFile);
  1060. wchar_t *wszDestinationFile = new wchar_t[MAX_PATH+1];
  1061. if (NULL == wszDestinationFile) return WBEM_E_OUT_OF_MEMORY;
  1062. CVectorDeleteMe<wchar_t> vdm3(wszDestinationFile);
  1063. HRESULT hr = WBEM_S_NO_ERROR;
  1064. //MOVE EACH OF THE FILES, ONE BY ONE
  1065. for (int i = 0; SUCCEEDED(hr) && (i != 6); i++)
  1066. {
  1067. StringCchCopy(wszSourceFile,MAX_PATH+1, wszSourceDirectory);
  1068. StringCchCopy(wszDestinationFile,MAX_PATH+1, wszDestinationDirectory);
  1069. if (i != 0)
  1070. {
  1071. StringCchCat(wszSourceFile,MAX_PATH+1, L"\\fs");
  1072. }
  1073. StringCchCat(wszSourceFile,MAX_PATH+1, filename[i]);
  1074. StringCchCat(wszDestinationFile,MAX_PATH+1, filename[i]);
  1075. if (bMoveForwards)
  1076. {
  1077. if (!MoveFileW(wszSourceFile, wszDestinationFile))
  1078. {
  1079. if ((GetLastError() != ERROR_FILE_NOT_FOUND) && (GetLastError() != ERROR_PATH_NOT_FOUND))
  1080. {
  1081. hr = WBEM_E_FAILED;
  1082. break;
  1083. }
  1084. }
  1085. }
  1086. else
  1087. {
  1088. if (!MoveFileW(wszDestinationFile, wszSourceFile))
  1089. {
  1090. if ((GetLastError() != ERROR_FILE_NOT_FOUND) && (GetLastError() != ERROR_PATH_NOT_FOUND))
  1091. {
  1092. hr = WBEM_E_FAILED;
  1093. break;
  1094. }
  1095. }
  1096. }
  1097. }
  1098. return hr;
  1099. }
  1100. HRESULT DeleteSavedRepository(const wchar_t *wszRepositoryBackup)
  1101. {
  1102. wchar_t *wszDestinationFile = new wchar_t[MAX_PATH+1];
  1103. if (NULL == wszDestinationFile) return WBEM_E_OUT_OF_MEMORY;
  1104. CVectorDeleteMe<wchar_t> vdm3(wszDestinationFile);
  1105. HRESULT hr = WBEM_S_NO_ERROR;
  1106. //MOVE EACH OF THE FILES, ONE BY ONE
  1107. for (int i = 0; SUCCEEDED(hr) && (i != 6); i++)
  1108. {
  1109. static wchar_t *filename[] = { L"\\$winmgmt.cfg", L"\\index.btr", L"\\objects.data", L"\\mapping1.map", L"\\mapping2.map" , L"\\mapping.ver" };
  1110. StringCchCopy(wszDestinationFile,MAX_PATH+1, wszRepositoryBackup);
  1111. StringCchCat(wszDestinationFile,MAX_PATH+1, filename[i]);
  1112. if (!DeleteFileW(wszDestinationFile))
  1113. {
  1114. if ((GetLastError() != ERROR_FILE_NOT_FOUND) && (GetLastError() != ERROR_PATH_NOT_FOUND))
  1115. hr = WBEM_E_FAILED;
  1116. }
  1117. }
  1118. if (SUCCEEDED(hr))
  1119. RemoveDirectoryW(wszRepositoryBackup);
  1120. return hr;
  1121. }