Schreibschutz auf W2K3 Server
Moderator: Moderatoren
- Manfred
- Foren-Administrator
- Beiträge: 21248
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 211 Mal
- Danksagung erhalten: 71 Mal
Schreibschutz auf W2K3 Server
Hi,
ich habe derzeit ein interessantes Phänomen. Ich habe mich gewundert, dass auf einem W2003 Server immer die Fehlermeldung unbekannter Alias kam. Es liegt daran, das die DBF Tabellen in dem Verzeichnis schreibgeschützt liegen. Was mich aber noch mehr verwundert, ist die Tatsache, dass es keine Fehlermeldung beim Öffnen der DBF gibt, obwohl sie in einem Begin Sequence liegt.
Also habe ich ein wenig probiert. In der Sicherheit, das Recht auf Schreiben gegeben, alles klappt wieder. Schreibrecht wieder weggenommen, dafür aber die DBF ReadOnly geöffnet klappt auch.
Jetzt habe ich mir überlegt, wie ich sowas abfangen kann. Also auch bei mir Sambaserver, bzw. auf lokaler Platte unter WinXP jeweils Schreiben deaktiviert um dann im Debugger zu sehen, was denn da passiert. Und siehe da, jetzt kommt eine Fehlermeldung, das die DBF nicht geöffnet werden kann. Genau so, wie ich es erwarten würde. Was ist denn auf einem W2003 Server anders, dass so etwas passieren kann?
ich habe derzeit ein interessantes Phänomen. Ich habe mich gewundert, dass auf einem W2003 Server immer die Fehlermeldung unbekannter Alias kam. Es liegt daran, das die DBF Tabellen in dem Verzeichnis schreibgeschützt liegen. Was mich aber noch mehr verwundert, ist die Tatsache, dass es keine Fehlermeldung beim Öffnen der DBF gibt, obwohl sie in einem Begin Sequence liegt.
Also habe ich ein wenig probiert. In der Sicherheit, das Recht auf Schreiben gegeben, alles klappt wieder. Schreibrecht wieder weggenommen, dafür aber die DBF ReadOnly geöffnet klappt auch.
Jetzt habe ich mir überlegt, wie ich sowas abfangen kann. Also auch bei mir Sambaserver, bzw. auf lokaler Platte unter WinXP jeweils Schreiben deaktiviert um dann im Debugger zu sehen, was denn da passiert. Und siehe da, jetzt kommt eine Fehlermeldung, das die DBF nicht geöffnet werden kann. Genau so, wie ich es erwarten würde. Was ist denn auf einem W2003 Server anders, dass so etwas passieren kann?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
Hallo Manfred,
wie fragst du denn ab ob use erfolgreich war ?
neterr()
BEGIN SEQUENCE ist dafür nicht gedacht und wird dir kein fehlgeschlagenes USE melden !
Wenn eine DBF schreibgeschützt ist, kannst du sie bestenfalls mit use ... READONLY öffnen.
wie fragst du denn ab ob use erfolgreich war ?
neterr()
BEGIN SEQUENCE ist dafür nicht gedacht und wird dir kein fehlgeschlagenes USE melden !
Wenn eine DBF schreibgeschützt ist, kannst du sie bestenfalls mit use ... READONLY öffnen.
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
Wenn der ErrorBlock überlagert ist, schlägt das Standard-Errorhandling fehl, also wird auch die Fehlersituation nicht abgefangen, die die Get-/Set-Funktion "NetErr()" mit ".T." antworten lässt. In diesem Fall erzeugt eine Sharing Violation eben auch einen Laufzeitfehler. Dasselbe erlebt man z.B. mit Xb2.Net, da der HTTPErrorHandler von Boris standardmäßig nicht "oError:OsCode = 32 .and. oError:CanDefault" abfängt (böse Falle übrigens ). Da man vor einer Sequence üblicherweise genau das macht, also den ErrorBlock überlagert, wundert es kaum, wenn dort dann ein Laufzeitfehler erzeugt wird. Im Standard-Errorhandling (ERRORSYS.PRG) wird sonst diese Situation geprüft, NetErr() wird auf ".T." gesetzt und das Fehlersystem beendet sich wieder. Einfach mal in den Code der (ggf. selbst gestrickten) Errorsys schauen!
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
du meinst es ist abgeschaltetTom hat geschrieben:Wenn der ErrorBlock überlagert ist, schlägt das Standard-Errorhandling fehl
Was soll "Get-/Set-Funktion" heißen, es gilt schon seit Clipper, dass man nach USE zwingend NETERR() abfragen muss !Tom hat geschrieben:Get-/Set-Funktion "NetErr()"
Und in der "normalen" ErrorSys.PRG findet man keinen Eintrag zu NetErr(), also frage ich mich was du meinst
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
NetErr() ist eine Get-/Set-Funktion. Das bedeutet: Man kann sie mit einem Parameter (.T. oder .F.) aufrufen, sie speichert diesen Wert (das ist der "Set"-Teil der Funktion). Wenn man sie danach ohne Parameter aufruft, gibt sie den zuletzt gesetzten Wert zurück (das ist der "Get"-Teil). Du kannst NetErr(.T.) einfach selbst setzen, wenn Du Lust hast. Wenn Du danach dann eine Datei öffnest, ohne dass der Laufzeitfehler mit dem OS-Code 32 (Sharing Violation) auftritt, liefert die danach folgende Abfrage von NetErr() trotzdem .T. zurück. Get-/Set-Funktionen sind sehr hilfreich, um nur innerhalb eines Applikationslaufes gültige Parameter zu speichern und abzurufen. Aber es ist eben nicht so, dass NetErr() irgendwie prüft, ob eine Sharing Violation eintrat. Sie wird nur anschließend gesetzt. Ich zitiere die Doku zu NetErr():
Falls bei einem dieser Befehle ein Fehler auftritt, entsteht ein Laufzeitfehler, der durch die Standard-Fehlerbehandlungsroutine in Xbase++ behoben wird. In dieser Routine wird NetErr(.T.) aufgerufen.
Wenn man nun die Standard-Fehlerbehandlungsroutine stoppt, wird von dieser natürlich auch nicht mehr NetErr(.T.) aufgerufen. Damit behält NetErr() den zuletzt zugewiesenen Wert, und der ist sehr wahrscheinlich .F. - und außerdem ensteht ein Laufzeitfehler.
Falls bei einem dieser Befehle ein Fehler auftritt, entsteht ein Laufzeitfehler, der durch die Standard-Fehlerbehandlungsroutine in Xbase++ behoben wird. In dieser Routine wird NetErr(.T.) aufgerufen.
Wenn man nun die Standard-Fehlerbehandlungsroutine stoppt, wird von dieser natürlich auch nicht mehr NetErr(.T.) aufgerufen. Damit behält NetErr() den zuletzt zugewiesenen Wert, und der ist sehr wahrscheinlich .F. - und außerdem ensteht ein Laufzeitfehler.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
Da hatte ich wohl zu sehr das GET System gedacht klar ist es eine Get/Set Funktion ...
Dennoch ist genau NETERR() die Lösung für Manfreds Problem, denn - wenn ich nicht wieder was überlesen habe -
hat er es unterlassen nach USE den Zustand von NETERR() abzufragen und das darf man nicht bei gesharten Dateien.
Die Stelle im ErrorHandler habe ich auch gefunden ...
wenn ER dieses Standardverhalten abgeändert hat ODER selbst NETERR() setzt, muss er natürlich das überprüfen.
Wenn er eXpress++ einsetzt (keine Ahnung) könnte es auch dort geändert worden sein ... dann muss man dort auch in der Doku nachsehen.
Dennoch ist genau NETERR() die Lösung für Manfreds Problem, denn - wenn ich nicht wieder was überlesen habe -
hat er es unterlassen nach USE den Zustand von NETERR() abzufragen und das darf man nicht bei gesharten Dateien.
Die Stelle im ErrorHandler habe ich auch gefunden ...
Code: Alles auswählen
/* Fehler beim Öffnen einer Datei im Netzwerk */
CASE oError:genCode == XPP_ERR_OPEN .AND. ;
oError:osCode == 32 .AND. ;
oError:canDefault
RETURN(.F.)
Wenn er eXpress++ einsetzt (keine Ahnung) könnte es auch dort geändert worden sein ... dann muss man dort auch in der Doku nachsehen.
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
In den Standard-Errorsys.PRG früherer Xbase++-Versionen (vor 1.8 oder 1.7, ich weiß es nicht mehr genau) war das explizite Setzen von NetErr() auch noch enthalten, aber vermutlich haben so viele Programmierer daran herumgemurkst, dass Alaska das irgendwann gekapselt hat.
eXpress++ hat keine eigene ErrorSys, aber wenn man den Dot-Prompt oder DC_Interpret() benutzt hat, bleibt bisweilen das interne Fehlerbehandlungssystem "hängen" (jedenfalls bis Build 254).
Whatsoever, wenn man im Rahmen einer Sequence das Fehlersystem ausgehebelt hat, kann NetErr() auch nicht mehr feuern. Dann müsste man innerhalb der Sequence der Fehler direkt abgefangen werden. Oder im Anschluss der Sequence durch ein simples "Used()" auf der Workarea, in der man die geöffnete Datei erwartet.
eXpress++ hat keine eigene ErrorSys, aber wenn man den Dot-Prompt oder DC_Interpret() benutzt hat, bleibt bisweilen das interne Fehlerbehandlungssystem "hängen" (jedenfalls bis Build 254).
Whatsoever, wenn man im Rahmen einer Sequence das Fehlersystem ausgehebelt hat, kann NetErr() auch nicht mehr feuern. Dann müsste man innerhalb der Sequence der Fehler direkt abgefangen werden. Oder im Anschluss der Sequence durch ein simples "Used()" auf der Workarea, in der man die geöffnete Datei erwartet.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Schreibschutz auf W2K3 Server
Clipper/Xbase++ Standardverhalten, WENN es den Fehler beheben kann (CANDEFAULT), dann wird NETERR() auf .t. gesetzt,Manfred hat geschrieben:Was mich aber noch mehr verwundert, ist die Tatsache, dass es keine Fehlermeldung beim Öffnen der DBF gibt, obwohl sie in einem Begin Sequence liegt.
das muss man im Quellcode abfragen und selbst entsprechend reagieren !
logisch, standardmäßig wird shared (Xbase++, sonst exclusive) geöffnet, das braucht schreibzugriff !Manfred hat geschrieben: In der Sicherheit, das Recht auf Schreiben gegeben, alles klappt wieder.
Schreibrecht wieder weggenommen, dafür aber die DBF ReadOnly geöffnet klappt auch.
Wenn man readonly offnet kann es nur bei exclusive geöffneten Dateien Probleme geben.
Es könnte natürlich sein, dass ein anderer Wert zurückgeliefert (OS-Err oder CANDEFAULT) wird, aber ich konnte nochManfred hat geschrieben: Und siehe da, jetzt kommt eine Fehlermeldung, das die DBF nicht geöffnet werden kann.
Genau so, wie ich es erwarten würde. Was ist denn auf einem W2003 Server anders, dass so etwas passieren kann?
nie einen Unterschied feststellen. Vermutlich fragt der Debugger intern nach neterr() und gibt eine Fehlermeldung,
oder der Code ist unterschiedlich !
jetzt verstehe ich unsere unterschiedlichen Sichtweisen.Tom hat geschrieben:Whatsoever, wenn man im Rahmen einer Sequence das Fehlersystem ausgehebelt hat,
Du gehst davon aus, dass Manfred ein eigenes Errorsystem mit begin sequence und Error-Objekt gesetzt hat:
Code: Alles auswählen
bSaveError := ErrorBlock()
ErrorBlock( {|e| Break(e)} )
BEGIN SEQUENCE
...
RECOVER USING oError
ErrorBlock( bSaveError )
IF oError:osCode == ... // Zurück zu BEGIN SEQUENCE
...
ENDIF
END SEQUENCE
ErrorBlock( bSaveError )
Code: Alles auswählen
// sowas kann nicht funktionieren, bitte bei NETERR() nachlesen warum :-)
BEGIN SEQUENCE
use xyz
RECOVER
? "Fehlermeldung Datei kann nicht geöffnet werden!"
END SEQUENCE
PS: Append Blank() braucht auch NetErr()
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21248
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 211 Mal
- Danksagung erhalten: 71 Mal
Re: Schreibschutz auf W2K3 Server
Ich habe sowas hier
Code: Alles auswählen
********************************************************************************
METHOD datenbank:oeffnedatenbank(lShared, lInaDb, lReadonly, lSperren, lNewArea)
LOCAL bSaveError := ErrorBlock( {|e|BREAK(e)})
LOCAL cFileName := ::cPfad + ::cDbank + ::cSuffix // Zusammenbau des kompletten Pfades mit Namen
LOCAL nVersuche := 0
LOCAL oError
MEMVAR oSysPara
DEFAULT lShared TO .T. // von Hause aus wird jede DB im Multiuserbetrieb geöffnet, also Shared
DEFAULT lInaDb TO .T.
DEFAULT lReadOnly TO .F.
DEFAULT lSperren TO .F.
DEFAULT lNewArea TO .T.
::erzeugeVerzeichnisse(::cPfad) // dann sind wir immer auf der sicheren Seite (16.08.2010)
DO WHILE .T.
ErrorBlock( {|e| BREAK(e)}) // was passiert hier?? .
BEGIN SEQUENCE // hiermit werden kontrolliert Fehlermeldungen abgehandelt .
DbUseArea(lNewArea, ::cDbe, cFileName, ::cAlias, lShared, lReadOnly) // Öffnungsversuch der Datenbank .
::nArea := Select() // es wird sich grundsätzlich der Selectbereich gemerkt, in dem die DB geöffnet wurde
::nRecordMenge := (::nArea)->(Reccount()) // für irgendwelche Zwecke wird sich die aktuelle menge gemerkt .
IF Empty(::cAlias) // es wurde kein Alias vorgegeben .
::cAlias := (::nArea)->(Alias()) // also gibt es den Standardnamen .
ENDIF
IF lInaDb
AAdd(::aDb, {self,NIL}) // 1.Objekt für DB 2.NIL weil man auch den führenden Index angeben kann
ENDIF
IF lSperren
::db_sperren("Die DB: " + Upper(::cDbank) + " kann nicht gelockt werden.")
ENDIF
IF (::nArea)->(RecSize()) * (::nArea)->(Lastrec()) + (::nArea)->(Header()) + 1 > KRITISCHE_GROESSE_DB
oSysPara:oMessage:anzeigen("Die Datenbank " + UPPER(::cDbank) + " hat eine kritische Grösse erreicht!!", + CRLF, +;
"Am besten sofort eine Reduzierung der DatensΣtze veranlassen!!!",,,"W")
ELSE // wenn dies nicht der Fall, dann braucht erst die Leerprüfung stattzufinden
IF ::lMin1Record .AND. ::cAlias <> "neu" // wird nur geprüft, wenn es keine Neuerstellung einer Db ist, weil die dann immer leer ist
IF (::nArea)->(LastRec()) = 0
(::nArea)->(DbAppend())
IF ::lMin1RecordHinweis
oSysPara:oMessage:anzeigen("Die Datenbank " + UPPER(::cDbank) + " hat noch KEINEN Datensatz. Bitte erfassen!")
ENDIF
ENDIF
ENDIF
ENDIF
RECOVER USING oError // und was macht dass hier?
altd() // der dient der Fehlersuche
IF ++nVersuche > 5
IF oSysPara:oPruefen:fehlerbehandlung(oError,self)
LOOP
ENDIF
ENDIF
END SEQUENCE
ErrorBlock(bSaveError) // Standard wieder herstellen
EXIT
ENDDO .T.
RETURN self
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!