We are proud to announce the conversion of StrSafe.h header: JwaStrSafe.pas conversion is now available through the JEDI API Lib subversion repository. You can also get the header here (only temporary).

What is JwaStrSafe.pas ?

StrSafe defines safer C library string routine replacements. These are meant to make C a bit more safe in reference to security and robustness.

The functions are not exported by any DLL, so the function code is directly implemented in C code and linked into Delphi applications using an object file.

The unit supports:

  • ANSI and UNICODE
    • ANSI functions have an A appendix like CopyA
    • UNICODE functions have a W appendix like CopyW
  • Char and byte count parameters. Using char count parameters means that the count of chars in an unicode and ansicode string is the same. It is in contrast to byte count parameters where widestrings have as twice as the length of their ansi variants.
    • Functions that use char parameters contains CCh (Count Chars) like StringCchCopy
    • Functions that use byte parameters contains Cb (Count bytes) like StringCbCopy

The following available functions use byte count parameters:

StringCbCat
StringCbCatEx
StringCbCatN
StringCbCatNEx
StringCbCopy
StringCbCopyEx
StringCbCopyN
StringCbCopyNEx
StringCbLength

The following available functions use char count parameters:

StringCchCat
StringCchCatEx
StringCchCatN
StringCchCatNEx
StringCchCatN
StringCchCopy
StringCchCopyEx
StringCchCopyN
StringCchCopyNEx
StringCchLength

The following available functions are implemented in Delphi:

STRSAFE_FAILURE_BYTE
STRSAFE_GET_FILL_PATTERN
STRSAFE_GET_FILL_PATTERN

The following functions are not available :
StringCchVPrintf, StringCbVPrintf, StringCchPrintf, StringCbPrintf, StringCchPrintfEx, StringCbPrintfEx, StringCchVPrintfEx, StringCbVPrintfExA, StringCchGets, StringCbGets, StringCchGetsEx and StringCbGetsEx


Working with JwaStrSafe.pas: The strsafe functions use a HRESULT return value rather than a pointer. Check for the return value to find errors like buffer overflows.

uses ComObj;
var AA : Array[0..1] of widechar;
    H : HRESULT;
begin
  H := StringCbCopyW(AA, sizeof(AA), PWideChar(WideString(’123′)));
  OleCheck(H);
end;

This way you can get information about a failed string copy, because the second parameter defines how many bytes are available in destination string AA. The copying fails because string ’123′ needs (3+1)*sizeof(WIDECHAR) = 6 + 2 bytes space. Two more bytes are necessary for the mandatory null wide char.

The other way around (from PWideChar to Delphi’s WideString) uses SetLength and the character count function type.

uses ComObj;
var WStr : WideString;
begin
  SetLength(WStr, 10);
  OleCheck(StringCchCopyW(@PWideChar(WStr)[1], Length(WStr), WStr);

We explicitly use character count because Length returns the actual count of characters and not bytes.
Warning:

1. Mixing up Delphi’s type WideString and PWideChar may lead to crash if the pointer is changed.

var P : PWideChar;
begin
  GetMem(P, 100);
  P := PWideChar(WideString(’1234′));

The following operations crashes on P.

FreeMem(P);
ZeroMemory(P, 100);
StringCchCopyW(P, 3, PWideChar(WideString(’123′)));

However read operations are possible.

2. Use WideString type cast if you want to convert from ansi to unicode.

PWideChar(WideString(’123′))

or use a string variable

var S : String;
    P := PWideChar;
begin
  S := ’123′;
  P := PWideChar(WideString(S));

Tell me how you liked this blog entry by adding a comment.