|
|
/********************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name: srrpcc.cpp
Abstract: implements functions exported in srclient.DLL Exported API: SRSetRestorePoint / SRRemoveRestorePoint DisableSR / EnableSR DisableFIFO / EnableFIFO Revision History:
Brijesh Krishnaswami (brijeshk) - 04/10/00 - Created
********************************************************************/
#include "stdafx.h"
#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__; #define THIS_FILE __szTraceSourceFile
//
// function to check if SR configuration is disabled
// via group policy
//
DWORD CheckPolicy() { DWORD dwPolicyEnabled = 0; DWORD dwErr = ERROR_SUCCESS; HKEY hKey = NULL; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, s_cszGroupPolicy, 0, KEY_READ, &hKey)) { // if this value exists,
// then config policy is either enabled or disabled
// we need to disable access in both cases
if (ERROR_SUCCESS == RegReadDWORD(hKey, s_cszDisableConfig, &dwPolicyEnabled)) dwErr = ERROR_ACCESS_DENIED;
RegCloseKey(hKey); } return dwErr; }
// bind handle to endpoint
DWORD SRRPCInit( RPC_IF_HANDLE * pIfHandle, BOOL fVerifyRights) { RPC_STATUS status; LPWSTR pszStringBinding = NULL; DWORD dwRc = ERROR_SUCCESS;
InitAsyncTrace(); TENTER("SRRPCInit");
//
// if admin rights are required
//
if (fVerifyRights && ! IsAdminOrSystem()) { TRACE(0, "Caller does not have admin or localsystem rights"); dwRc = ERROR_ACCESS_DENIED; goto exit; } //
// check if the service is stopping
// if it is, then we don't want to accept any more rpc calls
//
if (IsStopSignalled(NULL)) { TRACE(0, "Service shut down - not accepting rpc call"); dwRc = ERROR_SERVICE_DISABLED; goto exit; } // compose string to pass to binding api
dwRc = (DWORD) RpcStringBindingCompose(NULL, s_cszRPCProtocol, NULL, s_cszRPCEndPoint, NULL, &pszStringBinding); if (dwRc != ERROR_SUCCESS) { TRACE(0, "RPCStringBindingCompose: error=%ld", dwRc); goto exit; }
// set the binding handle that will be used to bind to the server.
dwRc = (DWORD) RpcBindingFromStringBinding(pszStringBinding, pIfHandle);
if (dwRc != ERROR_SUCCESS) { TRACE(0, "RPCBindingFromStringBinding: error=%ld", dwRc); }
// free string
RpcStringFree(&pszStringBinding);
if (dwRc != ERROR_SUCCESS) goto exit;
RPC_SECURITY_QOS qos;
qos.Version = RPC_C_SECURITY_QOS_VERSION; qos.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; // Important!!!
qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
dwRc = RpcBindingSetAuthInfoEx(*pIfHandle, L"NT AUTHORITY\\SYSTEM", RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_WINNT, 0, 0, &qos);
exit: TLEAVE(); return dwRc; }
// free binding handle
DWORD SRRPCTerm( RPC_IF_HANDLE * pIfHandle) { RPC_STATUS status;
TENTER("SRRPCTerm"); // free binding handle
if (pIfHandle && *pIfHandle) status = RpcBindingFree(pIfHandle);
TLEAVE();
TermAsyncTrace(); return (DWORD) status; }
// API to disable System Restore
extern "C" DWORD WINAPI DisableSR(LPCWSTR pszDrive) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("DisableSR");
//
// check if sr config is disabled via group policy
//
dwRc = CheckPolicy(); if (dwRc != ERROR_SUCCESS) { goto exit; } // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = DisableSRS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "DisableSRS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
// private function to start the SR service
// fWait - if TRUE : function is synchronous - waits till service is started completely
// if FALSE : function is asynchronous - does not wait for service to complete starting
DWORD StartSRService(BOOL fWait) { DWORD dwRc = ERROR_SUCCESS; SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); SERVICE_STATUS Status; if (hSCM) { SC_HANDLE hSR = OpenService(hSCM, s_cszServiceName, SERVICE_ALL_ACCESS); if (hSR) { if (FALSE == StartService(hSR, 0, NULL)) { dwRc = GetLastError(); if (dwRc == ERROR_SERVICE_ALREADY_RUNNING) { goto done; } if (FALSE == QueryServiceStatus(hSR, &Status)) { goto done; } else { dwRc = Status.dwWin32ExitCode; goto done; } }
if (fWait) { //
// query the service until it starts or stops
// try thrice
//
for (int i = 0; i < 3; i++) { Sleep(2000); if (FALSE == QueryServiceStatus(hSR, &Status)) { goto done; }
if (Status.dwCurrentState == SERVICE_STOPPED) { dwRc = Status.dwWin32ExitCode; if (dwRc == ERROR_SUCCESS) { //
// service masks DISABLED error code
// to avoid unnecessary event log messages
//
dwRc = ERROR_SERVICE_DISABLED; } goto done; }
if (Status.dwCurrentState == SERVICE_RUNNING) { //
// wait on init event
//
HANDLE hInit = OpenEvent(SYNCHRONIZE, FALSE, s_cszSRInitEvent); if (hInit) { dwRc = WaitForSingleObject(hInit, 120000); // wait for 2 minutes
CloseHandle(hInit); if (dwRc == WAIT_OBJECT_0) { dwRc = ERROR_SUCCESS; goto done; } else { dwRc = ERROR_TIMEOUT; goto done; } } } } } CloseServiceHandle(hSR); } else { dwRc = GetLastError(); } CloseServiceHandle(hSCM); } else { dwRc = GetLastError(); }
done: return dwRc; }
DWORD SetDisableFlag(DWORD dwValue) { HKEY hKeySR = NULL; DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, s_cszSRRegKey, 0, KEY_WRITE, &hKeySR); if (ERROR_SUCCESS != dwRc) goto done; dwRc = RegWriteDWORD(hKeySR, s_cszDisableSR, &dwValue); if (ERROR_SUCCESS != dwRc) goto done; done: if (hKeySR) RegCloseKey(hKeySR);
return dwRc; }
// API to enable System Restore
extern "C" DWORD WINAPI EnableSR(LPCWSTR pszDrive) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("EnableSR");
//
// check if sr config is disabled via group policy
//
dwRc = CheckPolicy(); if (dwRc != ERROR_SUCCESS) { goto exit; } // if whole of SR is enabled, then
// set the boot mode of service/filter to automatic
// and start the service
if (! pszDrive || IsSystemDrive((LPWSTR) pszDrive)) { //
// if safe mode, then don't
//
if (0 != GetSystemMetrics(SM_CLEANBOOT)) { TRACE(0, "This is safemode"); dwRc = ERROR_BAD_ENVIRONMENT; goto exit; } dwRc = SetServiceStartup(s_cszServiceName, SERVICE_AUTO_START); if (ERROR_SUCCESS != dwRc) goto exit;
dwRc = SetServiceStartup(s_cszFilterName, SERVICE_BOOT_START); if (ERROR_SUCCESS != dwRc) goto exit;
// set the disable flag to false
// BUGBUG - this piece of code is duplicated in the service code as well
// reason is: we need the ability to disable/enable SR from within and outside
// the service
dwRc = SetDisableFlag(FALSE); if (ERROR_SUCCESS != dwRc) goto exit; dwRc = StartSRService(FALSE); } else { // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = EnableSRS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "EnableSRS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle); }
exit: TLEAVE(); return dwRc; }
// API to enable System Restore - extended version
extern "C" DWORD WINAPI EnableSREx(LPCWSTR pszDrive, BOOL fWait) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("EnableSREx");
//
// check if sr config is disabled via group policy
//
dwRc = CheckPolicy(); if (dwRc != ERROR_SUCCESS) { goto exit; } // if whole of SR is enabled, then
// set the boot mode of service/filter to automatic
// and start the service
if (! pszDrive || IsSystemDrive((LPWSTR) pszDrive)) { //
// if safe mode, then don't
//
if (0 != GetSystemMetrics(SM_CLEANBOOT)) { TRACE(0, "This is safemode"); dwRc = ERROR_BAD_ENVIRONMENT; goto exit; } dwRc = SetServiceStartup(s_cszServiceName, SERVICE_AUTO_START); if (ERROR_SUCCESS != dwRc) goto exit;
dwRc = SetServiceStartup(s_cszFilterName, SERVICE_BOOT_START); if (ERROR_SUCCESS != dwRc) goto exit;
// set the disable flag to false
// BUGBUG - this piece of code is duplicated in the service code as well
// reason is: we need the ability to disable/enable SR from within and outside
// the service
dwRc = SetDisableFlag(FALSE); if (ERROR_SUCCESS != dwRc) goto exit; dwRc = StartSRService(fWait); } else { // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = EnableSRS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "EnableSRS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle); }
exit: TLEAVE(); return dwRc; }
// API to update the list of protected files - UNICODE version
// pass the fullpath name of the XML file containing the updated list of files
extern "C" DWORD WINAPI SRUpdateMonitoredListA( LPCSTR pszXMLFile) { DWORD dwRc = ERROR_INTERNAL_ERROR; LPWSTR pwszXMLFile = NULL; handle_t srrpc_IfHandle = NULL; TENTER("SRUpdateMonitoredListA"); pwszXMLFile = ConvertToUnicode((LPSTR) pszXMLFile); if (! pwszXMLFile) { TRACE(0, "ConvertToUnicode"); goto exit; }
// initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = SRUpdateMonitoredListS(srrpc_IfHandle, pwszXMLFile); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRUpdateMonitoredListS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: if (pwszXMLFile) SRMemFree(pwszXMLFile);
TLEAVE(); return dwRc; }
// API to update the list of protected files - UNICODE version
// pass the fullpath name of the XML file containing the updated list of files
extern "C" DWORD WINAPI SRUpdateMonitoredListW( LPCWSTR pwszXMLFile) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRUpdateMonitoredListW"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = SRUpdateMonitoredListS(srrpc_IfHandle, pwszXMLFile); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRUpdateMonitoredListS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
// API to set a restore point - ANSI version
extern "C" BOOL SRSetRestorePointA( PRESTOREPOINTINFOA pRPInfoA, PSTATEMGRSTATUS pSMgrStatus) { BOOL fRc = FALSE; RESTOREPOINTINFOW RPInfoW; LPWSTR pszDescW = NULL; handle_t srrpc_IfHandle = NULL; TENTER("SRSetRestorePointA");
// Initialize return values
if (! pSMgrStatus || ! pRPInfoA) { goto exit; } pSMgrStatus->llSequenceNumber = 0; pSMgrStatus->nStatus = ERROR_INTERNAL_ERROR;
// convert struct to unicode
// since the string is the last member of the struct, we can memcpy
// all
memcpy(&RPInfoW, pRPInfoA, sizeof(RESTOREPOINTINFOA)); pszDescW = ConvertToUnicode(pRPInfoA->szDescription); if (! pszDescW) { TRACE(0, "ConvertToUnicode"); goto exit; } lstrcpy(RPInfoW.szDescription, pszDescW);
// initialize
// don't need admin rights to call this api
pSMgrStatus->nStatus = SRRPCInit(&srrpc_IfHandle, FALSE); if (pSMgrStatus->nStatus != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { fRc = SRSetRestorePointS(srrpc_IfHandle, &RPInfoW, pSMgrStatus); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { // set right error code if SR is disabled
DWORD dwRc = RpcExceptionCode(); if (RPC_S_SERVER_UNAVAILABLE == dwRc || RPC_S_UNKNOWN_IF == dwRc) { pSMgrStatus->nStatus = ERROR_SERVICE_DISABLED; } else { pSMgrStatus->nStatus = dwRc; }
TRACE(0, "SRSetRestorePointS threw exception: nStatus=%ld", pSMgrStatus->nStatus); } RpcEndExcept // terminate
SRRPCTerm(&srrpc_IfHandle);
exit: if (pszDescW) SRMemFree(pszDescW);
TLEAVE(); return fRc; }
// API to set a restore point - UNICODE version
extern "C" BOOL SRSetRestorePointW( PRESTOREPOINTINFOW pRPInfoW, PSTATEMGRSTATUS pSMgrStatus) { BOOL fRc = FALSE; DWORD dwRc = ERROR_SUCCESS; handle_t srrpc_IfHandle = NULL; TENTER("SRSetRestorePointW");
// Initialize return values
if (! pSMgrStatus || ! pRPInfoW) { goto exit; } pSMgrStatus->llSequenceNumber = 0; pSMgrStatus->nStatus = ERROR_INTERNAL_ERROR;
// initialize
pSMgrStatus->nStatus = SRRPCInit(&srrpc_IfHandle, FALSE); if (pSMgrStatus->nStatus != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { fRc = SRSetRestorePointS(srrpc_IfHandle, pRPInfoW, pSMgrStatus); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { // set right error code if SR is disabled
DWORD dwRc = RpcExceptionCode(); if (RPC_S_SERVER_UNAVAILABLE == dwRc || RPC_S_UNKNOWN_IF == dwRc) { pSMgrStatus->nStatus = ERROR_SERVICE_DISABLED; } else { pSMgrStatus->nStatus = dwRc; }
TRACE(0, "SRSetRestorePointS threw exception: nStatus=%ld", pSMgrStatus->nStatus); } RpcEndExcept // terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return fRc; }
// API to remove a restore point
extern "C" DWORD SRRemoveRestorePoint( DWORD dwRPNum) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRRemoveRestorePoint");
// initialize
dwRc = SRRPCInit(&srrpc_IfHandle, FALSE); if (dwRc != ERROR_SUCCESS) goto exit;
// call remote procedure
RpcTryExcept { dwRc = SRRemoveRestorePointS(srrpc_IfHandle, dwRPNum); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRRemoveRestorePointS threw exception: error=%ld", dwRc); } RpcEndExcept // terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
// api to disable FIFO
extern "C" DWORD WINAPI DisableFIFO( DWORD dwRPNum) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("DisableFIFO"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = DisableFIFOS(srrpc_IfHandle, dwRPNum); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "DisableFIFOS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle); exit: TLEAVE(); return dwRc; }
// api to enable FIFO
extern "C" DWORD WINAPI EnableFIFO() { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("EnableFIFO"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = EnableFIFOS(srrpc_IfHandle); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "EnableFIFOS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
// api to reset SR
extern "C" DWORD WINAPI ResetSR( LPCWSTR pszDrive) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("ResetSR"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = ResetSRS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "ResetSRS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle); exit: TLEAVE(); return dwRc; }
// api to refresh the drive table from disk
// restore UI will call this - service will update its drivetable in memory
extern "C" DWORD WINAPI SRUpdateDSSize(LPCWSTR pszDrive, UINT64 ullSizeLimit) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRUpdateDSSize"); //
// check if sr config is disabled via group policy
//
dwRc = CheckPolicy(); if (dwRc != ERROR_SUCCESS) { goto exit; }
// initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = SRUpdateDSSizeS(srrpc_IfHandle, pszDrive, ullSizeLimit); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRUpdateDSSizeS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
extern "C" DWORD WINAPI SRSwitchLog() { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRSwitchLog"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, FALSE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = SRSwitchLogS(srrpc_IfHandle); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRSwitchLogS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
extern "C" void WINAPI SRNotify(LPCWSTR pszDrive, DWORD dwFreeSpaceInMB, BOOL fImproving) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRNotify"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, FALSE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { SRNotifyS(srrpc_IfHandle, pszDrive, dwFreeSpaceInMB, fImproving); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRNotifyS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return; }
extern "C" void WINAPI SRPrintState() { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("SRPrintState"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, FALSE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { SRPrintStateS(srrpc_IfHandle); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "SRPrintStateS threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return; }
extern "C" DWORD WINAPI SRFifo(LPCWSTR pszDrive, DWORD dwTargetRp, int nPercent, BOOL fIncludeCurrentRp, BOOL fFifoAtleastOneRp) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("Fifo"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = FifoS(srrpc_IfHandle, pszDrive, dwTargetRp, nPercent, fIncludeCurrentRp, fFifoAtleastOneRp); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "Fifo threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
extern "C" DWORD WINAPI SRCompress(LPCWSTR pszDrive) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("Compress"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = CompressS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "Compress threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
extern "C" DWORD WINAPI SRFreeze(LPCWSTR pszDrive) { DWORD dwRc = ERROR_INTERNAL_ERROR; handle_t srrpc_IfHandle = NULL; TENTER("Freeze"); // initialize
dwRc = SRRPCInit(&srrpc_IfHandle, TRUE); if (dwRc != ERROR_SUCCESS) { goto exit; }
// call remote procedure
RpcTryExcept { dwRc = FreezeS(srrpc_IfHandle, pszDrive); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { dwRc = RpcExceptionCode(); TRACE(0, "Freeze threw exception: error=%ld", dwRc); } RpcEndExcept
// terminate
SRRPCTerm(&srrpc_IfHandle);
exit: TLEAVE(); return dwRc; }
// registration of callback method for third-parties to
// do their own snapshotting and restoration for their components
// clients will call this method with the full path of their dll.
// system restore will call "CreateSnapshot" and "RestoreSnapshot"
// methods in the registered dll when creating a restore point and
// when restoring respectively
extern "C" DWORD WINAPI SRRegisterSnapshotCallback( LPCWSTR pszDllPath) { DWORD dwErr = ERROR_SUCCESS; HKEY hKey = NULL; LPWSTR pszDllName = NULL; WCHAR szKey[MAX_PATH]; DWORD dwDisposition; TENTER("RegisterSnapshotCallback");
//
// allow this only if admin or system
//
if (! IsAdminOrSystem()) { dwErr = ERROR_ACCESS_DENIED; trace(0, "Not admin or system"); goto Err; }
if (pszDllPath == NULL) { dwErr = ERROR_INVALID_PARAMETER; trace(0, "pszDllPath = NULL"); goto Err; }
//
// add the dll to Software\...\SystemRestore\SnapshotCallbacks
// each dll will be a value
// value name : name of dll, value: fullpath of dll
// this way, the registration is idempotent
//
//
// create/open the key
//
lstrcpy(szKey, s_cszSRRegKey); lstrcat(szKey, L"\\"); lstrcat(szKey, s_cszCallbacksRegKey);
CHECKERR( RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition), L"RegCreateKeyEx" );
//
// get the dll name from the path
// if the path is not specified, this is same as input param
//
pszDllName = wcsrchr(pszDllPath, L'\\'); if (pszDllName == NULL) { pszDllName = (LPWSTR) pszDllPath; } else { pszDllName++; // skip the '\'
}
//
// if the value already exists
// bail
//
if (ERROR_SUCCESS == RegQueryValueEx(hKey, pszDllName, 0, NULL, NULL, NULL)) { trace(0, "Dll is already registered"); dwErr = ERROR_ALREADY_EXISTS; goto Err; }
//
// add the value
//
CHECKERR(RegSetValueEx(hKey, pszDllName, 0, REG_SZ, (BYTE *) pszDllPath, (lstrlen(pszDllPath)+1)*sizeof(WCHAR)), L"RegSetValueEx");
trace(0, "Added %S as snapshot callback", pszDllPath);
Err: if (hKey) { RegCloseKey(hKey); }
TLEAVE(); return dwErr; }
// corresponding unregistration function to above function
// clients can call this to unregister any snapshot callbacks
// they have already registered
extern "C" DWORD WINAPI SRUnregisterSnapshotCallback( LPCWSTR pszDllPath) { DWORD dwErr = ERROR_SUCCESS; HKEY hKey = NULL; LPWSTR pszDllName = NULL; WCHAR szKey[MAX_PATH];
TENTER("SRUnregisterSnapshotCallback");
//
// allow this only if admin or system
//
if (! IsAdminOrSystem()) { dwErr = ERROR_ACCESS_DENIED; trace(0, "Not admin or system"); goto Err; }
if (pszDllPath == NULL) { dwErr = ERROR_INVALID_PARAMETER; trace(0, "pszDllPath = NULL"); goto Err; }
//
// add the dll to Software\...\SystemRestore\SnapshotCallbacks
// each dll will be a value
// value name : name of dll, value: fullpath of dll
// this way, the registration is idempotent
//
//
// open the key
//
lstrcpy(szKey, s_cszSRRegKey); lstrcat(szKey, L"\\"); lstrcat(szKey, s_cszCallbacksRegKey);
CHECKERR( RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_ALL_ACCESS, &hKey), L"RegOpenKeyEx" );
//
// get the dll name from the path
// if the path is not specified, this is same as input param
//
pszDllName = wcsrchr(pszDllPath, L'\\'); if (pszDllName == NULL) { pszDllName = (LPWSTR) pszDllPath; } else { pszDllName++; // skip the '\'
} //
// remove the value
//
CHECKERR(RegDeleteValue(hKey, pszDllName), L"RegDeleteValue");
trace(0, "Removed %S from snapshot callback", pszDllPath);
Err: if (hKey) { RegCloseKey(hKey); }
TLEAVE(); return dwErr; }
//
// test functions for snapshot callbacks
//
extern "C" DWORD WINAPI CreateSnapshot(LPCWSTR pszSnapshotDir) { TENTER("CreateSnapshot");
WCHAR szFile[MAX_PATH]; wsprintf(szFile, L"%s\\srclient.txt", pszSnapshotDir); DebugTrace(0, "Callback createsnapshot"); if (FALSE == CopyFile(L"c:\\srclient.txt", szFile, FALSE)) { trace(0, "! CopyFile"); }
TLEAVE(); return ERROR_SUCCESS; }
extern "C" DWORD WINAPI RestoreSnapshot(LPCWSTR pszSnapshotDir) { TENTER("RestoreSnapshot");
WCHAR szFile[MAX_PATH]; wsprintf(szFile, L"%s\\srclient.txt", pszSnapshotDir); DebugTrace(0, "Callback restoresnapshot"); if (FALSE == CopyFile(szFile, L"c:\\restored.txt", FALSE)) { trace(0, "! CopyFile"); } TLEAVE(); return ERROR_SUCCESS; }
// alloc/dealloc functions for midl compiler
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) { return(SRMemAlloc((DWORD) len)); }
void __RPC_USER midl_user_free(void __RPC_FAR * ptr) { SRMemFree(ptr); }
|