/*++ Copyright (c) 1999 Microsoft Corporation Abstract: @doc @module vssadmin.hxx | header of VSS demo @end Author: Adi Oltean [aoltean] 09/17/1999 TBD: Add comments. Revision History: Name Date Comments aoltean 09/17/1999 Created --*/ #ifndef __VSS_DEMO_H_ #define __VSS_DEMO_H_ ///////////////////////////////////////////////////////////////////////////// // Defines and pragmas // C4290: C++ Exception Specification ignored #pragma warning(disable:4290) // warning C4511: copy constructor could not be generated #pragma warning(disable:4511) // warning C4127: conditional expression is constant #pragma warning(disable:4127) ///////////////////////////////////////////////////////////////////////////// // Includes #include #include #include #include // Enabling asserts in ATL and VSS #include "vs_assert.hxx" // ATL #include #include // Application specific #include "vs_inc.hxx" // Generated MIDL headers #include "vs_idl.hxx" #include "copy.hxx" #include "pointer.hxx" #include "resource.h" #include "vssmsg.h" #include "msg.h" #include "vswriter.h" #include "vsbackup.h" ///////////////////////////////////////////////////////////////////////////// // Constants const x_nStringBufferSize = 1024; // Includes the zero character const x_nPollingInterval = 2500; // Three seconds const x_nMaxRetriesCount = 4; // Retries for polling const WCHAR x_wszVssOptBoolTrue[] = L"TRUE"; #define VSSADM_E_NO_ITEMS_IN_QUERY S_FALSE #define VSSADM_E_FIRST_PARSING_ERROR 0x1001 #define VSSADM_E_INVALID_NUMBER 0x1001 #define VSSADM_E_INVALID_COMMAND 0x1002 #define VSSADM_E_INVALID_OPTION 0x1003 #define VSSADM_E_INVALID_OPTION_VALUE 0x1004 #define VSSADM_E_DUPLICATE_OPTION 0x1005 #define VSSADM_E_OPTION_NOT_ALLOWED_FOR_COMMAND 0x1006 #define VSSADM_E_REQUIRED_OPTION_MISSING 0x1007 #define VSSADM_E_INVALID_SET_OF_OPTIONS 0x1008 #define VSSADM_E_SNAPSHOT_NOT_FOUND 0x1009 #define VSSADM_E_DELETION_DENIED 0x100a #define VSSADM_E_LAST_PARSING_ERROR 0x100a // Note: if any skus are added in the CVssSKU class, they need to // be updated here. Make sure to update the SKU_INT and SKU_A // definitions as well. #define SKU_C CVssSKU::VSS_SKU_CLIENT #define SKU_S CVssSKU::VSS_SKU_SERVER #define SKU_N CVssSKU::VSS_SKU_NAS #define SKU_I CVssSKU::VSS_SKU_INVALID #define SKU_INT ((DWORD)(~SKU_C & ~ SKU_S & ~SKU_N)) #define SKU_A ( SKU_C | SKU_S | SKU_N | SKU_INT) // 0xffff #define SKU_SN ( SKU_S | SKU_N ) #define SKU_SNI (SKU_S | SKU_N | SKU_INT) enum EVssAdmSnapshotType { VSSADM_ST_FIRST = 0, VSSADM_ST_NAS_ROLLBACK = 0, VSSADM_ST_PERSISTENT_TIMEWARP, VSSADM_ST_TIMEWARP, VSSADM_ST_NUM_TYPES, VSSADM_ST_INVALID, VSSADM_ST_ALL }; struct SVssAdmSnapshotTypeName { LPCWSTR pwszName; DWORD dwSKUs; // Specifies which SKUs this type is supported for snapshot creation using vssadmin, formed from ORing CVssSKU::EVssSKUType LONG lSnapshotContext; // The snapshot context from vss.idl LONG pwszDescription; }; // // List of all options. This list must remain in sync with the g_asAdmOptions list. // enum EVssAdmOption { VSSADM_O_FIRST = 0, VSSADM_O_ALL = 0, VSSADM_O_AUTORETRY, VSSADM_O_EXPOSE_USING, VSSADM_O_FOR, VSSADM_O_MAXSIZE, VSSADM_O_OLDEST, VSSADM_O_ON, VSSADM_O_PROVIDER, VSSADM_O_QUIET, VSSADM_O_SET, VSSADM_O_SHAREPATH, VSSADM_O_SNAPSHOT, VSSADM_O_SNAPTYPE, VSSADM_O_NUM_OPTIONS, VSSADM_O_INVALID }; // // LIst of all commands. This list must remain in sync with the g_asAdmCommands list. // enum EVssAdmCommand { VSSADM_C_FIRST = 0, VSSADM_C_ADD_DIFFAREA_INT = 0, VSSADM_C_ADD_DIFFAREA_PUB, VSSADM_C_CREATE_SNAPSHOT_INT, VSSADM_C_CREATE_SNAPSHOT_PUB, VSSADM_C_DELETE_SNAPSHOTS_INT, VSSADM_C_DELETE_SNAPSHOTS_PUB, VSSADM_C_DELETE_DIFFAREAS_INT, VSSADM_C_DELETE_DIFFAREAS_PUB, VSSADM_C_EXPOSE_SNAPSHOT, VSSADM_C_LIST_PROVIDERS, VSSADM_C_LIST_SNAPSHOTS_INT, VSSADM_C_LIST_SNAPSHOTS_PUB, VSSADM_C_LIST_DIFFAREAS_INT, VSSADM_C_LIST_DIFFAREAS_PUB, VSSADM_C_LIST_VOLUMES_INT, VSSADM_C_LIST_VOLUMES_PUB, VSSADM_C_LIST_WRITERS, VSSADM_C_RESIZE_DIFFAREA_INT, VSSADM_C_RESIZE_DIFFAREA_PUB, VSSADM_C_NUM_COMMANDS, VSSADM_C_INVALID }; enum EVssAdmOptionType { VSSADM_OT_BOOL = 0, // no qualifier on the option, i.e. /quiet, TRUE if present VSSADM_OT_STR, VSSADM_OT_NUM }; struct SVssAdmOption { EVssAdmOption eOpt; LPCWSTR pwszOptName; // The option name as typed on the command-line, i.e. the "for" in /for=XXXX EVssAdmOptionType eOptType; }; // // Specifies the validity of the option for a particular command. // enum EVssAdmOptionFlag { V_NO = 0, // Option not allowed V_YES, // Option manditory V_OPT // Option optional }; // // The main command structure. The commands are structured like: // vssadmin // struct SVssAdmCommandsEntry { LPCWSTR pwszMajorOption; LPCWSTR pwszMinorOption; EVssAdmCommand eAdmCmd; DWORD dwSKUs; // Specifies which SKUs this command is supported, formed from ORing CVssSKU::EVssSKUType LONG lMsgGen; LONG lMsgDetail; BOOL bShowSSTypes; // If true, in detailed usage show a list of valid snapshot types at end of message EVssAdmOptionFlag aeOptionFlags[VSSADM_O_NUM_OPTIONS]; // Array of option flags indexed by EVssAdmOption }; // // The structure of the parsed command. One of these is created by the // ParseCmdLine method. // struct SVssAdmParsedCommand { EVssAdmCommand eAdmCmd; LPWSTR apwszOptionValues[VSSADM_O_NUM_OPTIONS]; // Simple initializer constructor SVssAdmParsedCommand() { eAdmCmd = VSSADM_C_INVALID; // psUnnamedOptions = NULL; // Clear out the option values arrays for ( INT i = 0; i < VSSADM_O_NUM_OPTIONS; ++i ) apwszOptionValues[ i ] = NULL; }; ~SVssAdmParsedCommand() { // Free any allocated memory for ( INT i = 0; i < VSSADM_O_NUM_OPTIONS; ++i ) ::VssFreeString( apwszOptionValues[ i ] ); } }; extern const SVssAdmOption g_asAdmOptions[]; extern const SVssAdmCommandsEntry g_asAdmCommands[]; extern const SVssAdmSnapshotTypeName g_asAdmTypeNames[]; LPWSTR GuidToString( IN GUID guid ); LPWSTR LonglongToString( IN LONGLONG llValue ); LPWSTR DateTimeToString( IN VSS_TIMESTAMP *pTimeStamp ); WCHAR MyGetChar( ); BOOL MapVssErrorToMsg( IN HRESULT hr, OUT LONG *plMsgNum ) throw( HRESULT ); ///////////////////////////////////////////////////////////////////////////// // class CVssAdminCLI class CCommandVerifier; class CVssAdminCLI { // Enums and typedefs private: enum _RETURN_VALUE { VSS_CMDRET_SUCCESS = 0, VSS_CMDRET_EMPTY_RESULT = 1, VSS_CMDRET_ERROR = 2, }; // Constructors& destructors private: CVssAdminCLI(const CVssAdminCLI&); CVssAdminCLI(); public: CVssAdminCLI( IN INT argc, IN PWSTR argv[] ); ~CVssAdminCLI(); // Attributes private: BOOL IsQuiet() { return GetOptionValueBool( VSSADM_O_QUIET ); } INT GetReturnValue() { return m_nReturnValue; }; LPWSTR GetOptionValueStr( IN EVssAdmOption eOption ) { CVssFunctionTracer ft( VSSDBG_VSSADMIN, L"CVssAdminCLI::GetOptionValueStr" ); BS_ASSERT( g_asAdmOptions[ eOption ].eOptType == VSSADM_OT_STR ); // BS_ASSERT( g_asAdmCommands[ m_sParsedCommand.eAdmCmd].aeOptionFlags[ eOption ] != V_NO ); return m_sParsedCommand.apwszOptionValues[ eOption ]; }; BOOL GetOptionValueBool( IN EVssAdmOption eOption ) { CVssFunctionTracer ft( VSSDBG_VSSADMIN, L"CVssAdminCLI::GetOptionValueBool" ); BS_ASSERT( g_asAdmOptions[ eOption ].eOptType == VSSADM_OT_BOOL ); BS_ASSERT( g_asAdmCommands[ m_sParsedCommand.eAdmCmd].aeOptionFlags[ eOption ] != V_NO ); return m_sParsedCommand.apwszOptionValues[ eOption ] != NULL; }; BOOL GetOptionValueNum( IN EVssAdmOption eOption, OUT LONGLONG *pllValue, IN BOOL bSuffixAllowed = TRUE ) throw( HRESULT ) { CVssFunctionTracer ft( VSSDBG_VSSADMIN, L"CVssAdminCLI::GetOptionValueNum" ); BS_ASSERT( g_asAdmOptions[ eOption ].eOptType == VSSADM_OT_NUM ); BS_ASSERT( g_asAdmCommands[ m_sParsedCommand.eAdmCmd].aeOptionFlags[ eOption ] != V_NO ); if ( m_sParsedCommand.apwszOptionValues[ eOption ] == NULL ) { BS_ASSERT( g_asAdmCommands[ m_sParsedCommand.eAdmCmd].aeOptionFlags[ eOption ] == V_OPT ); // Option wasn't specified on command line - an optional one *pllValue = 0; return FALSE; } *pllValue = ScanNumber( m_sParsedCommand.apwszOptionValues[ eOption ], bSuffixAllowed ); return TRUE; }; // Operations public: static HRESULT Main( IN INT argc, IN PWSTR argv[] ); private: void Initialize( ) throw(HRESULT); BOOL ParseCmdLine( ) throw(HRESULT); void DoProcessing( ) throw(HRESULT); void Finalize(); // Processing private: void PrintUsage( ) throw(HRESULT); // The following are the methods that get called for each command. void AddDiffArea( ) throw(HRESULT); void CreateSnapshot( ) throw(HRESULT); void DeleteDiffAreas( ) throw(HRESULT); void DeleteSnapshots( ) throw(HRESULT); void ExposeSnapshot( ) throw(HRESULT); void ListDiffAreas( ) throw(HRESULT); void ListProviders( ) throw(HRESULT); void ListSnapshots( ) throw(HRESULT); void ListVolumes( ) throw(HRESULT); void ListWriters( ) throw(HRESULT); void ResizeDiffArea( ) throw(HRESULT); // Implementation private: static BOOL UnloggableError(IN HRESULT hError); void GetDifferentialSoftwareSnapshotMgmtInterface( IN VSS_ID ProviderId, IN IVssSnapshotMgmt *pIMgmt, OUT IUnknown** ppItf ); LPCWSTR GetVolumeDisplayName( IN LPCWSTR pwszVolumeName ); LONG DetermineSnapshotType( IN LPCWSTR pwszType ) throw(HRESULT); LPWSTR DetermineSnapshotType( IN LONG lSnapshotAttributes ) throw(HRESULT); void DisplayDiffAreasPrivate( IVssEnumMgmtObject *pIEnumMgmt ) throw(HRESULT); LPWSTR BuildSnapshotAttributeDisplayString( IN DWORD Attr ) throw(HRESULT); void DumpSnapshotTypes( ) throw(HRESULT); LPCWSTR LoadString( IN UINT nStringId ) throw(HRESULT); LPCWSTR GetNextCmdlineToken( IN bool bFirstToken = false ) throw(HRESULT); bool Match( IN LPCWSTR wszString, IN LPCWSTR wszPatternString ) throw(HRESULT); bool ScanGuid( IN LPCWSTR wszString, OUT VSS_ID& Guid ) throw(HRESULT); void Output( IN LPCWSTR wszFormat, ... ) throw(HRESULT); void OutputMsg( IN LONG msgId, ... ) throw(HRESULT); void OutputOnConsole( IN LPCWSTR wszStr ); LPWSTR GetMsg( IN BOOL bLineBreaks, IN LONG msgId, ... ); void AppendMessageToStr( IN LPWSTR pwszString, IN SIZE_T cMaxStrLen, IN LONG lMsgId, IN DWORD AttrBit, IN LPCWSTR pwszDelimitStr ) throw( HRESULT ); LONGLONG ScanNumber( IN LPCWSTR pwszNumToConvert, IN BOOL bSuffixAllowed ) throw( HRESULT ); LPWSTR FormatNumber( IN LONGLONG llNum ) throw(HRESULT); void OutputErrorMsg( IN LONG msgId, ... ) throw(HRESULT); BOOL PromptUserForConfirmation( IN LONG lPromptMsgId, IN ULONG ulNum ); void GetProviderId( OUT VSS_ID *pProviderId ); LPCWSTR GetProviderName( IN VSS_ID& ProviderId ) throw(HRESULT); BOOL GetProviderIdByName( IN LPCWSTR pwszProviderName, OUT VSS_ID *pProviderId ) throw(HRESULT); // Data members private: CCommandVerifier* m_pVerifier; HANDLE m_hConsoleOutput; CVssSimpleMap m_mapCachedResourceStrings; CVssSimpleMap m_mapCachedProviderNames; CVssSimpleMap *m_pMapVolumeNames; INT m_nReturnValue; INT m_argc; PWSTR *m_argv; EVssAdmCommand m_eCommandType; SVssAdmParsedCommand m_sParsedCommand; VSS_OBJECT_TYPE m_eFilterObjectType; VSS_OBJECT_TYPE m_eListedObjectType; VSS_ID m_FilterSnapshotId; }; class CVssAutoSnapshotProperties { // Constructors/destructors private: CVssAutoSnapshotProperties(const CVssAutoSnapshotProperties&); public: CVssAutoSnapshotProperties(VSS_SNAPSHOT_PROP &Snap): m_pSnap(&Snap) {}; CVssAutoSnapshotProperties(VSS_OBJECT_PROP &Prop): m_pSnap(&Prop.Obj.Snap) {}; // Automatically closes the handle ~CVssAutoSnapshotProperties() { Clear(); }; // Operations public: // Returns the value VSS_SNAPSHOT_PROP *GetPtr() { return m_pSnap; } // NULLs out the pointer. Used after a pointer has been transferred to another // funtion. void Transferred() { m_pSnap = NULL; } // Clears the contents of the auto string void Clear() { if ( m_pSnap != NULL ) { ::VssFreeSnapshotProperties(m_pSnap); m_pSnap = NULL; } } // Returns the value to the actual pointer VSS_SNAPSHOT_PROP* operator->() const { return m_pSnap; } // Returns the value of the actual pointer operator VSS_SNAPSHOT_PROP* () const { return m_pSnap; } private: VSS_SNAPSHOT_PROP *m_pSnap; }; #endif //__VSS_DEMO_H_