There are several ways in which a program can query security attributes (Owner, Group and ACLs) of one file and copy them to another file.
In a true Microsoft's way, some are well-documented, but they don't work as advertised, and some work as needed, but they are not documented.
First hit on Google is
. The name checks out, it accepts a HANDLE, so it should be quick and simple way to do what we want.
Nope, it's not.
It's an older API that doesn't correctly handle inheritable ACLs and its use is not recommended. Not by the API documentation, mind you, but by a random blog post from one of many Microsoft development teams, which you still need to find first. What they recommend instead is
And you'd still naively think it's the one.
Nope, it's not.
The problem is that SetSecurityInfo will fail with "access denied" if you are trying to set DACL and the file is not opened with READ_CONTROL.
You may wonder why the heck it needs
question. That's because it wants to look up the name of the file and then *feed that name into Set
SecurityInfo function*. The latter will then re-open the file and start spraying kernel with requests, which is the last thing you need when
are already quite busy with copying a million of files from A to B.
Looking at the trace of SetSecurityInfo with Procmon shows that it generates over a
of kernel calls... whereas only one is really needed.
The name of that one call that we want is
, but it's a part of so-called Native API and as such it is officially off-limits for any application use.
However, if we are to comb several pagefuls of
, we may spot something called
, which looks suspiciously like NtSetSecurityObject.
Long story short, you want to copy security attributes - use
Get / SetKernelObjectSecurity
. So now you know. Congratulations :)