* Windows GetFileSecurity, GetSecurityDescriptorOwner, LookupAccountSidA sample code; * Richard A. DeVenezia; * http://www.devenezia.com; * Tested on Windows 2000 SP 3; options nosource nonotes; filename SASCBTBL catalog 'work.win.api.source'; data _null_; file SASCBTBL; input; put _infile_; cards4; ROUTINE GetFileSecurityA MODULE=advapi32 MINARG=5 MAXARG=5 STACKPOP=CALLED RETURNS=LONG ; arg 1 NUM BYVALUE FORMAT=IB4.; * lpFileName; arg 2 NUM BYVALUE FORMAT=IB4.; * RequestedInformation; arg 3 NUM BYVALUE FORMAT=IB4.; * pSecurityDescriptor; arg 4 NUM BYVALUE FORMAT=IB4.; * nLength; arg 5 NUM FORMAT=IB4.; * lpnLengthNeeded; ROUTINE GetSecurityDescriptorOwner MODULE=advapi32 MINARG=3 MAXARG=3 STACKPOP=CALLED RETURNS=LONG ; arg 1 NUM BYVALUE FORMAT=IB4. ; * pSecurityDescriptor ; arg 2 NUM FORMAT=IB4. ; * pOwner; arg 3 NUM FORMAT=IB4. ; * lpbOwnerDefaulted; ROUTINE LookupAccountSidA MODULE=advapi32 MINARG=7 MAXARG=7 STACKPOP=CALLED RETURNS=LONG ; arg 1 BYVALUE FORMAT=IB4. ; * lpSystemName; arg 2 BYVALUE FORMAT=IB4. ; * Sid; arg 3 BYVALUE FORMAT=IB4. ; * Name; arg 4 BYADDR FORMAT=IB4. ; * cbName; arg 5 BYVALUE FORMAT=IB4. ; * ReferencedDomainName; arg 6 BYADDR FORMAT=IB4. ; * cbReferencedDomainName ; arg 7 BYADDR FORMAT=IB4. ; * peUse; routine GetCommandLineA module = kernel32 minarg = 0 maxarg = 0 stackpop = called returns = long ;;;; run; options notes; %macro OwnerOf (file=, sdBuffLen=100, nameBuffLen=100, domainBuffLen=100); /* * 11/01/02 RAD Adapted to SAS from sample at * http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q218965& */ %local this; %let this = OwnerOf; %if not %sysfunc(fileexist (&file)) %then %do; %put WARNING: &this: File &file does not exist.; %*goto EndMacro; %end; data _null_; array sdBuff [&sdBuffLen] $1 _temporary_; * determine how bytes needed to hold security info; filename = "&file"||"00"x; sdSize=0; rc = modulen ("GetFileSecurityA", addr(filename), 01x, addr(sdBuff[1]), sdSize, sdSize); if &sdBuffLen < sdSize then do; put "ERROR: &this: SD buffer length is &sdBuffLen, need " sdSize; stop; end; rc = modulen ("GetFileSecurityA", addr(filename), 01x, addr(sdBuff[1]), sdSize, sdSize); if rc = 0 then do; put "ERROR: &this: GetFileSecurity had an error."; stop; end; pOwner = 0; flag = 0; rc = modulen ("GetSecurityDescriptorOwner", addr(sdBuff[1]), pOwner, flag); if rc = 0 then do; put "ERROR: &this: GetSecurityDescriptorOwner had an error."; stop; end; length name $&nameBuffLen; length domain $&domainBuffLen; system = "00"x; name = "00"x; name_len = 0; domain = "00"x; domain_len = 0; use = 0; rc = modulen ( "LookupAccountSidA", addr(system), pOwner, addr(name), name_len, addr(domain), domain_len, use); if &nameBuffLen < name_len then do; put "ERROR: &this: Name buffer length is &nameBuffLen, need " name_len; stop; end; if &domainBuffLen < domain_len then do; put "ERROR: &this: Name buffer length is &domainBuffLen, need " domain_len; stop; end; rc = modulen ( "LookupAccountSidA", addr(system), pOwner, addr(name), name_len, addr(domain), domain_len, use); file = compress (filename, '00'x); domain = compress (domain, '00'x); name = compress (name, '00'x); put file= "in " domain= "is owned by " name=; stop; run; %EndMacro: %mend; data _null_; addr = modulen ('GetCommandLineA'); if addr > 0 then do; cmdline = peekc (addr,200); z = index (cmdline, '0000'x); cmdline = translate (substr (cmdline,1,z), ' ', '00'x); put cmdline=; if cmdline =:'"' then call symput ('SASEXE', scan(cmdline,1,'"')); else call symput ('SASEXE', scan(cmdline,1,' ')); end; stop; run; %ownerOf (file=&SASEXE); filename SASCBTBL; options source;