Seite 1 von 3

#REG_MULTI_SZ schreiben

Verfasst: 11.03.2007 16:41
von PureBasic4.0
Hi, Leute

Ich möchte gerne einen #REG_MULTI_SZ in die Registry schreiben. Habe schon die PBOSL-Registry-Lib ausprobiert, diese schreibt aber nach dem Eintrag ein Leerzeichen und eine Null. Denke, dass ist nicht richtig, denn wenn ich den Eintrag von Windows reinschreiben lasse, gibt es kein Leerzeichen und keine Null am Ende. Stattdessen gibt es im Hex-Modus noch 5x 0 Paare:
Bild
Hat jemand noch eine lib oder nen code?

Danke,
PureBasic4.0

Verfasst: 11.03.2007 19:39
von ts-soft
Mit was läßt den die 5 0 Paare anzeigen :freak:
Entweder das ist verkehrt, oder das ist kein REG_MULTI_SZ
Ausserdem solltest Du dir Strings auch als solche anschauen

Verfasst: 12.03.2007 18:05
von PureBasic4.0
Bild
Wie du siehst: Es sind #REG_MULTI_SZs. Die Hex-Daten bekommst du mit "Rechte Maustaste auf das gewünschte Element --> Binärdaten ändern"

So sehen die Binärdaten aus, wenn man sie von Windows reinschreiben lässt:
Bild

Und so, wenn man sie per WriteMultiLineString reinschreibt:
Bild

//edit: Ich schreibe genau das gleiche mit WriteMultiLineString in die Registry. Ich füge kein Leerzeichen oder so hinzu

Verfasst: 12.03.2007 18:10
von ts-soft
Dann probiere mal JHRegistry von Jens, findeste auf PureArea.net oder
versuch den Source der Lib anzupassen, ich hab da im moment keine Zeit
und Lust zu.

Gruß
Thomas

Verfasst: 12.03.2007 18:12
von PureBasic4.0
gut. danke. ich probier's

Verfasst: 13.03.2007 12:33
von Shardik
Ich konnte den Fehler in der Bibliothek PBOSL_Registry verifizieren. Diese Zeile in der Prozedur Reg_WriteMultiLineString() ist fehlerhaft

Code: Alles auswählen

    Mem = AllocateMemory((MemoryStringLength(@Value) + 1) * SizeOf(Character))
und sollte durch diese Zeile ersetzt werden

Code: Alles auswählen

    Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character))
@ts-soft
Bitte ändere dies in der Bibliothek PBOSL_Registry schnell ab, weil dieser Fehler schlimmstenfalls auch zu Registry-Fehlern führen könnte. Der von Dir angeforderte Puffer ist im ASCII-Modus um 1 Byte bzw. im Unicode-Modus um 2 Bytes zu klein. Bei mir führte dies bei einem Unicode-Eintrag dazu, daß am Eintragsende hinter 3 Null-Bytes die Bytes 2B 02 folgten, was in RegEdit zu einer merkwürdigen Anzeige mit vielen wirren Zeichen am Eintragsende führte. Glücklicherweise ließ sich der Eintrag bearbeiten und löschen.

Wenn Du übrigens einmal den Wert von (MemoryStringLength(@Value) + 1) * SizeOf(Character) mit dem von MemorySize(Mem) verglichen hättest, hättest Du festgestellt, daß die beiden Werte unterschiedlich sind... :wink:

Verfasst: 13.03.2007 15:12
von PureBasic4.0
ok. danke

Verfasst: 14.03.2007 14:28
von PureBasic4.0
@Shardik
Dein Bugfix hat noch eine Macke: Durch die Zeile

Code: Alles auswählen

Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character))
werden jetzt zwei Zeilen hinzugefügt.
Bild
Hex-Ansicht:
Bild
Möchte aber immernoch, dass es so aussieht:
Bild
Kannst du das bitte noch ausbessern?

Danke,
PureBasic4.0

Verfasst: 14.03.2007 16:54
von Shardik
PureBasic4.0 hat geschrieben: Dein Bugfix hat noch eine Macke: Durch die Zeile

Code: Alles auswählen

Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character)) 
werden jetzt zwei Zeilen hinzugefügt.
Sorry :oops:
Obwohl ich dies gestern ausgiebig unter WinXP SP2 und WinNT SP6 getestet habe (Unicode bekomme ich unter WinNT allerdings bis jetzt noch nicht in die Registry geschrieben!), ist mir da doch noch ein Fehler unterlaufen: ich wollte die zu ersetzende Zeile so ähnlich wie möglich wie die von ts-softs Originalzeile gestalten. Diese Zeile arbeitet aber wie von Dir erwartet:

Code: Alles auswählen

    Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character))
Bei mir wird mit dem folgenden Komplett-Beispiel (aus der PBOSL_Registry und mit der oben angegebenen veränderten Code-Zeile) unter WinXP SP2 dieser Test-Eintrag erstellt:

HKEY_CURRENT_USER\Test

und der Schlüssel Gateway wird dort eingetragen. Wenn man den Schlüssel mit "Binärwert bearbeiten" öffnet, sieht der Inhalt genauso aus wie in Deinem Snapshot bzw. wie mit Windows direkt erstellt.

Code: Alles auswählen

Global Reg_ErrorNr.l, Reg_ErrorMsg.s

Procedure Reg_SetLastError(Error.l = 0)
  Protected Buffer.l
  If Error
    Reg_ErrorNr = Error
  Else
    Reg_ErrorNr = GetLastError_()
  EndIf
  FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM, 0, Reg_ErrorNr, 0, @Buffer, 0, 0)
  If Buffer
    Reg_ErrorMsg = PeekS(Buffer)
    LocalFree_(Buffer)
  EndIf
EndProcedure

Procedure Reg_ResetError()
  Reg_ErrorNr = 0
  Reg_ErrorMsg = ""
EndProcedure

ProcedureDLL.l Reg_WriteMultiLineString(topKey.l, KeyName.s, ValueName.s, Value.s); write a StringField, separate with #LF$, to specified ValueName
  Protected Result.l, hKey.l, Error.l, dwDisposition.l, Mem.l
  Reg_ResetError()

  If Right(KeyName, 1) = "" : KeyName = Left(KeyName, Len(KeyName) - 1) : EndIf
  Error = RegCreateKeyEx_(topKey, KeyName, 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, 0, @hKey, @dwDisposition)
  If Error = #ERROR_SUCCESS
    Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character))
    If Mem
      PokeS(Mem, Value)
      Error = RegSetValueEx_(hKey, ValueName, 0, #REG_MULTI_SZ, Mem, MemorySize(Mem) + SizeOf(Character))
      If Error = #ERROR_SUCCESS
        Result = #True
      Else
        Reg_SetLastError(Error)
      EndIf
      FreeMemory(Mem)
    Else
      Reg_ErrorNr = -1
      Reg_ErrorMsg = "can't allocate memory"
    EndIf
  Else
    Reg_SetLastError(Error)
  EndIf
  If hKey : RegCloseKey_(hKey) : EndIf
  ProcedureReturn Result
EndProcedure

Reg_WriteMultiLineString(#HKEY_CURRENT_USER, "Test", "Gateway", "192.168.0.1")

Verfasst: 14.03.2007 17:00
von ts-soft
Meine Orginalzeile + 1 * SizeOf(charachter) sollte rein mathematisch
dasselbe ergeben :wink:

Aber schön wenn ich auf diese Art an die noch vorhandenen Fehler komme,
weil zum Testen fehlt mir die Notwendigkeit und Zeit.

Gruß
Thomas

Code: Alles auswählen

Mem = AllocateMemory((MemoryStringLength(@Value) + 1) * SizeOf(Character)) 
Sollte dasselbe sein wie:

Code: Alles auswählen

Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character)) 
// Test:

Code: Alles auswählen

value.s = "Hallo die Enten"

Debug (MemoryStringLength(@Value) + 1) * SizeOf(Character)
Debug MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character)
Wichtig ist nur die Klammersetzung