Use ShellExecute to run icacls with multiple parameters

2.3k Views Asked by At

I am trying to execute icacls from c++. Code below does nothing. I still don't know why it does nothing. I cannot see what icacls return to me because cmd windows automactly closes. HINSTANCE also doesnt provides me much. How i can use icacls with multiple parameters?

HINSTANCE hInst = ShellExecute( NULL, 
NULL,  
L"icacls",  
L"s.jpg /grant:r %username%:W",     
L"C:/",    
SW_NORMAL 
); 
3

There are 3 best solutions below

0
On

Undeleting post:

I had written up this bit of code earlier, unfortunately it is CLR/.NET specific. However, since you professed that using 'the API' is hard (it is, I did it 10 years ago and NTFS ACLS are no picknick), you might be motivated by the below sample to integrate a bit of .NET code (C++/CLI or Interop based?)


Any specific reason not to use C# code?

AddFileSecurity(fileName, @"DomainName\AccountName",
        FileSystemRights.ReadData, AccessControlType.Allow);

RemoveFileSecurity(fileName, @"DomainName\AccountName",
        FileSystemRights.ReadData, AccessControlType.Allow);

With the following helpers from MSDN: How to: Add or Remove Access Control List Entries:

public static void AddFileSecurity(string fileName, string account,
        FileSystemRights rights, AccessControlType controlType)
{
    FileSecurity fSecurity = File.GetAccessControl(fileName);
    fSecurity.AddAccessRule(new FileSystemAccessRule(account,
                rights, controlType));
    File.SetAccessControl(fileName, fSecurity);
}

public static void RemoveFileSecurity(string fileName, string account,
        FileSystemRights rights, AccessControlType controlType)
{
    FileSecurity fSecurity = File.GetAccessControl(fileName);
    fSecurity.RemoveAccessRule(new FileSystemAccessRule(account,
                rights, controlType));
    File.SetAccessControl(fileName, fSecurity);
}

See the article for full details and comments

0
On

Your lpFile parameter probably should be "icacls.exe" with an .exe extension.

Also, you should always check for errors. If ShellExecute() succeeds, it returns a value greater than 32. See MSDN for a list of error codes that may be returned.

0
On

For testing purposes, you can look at the output from icacls by wrapping it in cmd /k:

HINSTANCE hInst = ShellExecute( NULL,
    NULL,
    L"cmd",
    L"/k icacls s.jpg /grant %username%:W",
    L"C:/",
    SW_NORMAL
);

[Why grant:r?]