AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Prüfen, ob VirtualStore aktiv ist
Thema durchsuchen
Ansicht
Themen-Optionen

Prüfen, ob VirtualStore aktiv ist

Ein Thema von berens · begonnen am 24. Nov 2011 · letzter Beitrag vom 24. Nov 2011
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#1

Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 11:38
Hallo zusammen,
aus vielen Gründen kann es notwendig sein zu prüfen, ob eine Datei oder ein Ordner von Windows "heimlich" umgeleitet werden auf den VirtualStore.

Anstelle einer Fehlermeldung, dass z.B. nach "c:\program files\project1\datenbank.mdb" nicht geschrieben werden kann, wird von Windows einfach eine Kopie der Datei angefertigt und zukünftig -für diesen Benutzer- mit der Kopie gearbeitet. Das ist gravierend, wenn mehrere Benutzer mit der selben Datenbank arbeiten, die evtl. ein Administrator (absichtlich/versehentlich) im "Programme"-Ordner platziert hat: Der Administrator arbeitet mit der tatsächlichen Datei unter "Programme", die anderen Benutzer jeweils mit einer Kopie vom aller ersten Zugriff auf diese Datei. Somit haben alle Benutzer jeweils einen verschiedenen Stand der Datenbank. Mit dieser Routine möchte ich auf dieses Problem prüfen und -bei vorhandensein dieses Problems- ggf. eine Warnmeldung an den Benutzer ausgeben, dass er mit Administrator-Rechten die Datenbank an einen anderen Ort verschiebt und die (virtuellen) Kopien löscht.

Evtl. könnte man auch das Manifest "runterschrauben", so dass statt der Ordner-Umleitung eine Fehlermeldung erscheint. Hier möchte ich aber -falls das sprichwörtliche Kind bereits in den Brunnnen gefallen ist- einfach nur prüfen, ob das Problem bereits besteht.

Falls jemand eine elegantere Methode kennt -speziell um den "VirtualStore"-Ordner zu ermitteln, statt ihn wie hier zusammenzustückeln-, möge es es bitte als Antwort posten.

Was meint ihr? Ist diese Funktion ok, oder geht man da komplett anders ran?


Delphi-Quellcode:
// Prüft, ob die zu testende Datei, z.B. "c:\program files\project1\datenbank.mdb",
// wirklich unter "c:\program files\project1\" geschrieben wird (Result = False) oder
// wegen Windows UAC o.ä. nach "c:\users\benutzername\appdata\local\virtualstore\program files\project1\" (Result = True)
function RedirectionIsActive(_ProgramFilesFolderOrFile: string): Boolean;
var
  f: TextFile;
  strProgramFiles, strAppData: string;
  strTestFolder, strTestFile, strVirtualFolder: string;
const
  CSIDL_PROGRAM_FILES = $0026;
  CSIDL_LOCAL_APPDATA = $001C;
begin
  Result := False;

  // normalerweise: "c:\program files\" evtl mit "(x86)"
  strProgramFiles := IncludeTrailingPathDelimiter(LowerCase(GetShellFolder(CSIDL_PROGRAM_FILES)));

  // normalerweise "c:\users\benutzername\appdata\local\"
  strAppData := IncludeTrailingPathDelimiter(LowerCase(GetShellFolder(CSIDL_LOCAL_APPDATA)));

  // Befindet sich die Datei im "Programme" Ordner?
  if pos(strProgramFiles, _ProgramFilesFolderOrFile) > 0 then begin
     // Zufällige Testdatei erstellen
     strTestFolder := IncludeTrailingPathDelimiter(ExtractFileDir(_ProgramFilesFolderOrFile));
     strTestFile := FormatDateTime('yyyymmdd-HHnnss-' + IntToStr(Random(65000)), now) + '.txt';
     try
       AssignFile(f, strTestFolder + strTestFile);
       rewrite(f);
       writeln(f, 'TEST');
       closefile(f);
     except
       // Hier hat ggf. der Schreibschutz vom "wirklichen" C:\Programme\ gegriffen.
       // Das ist egal: Solange die Testdatei nicht geschrieben werden kann,
       // ist VirtualStore garantiert nicht aktiv.
     end;

     // Nimm den kompletten Ordnerpfad, entferne Laufwerksbuchstaben und setze es hinter "AppData" --> = VirtualStore
     strVirtualFolder := copy(strTestFolder, length(ExtractFileDrive(strTestFolder))+2, length(strTestFolder));
     strVirtualFolder := IncludeTrailingPathDelimiter(strAppData + 'virtualstore') + strVirtualFolder;

     // Wenn die -eben unter "Programme" erstellte- Test-Datei auch hier im VirtualStore existiert,
     // ist ganz sicher die Ordner-Umleitung von Windows aktiv aktiv.
     if FileExists(strVirtualFolder + strTestFile) then begin
       Result := True;
     end;

     // CleanUp
     if FileExists(strTestFolder + strTestFile) then DeleteFile(strTestFolder + strTestFile);
  end;


  // Wenn schon aus dem Dateinamen ersichtlich sein sollte, dass die Umleitung aktiv ist,
  // brauchen wir erst garkeine Test-Datei zu erstellen
  if pos(IncludeTrailingPathDelimiter(strAppData + 'virtualstore'), _ProgramFilesFolderOrFile) > 0 then begin
    Result := True;
  end;
end;
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#2

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 12:08
geht man da komplett anders ran?
Ich bemühe mich schon im Vorfeld, die Windowsrichtlinien zu beachten.
Seit NT darf ein User nicht unter "c:\programme" schreiben.
Daher ist es unpraktisch dort DB Dateien abzulegen.

Heran gehen:
Ermitteln ob die DB pro Benutzer oder pro Rechner genutzt werden soll.
Pro Benutzer muss diese im Benutzer-Profil liegen.
Pro PC muss diese unter Gemeinsame-Dateien liegen.

Wenn du die Ordner ermittelst, dann nutze bitte die Wellknown Folders von Windows über die API. Ermitteln die Ordner NICHT über die Registry!

Bei den Gemeinsame-Dateien Ordner musst du im Setup (am besten via MSI) die Ordnerrechte für "Authentifizierte Benutzer" auf Lesen und Schreiben setzen, da der Ordner sonst nur gelesen werden kann.

Deine Anwendung sollte auf jeden Fall ein Manifest haben!

In der DB sollte eine Versionsnummer abgelegt sein, welchen den Stand die DB Struktur hat.
Dein Programm müsste diese beim Start prüfen und ggf. ein DB Update durchführen.

Achtung in Domänen! Benutzer haben nicht immer auf allen PCs die gleiche Version vom Programm. Die DB könnte daher auf einen anderen PC aktualisiert worden sein. Dieses allerdings nur bei "roaming"-Daten im Profil.

Die Unterschiede der Ordner sind u.a. in
Entwickler Magazin (Ausgabe: 04.11) Artikel: Einstellungssachen - Anwendungsdaten und Einstellungen
beschrieben.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 12:19
Hallo generic,
danke für die Antwort.

Ich gebe dir in allen Punkten 100% recht. Davon werde ich einige Sachen noch in meinem Installer anpassen.

Mir geht es jetzt in diesem Thread aber speziell darum, mit dem nächsten Update zu erkennen, ob beim Kunden das beschriebene Problem bereits vorhanden ist (z.B. Installation einer uralten Version von unserem Programm auf einen neuen Windows 7 PC mit UAC nach C:\Programme; arbeiten mit der Datenbank unter C:\Programme), und ob die Funktion, die ich oben gepostet habe, eurer Meinung nach das Problem bzw. die Ordnerumleitung zuverlässig erkennt oder ob es da einfachere bzw. zuverlässigere Möglichkeiten gibt.

Ich dachte an Antworten im Sinne von "Die Funktion GetVirtualStoreRedirectonActive macht doch genau das gleiche??" (<-- gibt's natürlich nicht) oder "Das mit der Textdatei ist total unprofessionell!" oder "Ja, diese Funktion übernehme ich auch in mein Programm: falls meine Kunden mal ein Update von einer Uralt-Version machen, kann ich diesen Fehler gleich abfangen."

Was meint Ihr?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#4

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 13:28
Zitat:
ein Manifest haben!
Und darin angeben daß dieses Programm Vista-/Win7-kompatibel ist, damit Windows garnicht erst auf die Idee kommt sowas wie den VirtualStore zu aktivieren.

Es gibt auch einen Befehl, um die Verzeichnisumleitungen (FileSystem) zu (de)aktivieren, aber im Moment fällt mir dieser nicht ein.
Gleiches gilt für die Registry.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 13:41
Also ich habe mir nochmal die neuer Version von Deinem Manifestcreator runtergeladen. Bei meinem bestehenden Manifest haben tatsächlich die Zeilen
Code:
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
für Vista/W7 gefehlt. Komisch.

So sollte es klappen?

Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="X86"
    name="Private.Unknown.MySampleApp"
    type="Win32"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
    </application>
  </compatibility>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
</assembly>
Um die Umleitung in der Registry zu deaktiveren, verwende ich TRegistry.Create(KEY_ALL_ACCESS OR KEY_WOW64_64KEY), wobei dies ja nur 64-Bit Systeme betrifft. Macht Windows / die UAC auch in der Registry eine Umleitung für HKLM?
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#6

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 14:22
Im Prinzip reicht es auch aus "Themes" zu aktivieren.
Dadurch wird ein Manifest in die App gelinkt.
Dieses verhindert dann auch die Virtualisierung.

Diese "RedirectionActive" Prüfung halte ich für gefährlich.

Unter Windows 7 ist diese IMMER aktiv, wird aber abhängig von verarbeitenden Programm nicht angewendet. Bestimmt lässt Sie sich auch abschalten, was weitere Probleme für die Erkennung machen würde. Hinzu kommen noch die Kompatibilitäts-Modies. Kurz um, du kannst das nie mit Sicherheit sagen ob die an ist, ob die an war.

Ich denke euer Problem ist wie folgt zu umschreiben:
Wir haben eine nicht kompatibles Programm gehabt, damit ist das Kind in den Brunnen gefallen.
Nun haben wir eine kompatible Software und wollen den Fehler von damals beheben und die Kundendaten retten (, bei der neu Installation).

Da der Installationsort durch den Kunden geändert (in vielen Setups möglich) werden kann, müsstest du die Installation-Position vom alten Setup ermitteln.
Dann müsstest du in jedes Benutzerprofil schauen und deine Datei dort mit Hilfe des ermittelten Ordner suchen.
Wenn du das im Setup machst, dann hast du die erforderlichen Rechte dazu.
Das muss vor dem Deinstallieren der alten Version passieren. Sonst ist ja der Ordner nicht mehr zu ermitteln.
D.h. aber auch, dass du das nicht beim Programmstart machen kannst, sonst müsstest du jeden VirtualStore-Ordern des aktuellen Nutzers durchsuchen. Da das alte Setup zu dem Zeitpunkt dann weg ist, kann der Ordner nicht ermittelt werden. Auf anderen Nutzer hast du dann keinen Zugriff.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#7

AW: Prüfen, ob VirtualStore aktiv ist

  Alt 24. Nov 2011, 14:58
Im Prinzip reicht es auch aus "Themes" zu aktivieren.
Dadurch wird ein Manifest in die App gelinkt.
Dieses verhindert dann auch die Virtualisierung.
Jain.

Ja, es wird zwar ein Manifest eingelinkt, aber dieses ist dann nur für die CommonControls (Anzeige) zuständig.
Auf die Dateizugriffe hat dieses aber keinen Einfluß.


[add]
OK, die an-/abschaltbaren Umleitungsfunktionen, welche ich im Kopf hatte, bezogen sich wohl alle nur auf 32/64-Bit.
MSDN-Library durchsuchenWow64DisableWow64FsRedirection
MSDN-Library durchsuchenWow64EnableWow64FsRedirection
MSDN-Library durchsuchenWow64RevertWow64FsRedirection

Bleibt also vorerst nur der Weg über das Manifest.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (24. Nov 2011 um 15:05 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz