Archive for February, 2009

Prüfen auf Schreibrechte für eine Datei in C#

Saturday, February 28th, 2009

Hallo,

manchmal möchte man wissen, ob ein bestimmter Benutzer bestimmte Rechte (z.B. Schreibrechte) für eine bestimmte Datei besitzt. Wie sich herausstellt, ist diese Anforderung alles andere als leicht umzusetzen, weil dabei viele verschiedene Aspekte eine Rolle spielen. Die Vorgehensweise sieht prinzipiell so aus:

  • Abfragen der Access Control Listen für die Datei
  • Itererieren über alle Einträge und prüfen ob man für die Kennung oder die Gruppe des gewünschten Benutzers Einträge findet
  • Dabei die Präzedenz der Einträge beachten (explizite kommen vor vererbten Regeln, “Deny”-Regeln kommen for “Allow”-Regeln)

Den nicht unerheblichen Code hat dankenswerterweise Bruce Hatt in einem Artikel auf CodeProject.com veröffentlicht.

Man sollte bedenken, dass die Möglichkeit in eine Datei zu schreiben zusätzlich durch das “ReadOnly-flag” und die .NET Code Access Security eingeschränkt sein könnte. Beides wird in dieser Klasse nicht berücksichtigt.

Die Prüfung auf das ReadOnly-flag könnte man so schreiben:

FileAttributes attrs = File.GetAttributes(fileName);
 
if ((attrs & FileAttributes.ReadOnly) != 0)
{
    readOnly = true;
}

Und für die Prüfung im Rahmen der CAS könnte man folgenden Code verwenden:

FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.Write, fileName);
try
{
    fp.Demand();
}
 
catch (SecurityException)
{
    readOnly = true;
}

Wenn es nur um die Prüfung auf Schreibrechte geht, hört man oft den Vorschlag, einfach den Schreibvorgang auszuführen und ggf. die geworfene Exception zu fangen. Dieser Vorschlag ist aber nicht immer geeignet. In meinem Fall war es so, dass ich an einer Anwendung arbeite, in der Dateien editiert werden können. Falls Dateien nicht geschrieben werden können, soll dies visualisiert werden. Man möchte aber vermeiden, dazu bei jedem Start der Anwendung die zu editierenden Texte zu speichern, da damit der Timestamp verändert wäre, obwohl der Benutzer die Datei gar nicht geändert hat und auch nicht speichern wollte.

Viele Grüße,
Andreas

Technorati Tags: ,

Destruktor nicht gerufen in mixed mode C++ Anwendungen mit Visual C++ 2008

Monday, February 9th, 2009

Hallo,

in C++ gibt es ja das Resource Aquisition Is Initialization (RAII) pattern. Der Kern dieses Patterns besteht darin, dass ein Objekt bereits bei der Konstruktion die Ownership für eine Resource übernimmt und diese Resource bei seiner Zerstörung wieder frei gibt. Man wendet dieses pattern an, um Resourcen wie allokierten Speicher oder file handles sicher freizugeben. Dabei mancht man sich zu nutze, dass in C++ der Destruktor eines Objektes deterministisch aufgerufen wird, z. B. auch im Falle eine exception.

Dieses pattern ist sehr wichtig, um zuverlässige und robuste Software in C++ zu schreiben und ich nutze es regelmäßig. Nun hatte ich vor einiger Zeit in einem der Unittests in der Software, die ich für mein Unternehmen EmPowerTec schreibe, einen seltsamen Fehler in einem Unittest. Nach einer längeren Debugging-Session sah es so aus, als würden die Destruktoren für Objekte die in einer Methode auf dem Stack angelegt waren, beim Verlassen der Methode nicht mehr gerufen. Ein solches Verhalten führt mit Sicherheit zu Fehlern, wenn das RAII Pattern genutzt wird. Zunächst war ich darüber verblüfft, da ich mir nicht vorstellen konnte, dass ein derartig fundamentales Verhalten vom Microsoft C++ Compiler nicht richtig implementiert war. Tatsächlich war das aber der Fall, wie in folgendem Knowledge Base Eintrag beschrieben:

http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/8324a598-ad05-40e1-a271-6f64ce3b6008

Wie man dem Thread entnehmen kann, tritt das Problem auf, wenn man von einer C++/CLI Library eine native C++ library aufruft und diese mit inkompatiblen Einstellungen für das Exception handling übersetzt hat.

Und die Moral von der Geschicht,
Trau’ keinem Compiler nicht,

Unittests sollst Du machen,
Sonst hast Du nichts zu lachen

Viele Grüße,
Andreas

Technorati Tags: ,