Einzelnen Beitrag anzeigen

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