Sep-30-2001
-----------
 LPTSTR PrintToken(HANDLE hToken, LPCTSTR *SystemNames);

Note that some programs identify (call) process.token.user
as "owner". This is not correct.
Process.token.user should be called "user" or "context".

-----------
 PrintSD.h (C++ only) contains PrintSD, GetAclInfo and
GetSidInfo functions. Only preNT4 security functions
are called (high level functions load ntmarta and a lot
of next unuseful dlls) for Win95-import compatibility.
 LPTSTR GetSidInfo(PSID pSid, LPCTSTR *SystemNames)
returns pointer to string with information about passed
SID. Free memory with string using LocalFree.
 LPTSTR GetAclInfo(PACL pAcl, LPCTSTR *SystemNames)
returns pointer to string with information about passed
ACL. Free memory with string using LocalFree.
 LPTSTR PrintSD(HANDLE hObject, SECURITY_INFORMATION
ReqSecInfo, LPCTSTR *SystemNames) returns pointer to string
with information about passed SD (control, owner, group,
dacl). SID and ACL infos are included Free memory with
string using LocalFree. SystemNames is array of pointers
to strings - names of systems where to look up a SIDs.
SystemNames can be NULL, then is SID looked up on local
system else SystemNames must be initialized and the last
LPCTSTR must be -1.
 PrintSD.h serves as source pool: copy&past source to
your NT program source if you want.
 Undocumented function must be used for printing SIDs,
(NT4 doesn't have ConvertSidToStringSid) because
algorithm is "weird" (for example both {1,0,0,0,0,0}
and {0,0,0,0,3,0xe8} authorities have the same string
representation: "-1000-"; bad RtlLargeIntegerToUnicode?).
 See also: SetPrAcl.zip

ExesCountVsAcesCount.cpp shows that count of aces
mayn't be equal to count of explicit entries. {I've included
it because I saw in the programs written by professionals
something like for(i=0; i<ExesCount; i++) GetAce(..i..) }.
This example shows (on 2K, for NUL file) count of system aces
= 1 but count of explicit entries for SACL = 2. System
ace is of both success and failure type. GetExesFromAcl
divided this information to two entries - 1st for success,
2nd for failure.

 PrintSDDL.h (C++ only) contains PrintSDDL and ModifySD
functions. They work on W2K+ only.
LPTSTR PrintSDDL(HANDLE hObject, SECURITY_INFORMATION
ReqSecInfo, LPCTSTR *SystemNames) returns pointer to SD 
in SDDL format (text).
BOOL ModifySD(HANDLE hObject, SECURITY_INFORMATION
ForceNone, LPCTSTR *SystemNames, LPCTSTR pSDDL) tries
to convert SD in SDDL format to SD. ForceNone adds null
SD parts if they are not specified in SDDL string.