Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Volume Shadow Copy Service nutzen (https://www.delphipraxis.net/147733-volume-shadow-copy-service-nutzen.html)

HeikoAdams 15. Feb 2010 08:10


Volume Shadow Copy Service nutzen
 
Hallo,
gibt es hier jemanden, der den Volume Shadow Copy Service mit Delphi nutzt? :gruebel:
Die übersetzten Header-Dateien, die das Delphi Magazine veröffentlicht[1] hat, funktionieren leider nicht mehr unter Vista oder neuer. Beim Aufruf von "AddToSnapshotSet" gibt es jedes mal einen Integer-Overflow. Google war bei der Suche nach einer Lösung leider auch nicht hilfreich.

Viele Grüße

Heiko

[1] http://bit.ly/b0qkV9

Dezipaitor 15. Feb 2010 09:52

Re: Volume Shadow Copy Service nutzen
 
Die Header müssen funktionieren, da nach COM Regeln, sich die Schnittstellen nicht ändern, aber neue hinzukommen dürfen.

Scheint mir daher ein Programmier- bzw. Übersetzungsfehler zu sein.

HeikoAdams 15. Feb 2010 10:05

Re: Volume Shadow Copy Service nutzen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe mal die VSS-Dateien des Delphi Magazins, die ich verwende angehängt. Das einzige, was ich geändert habe, ist die Umstellung von static auf dynamic linking.

Folgende Routine dürfte ergo unter Vista/7 nicht durchlaufen
Delphi-Quellcode:
Const
  SYSTEM_WRITER_NAME         = 'System Writer';
  SYSTEM_FILES_COMPONENT_NAME = 'System Files';

Var
  InstanceGUID : TGUID;
  WriterGUID  : TGUID;
  BackupComps : IVssBackupComponents;
  SetGUID     : TGUID;
  SnapGUID    : TGUID;
  Async       : IVssAsync;
  SnapProp    : VSS_SNAPSHOT_PROP;
  SourceFile  : String;
  Drive       : String;
  ShadowPath  : String;
  Path        : String;
  DestPath    : String;
  ErrorMsg    : String;

begin
  BackupLogMemo.Clear();
  BackupLogMemo.Lines.Add('Starting backup operation.');
  BackupProgressBar.Position := 0;
  BackupProgressBar.Max := 10;
  GetVssGUIDsByName(SYSTEM_WRITER_NAME,InstanceGUID,WriterGUID);
  BackupLogMemo.Lines.Add('Writer name = "'+SYSTEM_WRITER_NAME+'".');
  BackupLogMemo.Lines.Add('Instance = '+GUIDToString(InstanceGUID)+'.');
  BackupLogMemo.Lines.Add('Writer = '+GUIDToString(WriterGUID)+'.');
  BackupProgressBar.StepIt();
  GetBackupComponentsAndInitialize(BackupComps,WriterGUID);
  BackupProgressBar.StepIt();
  OleCheck(BackupComps.SetBackupState(True,False,VSS_BT_COPY,False));
  BackupLogMemo.Lines.Add('Backup state has been set.');
  BackupProgressBar.StepIt();
  BackupLogMemo.Lines.Add('Starting a snapshot set...');
  OleCheck(BackupComps.StartSnapshotSet(SetGUID));
  BackupLogMemo.Lines.Add('Created backup set with ID '+GUIDToString(SetGUID)+'.');
  BackupProgressBar.StepIt();
  SourceFile := FileToBackUpEdit.Text;
  BackupLogMemo.Lines.Add('Source file = "'+SourceFile+'".');
  Drive := IncludeTrailingPathDelimiter(ExtractFileDrive(SourceFile));
  BackupLogMemo.Lines.Add('Drive to snapshot = '+Drive+'.');
  OleCheck(BackupComps.AddToSnapshotSet(Drive,GUID_NULL,SnapGUID)); // hier kommt immer der Integer overflow
  BackupLogMemo.Lines.Add('Drive '+Drive+' has been added to the set.');
  BackupLogMemo.Lines.Add('Snap GUID = '+GUIDToString(SnapGUID)+'.');
  BackupProgressBar.StepIt();
  OleCheck(BackupComps.AddComponent(InstanceGUID,WriterGUID,
           VSS_CT_FILEGROUP,nil,SYSTEM_FILES_COMPONENT_NAME));
  BackupLogMemo.Lines.Add('System component added.');
  BackupProgressBar.StepIt();
  Try
    OleCheck(BackupComps.PrepareForBackup(Async));
    Async.Wait(INFINITE);
    Async := nil;
    BackupLogMemo.Lines.Add('Preparations for backup finished.');
    BackupProgressBar.StepIt();
    OleCheck(BackupComps.DoSnapshotSet(Async));
    Async.Wait(INFINITE);
    Async := nil;
    BackupLogMemo.Lines.Add('Snapshot done.');
    BackupProgressBar.StepIt();
    { start the real backup }
    OleCheck(BackupComps.GetSnapshotProperties(SnapGUID,SnapProp));
    BackupLogMemo.Lines.Add('Got backup properties.');
    BackupProgressBar.StepIt();
    If ShowMetadataCheckBox.Checked Then Begin
      OutputBackupProperties(SnapProp);
    End;
    { copy files }
    Path := System.Copy(SourceFile,3,Length(SourceFile)-2); { remove drive ("C:") }
    ShadowPath := WideCharToString(SnapProp.m_pwszSnapshotDeviceObject);
    Path := ShadowPath+Path;
    DestPath := IncludeTrailingPathDelimiter(DestinationDirEdit.Text)+
                ExtractFileName(SourceFile);
    BackupLogMemo.Lines.Add('Shadow path (source) = "'+Path+'".');
    BackupLogMemo.Lines.Add('Destination file = "'+DestPath+'".');
    BackupProgressBar.StepIt();
    If (Not CopyFile(PAnsiChar(Path),PAnsiChar(DestPath),True)) Then Begin
      ErrorMsg := 'File backup failed: '+SysErrorMessage(GetLastError())+'.';
      BackupLogMemo.Lines.Add(ErrorMsg);
      ShowMessage(ErrorMsg);
    End
    Else Begin
      ErrorMsg := 'File backup OK!';
      BackupLogMemo.Lines.Add(ErrorMsg);
      ShowMessage(ErrorMsg);
    End;
    { clean up }
    BackupLogMemo.Lines.Add('Cleaning up resources...');
    VssFreeSnapshotProperties(@SnapProp);
    OleCheck(BackupComps.SetBackupSucceeded(InstanceGUID,WriterGUID,
             VSS_CT_FILEGROUP,nil,SYSTEM_FILES_COMPONENT_NAME,True));
  Finally
    BackupComps.BackupComplete(Async);
    Async.Wait(INFINITE);
    Async := nil;
    BackupLogMemo.Lines.Add('Backup is now complete.');
    BackupProgressBar.Position := 0;
  End;

himitsu 15. Feb 2010 10:07

Re: Volume Shadow Copy Service nutzen
 
Sind das auch gleichwertige OS?

Nicht daß es z.B. auf XP-32 geht und du es jetzt nur unter Vista/Seven-64 getestet hast.

HeikoAdams 15. Feb 2010 10:09

Re: Volume Shadow Copy Service nutzen
 
Also ich kann das nur unter Windows 7 32 Bit testen. Aber Du hast Recht, irgendwo hab ich was gelesen, das sich die API zwischen XP und Vista geändert hat und nicht mehr (binär) kompatibel ist.

Alter Mann 15. Feb 2010 10:32

Re: Volume Shadow Copy Service nutzen
 
Hi,

habe bei MSDN mal nachgeschaut, es steht immer noch Version 7.2 des SDK's zur Verfügung.
Allerdings gibt es in der VssAPI.pas ein kleinen Stolperstein, CreateVssBackupComponents hat
unter XP-32 den Index 12.

Gruss

HeikoAdams 15. Feb 2010 10:38

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von Alter Mann
Allerdings gibt es in der VssAPI.pas ein kleinen Stolperstein, CreateVssBackupComponents hat
unter XP-32 den Index 12.

Darum ja auch das dynamische Linken in der VssUtilities.pas mittels Delphi-Referenz durchsuchenSafeLoadLibrary und Delphi-Referenz durchsuchenGetProcAddress 8-)

himitsu 15. Feb 2010 10:47

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von HeikoAdams
Darum ja auch das dynamische Linken in der VssUtilities.pas mittels Delphi-Referenz durchsuchenSafeLoadLibrary und Delphi-Referenz durchsuchenGetProcAddress 8-)

Bist du sicher, daß diese Funktion dann auch gefunden wird?
Immerhin scheinst du dieses ja nicht zu prüfen.

Da diese Funktion sonst immer über einen Index und nicht via Name gelinkt wird, könnte es glatt sein, daß sie in der Exportabelle garnicht namentlich enthalten ist und somit auch nicht über einen Namen gefunden werden kann.

Und das Ergebnis von CreateVssBackupComponents prüfst du auch nicht mehr. (OleCheck)

HeikoAdams 15. Feb 2010 10:52

Re: Volume Shadow Copy Service nutzen
 
In der MSDN Beschreibung zu MSDN-Library durchsuchenCreateVssBackupComponents steht:
Zitat:

Note This function is exported as CreateVssBackupComponentsInternal, but you should call CreateVssBackupComponents, not CreateVssBackupComponentsInternal.
Also lasse ich GetProcAddress auf CreateVssBackupComponentsInternal losgehen. Oder mach ich schon was falsch?

Zitat:

Zitat von himitsu
Und das Ergebnis von CreateVssBackupComponents prüfst du auch nicht mehr. (OleCheck)

[x] fixed -> danke :thumb:

himitsu 15. Feb 2010 11:04

Re: Volume Shadow Copy Service nutzen
 
Hmmm, wenn MS das so sagt.

Warum nutzten dann die Anderen den Index?

Aber dennoch sollte man Prüfen, ob es auch wirklich gefunden wurde.

PS: Wenn du den Namen kennst, dann kannste das doch auch als Hartlink aufrufen.
Delphi-Quellcode:
Function CreateVssBackupComponents(
  Var ppBackup : IVssBackupComponents) : HRESULT; StdCall;
  External VSS_API_DLL Name 'CreateVssBackupComponentsInternal';
Zitat:

Doubly indirect pointer to the created IVssBackupComponents interface object.
Aber dieses "Doubly" kommt mir komisch vor

VAR ist doch nur ein einfacher Zeiger.

HeikoAdams 15. Feb 2010 11:17

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von himitsu
Warum nutzten dann die Anderen den Index?

Keine Ahnung, nur finde ich es sicherer, über den Namen anstatt des Indexes zu gehen. Ändert sich der Index aus irgendeinem Grund, hätte ich ein Problem. Gehe ich über den Namen, kann mir der Index schnuppe sein.
Ändert M$ jedoch den exportierten Namen einer Funktion, darf man wohl davon ausgehen, das der alte Name zumindest als Dummy auch weiterhin exportiert wird. Ansonsten wäre es mit der Abwärtskompatibilität ganz schnell Essig.

Zitat:

Zitat von himitsu
Zitat:

Doubly indirect pointer to the created IVssBackupComponents interface object.
Aber dieses "Doubly" kommt mir komisch vor

VAR ist doch nur ein einfacher Zeiger.

Ich habe keine Ahnung, wie man bei Delphi einen doppelten indirekten Zeiger deklariert bzw. welcher Datentyp das sein soll. Am ehesten dürfte dem wohl ein als VAR-Parameter übergebener Pointer entsprechen. :gruebel:

Zacherl 15. Feb 2010 11:49

Re: Volume Shadow Copy Service nutzen
 
Oder im C++ Style ein PPointer ^^

HeikoAdams 15. Feb 2010 14:04

Re: Volume Shadow Copy Service nutzen
 
Mein Problem, das
Delphi-Quellcode:
OleCheck(BackupComps.AddToSnapshotSet(Drive,GUID_NULL,SnapGUID));
immer einen Integer overflow verursacht, ist leider nicht dadurch behoben, das ich den Aufruf von CreateVssBackupComponents bzw. CreateVssBackupComponentsInternal ändere. Das IVssBackupComponents wird auch korrekt initialisiert, da die Funktionsaufrufe davor klappen.

Alter Mann 15. Feb 2010 14:24

Re: Volume Shadow Copy Service nutzen
 
Hi,

was kommt den Zurück?

Delphi-Quellcode:
...
var
   Ret : HResult;
...
  Ret := BackupComps.AddToSnapshotSet(Drive,GUID_NULL,SnapGUID);
  OleCheck(Ret);                                                // <- Haltepunkt und prüfen
...
Gruss

Dezipaitor 15. Feb 2010 14:44

Re: Volume Shadow Copy Service nutzen
 
Wäre es nicht einfacher eine Demo zu bauen, die man auch testen könnte?

HeikoAdams 15. Feb 2010 14:47

Re: Volume Shadow Copy Service nutzen
 
AddToSnapshotSet liefert als Ergebnis -2147212529 zurück

Zitat:

Zitat von Dezipaitor
Wäre es nicht einfacher eine Demo zu bauen, die man auch testen könnte?

Der Link im ersten Post führt zu einer Demo ;-)

Dezipaitor 15. Feb 2010 14:58

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von HeikoAdams
AddToSnapshotSet liefert als Ergebnis -2147212529 zurück

Zitat:

Zitat von Dezipaitor
Wäre es nicht einfacher eine Demo zu bauen, die man auch testen könnte?

Der Link im ersten Post führt zu einer Demo ;-)

Nein, das ist Codesearch. Da kann man sich die Dateien ansehen. Aber von Runterladen sehe ich nichts.

HeikoAdams 15. Feb 2010 15:02

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von Dezipaitor
Nein, das ist Codesearch. Da kann man sich die Dateien ansehen. Aber von Runterladen sehe ich nichts.

Naja, man kann sich die VSSApi, die VSSUtils per Copy&Paste "runterladen" und die Testroutine hab ich ja auch schon gepostet

Alter Mann 15. Feb 2010 15:14

Re: Volume Shadow Copy Service nutzen
 
Hi,

VSS_E_UNEXPECTED_PROVIDER_ERROR != Integer-Overflow

So wird das nichts...

himitsu 15. Feb 2010 15:17

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von Alter Mann
Hi,

VSS_E_UNEXPECTED_PROVIDER_ERROR != Integer-Overflow

So wird das nichts...

http://support.microsoft.com/kb/924262

Dezipaitor 15. Feb 2010 15:22

Re: Volume Shadow Copy Service nutzen
 
Der angegebene Fehler in Hex ist 8004230F. Man erkennt die Facility 4, welche FACILITY_ITF
(The source of the error code is COM/OLE Interface management) ist.
Die Meldungsid 230F ist jedoch völlig unbekannt.

COM Interface management sieht danach aus, als ob irgendetwas an der Deklaration nicht kompatibel ist.

Dezipaitor 15. Feb 2010 15:24

Re: Volume Shadow Copy Service nutzen
 
Zitat:

Zitat von HeikoAdams
Zitat:

Zitat von Dezipaitor
Nein, das ist Codesearch. Da kann man sich die Dateien ansehen. Aber von Runterladen sehe ich nichts.

Naja, man kann sich die VSSApi, die VSSUtils per Copy&Paste "runterladen" und die Testroutine hab ich ja auch schon gepostet

Ich bin wie eine Menge anderer Menschen von Natur aus faul.

HeikoAdams 15. Feb 2010 15:51

Re: Volume Shadow Copy Service nutzen
 
Ich bin mir noch nicht sicher, ob das etwas mit dem Ausgangsproblem zu tun hat, aber der Aufruf von
Delphi-Quellcode:
OleCheck(BackupComps.GatherWriterMetadata(Async));
in der GetBackupComponentsAndInitialize Prozedur der VssUtils.pas erzeugt einen "Zugriff verweigert" Eintrag im Ereignisprotokoll von Windows, obwohl ich Admin-Rechte habe. :wiejetzt: Evtl. ist mein ursprüngliches Problem nur ein Folgefehler :gruebel:

himitsu 15. Feb 2010 16:07

Re: Volume Shadow Copy Service nutzen
 
Vorallem in Win7 hat ein Programm nicht gleich volle Adminrechte, nur weil der User als Admin angemeldet ist.

HeikoAdams 15. Feb 2010 16:10

Re: Volume Shadow Copy Service nutzen
 
Das Zauberwort scheint
Delphi-Quellcode:
CoInitializeSecurity
zu heißen. Näheres aber erst Mittwoch. Morgen habe ich Urlaub :twisted:

Dezipaitor 15. Feb 2010 20:42

Re: Volume Shadow Copy Service nutzen
 
Mit CoInitializeSecurity kann man COM Verbindungseinstellungen und Sicherheitsattribute festlegen. Ohne, werden Defaulteinstellungen verwendet, die trotzdem funktionieren sollten, weil sie Einstellungen des Servers übernehmen.

HeikoAdams 15. Feb 2010 20:49

Re: Volume Shadow Copy Service nutzen
 
Das Problem dürfte wohl eher bei Windows liegen:
Für den Einsatz VSCS benötigt man Backup- oder Admin-Rechte. Zumindest letztere hat eine Anwendung ja seit Vista nicht mehr per se, selbst wenn Sie von einem Admin gestartet wird.

Geb einfach mal als Admin in der cmd "vssadmin list writer" ein, dann siehst Du, was ich meine.

HeikoAdams 22. Feb 2010 21:33

Re: Volume Shadow Copy Service nutzen
 
Also was ich bis jetzt definitiv sagen kann, ist, dass man (unter Vista/7) beim Start der Anwendung CoInitSecurity aufrufen muss. Ansonsten gibt es einen Haufen "Zugriff verweigert" Einträge im Ereignissprotokoll von Windows.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz