Пример #1
0
bool VSSClientGeneric::CloseRestore()
{
   //HRESULT hr;
   IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject;
   CComPtr<IVssAsync> pAsync;

   if (!pVssObj) {
      errno = ENOSYS;
      return false;
   }
#if 0
/* done by plugin now */
   if (SUCCEEDED(hr = pVssObj->PostRestore(&pAsync.p))) {
      // Waits for the async operation to finish and checks the result
      WaitAndCheckForAsyncOperation(pAsync.p);
      /* get latest info about writer status */
      if (!CheckWriterStatus()) {
         errno = b_errno_win32;
         return false;
      }
   } else {
      errno = b_errno_win32;
      return false;
   }
#endif
   return true;
}
Пример #2
0
// Query all the shadow copies in the given set
void VSSClientGeneric::QuerySnapshotSet(GUID snapshotSetID)
{
   if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) {
      Jmsg(m_jcr, M_FATAL, 0, "CreateVssBackupComponents or VssFreeSnapshotProperties API is NULL.\n");
      errno = ENOSYS;
      return;
   }

   memset(m_szShadowCopyName,0,sizeof (m_szShadowCopyName));

   if (snapshotSetID == GUID_NULL || m_pVssObject == NULL) {
      Jmsg(m_jcr, M_FATAL, 0, "snapshotSetID == NULL or VssObject is NULL.\n");
      errno = ENOSYS;
      return;
   }

   IVssBackupComponents* pVssObj = (IVssBackupComponents*) m_pVssObject;

   // Get list all shadow copies.
   CComPtr<IVssEnumObject> pIEnumSnapshots;
   HRESULT hr = pVssObj->Query( GUID_NULL,
         VSS_OBJECT_NONE,
         VSS_OBJECT_SNAPSHOT,
         (IVssEnumObject**)(&pIEnumSnapshots) );

   // If there are no shadow copies, just return
   if (FAILED(hr)) {
      Jmsg(m_jcr, M_FATAL, 0, "No Volume Shadow copies made.\n");
      errno = b_errno_win32;
      return;
   }

   // Enumerate all shadow copies.
   VSS_OBJECT_PROP Prop;
   VSS_SNAPSHOT_PROP& Snap = Prop.Obj.Snap;

   while (true) {
      // Get the next element
      ULONG ulFetched;
      hr = (pIEnumSnapshots.p)->Next( 1, &Prop, &ulFetched );

      // We reached the end of list
      if (ulFetched == 0)
         break;

      // Print the shadow copy (if not filtered out)
      if (Snap.m_SnapshotSetId == snapshotSetID)  {
         for (int ch='A'-'A';ch<='Z'-'A';ch++) {
            if (wcscmp(Snap.m_pwszOriginalVolumeName, m_wszUniqueVolumeName[ch]) == 0) {
               wcsncpy(m_szShadowCopyName[ch],Snap.m_pwszSnapshotDeviceObject, MAX_PATH-1);
               break;
            }
         }
      }
      p_VssFreeSnapshotProperties(&Snap);
   }
   errno = 0;
}
Пример #3
0
BOOL VSSClientGeneric::CloseBackup()
{
   BOOL bRet = FALSE;
   if (!m_pVssObject)
      errno = ENOSYS;
   else {
      IVssBackupComponents* pVss = (IVssBackupComponents*) m_pVssObject;
      CComPtr<IVssAsync>  pAsync;

      SetVSSPathConvert(NULL, NULL);

      m_bBackupIsInitialized = false;

      if (SUCCEEDED(pVss->BackupComplete(&pAsync.p))) {
         // Waits for the async operation to finish and checks the result
         WaitAndCheckForAsyncOperation(pAsync.p);
         bRet = TRUE;     
      } else {
         errno = b_errno_win32;
         pVss->AbortBackup();
      }

      /* get latest info about writer status */
      CheckWriterStatus();

      if (m_uidCurrentSnapshotSet != GUID_NULL) {
         VSS_ID idNonDeletedSnapshotID = GUID_NULL;
         LONG lSnapshots;

         pVss->DeleteSnapshots(
            m_uidCurrentSnapshotSet, 
            VSS_OBJECT_SNAPSHOT_SET,
            FALSE,
            &lSnapshots,
            &idNonDeletedSnapshotID);

         m_uidCurrentSnapshotSet = GUID_NULL;
      }

      pVss->Release();
      m_pVssObject = NULL;
   }

   // Call CoUninitialize if the CoInitialize was performed sucesfully
   if (m_bCoInitializeCalled) {
      CoUninitialize();
      m_bCoInitializeCalled = false;
   }

   return bRet;
}
Пример #4
0
// Check the status for all selected writers
BOOL VSSClientGeneric::CheckWriterStatus()
{
    /* 
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp
    */
    IVssBackupComponents* pVss = (IVssBackupComponents*) m_pVssObject;
    DestroyWriterInfo();

    // Gather writer status to detect potential errors
    CComPtr<IVssAsync>  pAsync;
    
    HRESULT hr = pVss->GatherWriterStatus(&pAsync.p);
    if (FAILED(hr)) {
       errno = b_errno_win32;
       return FALSE;
    } 

    // Waits for the async operation to finish and checks the result
    WaitAndCheckForAsyncOperation(pAsync.p);
      
    unsigned cWriters = 0;

    hr = pVss->GetWriterStatusCount(&cWriters);
    if (FAILED(hr)) {
       errno = b_errno_win32;
       return FALSE;
    }

    int nState;
    
    // Enumerate each writer
    for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) {
        VSS_ID idInstance = GUID_NULL;
        VSS_ID idWriter= GUID_NULL;
        VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN;
        CComBSTR bstrWriterName;
        HRESULT hrWriterFailure = S_OK;

        // Get writer status
        hr = pVss->GetWriterStatus(iWriter,
                             &idInstance,
                             &idWriter,
                             &bstrWriterName,
                             &eWriterStatus,
                             &hrWriterFailure);
        if (FAILED(hr)) {
            /* unknown */            
            nState = 0;
        }
        else {            
            switch(eWriterStatus) {
            case VSS_WS_FAILED_AT_IDENTIFY:
            case VSS_WS_FAILED_AT_PREPARE_BACKUP:
            case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT:
            case VSS_WS_FAILED_AT_FREEZE:
            case VSS_WS_FAILED_AT_THAW:
            case VSS_WS_FAILED_AT_POST_SNAPSHOT:
            case VSS_WS_FAILED_AT_BACKUP_COMPLETE:
            case VSS_WS_FAILED_AT_PRE_RESTORE:
            case VSS_WS_FAILED_AT_POST_RESTORE:
    #if  defined(B_VSS_W2K3) || defined(B_VSS_VISTA)
            case VSS_WS_FAILED_AT_BACKUPSHUTDOWN:
    #endif
                /* failed */                
                nState = -1;
                break;

            default:
                /* ok */
                nState = 1;
            }
        }
        /* store text info */
        char str[1000];
        char szBuf1[200];
        char szBuf2[200];
        char szBuf3[200];
        wchar_2_UTF8(szBuf1, bstrWriterName.p, sizeof(szBuf1));
        itoa(eWriterStatus, szBuf2, sizeof(szBuf2));
        wchar_2_UTF8(szBuf3, GetStringFromWriterStatus(eWriterStatus), sizeof(szBuf3));
	snprintf(str, sizeof(str), "\"%s\", State: 0x%s (%s)",
		szBuf1, szBuf2, szBuf3);

        AppendWriterInfo(nState, (const char *)str);     
    }

    hr = pVss->FreeWriterStatus();

    if (FAILED(hr)) {
        errno = b_errno_win32;
        return FALSE;
    } 

    errno = 0;
    return TRUE;
}
Пример #5
0
BOOL VSSClientGeneric::CreateSnapshots(char* szDriveLetters)
{
   /* szDriveLetters contains all drive letters in uppercase */
   /* if a drive can not being added, it's converted to lowercase in szDriveLetters */
   /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp */
   
   if (!m_pVssObject || m_bBackupIsInitialized) {
      errno = ENOSYS;
      return FALSE;  
   }

   m_uidCurrentSnapshotSet = GUID_NULL;

   IVssBackupComponents *pVss = (IVssBackupComponents*)m_pVssObject;

   /* startSnapshotSet */

   pVss->StartSnapshotSet(&m_uidCurrentSnapshotSet);

   /* AddToSnapshotSet */

   wchar_t szDrive[3];
   szDrive[1] = ':';
   szDrive[2] = 0;

   wstring volume;

   CComPtr<IVssAsync>  pAsync1;
   CComPtr<IVssAsync>  pAsync2;   
   VSS_ID pid;

   for (size_t i=0; i < strlen (szDriveLetters); i++) {
      szDrive[0] = szDriveLetters[i];
      volume = GetUniqueVolumeNameForPath(szDrive);
      // store uniquevolumname
      if (SUCCEEDED(pVss->AddToSnapshotSet((LPWSTR)volume.c_str(), GUID_NULL, &pid))) {
         wcsncpy (m_wszUniqueVolumeName[szDriveLetters[i]-'A'], (LPWSTR) volume.c_str(), MAX_PATH);
      } else {            
         szDriveLetters[i] = tolower (szDriveLetters[i]);               
      }
   }

   /* PrepareForBackup */
   if (FAILED(pVss->PrepareForBackup(&pAsync1.p))) {      
      errno = b_errno_win32;
      return FALSE;   
   }
   
   // Waits for the async operation to finish and checks the result
   WaitAndCheckForAsyncOperation(pAsync1.p);

   /* get latest info about writer status */
   if (!CheckWriterStatus()) {
      errno = b_errno_win32;
      return FALSE;
   }

   /* DoSnapShotSet */   
   if (FAILED(pVss->DoSnapshotSet(&pAsync2.p))) {      
      errno = b_errno_win32;
      return FALSE;   
   }

   // Waits for the async operation to finish and checks the result
   WaitAndCheckForAsyncOperation(pAsync2.p); 
   
   /* query snapshot info */   
   QuerySnapshotSet(m_uidCurrentSnapshotSet);

   SetVSSPathConvert(VSSPathConvert, VSSPathConvertW);

   m_bBackupIsInitialized = true;

   return TRUE;
}
Пример #6
0
// Check the status for all selected writers
bool VSSClientGeneric::CheckWriterStatus()
{
    /*
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp
    */
    IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject;
    if (!pVssObj) {
       Jmsg(m_jcr, M_FATAL, 0, "Cannot get IVssBackupComponents pointer.\n");
       errno = ENOSYS;
       return false;
    }
    DestroyWriterInfo();

    if (m_bWriterStatusCurrent) {
       m_bWriterStatusCurrent = false;
       pVssObj->FreeWriterStatus();
    }
    // Gather writer status to detect potential errors
    CComPtr<IVssAsync>  pAsync;

    HRESULT hr = pVssObj->GatherWriterStatus(&pAsync.p);
    if (FAILED(hr)) {
       JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatus");
       errno = b_errno_win32;
       return false;
    }

    // Waits for the async operation to finish and checks the result
    if (!WaitAndCheckForAsyncOperation(pAsync.p)) {
       errno = b_errno_win32;
       return false;
    }

    m_bWriterStatusCurrent = true;

    unsigned cWriters = 0;

    hr = pVssObj->GetWriterStatusCount(&cWriters);
    if (FAILED(hr)) {
       JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatusCount");
       errno = b_errno_win32;
       return false;
    }

    int nState;
    POOLMEM *szBuf = get_pool_memory(PM_FNAME);
    // Enumerate each writer
    for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) {
        VSS_ID idInstance = GUID_NULL;
        VSS_ID idWriter= GUID_NULL;
        VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN;
        CComBSTR bstrWriterName;
        HRESULT hrWriterFailure = S_OK;

        // Get writer status
        hr = pVssObj->GetWriterStatus(iWriter,
                             &idInstance,
                             &idWriter,
                             &bstrWriterName,
                             &eWriterStatus,
                             &hrWriterFailure);
        if (FAILED(hr)) {
            /* Api failed */
            JmsgVssApiStatus(m_jcr, M_WARNING, hr, "GetWriterStatus");
            nState = 0;         /* Unknown writer state -- API failed */
        } else {
            switch(eWriterStatus) {
            case VSS_WS_FAILED_AT_IDENTIFY:
            case VSS_WS_FAILED_AT_PREPARE_BACKUP:
            case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT:
            case VSS_WS_FAILED_AT_FREEZE:
            case VSS_WS_FAILED_AT_THAW:
            case VSS_WS_FAILED_AT_POST_SNAPSHOT:
            case VSS_WS_FAILED_AT_BACKUP_COMPLETE:
            case VSS_WS_FAILED_AT_PRE_RESTORE:
            case VSS_WS_FAILED_AT_POST_RESTORE:
    #if  defined(B_VSS_W2K3) || defined(B_VSS_VISTA)
            case VSS_WS_FAILED_AT_BACKUPSHUTDOWN:
    #endif
                /* Writer status problem */
                wchar_2_UTF8(&szBuf, bstrWriterName.p);
                JmsgVssWriterStatus(m_jcr, M_WARNING, eWriterStatus, szBuf);
                nState = -1;       /* bad writer state */
                break;

            default:
                /* ok */
                nState = 1;        /* Writer state OK */
            }
        }
        /* store text info */
        char str[1000];
        bstrncpy(str, "\"", sizeof(str));
        wchar_2_UTF8(&szBuf, bstrWriterName.p);
        bstrncat(str, szBuf, sizeof(str));
        bstrncat(str, "\", State: 0x", sizeof(str));
        itoa(eWriterStatus, szBuf, sizeof_pool_memory(szBuf));
        bstrncat(str, szBuf, sizeof(str));
        bstrncat(str, " (", sizeof(str));
        wchar_2_UTF8(&szBuf, GetStringFromWriterStatus(eWriterStatus));
        bstrncat(str, szBuf, sizeof(str));
        bstrncat(str, ")", sizeof(str));
        AppendWriterInfo(nState, (const char *)str);
    }
    free_pool_memory(szBuf);
    errno = 0;
    return true;
}
Пример #7
0
bool VSSClientGeneric::CloseBackup()
{
   bool bRet = false;
   HRESULT hr;
   BSTR xml;
   IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject;

   if (!m_pVssObject) {
      Jmsg(m_jcr, M_FATAL, 0, "VssOject is NULL.\n");
      errno = ENOSYS;
      return bRet;
   }
   CComPtr<IVssAsync>  pAsync;

   SetVSSPathConvert(NULL, NULL);

   m_bBackupIsInitialized = false;

   hr = pVssObj->BackupComplete(&pAsync.p);
   if (SUCCEEDED(hr)) {
      // Waits for the async operation to finish and checks the result
      WaitAndCheckForAsyncOperation(pAsync.p);
      bRet = true;
   } else {
      JmsgVssApiStatus(m_jcr, M_ERROR, hr, "BackupComplete");
      errno = b_errno_win32;
      pVssObj->AbortBackup();
   }

   /* get latest info about writer status */
   CheckWriterStatus();

   hr = pVssObj->SaveAsXML(&xml);
   if (SUCCEEDED(hr)) {
      m_metadata = xml;
   } else {
      m_metadata = NULL;
   }

   /* FIXME?: The docs http://msdn.microsoft.com/en-us/library/aa384582%28v=VS.85%29.aspx say this isn't required... */
   if (m_uidCurrentSnapshotSet != GUID_NULL) {
      VSS_ID idNonDeletedSnapshotID = GUID_NULL;
      LONG lSnapshots;

      pVssObj->DeleteSnapshots(
         m_uidCurrentSnapshotSet,
         VSS_OBJECT_SNAPSHOT_SET,
         false,
         &lSnapshots,
         &idNonDeletedSnapshotID);

      m_uidCurrentSnapshotSet = GUID_NULL;
   }

   if (m_bWriterStatusCurrent) {
      m_bWriterStatusCurrent = false;
      pVssObj->FreeWriterStatus();
   }

   pVssObj->Release();
   m_pVssObject = NULL;

   // Call CoUninitialize if the CoInitialize was performed sucesfully
   if (m_bCoInitializeCalled) {
      CoUninitialize();
      m_bCoInitializeCalled = false;
   }

   return bRet;
}
Пример #8
0
// Initialize the COM infrastructure and the internal pointers
bool VSSClientGeneric::Initialize(DWORD dwContext, bool bDuringRestore)
{
   CComPtr<IVssAsync>  pAsync1;
   VSS_BACKUP_TYPE backup_type;
   IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject;

   if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) {
      Dmsg2(0, "VSSClientGeneric::Initialize: p_CreateVssBackupComponents=0x%08X, p_VssFreeSnapshotProperties=0x%08X\n", p_CreateVssBackupComponents, p_VssFreeSnapshotProperties);
      Jmsg(m_jcr, M_FATAL, 0, "Entry point CreateVssBackupComponents or VssFreeSnapshotProperties missing.\n");
      return false;
   }

   HRESULT hr;
   // Initialize COM
   if (!m_bCoInitializeCalled) {
      hr = CoInitialize(NULL);
      if (FAILED(hr)) {
         Dmsg1(0, "VSSClientGeneric::Initialize: CoInitialize returned 0x%08X\n", hr);
         JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CoInitialize");
         errno = b_errno_win32;
         return false;
      }
      m_bCoInitializeCalled = true;
   }

   // Initialize COM security
   if (!m_bCoInitializeSecurityCalled) {
      hr =
         CoInitializeSecurity(
         NULL,                           //  Allow *all* VSS writers to communicate back!
         -1,                             //  Default COM authentication service
         NULL,                           //  Default COM authorization service
         NULL,                           //  reserved parameter
         RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  //  Strongest COM authentication level
         RPC_C_IMP_LEVEL_IDENTIFY,       //  Minimal impersonation abilities
         NULL,                           //  Default COM authentication settings
         EOAC_NONE,                      //  No special options
         NULL                            //  Reserved parameter
         );

      if (FAILED(hr)) {
         Dmsg1(0, "VSSClientGeneric::Initialize: CoInitializeSecurity returned 0x%08X\n", hr);
         JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CoInitializeSecurity");
         errno = b_errno_win32;
         return false;
      }
      m_bCoInitializeSecurityCalled = true;
   }

   // Release the any old IVssBackupComponents interface
   if (pVssObj) {
      pVssObj->Release();
      m_pVssObject = NULL;
   }

   // Create new internal backup components object
   hr = p_CreateVssBackupComponents((IVssBackupComponents**)&m_pVssObject);
   if (FAILED(hr)) {
      berrno be;
      Dmsg2(0, "VSSClientGeneric::Initialize: CreateVssBackupComponents returned 0x%08X. ERR=%s\n",
            hr, be.bstrerror(b_errno_win32));
      JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CreateVssBackupComponents");
      errno = b_errno_win32;
      return false;
   }

   /* Define shorthand VssObject with time */
   pVssObj = (IVssBackupComponents*)m_pVssObject;


   if (!bDuringRestore) {
#if   defined(B_VSS_W2K3) || defined(B_VSS_VISTA)
      if (dwContext != VSS_CTX_BACKUP) {
         hr = pVssObj->SetContext(dwContext);
         if (FAILED(hr)) {
            Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->SetContext returned 0x%08X\n", hr);
            JmsgVssApiStatus(m_jcr, M_FATAL, hr, "SetContext");
            errno = b_errno_win32;
            return false;
         }
      }
#endif

      // 1. InitializeForBackup
      hr = pVssObj->InitializeForBackup();
      if (FAILED(hr)) {
         Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->InitializeForBackup returned 0x%08X\n", hr);
         JmsgVssApiStatus(m_jcr, M_FATAL, hr, "InitializeForBackup");
         errno = b_errno_win32;
         return false;
      }

      // 2. SetBackupState
      switch (m_jcr->getJobLevel()) {
      case L_FULL:
         backup_type = VSS_BT_FULL;
         break;
      case L_DIFFERENTIAL:
         backup_type = VSS_BT_DIFFERENTIAL;
         break;
      case L_INCREMENTAL:
         backup_type = VSS_BT_INCREMENTAL;
         break;
      default:
         Dmsg1(0, "VSSClientGeneric::Initialize: unknown backup level %d\n", m_jcr->getJobLevel());
         backup_type = VSS_BT_FULL;
         break;
      }
      hr = pVssObj->SetBackupState(true, true, backup_type, false); /* FIXME: need to support partial files - make last parameter true when done */
      if (FAILED(hr)) {
         Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->SetBackupState returned 0x%08X\n", hr);
         JmsgVssApiStatus(m_jcr, M_FATAL, hr, "SetBackupState");
         errno = b_errno_win32;
         return false;
      }

      // 3. GatherWriterMetaData
      hr = pVssObj->GatherWriterMetadata(&pAsync1.p);
      if (FAILED(hr)) {
         Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->GatherWriterMetadata returned 0x%08X\n", hr);
         JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterMetadata");
         errno = b_errno_win32;
         return false;
      }
      // Waits for the async operation to finish and checks the result
      if (!WaitAndCheckForAsyncOperation(pAsync1.p)) {
         /* Error message already printed */
         errno = b_errno_win32;
         return false;
      }
   }

   // We are during restore now?
   m_bDuringRestore = bDuringRestore;

   // Keep the context
   m_dwContext = dwContext;

   return true;
}