Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
Delphi 10.4 Sydney
|
AW: Effizientes Einlesen und Verarbeiten von Textdatei
1. Jul 2022, 11:03
Zitat:
Der Zwischenschritt über TBytes (= array of Byte) ist meiner Meinung nach unnötig. Irgendwie bin ich aber zu blöd, direkt auf Lblob.pbData den Speicher zu reservieren, die Bytes des Strings mit Move dorthin zu kopieren, und anschließend den Speicher mit FreeMem wieder freizugeben, ohne dass es knallt (siehe auskommentierter Teil). Ja, ich weiß, dass Move die Adresse des Zielspeichers ändert und es deshalb knallt. Wie kann ich denn sonst die Bytes des Strings dorthin übertragen?
Falls es dir irgendwie eine Hilfe ist, aber in der HTTP-Request-Klasse der höheren Delphi-Versionen in der Unit System.Net.HttpClient.Win wird auch mit einem Stream (FClientCertificate) der Umweg über ein dynamisches TBytes-Array gegangen.
Delphi-Quellcode:
procedure TWinHTTPRequest.SetWinCertificate;
var
LStore: HCERTSTORE;
LCertContext: PCCERT_CONTEXT;
LBlob: CRYPT_DATA_BLOB;
LBytes: TBytes;
begin
if (FClientCertPath = '') and (FClientCertificate = nil) then
Exit;
if FClientCertPath <> '' then
LStore := CertOpenStore(PAnsiChar(CERT_STORE_PROV_FILENAME), X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
0, CERT_STORE_OPEN_EXISTING_FLAG or CERT_STORE_READONLY_FLAG, PChar(FClientCertPath))
else
begin
LBlob.cbData := FClientCertificate.Size; // <--- siehe von hier...
SetLength(LBytes, LBlob.cbData);
FClientCertificate.Position := 0;
FClientCertificate.Read(LBytes, LBlob.cbData);
LBlob.pbData := PByte(@LBytes[0]); // <--- ...bis hier!
LStore := PFXImportCertStore(@LBlob, PChar(FClientCertPassword), 0);
end;
if LStore = nil then
raise ENetHTTPRequestException.CreateResFmt(@SNetHttpCertFileOpenError,
[GetLastError, SysErrorMessage(GetLastError, TWinHttpLib.Handle)]);
try
LCertContext := CertFindCertificateInStore(LStore, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
0, CERT_FIND_ANY, nil, nil);
if LCertContext = nil then
raise ENetHTTPRequestException.CreateResFmt(@SNetHttpCertNotFoundError,
[GetLastError, SysErrorMessage(GetLastError, TWinHttpLib.Handle)]);
try
WinHttpSetOption(FWRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
LCertContext, SizeOf(CERT_CONTEXT));
finally
CertFreeCertificateContext(LCertContext);
end;
finally
CertCloseStore(LStore, 0);
end;
end;
Delphi-Quellcode:
// mit der Definition aus Winapi.Windows
type
_CRYPTOAPI_BLOB = record
cbData: DWORD;
pbData: PBYTE;
end;
...
CRYPT_DATA_BLOB = _CRYPTOAPI_BLOB;
|
|
Zitat
|