Entwickler-Ecke

Windows API - Wie kann man einen String umwandeln in LPLWSTR?


Nostromo - Sa 11.09.10 14:29
Titel: Wie kann man einen String umwandeln in LPLWSTR?
Ich möchte die Funktion CryptUnProtectData nutzen.
Dafür muss ich einen Parameter als LPLWSTR übergeben.
Leider finde ich darüber aber nichts. Kann mir jemand dabei helfen?


Gausi - Sa 11.09.10 14:35

Das dürfte doch das übliche Zeiger-gedöns bei API-Funktionen sein, oder? Wegen des "W" darin würde ich einen WideString vermuten, unter D7 müsste das dann so gehen:

Delphi-Quelltext
1:
PWideChar(WideString(DeinNormalerString));                    

Wenn da Unsinn bei rauskommt, wird doch ein AnsiString verlangt, dann halt nur über PChar(DeinNormalerString);


Martok - Sa 11.09.10 18:15

LPLWSTR? Kenn ich auch nicht.

MSDN [http://msdn.microsoft.com/en-us/library/cc230355%28PROT.10%29.aspx] kennt auch nur LPWSTR als ein Long Pointer to a WideSTRing -> PWideChar in Delphi.

EDIT: Da ist auch kein L [http://msdn.microsoft.com/en-us/library/aa380882%28VS.85%29.aspx] ;)


Nostromo - Sa 11.09.10 19:01

Funktioniert alles nicht.

Hab aber herausgefunden das wohl in der Jedi-Lib in Datei JwaWinCrypt unter Umständen ein Fehler ist.

Hier mal die definition der Funktion


Delphi-Quelltext
1:
2:
3:
function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: LPLPWSTR;
  pOptionalEntropy: PDATA_BLOB; pvReserved: PVOID;
  pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall;


Die Beschreibung von Microsoft findet sich hier.
http://msdn.microsoft.com/en-us/library/aa380882(VS.85).aspx
und dort steht als Definition LPWSTR. NICHT LPLPWSTR.

Meine Delphi-Funktion sieht so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
function DeCryptRDPPassword(sPassword: string): string;
var DataIn: DATA_BLOB;
    DataOut: DATA_BLOB;
    pwDescription: PWideChar;
    P: PByte;
    I: Integer;
    PwdHash: string;
begin
  PwdHash := '';

  DataOut.cbData := 0;
  DataOut.pbData := nil;

  // RDP uses UniCode
  DataIn.pbData := Pointer(WideString(sPassword));

  DataIn.cbData := Length(sPassword) * SizeOf(WChar);

  // RDP always sets description to psw
X pwDescription := WideString('psw');

  //CryptUnProtectData(pDataIn, ppszDataDescr, pOptionalEntropy, pvREserverd, pPromptStruct, dwFlags, pDataOut);
  if CryptUnProtectData(@DataIn,
X                     pwDescription,
                      nil,
                      nil,
                      nil,
                      CRYPTPROTECT_UI_FORBIDDEN, // Never show interface
                      @DataOut) then
  begin
    // Convert the DataBlob to Hex String
    P := DataOut.pbData;
    I := DataOut.cbData;

    PwdHash := '';
    while (I > 0do begin
      Dec(I);
      PwdHash := PwdHash + IntToHex(P^, 2);
      Inc(P);
    end;
  end else
  begin
    Showmessage('Error'+#13#10+SysErrorMessage(GetLastError));
  end;

  Result := PwdHash;

  // Cleanup
  pwDescription := nil;
  LocalFree(Cardinal(DataOut.pbData));
  LocalFree(Cardinal(DataIn.pbData));

end;



Wenn ich pwDescription auf nil setze erhalte ich den Fehler
"Die Daten sind unzulässig".

Wenn ich pwDescription wie oben stehend übergebe erhalte ich den Fehler
"Unzulässiger Zugriff auf einen Speicherbereich".

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Ich habe einen Beitrag gefunden der bereits eine Lösung enthält.

Für alle die es interessiert:
http://www.delphipraxis.net/88732-password-hash-rdp-files-2.html