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/)
-   -   Gelockte Datei trotzdem lesen (https://www.delphipraxis.net/156846-gelockte-datei-trotzdem-lesen.html)

Stefan H 16. Dez 2010 21:31

Gelockte Datei trotzdem lesen
 
Hallo,
ich habe folgendes Problem: Ich will Teile einer Datei sperren, so dass nur ein Thread Schreibzugriff hat. Die anderen Threads/Programme sollen aber trotzdem auf diesen Bereich zugreifen können (auch auf die Gefahr hin, dass im entsprechenden Bereich dann Müll steht).
Bisheriger Ansatz: Ich öffne die Datei per:
Code:
  FileHandle:=Integer(Windows.CreateFile(PChar(editDateinamen.Text),
                                         DesiredAccess,
                                         ShareMode,
                                         nil,
                                         OPEN_EXISTING,
                                         FILE_ATTRIBUTE_NORMAL,
                                         0)
                                         );
Wobei ich mit Sharemode und desiredaccess bereits alle Varianten durchgespielt habe.

Anschließend wird der entsprechende Bereich gesperrt:
Code:
Windows.LockFile(FileHandle,o.Offset,o.OffsetHigh,128,0);
Egal was ich jetzt mache, und wie ich mit den Attributen des zweiten Programms spiele, ich kann nicht mehr auf diesen Bereich zugreifen.
Ansich wäre das soweit ja logisch, allerdings kann ich die Datei problemlos mit notepad öffnen und ansehen. Erst beim Speichern kommt es zum Fehler, dass die Date von einem anderen Prozess verwendet wird. Genau dieses Verhalten möchte ich nachbilden. Ich will aus meine Programm heraus trotz des Locks zugreifen, speichern will ich an dieser Stelle sowieso nicht.

Dieser Hexeditor kann das beispielsweise auch: http://www.flexhex.com/docs/howtos/locked-files.phtml

Das hier habe ich dazu auch noch gefunden, kanns aber irgendwie nicht nachbauen, so dass es funktionieren würde: http://www.flexhex.com/docs/howtos/locked-files.phtml

Wenn irgendjemand eine Idee für mich hätte wäre ich dankbar :)

Assarbad 16. Dez 2010 23:07

AW: Gelockte Datei trotzdem lesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Stefan H (Beitrag 1068988)
Dieser Hexeditor kann das beispielsweise auch: http://www.flexhex.com/docs/howtos/locked-files.phtml

So wie sich das liest, braucht man mindestens Adminrechte, vielleicht sogar überhaupt nur über einen Treiber.

So, mal kurz installiert:
Den Nachweis bzgl. erforderlichen Rechte findest du als angehängtes Bild. Meine Theorie wäre, daß dort die MFT geparst und die Cluster ermittelt werden welche der Datei gehören und diese dann ggf. ungecacht geschrieben werden.

Luckie 17. Dez 2010 01:57

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Stefan H (Beitrag 1068988)
Ich will Teile einer Datei sperren, so dass nur ein Thread Schreibzugriff hat. Die anderen Threads/Programme sollen aber trotzdem auf diesen Bereich zugreifen können.

Was denn jetzt? Sperren oder nicht sperren?

Assarbad 17. Dez 2010 02:07

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Luckie (Beitrag 1069014)
Was denn jetzt? Sperren oder nicht sperren?

Er will "cheaten". Das System veräppeln :stupid:

Jetzt weiß ich wie du diese Menge Beiträge zusammenbekommen hast :lol:

Luckie 17. Dez 2010 02:16

AW: Gelockte Datei trotzdem lesen
 
Vielleicht bin ich pedantisch, aber ich habe gehört, dass eine gute, exakte Problembeschreibung manchmal recht hilfreich sein soll beim Helfen. Darauf wollte ich eigentlich hinweisen. Und wenn man sich dann mal hinsetzt und versucht sein Problem mal klar und verständlich zu formulieren, dann kommt man manchmal schon von alleine auf die Lösung oder man stellt fest, dass die Formulierung Mist ist.

Assarbad 17. Dez 2010 03:42

AW: Gelockte Datei trotzdem lesen
 
Schon klar, aber verständlich war es schon. Er wollte eine Dateisperre umgehen.

Kritik ist da bei anderen Fragestellungen wo man nichtmal Kontext geboten bekommt und wo der Fragesteller danach die Diskutanten mit jeweils einem Satz in der Antwort (dafür aber x Antworten) abfrühstückt eher angebracht.

Stefan H 17. Dez 2010 06:35

AW: Gelockte Datei trotzdem lesen
 
Guten Morgen,
danke schonmal soweit für die Antworten.

Um das nochmal zu konkretisieren: Ich habe eine Anwendung, in der sehr viele Daten in eine Datei geschrieben werden (eigentlich eine Datenbank). Dabei muss sichergestellt sein, dass immer alle Daten geschrieben werden können, die zu einer Transaktion gehören.
Daher wird, wenn ein Datensatz schreibend angefordert wird, der entsprechende Datensatz exklusiv gelockt.
Das Ganze wird aber sehr langsam, wenn jemand eine Routine ausführt, die zwischen dem Laden und dem Speichern viele Berechnungen durchführt. In dieser Zeit können andere Nutzer nicht auf diesen Datensatz zugreifen, also auch keine Auswertungen machen, bei denen es nicht so tragisch wäre, wenn ein Datensatz Müll ist, weil gerade in diesem Moment der Schreibzugriff stattfindet.
Daher brauche ich einerseits die Möglichkeit den Datensatz zu locken, damit keine zwei Prozesse zeitgleich schreiben können, andererseits kann ich dann (was für die meisten Andwendungen auch Sinn macht, für mich jedoch nicht) nicht mehr lesend auf den Datensatz zugreifen.
Ich könnte mich ja damit abfinden, dass das auf diesem Weg nicht geht, allerdings kann ich nicht akzeptieren, dass so ein kleines Programm wie Notepad diese Dateien einfach so öffnen kann :)

Kurzgesagt: Ich suche einen Weg, der mir einen Dateizugriff so ermöglicht wie Notepad ihn macht.
Assarbad hat das ganz gut zusammen gefasst
Zitat:

Zitat von Assarbad (Beitrag 1069015)
Zitat:

Zitat von Luckie (Beitrag 1069014)
Was denn jetzt? Sperren oder nicht sperren?

Er will "cheaten". Das System veräppeln :stupid:

Ich will sperren, und das anschließend umgehen, weil mir das Betriebssystem meines Wissens nach keine möglichkeit bietet eine reine Schreibsperre zu setzen, die Lesezugriffe erlaubt.

Ich hoffe, dass es damit etwas klarer geworden ist?

TBx 17. Dez 2010 06:48

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Stefan H (Beitrag 1069027)
(eigentlich eine Datenbank)

äähm, warum verwendest Du nicht eine solche? Genau für solche Fälle ist doch das Transaktionshandling von Datenbanken da! :gruebel:

himitsu 17. Dez 2010 06:57

AW: Gelockte Datei trotzdem lesen
 
Wenn man eine Datei "offiziell" für Schreibzugriffe sperren will, dann offnet man sie und gewährt bei ShareMode nur den Lesezugriff.

> über andere Datei-Handle (also auch andere Programme) kann man die Datei auslesen
> aber schreiben und löschen kann dann kein Anderer.


@Assarbad: ich müßte mal probieren, ob mein XP-Trick noch geht ... jedenfalls konnte ich unter XP eine Datei öffnen (ohne Adminrechte und sonstige Tricks) und andere Programme konnten diese Datei (danach) dennoch exclisiv öffnen.

Stefan H 17. Dez 2010 07:32

AW: Gelockte Datei trotzdem lesen
 
@TBx: Wir können das Projekt nicht mal eben kurz auf eine Datenbank umstellen, das wäre eine Aufgabe von Jahren :)

Code:
Wenn man eine Datei "offiziell" für Schreibzugriffe sperren will, dann offnet man sie und gewährt bei ShareMode nur den Lesezugriff.
Ja, das Problem ist aber ja, das nur einzelne Bereiche (eben immer genau ein Datensatz) gesperrt werden muss, die anderen Datensätz müssen weiterhin beschreibbar sein. Ich muss also beim ShareMode Read und Write setzen, und dann die Bereiche per Lockfile sperren.

himitsu 17. Dez 2010 07:38

AW: Gelockte Datei trotzdem lesen
 
OK, du könntest es ja auch mal über MSDN-Library durchsuchenLockFileEx versuchen?

Zitat:

Zitat von MSDN
To specify additional options, for example creating a shared lock or for block-on-fail operation, use the LockFileEx function.


Stefan H 17. Dez 2010 07:54

AW: Gelockte Datei trotzdem lesen
 
LockFileEx zeigt das selbe Verhalten: Notepad kanns öffnen, über Delphi schaff ichs nicht die Datei zu lesen.

himitsu 17. Dez 2010 08:00

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Stefan H (Beitrag 1069041)
LockFileEx zeigt das selbe Verhalten: Notepad kanns öffnen, über Delphi schaff ichs nicht die Datei zu lesen.

Und wie genau sieht nun dein DesiredAccess/ShareMode aus?

Stefan H 17. Dez 2010 08:01

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von himitsu (Beitrag 1069042)
Zitat:

Zitat von Stefan H (Beitrag 1069041)
LockFileEx zeigt das selbe Verhalten: Notepad kanns öffnen, über Delphi schaff ichs nicht die Datei zu lesen.

Und wie genau sieht nun dein DesiredAccess/ShareMode aus?

Ich hab alle Kombinationen durch :)

himitsu 17. Dez 2010 08:03

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Stefan H (Beitrag 1069044)
Ich hab alle Kombinationen durch :)

Und Welche?

Vielleicht machst du ja was falsch? Und deswegen fragte ich ja auch danach.

Stefan H 17. Dez 2010 08:21

AW: Gelockte Datei trotzdem lesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
DesiredAcces wird nach folgendem Schema befüllt (die Form hat checkboxen über die ich auswählen kann wie ich die Datei öffnen will):
Code:
procedure TformLockReadable.buttonOpenClick(Sender: TObject);
var
  DesiredAccess: Cardinal;
  ShareMode: Cardinal;
begin
  if FileHandle<>INVALID_HANDLE_VALUE then exit;

  DesiredAccess:=0;
  if checkboxAccessRead.Checked then DesiredAccess:=DesiredAccess or GENERIC_READ;
  if checkboxAccessWrite.Checked then DesiredAccess:=DesiredAccess or GENERIC_WRITE;

  ShareMode:=0;
  if checkboxShareRead.Checked then ShareMode:=ShareMode or FILE_SHARE_READ;
  if checkboxShareWrite.Checked then ShareMode:=ShareMode or FILE_SHARE_WRITE;

  FileHandle:=Integer(Windows.CreateFile(PChar(editDateinamen.Text),
                                         DesiredAccess,
                                         ShareMode,
                                         nil,
                                         OPEN_EXISTING,
                                         FILE_ATTRIBUTE_NORMAL,
                                         0)
                      );

  //FileHandle:=FileOpen(editDateinamen.Text,fmOpenReadWrite or fmShareDenyNone);

  if FileHandle=INVALID_HANDLE_VALUE then Showmessage(Format('Fehler beim Öffnen: %d',[GetLastError]));

  EnableButtons;

  ReadOnlyLocked:=False;
end;
Ich hab das ganze Testprojekt mal angehängt, als Delphi 2006 Version. Kann problemlos auf XE überführt werden, nur kam bei mir eine Meldung, dass ein Verweis nicht mehr gültig sei. Den einfach entfernen.

Edit: Sorry, musste sie nochmal kurz rausnehmen, ist jetzt wieder drin.

Lemmy 17. Dez 2010 09:08

AW: Gelockte Datei trotzdem lesen
 
Hi,

vielleicht verstehe ich das Problem nicht ganz: Warum verwendest Du denn nicht TFileStream? Da kannst Du doch sehr schön einstellen wer was wann mit der Datei machen darf... Und wenn die anderen Anwendungen auch von dir kommen, dann kannst Du doch ebenfalls darauf reagieren und nur mit einem Lese-Zugriff die Datei holen....

Grüße

Assarbad 17. Dez 2010 10:01

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von TBx (Beitrag 1069029)
äähm, warum verwendest Du nicht eine solche? Genau für solche Fälle ist doch das Transaktionshandling von Datenbanken da! :gruebel:

Wenn man aber die DB selber implementiert, wird's schon schwieriger, oder? Es sei denn man hat Vista und Dateitransaktionen.

Zitat:

Zitat von himitsu (Beitrag 1069030)
@Assarbad: ich müßte mal probieren, ob mein XP-Trick noch geht ... jedenfalls konnte ich unter XP eine Datei öffnen (ohne Adminrechte und sonstige Tricks) und andere Programme konnten diese Datei (danach) dennoch exclisiv öffnen.

Das gilt aber für die gesamte Datei. Wenn ich die Aufgabenstellung korrekt verstehe, geht es ihm um eine Differenzierung der Zugriffsmöglichkeiten zwischen einzelnen Threads. Wobei der Sinn mal dahingestellt bleibt (das wäre so wie wenn man einem Treiber verordnete weniger Zugriffsmöglichkeiten zu haben als ein anderer Treiber, da alle in der TCB laufen, ist das aber unsinnig).

Also wie gesagt, erfahrungsgemäß wirst du ohne MFT-Zugriff nicht hinkommen und für diesen brauchste Adminrechte. Fakt. :stupid:

Stefan H 17. Dez 2010 10:51

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Lemmy (Beitrag 1069055)
Warum verwendest Du denn nicht TFileStream? Da kannst Du doch sehr schön einstellen wer was wann mit der Datei machen darf...

Ja, aber das gilt ja nur wieder für die ganze Datei, und ich muss einen einzelnen Datensatz innerhalb der Datei für Schreibzugriffe sperren können.

Zitat:

Zitat von Assarbad (Beitrag 1069060)
Wenn ich die Aufgabenstellung korrekt verstehe, geht es ihm um eine Differenzierung der Zugriffsmöglichkeiten zwischen einzelnen Threads. Wobei der Sinn mal dahingestellt bleibt (das wäre so wie wenn man einem Treiber verordnete weniger Zugriffsmöglichkeiten zu haben als ein anderer Treiber, da alle in der TCB laufen, ist das aber unsinnig).
Also wie gesagt, erfahrungsgemäß wirst du ohne MFT-Zugriff nicht hinkommen und für diesen brauchste Adminrechte.

Eigentlich ist mein Wunsch ganz einfach: Ein Prozess soll einen Datensatz zum bearbeiten, also für schreibenden Zugriff, anfordern können. Das muss ich den anderen Prozessen irgendwie mitteilen, damit kein zweiter mehr daherkommt und ebenfalls reinschreibt. Außerdem will ich aber, und das ist das ungewöhnliche an der Sache, den selben Datensatz, während er vom einen Prozess für Schreibzugriffe gesperrt ist, lesen können. Mit allen Risiken die dabei entstehen können, wie dass der eine Prozess einen halb alten und halb neuen Datensatz liest, weil der andere gerade währenddessen reinschreibt.

Und ich kann nicht glauben, dass es dafür keine Lösung gibt, weil Notepad mir die entsprechenden Dateien ohne irgendeine Meldung anzeigt.

Wenn Windows ein Opensource-Projekt wäre, würde ich ja einfach nachschauen wie Notepad die Dateien öffnet, aber ganz so einfach ist es ja nciht ;)

Assarbad 17. Dez 2010 11:12

AW: Gelockte Datei trotzdem lesen
 
Zitat:

Zitat von Stefan H (Beitrag 1069068)
Eigentlich ist mein Wunsch ganz einfach: Ein Prozess soll einen Datensatz zum bearbeiten, also für schreibenden Zugriff, anfordern können. Das muss ich den anderen Prozessen irgendwie mitteilen, damit kein zweiter mehr daherkommt und ebenfalls reinschreibt. Außerdem will ich aber, und das ist das ungewöhnliche an der Sache, den selben Datensatz, während er vom einen Prozess für Schreibzugriffe gesperrt ist, lesen können. Mit allen Risiken die dabei entstehen können, wie dass der eine Prozess einen halb alten und halb neuen Datensatz liest, weil der andere gerade währenddessen reinschreibt.

Und warum können sich deine Prozesse nicht an eine Konvention halten und bspw. per Mutex oder Semaphore den Zugriff regeln?

Nochmals: wenn du es machst wie Filehex, mußt du die MFT parsen und brauchst Adminrechte. Zusätzlich agierst du dabei am Dateisystemtreiber vorbei, womit du ein sehr seeeeehr riskantes Spielchen mit deinen Daten spielst. Und Datenintegrität ist üblicherweise eine der der Grundsäulen des Datenbankdesigns.

Abgesehen davon scheinst du zu übersehen, daß MSDN-Library durchsuchenLockfile den Zugriff für andere Prozesse komplett verhindert. Der eigene Prozeß darf aber weiterhin zugreifen. Also selbst bei deiner neuesten Problembeschreibung sehe ich kein Problem. Wenn der einzige Prozeß welcher schreibend zugreift die Datei mit GENERIC_READ öffnet, dürfen alle anderen weiterhin lesen. Und siehe da, es klappt. Wenn die Prozesse welche schreibend zugreifen dürfen wechseln, solltest du entweder dein Design komplett überdenken oder dich ernsthaft mit IPC-Mechanismen auseinandersetzen.

Zitat:

Zitat von Stefan H (Beitrag 1069068)
Und ich kann nicht glauben, dass es dafür keine Lösung gibt, weil Notepad mir die entsprechenden Dateien ohne irgendeine Meldung anzeigt.

Ja und? Du gibst schließlich FILE_SHARE_READ mit. Natürlich können andere Prozesse es dann lesen.

Zitat:

Zitat von Stefan H (Beitrag 1069068)
Wenn Windows ein Opensource-Projekt wäre, würde ich ja einfach nachschauen wie Notepad die Dateien öffnet, aber ganz so einfach ist es ja nciht ;)

Dazu braucht's nur einen Disassembler und RCE-Kenntnisse. Wenn ich mich recht entsinne, benutzten die MMFs, da diese eben auch ermöglichen große Dateien halbwegs performant zu öffnen.

Zuguterletzt kannst du nachgucken wie Bei Google suchenSQLite es macht, denn dort funktioniert es auch ohne die Vista-APIs und die Lösung steht damit bereit. Aber die absolut einfachste Methode ist es einfach SQLite zu benutzen.

Stefan H 20. Dez 2010 06:33

AW: Gelockte Datei trotzdem lesen
 
Danke für das Stichwort mit den Mutexen, das könnte wirklich eine Lösung sein. Die Dateisperrenlösung hatte zwar den Charme, dass dann auch Programme die nicht von uns sind nicht darauf zu greifen können, aber das ist verschmerzbar.

Zitat:

Zitat von Assarbad (Beitrag 1069073)
Zitat:

Zitat von Stefan H (Beitrag 1069068)
Und ich kann nicht glauben, dass es dafür keine Lösung gibt, weil Notepad mir die entsprechenden Dateien ohne irgendeine Meldung anzeigt.

Ja und? Du gibst schließlich FILE_SHARE_READ mit. Natürlich können andere Prozesse es dann lesen.

Eben nicht, wenn ichs versuche im Wordpad oder Word zu öffnen, bekomme ich die Meldung, dass ein anderer Prozess die Datei gerade hält. Nur Notepad öffnet alles völlig schmerzfrei :)

Zitat:

Aber die absolut einfachste Methode ist es einfach SQLite zu benutzen.
Ja, das mag sein, aber wie oben schon erwähnt lässt sich das nicht auf die schnelle Umstellen.

Mal sehen wie das mit den Mutexen läuft, wenn das klappt bin ich durchaus erstmal zufrieden ;)

Danke soweit schonmal an alle, insbesondere natürlich an dich, Assarbad!


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:22 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