Let's say that your application has some functionality which requires administrative privileges to accomplish its task. For instance, you need to write some settings out to HKLM, or register some file types in HKCR. Well, in the "olden days" (read: any time before Vista), you could generally assume that the user was running with admin rights and could do this. Of course, your assumptions could be wrong plenty of the time too since millions of people run as standard users even in XP and Win2k. But in Vista, chances are pretty good (about 99%) that the user doesn't have sufficient privileges to do this sort of thing. But you still need to do it. What now?
Well, the proper way to do this in Vista is to have a helper application which is launched with sufficient privileges to do the task. Then you have some sort of UI which indicates to the user that the action needs administrative rights.
For instance, if you take a look at many of the control panels, they'll show you the proper UI. You'll notice how the properties button has a shield icon next to it. That's the visual cue that tells the user they need to do something special here.

We're going to accomplish exactly that with a simple example project. We're going to pretend that we need to run Notepad with elevated privileges, and we'll do it from a button.
There's only two things you need to do to make this work. 1) Use the BCM_SETSHIELD message to tell the button to display the shield icon. 2) Use the ShellExecuteEx API to run Notepad as an admin. That's it!
1)
Const BCM_SETSHIELD = &h160C
Const BCM_GETIDEALSIZE = &h1601
Declare Sub SendMessageA Lib "User32" ( hwnd as Integer, msg as Integer, wParam as Integer, lParam as Integer )
Declare Sub SendMessageA Lib "User32" ( hwnd as Integer, msg as Integer, wParam as Integer, lParam as Ptr )
SendMessageA( me.Handle, BCM_SETSHIELD, 0, 1 )
dim size as new MemoryBlock( 8 )
SendMessageA( me.Handle, BCM_GETIDEALSIZE, 0, size )
me.Width = 12 + size.Long( 0 ) + 12
me.Height = 2 + size.Long( 4 ) + 2
(I cheated and used the BCM_GETIDEALSIZE message to resize the button properly.)
2)
Declare Function ShellExecuteExW Lib "Shell32" ( info as Ptr ) as Boolean
dim info as new MemoryBlock( 15 * 4 )
dim verb as new MemoryBlock( 32 )
dim file as new MemoryBlock( 260 * 2 )
info.Long( 0 ) = info.Size
info.Long( 8 ) = self.Handle
verb.WString( 0 ) = "runas"
file.WString( 0 ) = "c:\Windows\Notepad.exe"
info.Ptr( 12 ) = verb
info.Ptr( 16 ) = file
Const SW_SHOWNORMAL = 1
info.Long( 28 ) = SW_SHOWNORMAL
dim ret as Boolean = ShellExecuteExW( info )
Ta da! That's all there is to it! Check out the example project to see a working instance of this (note: I left out error checking in the example). But before I leave you to play around with this, I want to tell you some very important things.
For starters, the reason you have to do it this way is because Windows (like all other OSes) doesn't let you elevate an application's privileges if it's already running. That's why you must start up a new process. So whatever chores you need to accomplish as an administrator you should refactor into a separate process that can be launched this way. The next thing you need to know relates to the first -- do what you need to do and terminate! Running as admin means you own the machine. So whatever you do, do it fast and get out of there to minimize the security risks. Finally, be wary of doing this at all! Sneaky people can do sneaky things with this. For instance, let's say you have two accounts on the machine. One is admin named Mom, the other is a parentally controlled user named Little Billy. One day, Little Billy convinces Mom to launch Notepad with admin rights. Little Billy then goes to File->Open and uses it to navigate to the system directory (which he never could see before), and open up the control panel for parental controls (which he never could open before) and turn off the parental controls for his account. Oops. So remember, there are side effects to launching things with admin rights that you probably never thought of. Minimize the risk by doing as little as possible and allowing the user as little control as possible.
You wouldn't happen to know the APIs to elevate a process to root in linux, do you? I want to use ports less that 1024, and can't find the API anywhere.
I've always just used chmod and getuid/geteuid/setreuid to do it.
# Set the owner and group of the file to root/wheel (you must be running as root to do this!)
chown root MyApplication
# Now set the executable and setuid bits
chmod 4755 MyApplication
Soft Declare Function getuid Lib "libc" () as Integer
Soft Declare Function geteuid Lib "libc" () as Integer
Soft Declare Function setreuid Lib "libc" (ruid as Integer, euid as Integer ) as Integer
// Get the effective and real user IDs
euid = geteuid
ruid = getuid
// Drop privs immediately by setting us to the real user ID
Call setreuid(euid, ruid )
// Become root by setting effective user id, do stuff, then drop privs again
Call setreuid(ruid, euid )
DoMyImportantAndScaryThings()
Call setreuid( euid, ruid )
That would work, thanks Aaron. I was just hoping there was some common API to use that dialog box that prompts for the root password to do anything. I figured that would be more secure. But if I can't find it, then I *might* use that.
Thanks again!