Elevating User Account Control with Delphi
If you have medium size of Delphi based application that required some privileges access to Windows OS particularly, then you might face problem with User Account Control (UAC). User Account Control (UAC) is a technology and security infrastructure introduced since Microsoft's Windows Vista. It aims to improve the security of Windows by limiting application software to standard user privileges until an administrator authorizes an increase or elevation. However without privileges access, application that need access to system folder or database might impact to failure.
This time lesson will share you 2 alternatives how the application "playing" with UAC. The first option order user to elevating the authorization manually by executing application using Run As Administrator from right click context menu of the EXE binary. While last option inject an embedding code to elevating user automatically. Both alternatives options came with the same scenario, a login form with Login button enabled if user has full privileges access, and so on in contrary. Let the learn begin, and here the detail explanation:
1. Detecting Elevation Level with ElevationType
We know that UAC only affect with OS greater than Windows XP, so you need also to detect what kind of OS version where the application currently running on. In order so, put below function on the code:
Then, you can put elevation user account detector on form onShow event just like code below :
That's all. Try to execute the application in Windows 7, here's what I've got:
The Login button disabled since the application not executed with Run As Administrator context menu.
But, if the application running from Run As Administrator, the Login button now enabled!
Note that above code will not impact on Windows XP, since OS assumed that user running it as Administrator account even it executed from context menu or not.
2. Elevate Execution Level by Manifest file
Create a .manifest file :
Save it as.manifest . Continue to create a .rc file and named it as .rc .
Ah... don't forget to save the .manifest and .rc file in the same folder with the application source code. Then, continue to open command prompt, switch to directory where brcc32.exe (Borland Resource Compiler) exist and gives below syntax:
After the syntax succesfully compiled, it will automatically created a.res and .rec .
Back to the application source code and move to Project Manager window, right click to Project Files and point to View Source menu.
On .DPR menu, gives a line syntax after $R compiler directive just like picture below:
Finished! You may test the application and see what the different between options no #1 and #2.
Have a great fuckin' day!
This time lesson will share you 2 alternatives how the application "playing" with UAC. The first option order user to elevating the authorization manually by executing application using Run As Administrator from right click context menu of the EXE binary. While last option inject an embedding code to elevating user automatically. Both alternatives options came with the same scenario, a login form with Login button enabled if user has full privileges access, and so on in contrary. Let the learn begin, and here the detail explanation:
1. Detecting Elevation Level with ElevationType
We know that UAC only affect with OS greater than Windows XP, so you need also to detect what kind of OS version where the application currently running on. In order so, put below function on the code:
function osver: string;
begin
result := 'Unknown (Windows ' + IntToStr(Win32MajorVersion) + '.' + IntToStr(Win32MinorVersion) + ')';
case Win32MajorVersion of
4:
case Win32MinorVersion of
0: result := 'W95';
10: result := 'W98';
90: result := 'WME';
end;
5:
case Win32MinorVersion of
0: result := 'W2K';
1: result := 'WXP';
end;
6:
case Win32MinorVersion of
0: result := 'WVista';
1: result := 'W7';
end;
end;
end;
Then, you can put elevation user account detector on form onShow event just like code below :
procedure TForm1.FormShow(Sender: TObject);
const
TokenElevationType = 18;
TokenElevation = 20;
TokenElevationTypeDefault = 1;
TokenElevationTypeFull = 2;
TokenElevationTypeLimited = 3;
var
token: Cardinal;
ElevationType: Integer;
Elevation: DWord;
dwSize: Cardinal;
RunAsAdministrator:boolean;
level: string;
begin
SB.Panels[0].Text:='OS type: ' + osver;
// Run As Administrator Validator
RunAsAdministrator:=false;
if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, token) then
try
if GetTokenInformation(token, TTokenInformationClass(TokenElevationType), @ElevationType, SizeOf(ElevationType), dwSize) then
case ElevationType of
TokenElevationTypeDefault: RunAsAdministrator:=false;
TokenElevationTypeFull: RunAsAdministrator:=true;
TokenElevationTypeLimited: RunAsAdministrator:=false;
else
RunAsAdministrator:=false;
end
else if (osver='W95') or (osver='W98') or (osver='WXP') then RunAsAdministrator:=true;
if GetTokenInformation(token, TTokenInformationClass(TokenElevation), @Elevation, SizeOf(Elevation), dwSize) then
begin
if Elevation = 0 then RunAsAdministrator:=false
else RunAsAdministrator:=true;
end
else if (osver='W95') or (osver='W98') or (osver='WXP') then RunAsAdministrator:=true;
finally
CloseHandle(token);
end;
level:='(Administrator)';
btnLogin.Enabled:=true;
if not RunAsAdministrator then
begin
level:='(NOT Administrator)';
btnLogin.Enabled:=false;
end;
SB.Panels[0].Text:=SB.Panels[0].Text + ' ' + level;
end;
That's all. Try to execute the application in Windows 7, here's what I've got:
The Login button disabled since the application not executed with Run As Administrator context menu.
But, if the application running from Run As Administrator, the Login button now enabled!
Note that above code will not impact on Windows XP, since OS assumed that user running it as Administrator account even it executed from context menu or not.
2. Elevate Execution Level by Manifest file
Create a .manifest file :
Save it as
Ah... don't forget to save the .manifest and .rc file in the same folder with the application source code. Then, continue to open command prompt, switch to directory where brcc32.exe (Borland Resource Compiler) exist and gives below syntax:
After the syntax succesfully compiled, it will automatically created a
Back to the application source code and move to Project Manager window, right click to Project Files and point to View Source menu.
On .DPR menu, gives a line syntax after $R compiler directive just like picture below:
Finished! You may test the application and see what the different between options no #1 and #2.
Have a great fuckin' day!
Labels: Delphi, Programming