AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Probleme mit PWideChar

Ein Thema von Benmik · begonnen am 12. Mai 2020 · letzter Beitrag vom 12. Mai 2020
Antwort Antwort
Benmik

Registriert seit: 11. Apr 2009
443 Beiträge
 
Delphi 10.4 Sydney
 
#1

Probleme mit PWideChar

  Alt 12. Mai 2020, 17:16
Ich parse die MFT mittels eines USN-Records:
Delphi-Quellcode:
  USN_RECORD = record
    ...
    FileNameLength: Word;
    FileNameOffset: Word;
    FileName: PWChar;
  end;
Dort ist FileName als PWChar deklariert, was über MarshaledString ein PWideChar ist.
Die Zuweisung von FileName geschieht in function USNRecFromPointer(const P: Pointer): TUSNRecord; (P ist ein Pointer auf den Laufwerks-Char) mittels Result.FileName := PWChar(Integer(P) + Result.FileNameOffset); Wenn ich mir nun innerhalb dieser Funktion den Wert von Result.FileName im Debugger anzeigen lasse, dann wird der korrekte Dateiname angezeigt. In der Prozedur, die USNRecFromPointer aufruft und den TUSNRecord zurück erhält, ist aber FileName plötzlich ein String der Länge FileNameLength voller kryptischer Unicode-Zeichen. Die Zuweisung an eine String-Variable ändert daran nichts.

Die einzige funktionierende Lösung, die ich gefunden habe, ist WideCharToString(PWChar(Integer(AUSN) + AUSN.FileNameOffset) .

Hier fiel mir nun auf, dass der Dateiname in einigen Fällen um ein oder zwei Zeichen zu lang war. Ich dachte mir, dass der Record die FileNameLength vielleicht nicht umsonst mitliefert. Da ein WideChar 2 Bytes umfasst, musste ich die Länge halbieren und kam auf WideCharLenToString(PWChar(Integer(AUSN) + AUSN.FileNameOffset),Round(AUSN.FileNameLength / 2)) , was auch endlich anstandslos funktioniert. Aber das kann es ja wohl nicht sein. Was geht da eigentlich vor? Und warum wird FileName im identischen Record einmal "richtig" und einmal als UTF-16-String angezeigt?
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.229 Beiträge
 
#2

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 17:39
Also, dies entspricht in etwa einem UNICODE_STRING der kommt im Kernel und Usermode auf Windows massig vor. Wichtig ist, daß es ein gezählter String ist (das dient der Sicherheit).

Der Inhalt dieser Strings muß nicht zwingend nullterminiert sein. Liegt hier vielleicht schon das Problem?

Außerdem sind die beiden Längenangaben immer gerade Zahlen, da sie die Anzahl in Bytes und nicht etwa in WideChar angeben.

Leider gibst du keinen relevanten Code, weshalb ich nur diese beiden Punkte als Denkanstoß liefern kann. Kannst du noch Code nachliefern (WideCharLenToString, WideCharToString ...)?
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
443 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 17:41
Ich dachte, ich hätte alles Wichtige an Code mitgeliefert. Was fehlt dir?

EDIT: Das sind Delphi-Funktionen.

Geändert von Benmik (12. Mai 2020 um 17:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.229 Beiträge
 
#4

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 17:46
Ich dachte, ich hätte alles Wichtige an Code mitgeliefert. Was fehlt dir?

EDIT: Das sind Delphi-Funktionen.
Alles klar. Dann übergebe ich mal an die Delphianer die es noch immer sind.

Das mit der Nullterminierung ist also schon ausgeschlossen? Kurzum: nach wiederholter Lektüre deines Beitrags eingangs, scheinst du dich über die Zählung in Bytes zu ärgern und über die Tatsache, daß die Strings nicht nullterminiert daherkommen, oder? Umgekehrt gefragt: woher die Annahme daß das nicht sein kann? Eigentlich ist das so ganz normal.

Übrigens ist Round() falsch. Wenn du einen ungeraden Zahlwert in dem Feld siehst, darfst du getrost davon ausgehen, daß der Wert nicht stimmt.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)

Geändert von Assarbad (12. Mai 2020 um 17:49 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
443 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 17:53
...scheinst du dich über die Zählung in Bytes zu ärgern und über die Tatsache, daß die Strings nicht nullterminiert daherkommen, oder?
Nein, mein Code erscheint mir als Gefrickel und ich denke, dass es eine bessere Lösung gibt.

Das Round ist notwendig, damit ein Integer rauskommt. Ich hätte auch Trunc() nehmen können.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.570 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 18:00
Ja, der Debugger sieht den Typ "PWideChar" und nimmt das als Nullterminiert an,
was aber egal ist, so lange doe Werte in FileName und FileNameLength korrekt sind und zusammenpassen, gehen die entsprechenden Funktionen damit "richtig" um, welche diesen Typ dann auch korrekt via Längenangabe auswerten.

Wie Assarbad schon sagte, wenn dieser Typ nicht nullterminiert ist (sein muß), dann muß man eben auch die Längenangabe verwenden, wenn man den String auslesen will.

Neben WideCharLenToString gibt es auch noch Delphi-Referenz durchsuchenSetString,
aber diese brauchst du ja nur, wenn du selber diesen "String" auslesen und in einen Delphi-String umwandeln willst.


Das, was du als Zeiger an USNRecFromPointer übergibst, das wird nicht zufällig zwischendurch freigegeben, nachdem du diese Funktion aufgerufen hattest?
Der Dateiname bleibt weiterhin in der anderen Struktur und dieses USNRecFromPointer scheint nur einen Record zu erstellen, der darauf zeigt. (jedenfalls sieht die halbgezeigt Zeile Code danach aus)

Würde dann in etwa so aussehn.
SetString(S, PWideChar(NativeInt(AUSN) + AUSN.FileNameOffset), AUSN.FileNameLength div SizeOf(WideChar)); // oder einfach nur "div 2"


PS: statt NativeInt bzw. NativeUInt verwende ich lieber einen Typ IntPtr (was im Prinzip auch nur ein NativeInt ist, aber so besser anzeigt, was er machen will).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (12. Mai 2020 um 18:08 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
443 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Probleme mit PWideChar

  Alt 12. Mai 2020, 18:18
Da bringt mich ja schon mal gut weiter.

Die aufrufende Routine heißt function TFrmMFT.MFTEnumCallback(AUSN: PUSNRecord; Extra: Pointer): Boolean; , und sie ruft als Erstes USNRecFromPointer(AUSN); auf. Dazwischen geschieht nichts.

Bei einem Beispiel-Dateinamen werden 41 Zeichen übergeben, das letzte ist nicht #0; die FileNameLength ist 22 und der Dateiname 11 Zeichen lang.

EDIT: SetString funktioniert auch einwandfrei.

Geändert von Benmik (12. Mai 2020 um 18:32 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 06:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf