/*++ Copyright (c) 1999 Microsoft Corporation Abstract: @doc @module vs_reg.hxx | Declaration of CVssRegistryKey @end Author: Adi Oltean [aoltean] 03/13/2001 Revision History: Name Date Comments aoltean 03/13/2001 Created --*/ #ifndef __VSGEN_REGISTRY_HXX__ #define __VSGEN_REGISTRY_HXX__ #if _MSC_VER > 1000 #pragma once #endif //////////////////////////////////////////////////////////////////////// // Standard foo for file name aliasing. This code block must be after // all includes of VSS header files. // #ifdef VSS_FILE_ALIAS #undef VSS_FILE_ALIAS #endif #define VSS_FILE_ALIAS "SPRREGMH" // //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Constants const x_nVssMaxRegBuffer = MAX_PATH; const x_nVssMaxRegNumBuffer = 30; // Enough for storing numbers ///////////////////////////////////////////////////////////////////////////// // Constants const WCHAR x_wszVSSKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS"; // Provider registration const WCHAR x_wszVSSKeyProviders[] = L"Providers"; const WCHAR x_wszVSSKeyProviderCLSID[] = L"CLSID"; const WCHAR x_wszVSSProviderValueName[] = L""; const WCHAR x_wszVSSProviderValueType[] = L"Type"; const WCHAR x_wszVSSProviderValueVersion[] = L"Version"; const WCHAR x_wszVSSProviderValueVersionId[] = L"VersionId"; const WCHAR x_wszVSSCLSIDValueName[] = L""; // Diff area const WCHAR x_wszVssVolumesKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Volumes"; const WCHAR x_wszVssAssociationsKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Volumes\\Associations"; const WCHAR x_wszVssMaxDiffValName[] = L"MaxDiffSpace"; const WCHAR x_wszVssAccessControlKey[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\VssAccessControl"; // COM Registry keys/values const WCHAR x_wszDefaultLaunchPermissionKeyName[] = L"Software\\Microsoft\\Ole"; const WCHAR x_wszDefaultLaunchPermissionValueName[] = L"DefaultLaunchPermission"; const WCHAR x_wszAppLaunchPermissionValueName[] = L"LaunchPermission"; // Diag data const WCHAR x_wszVssDiagPath[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Diag"; const WCHAR x_wszVssDiagEnabledValue[] = L"Enabled"; // Setup key const WCHAR x_SetupKey[] = L"SYSTEM\\Setup"; const WCHAR x_SystemSetupInProgress[] = L"SystemSetupInProgress"; const WCHAR x_UpgradeInProgress[] = L"UpgradeInProgress"; // Event Log source const WCHAR g_wszVssEventLogSourceKey[] = L"System\\CurrentControlSet\\Services\\EventLog\\Application\\VSS"; const WCHAR g_wszVssEventTypesSupportedValName[] = L"TypesSupported"; const WCHAR g_wszVssEventMessageFileValName[] = L"EventMessageFile"; const WCHAR g_wszVssBinaryPath[] = L"%SystemRoot%\\System32\\VSSVC.EXE"; const DWORD g_dwVssEventTypesSupported = 7; // Safeboot key const WCHAR x_SafebootKey[] = L"SYSTEM\\currentcontrolset\\control\\safeboot\\option"; const WCHAR x_SafebootOptionValue[] = L"OptionValue"; // Client accessible settings path const WCHAR x_wszVssCASettingsPath[] = L"SYSTEM\\CurrentControlSet\\Services\\VSS\\Settings"; const WCHAR x_wszVssCAMaxShadowCopiesValueName[] = L"MaxShadowCopies"; const WCHAR x_wszVssOfflineTimeoutValueName[] = L"ClusterOfflineTimeout"; const WCHAR x_wszVssOnlineTimeoutValueName[] = L"ClusterOnlineTimeout"; ///////////////////////////////////////////////////////////////////////////// // Classes // Implements a low-level API for registry manipulation class CVssRegistryKey { // Constructors/destructors private: CVssRegistryKey(const CVssRegistryKey&); public: CVssRegistryKey( IN REGSAM samDesired = KEY_ALL_ACCESS, IN DWORD dwKeyCreateOptions = REG_OPTION_NON_VOLATILE ); ~CVssRegistryKey(); // Operations public: // Creates the registry key. // Throws an error if the key already exists void Create( IN HKEY hAncestorKey, IN LPCWSTR pwszPathFormat, IN ... ) throw(HRESULT); // Opens a registry key. Returns "false" if the key does not exist bool Open( IN HKEY hAncestorKey, IN LPCWSTR pwszPathFormat, IN ... ) throw(HRESULT); // Recursively deletes a subkey. // Throws an error if the subkey does not exist void DeleteSubkey( IN LPCWSTR pwszPathFormat, IN ... ) throw(HRESULT); // Deletes a value. // Throws an error if the value does not exist void DeleteValue( IN LPCWSTR pwszValueName ) throw(HRESULT); void SetValue( IN LPCWSTR pwszValueName, IN DWORD dwValue ) throw(HRESULT); // Adds a LONGLONG value to the registry key void SetValue( IN LPCWSTR pwszValueName, IN LONGLONG llValue ) throw(HRESULT); // Adds a REG_SZ/REG_EXPAND_SZ value to the registry key void SetValue( IN LPCWSTR pwszValueName, IN LPCWSTR pwszValue, IN REGSAM eSzType = REG_SZ ) throw(HRESULT); // Adds a multi-string value to the registry key void SetMultiszValue( IN LPCWSTR pwszValueName, IN LPCWSTR pwszValue ) throw(HRESULT); // Adds a binary value to the registry key void SetBinaryValue( IN LPCWSTR pwszValueName, IN BYTE * pbData, IN DWORD dwSize ) throw(HRESULT); // Reads a LONGLONG value from the registry key bool GetValue( IN LPCWSTR pwszValueName, OUT LONGLONG & llValue, IN bool bThrowIfNotFound = true ) throw(HRESULT); // Reads a VSS_PWSZ value from the registry key bool GetValue( IN LPCWSTR pwszValueName, OUT VSS_PWSZ & pwszValue, IN bool bThrowIfNotFound = true ) throw(HRESULT); // Reads a DWORD value from the registry key bool GetValue( IN LPCWSTR pwszValueName, OUT DWORD & dwValue, IN bool bThrowIfNotFound = true ) throw(HRESULT); // Reads a binary value from the registry key bool GetBinaryValue( IN LPCWSTR pwszValueName, OUT BYTE* & pbData, OUT DWORD & lSize, IN bool bThrowIfNotFound = true ) throw(HRESULT); // Closing the registry key void Close(); // Get the handle for the currently opened key HKEY GetHandle() const { return m_hRegKey; }; // Implementation private: REGSAM m_samDesired; DWORD m_dwKeyCreateOptions; HKEY m_hRegKey; CVssAutoPWSZ m_awszKeyPath; // For debugging only }; // Implements a low-level API for registry key enumeration // We assume that the keys don't change during enumeration class CVssRegistryKeyIterator { // Constructors/destructors private: CVssRegistryKeyIterator(const CVssRegistryKeyIterator&); public: CVssRegistryKeyIterator(); // Operations public: // Attach the iterator to a key void Attach( IN CVssRegistryKey & key ) throw(HRESULT); // Detach the iterator from a key. void Detach(); // Tells if the current key is invalid (end of enumeration?) bool IsEOF(); // Return the number of subkeys at the moment of attaching DWORD GetSubkeysCount(); // Set the next key as being the current one in the enumeration void MoveNext(); // Returns the name of the current key, if any VSS_PWSZ GetCurrentKeyName() throw(HRESULT); // Implementation private: HKEY m_hParentKey; DWORD m_dwKeyCount; DWORD m_dwCurrentKeyIndex; DWORD m_dwMaxSubKeyLen; CVssAutoPWSZ m_awszSubKeyName; bool m_bAttached; }; // Implements a low-level API for registry value enumeration // We assume that the values don't change during enumeration class CVssRegistryValueIterator { // Constructors/destructors private: CVssRegistryValueIterator(const CVssRegistryValueIterator&); public: CVssRegistryValueIterator(); // Operations public: // Attach the iterator to a key void Attach( IN CVssRegistryKey & key ) throw(HRESULT); // Detach the iterator from a key. void Detach(); // Tells if the current key is invalid (end of enumeration?) bool IsEOF(); // Return the number of subkeys at the moment of attaching DWORD GetValuesCount(); // Set the next key as being the current one in the enumeration void MoveNext(); // Returns the name of the current value VSS_PWSZ GetCurrentValueName() throw(HRESULT); // Returns the type of the current value DWORD GetCurrentValueType() throw(HRESULT); // Read the current value assuming it has REG_SZ type // WARNING: The caller is responsible for deallocating the value! void GetCurrentValueContent( OUT VSS_PWSZ & pwszValue ) throw(HRESULT); // Read the current value assuming it has REG_DWORD type void GetCurrentValueContent( OUT DWORD & dwValue ) throw(HRESULT); // Read the current value assuming it has REG_BINARY type void GetCurrentValueContent( OUT PBYTE & pbValue, // Must be deleted with "delete[]" OUT DWORD & cbSize ) throw(HRESULT); // Implementation private: void ReadCurrentValueDetails() throw(HRESULT); HKEY m_hKey; DWORD m_dwValuesCount; DWORD m_dwCurrentValueIndex; DWORD m_dwCurrentValueType; CVssAutoPWSZ m_awszValueName; DWORD m_cchMaxValueNameLen; DWORD m_cbValueDataSize; bool m_bSeekDone; bool m_bAttached; }; // +-----------------+-----------------+ // | Structure size | 0 (reserved) | // +-----------------+-----------------+ // | Timestamp | // +-----------------+-----------------+ // | Process ID | Thread ID | // +-----------------+-----------------+ // | Event ID | Enter/Leave flag| // +-----------------+-----------------+ // | Current State | Last Error (HR) | // +-----------------+-----------------+ // | Snapshot Set ID | // | | // +-----------------+-----------------+ // | LPVOID reserved | // +-----------------+-----------------+ struct CVssDiagData { DWORD m_dwSize; // For future compatibility DWORD m_dwReserved; // Reserved - zero LONGLONG m_llTimestamp; DWORD m_dwProcessID; DWORD m_dwThreadID; DWORD m_dwEventID; DWORD m_dwEventContext; DWORD m_dwCurrentState; DWORD m_hrLastErrorCode; VSS_ID m_guidSnapshotSetID; LPVOID m_pReserved1; // Reserved - NULL LPVOID m_pReserved2; // Reserved - NULL }; struct CVssQueuedEventData { CVssDiagData m_diag; // Diag data for that event LPCWSTR m_pwszEventName; // This is a static string }; // // Defines a writer operation // typedef enum VSS_OPERATION { // Writers VSS_IN_IDENTIFY = 1000, VSS_IN_PREPAREBACKUP, VSS_IN_PREPARESNAPSHOT, VSS_IN_FREEZE, VSS_IN_THAW, VSS_IN_POSTSNAPSHOT, VSS_IN_BACKUPCOMPLETE, VSS_IN_PRERESTORE, VSS_IN_POSTRESTORE, VSS_IN_GETSTATE, // Added for diag VSS_IN_ABORT, // Added for diag VSS_IN_BACKUPSHUTDOWN, VSS_IN_BKGND_FREEZE_THREAD, // Lovelace VSS_IN_OPEN_VOLUME_HANDLE, VSS_IN_IOCTL_FLUSH_AND_HOLD, VSS_IN_IOCTL_RELEASE, // Replacement for S_OK (S_OK conflicts with VSS_WS_UNKNOWN) // (Used in Diag code only) - to be used only in VSS_HRESULT_CASE_STMT VSS_S_OK = 0xffffffff }; const x_nMaxQueuedDiagData = 10; // Implements a lightweight diagnose tool for recording events class CVssDiag { // Constructors/destructors private: CVssDiag(const CVssDiag&); CVssDiag& operator = (const CVssDiag&); public: CVssDiag(): m_bInitialized(false), m_key(KEY_ALL_ACCESS, REG_OPTION_VOLATILE), m_dwQueuedElements(0) {}; ~CVssDiag() { if (m_bInitialized) FlushQueue(); } // Operations public: enum { VSS_DIAG_LEAVE_OPERATION = 0x00000000, VSS_DIAG_ENTER_OPERATION = 0x00000001, VSS_DIAG_IGNORE_LEAVE = 0x00000002, VSS_DIAG_IS_STATE = 0x00000004, VSS_DIAG_IS_HRESULT = 0x00000008, }; // Initialize the diagnose tool // Does not throw errora void Initialize( IN LPCWSTR pwszStaticContext ); // Records an writer event. // Does not throw errors void RecordWriterEvent( IN VSS_OPERATION eOperation, IN DWORD dwEventContext, IN DWORD dwCurrentState, IN HRESULT hrLastError, IN GUID guidSnapshotSetID = GUID_NULL ); // Records an generic event. // Does not throw errors void RecordGenericEvent( IN DWORD dwEventID, IN DWORD dwEventContext, IN DWORD dwCurrentState, IN HRESULT hrLastError, IN GUID guidSnapshotSetID = GUID_NULL ); // Implementation private: // convert an event into the corresponding writer description LPCWSTR GetStringFromOperation( IN bool bInOperation, IN DWORD dwOperation ); bool IsQueuedMode( IN DWORD dwEventID, IN DWORD dwEventContext ); void FlushQueue(); CVssRegistryKey m_key; // Registry key to hold data for each event bool m_bInitialized; // If the registry key is initialized CVssQueuedEventData m_QueuedDiagData[x_nMaxQueuedDiagData]; DWORD m_dwQueuedElements; }; // General info about the current machine class CVssMachineInformation { public: static bool IsDuringSetup(); static bool IsDuringSafeMode(); }; #endif // __VSGEN_REGISTRY_HXX__