1

I'm converting this code from C++ to Delphi but I don't get the following part of the code. Can anyone explain me what the following code means; what's happening to the szBuff buffer ?

I'm pretty sure it's such kind of formatting (replacement), but I don't even know what is expected as a result and I can't find any sensible documentation of the used functions (maybe I'm just a lame :)

Can anyone help me with the translation of this code to Delphi (or direct me to proper documentation) ?

I don't like this how do you convert kind of questions by myself, so I mentioned at least function names in the question title so it might searchable to someone else in the future.

function TSecInfo.BuildSecurityAttributes(var SecAttrs: TSecurityAttributes): boolean;
var
  pszSidUser: PChar;
  szBuff: array [0..1024] of Char;
begin

// pszSidUser at this time contains user SID like this
// S-1-5-21-1454471165-1004336348-1606980848-5555

// TCHAR szBuff[1024]; // I'm not sure with array [0..1024] of Char;

  _tcscpy(szBuff, _T("D:"));
  _tcscat(szBuff, _T("(A;;GA;;;"));
  _tcscat(szBuff, pszSidUser);
  _tcscat(szBuff, _T(")"));
  _tcscat(szBuff, _T("(A;;GWGR;;;AN)"));
  _tcscat(szBuff, _T("(A;;GWGR;;;WD)"));

...

  _tcscat(szBuff, _T("S:(ML;;NW;;;S-1-16-0)"));

end;

For those who are interested in what's the whole code from the link about I can tell it should be a trick how to access network pipes for writing as an anonymous user on Windows Vista above. To the whole article follow this link.

Thanks for your time
Regards

  • Are you sure it is c++? Doesn't look like – BЈовић Jun 30 '11 at 16:49
  • @VJo - no; sure not; but the source code files has *.cpp extension and library linking like this `#include ` –  Jun 30 '11 at 16:52
  • @VJo: The original code behind the link is C++. – Mason Wheeler Jun 30 '11 at 16:53
  • In fact it originates from [this example](http://support.microsoft.com/kb/813414/en-us) where they are using Microsoft Visual C++ –  Jun 30 '11 at 17:00
  • This is C++ code embedded inside a Pascal function. – Andreas Rejbrand Jun 30 '11 at 17:09
  • 2
    `szBuff[1024]` implies there are 1024 elements. `array [0..1024]` is 1025 elements. You need `array[0..1024 - 1]`, sometimes written `array[0..1023]`. – Andreas Rejbrand Jun 30 '11 at 17:11
  • @Andreas - yeah; it is; with a special `...` command :) Maybe I might omit the header. –  Jun 30 '11 at 17:11
  • @Andreas - thanks for this point; I would say there is reserve though but would you use `PChar` rather than `array of Char` ? –  Jun 30 '11 at 17:14
  • 1
    If I'm reading it correctly the sample code also uses "Shlemiel the Painter's) string concatenation (http://www.joelonsoftware.com/articles/fog0000000319.html) – Gerry Coll Jul 01 '11 at 02:02

2 Answers2

2

_tcscpy and _tcscat are TCHAR macro versions of C standard library functions strcpy and strcat for copying and concatenating C strings. They evaluate to ANSI or Unicode versions depending on whether or the type of project you are targeting. It's really C code rather than C++ code in my view.

In Delphi you would simply use string variables like this:

function TSecInfo.BuildSecurityAttributes(var SecAttrs: TSecurityAttributes): boolean;
var
  pszSidUser: PChar;
  Buff: string;
begin
  // pszSidUser at this time contains user SID like this
  // S-1-5-21-1454471165-1004336348-1606980848-5555

  Buff := 'D:(A;;GA;;;'+pszSidUser+')(A;;GWGR;;;AN)(A;;GWGR;;;WD)S:(ML;;NW;;;S-1-16-0)';
  SomeOtherWindowsAPICall(PChar(Buff));    
end;

Presumably in the C code there is a call to another Windows API function that receives an LPCTSTR. The C code will pass szBuff but you can simply pass PChar(Buff) as I have shown above.

The C code is using a fixed length buffer because it doesn't have available a dynamically allocated string class like Delphi's string or std::string in C++. Fixed length buffers like this often lead to buffer overruns. In Delphi don't use a fixed length buffer if you can avoid it.

This is a classic example of why languages with built in string handling are so much easier to work with than C.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • +1 and accept. Thanks for the explanation; Yes the [ConvertStringSecurityDescriptorToSecurityDescriptor](http://msdn.microsoft.com/en-us/library/aa376401%28v=vs.85%29.aspx) is called after this where I'll use what you suggested. –  Jun 30 '11 at 17:28
  • God bless this dynamic allocation in Delphi :) The C code still looks for me like a spilled tea. –  Jun 30 '11 at 17:37
  • 1
    @daemon_x The C code would be a lot better if it dropped support for dual ANSI/Unicode builds, and better still if it was C++ and used `std::wstring`. – David Heffernan Jun 30 '11 at 17:39
1

It looks like the code is using TCHARS, basically they are a macro which makes going from unicode to non-unicode easier. _tcscpy is copying the parameter to szBuff, _tcscat is appending the parameter to szBuff. If you are familar with strcpy and strcat they do the same thing.

_tcscpy(szBuff, _T("D:")); //szBuff == "D:"
_tcscat(szBuff, _T("(A;;GA;;;")); //szBuff == "D:A;;GA;;;"
...
daalbert
  • 1,465
  • 9
  • 7
  • Thanks; so this means that the subsequent calling of [strcat](http://www.cplusplus.com/reference/clibrary/cstring/strcat/) only concatenates all those strings together and it's used probably to the code be more readable ? Aren't there any special characters ? –  Jun 30 '11 at 17:08
  • Yes, that is correct. Also `_T("string")` will be `"string"` w/o UNICODE or will be `L"string"` with UNICODE. – daalbert Jun 30 '11 at 17:12