Friday, July 15, 2011

Problem : How to give permission to a folder for a built in group in any Windows machine ( including Non english version ) from command line \ script

Solution :

Alright I will start with solution and then explain things. If you want to set permission for any built in groups like Users, then use the SID instead of group account name. You can get the SID using WMI and set permission using icacls tool.

For a Users(SID - S-1-5-32-545 ) group, Here is a way of doing it.

In Vista, 7 and server2008 and above :

icacls "c:\Program Files\YourFolder" /T /C /Grant:r *S-1-5-32-545:(OI)(CI)(M)


older version:

cacls "c:\Program Files\YourFolder" /T /E /C /G Users:C


Using Windows Management Instrumentation(WMI) to get the SID.

Here is the vb script to get the SID value for all local account using WMI

Dim strComputer
Dim strUsers

strComputer = "."
Set objWMIService = GetObject( _
"winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_Group Where LocalAccount = True")
For Each objItem in colItems
Wscript.Echo "Local Account: " & objItem.LocalAccount & VBNewLine _
& "Name: " & objItem.Name & VBNewLine _
& "SID: " & objItem.SID & VBNewLine _
& "SID Type: " & objItem.SIDType & VBNewLine _
& "Status: " & objItem.Status & VBNewLine
Next


How to Change permission for a folder from a script \ command line:

Use the icacls tool ( for xp and older versions it is "cacls" ), to set the permission.

icacls :
Displays or modifies discretionary access control lists (DACLs) on specified files, and applies stored DACLs to files in specified directories.

for more info ... below are the links...

Icacls\cacls :

http://technet.microsoft.com/en-us/library/cc753525%28WS.10%29.aspx
http://technet.microsoft.com/en-us/library/bb490872.aspx

WMI
http://msdn.microsoft.com/en-us/library/aa394582%28v=VS.85%29.aspx
http://technet.microsoft.com/en-us/library/ee156560.aspx

Thanks,
KKM.

Tuesday, July 5, 2011

Administrator privilege for VC++ Application using Manifest file and Visual Studio 2008


How to make your Visual C++ application run with administrator privilege.

================================================================

Today I wanted to make my application run with administrator privilege on all my client Windows 7 boxes. Below are some of the ways of doing it after installation.

Method 1.
Right click on the Application, select "Run As Administrator"
Method 2.
In properties - > shortcut tab -> Advanced -> check the "Run As Administrator".


These options are good workaround for application already installed. But this doesn't solve the real problem. I wanted my application by itself always run as administrator
with out client doing any thing after installation . Below is the way of solving this using manifest file.

Method 3
Manifest files are XML files that describes the dependencies that an application uses. So to make an application run as administrator, we need to add the below xml to the manifest.




Adding a manifest file with requestedExecutionLevel set to "requireAdministrator" will make the application to execute with administrator privilege always.

How to embed manifest to a project or build in visual studio 2008 or above :

1. Directly configure the visual studio project properties to generate and embed the manifest file.

Project Properties Dialog -> Configuration Properties -> Linker -> Manifest File -> Set the UAC Execution Level = requireAdministrator.

Also make sure the Generate Manifest is 'Yes'.

During build \ linking, an intermediate manifest file will be generated. Later this file will be embedded in to the binary ( make sure Project Properties Dialog -> Configuration Properties -> Manifest Tool -> Input and Output -> Embed Manifest is set to 'Yes'.

2. Using mt.exe tool.
mt.exe tool is another way of adding the manifest file in to the binary (exe or dll ). Visual Studio internally uses this tool and does the thing for us in the above case. Also If we want to do more with manifest then use mt.exe.


To embed a manifest file(yourappn.exe.manifest) to your appn (yourappn.exe ) :

> mt.exe /manifest yourappn.exe.manifest /outputresource:.yourappn.exe;#1


To extract a manifest file from a existing appn :
> mt.exe -inputresource:youapplication.exe;#1 -out:extracted.manifest



How to embed manifest if you are using QT \QMAKE to create project files.
Here we go, this was my real problem. In my application the visual studio project file is generated from the QT pro file. So I need to find another way to specify the manifest file.
There seems to be two ways.

1(Better approach ..but didn't work with my QT version ..bug ?? )
In the pro file, add the below

QMAKE_LFLAGS_WINDOWS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"

2. (alternate approach ... not a good way ..but if no other way ... go with this )

QMAKE_POST_LINK = \"$(WindowsSdkDir)bin\mt.exe\" /manifest \"$(ProjectDir)yourappn.exe.manifest\" /outputresource:.\\$(ConfigurationName)\yourappn.exe

This one add the command script to embed the manifest file.



Debug and Release versions of manifest File for vc++ 9 :

The manfiest file generated from visual studio for vc++ 9 ( may be any other vc++ version ) will be different for debug and release. This is primarily due to the dependent assembly that get added to the manifest file.

Release version will have below xml



Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">


Debug version will have below in xml

"Microsoft.VC90.DebugCRT"

So if you are trying to add your own manifest file make sure you include the correct dependent assembly.