수요일, 2월 10, 2010

How to privilege elevation without UAC Dialog Window in VISTA and higher.

How to privilege elevation without UAC Dialog Window in VISTA and higher.

한번씩 사용하게 되는데 잊어 버릴까봐 적어 둔다. -_-;

Below codes are works very well for me. (VC++, Delphi) ㅋㅋ
You can makes an UAC elevation executor binary for distribute ActiveX.
(confer section [hook] in xxx.inf)

아래 VC++ 와 Delphi 코드는 내가 테스트할 때에는 잘 동작했다.
UAC Elevation 은 아래 코드와 같이 사용하니 편하실 대로 적절히 변경해서 사용하면 될 것이다.
그리고 inf 에서 HOOK 을 사용할 때에도 아래를 보고 하면 된다.

like this... (xxx.inf)
[Add.Code]
test_vista.ocx=test_vista.ocx
uacelevator.exe=uacelevator.exe
;
[...]
...
[uacelevator.exe]
file=thiscab
FileVersion=1,0,0,1
[Setup Hooks]
hook1=hook1
[hook1]
Run=%EXTRACT_DIR%\uacelevator.exe "test_vista.ocx"
;


Codes are here...
Source:
http://stackoverflow.com/questions/923350/delphi-prompt-for-uac-elevation-when-needed
http://pascalfonteneau.developpez.com/articles/delphi/vista/uac/VistaUACandDelphi.pdf

// VC++
// Calls UAC Dialog Window
// Note:
//    http://byung.egloos.com/2869040
BOOL RunAsAdmin( HWND hWnd, LPTSTR lpFile, LPTSTR lpParameters ) {
    SHELLEXECUTEINFO   sei;
    ZeroMemory ( &sei, sizeof(sei) );

    sei.cbSize          = sizeof(SHELLEXECUTEINFOW);
    sei.hwnd            = hWnd;
    sei.fMask           = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
    sei.lpVerb          = _TEXT("runas");
    sei.lpFile          = lpFile;
    sei.lpParameters    = lpParameters;
    sei.nShow           = SW_SHOWNORMAL;

    if( ! ShellExecuteEx(&sei) ) {
        printf( "Error: ShellExecuteEx failed 0x%x\n", GetLastError() );
        return FALSE;
    }

    return TRUE;
}

// Delphi
// Without UAC Dialog Window ( * NOTE: DOES NOT WORK!)
// Note:
//    http://stackoverflow.com/questions/923350/delphi-prompt-for-uac-elevation-when-needed
function RunAsAdmin(filename: string);
var
    ProcInfo: PROCESS_INFORMATION;
    StartInfo: TStartupInfo;
begin
  ZeroMemory( @StartInfo, sizeof(StartInfo) );
  StartInfo.cb := sizeof( StartInfo );
  StartInfo.wShowWindow := SW_SHOW;
  if not CreateProcessA(PAnsiChar(fileName), nil, nil, nil, false, CREATE_NEW_CONSOLE, nil, nil, StartInfo, ProcInfo) then

  //if not CreateProcessW(PWideChar(fileNameW), nil, nil, nil, false, CREATE_NEW_CONSOLE, nil, nil, StartInfo, ProcInfo) then
  //or: //if not CreateProcessW(nil,PWideChar(PathName), nil, nil, false, CREATE_NEW_CONSOLE, nil, nil, StartInfo, ProcInfo) then
  //ShowMessage(Format(‘The application could not be started: (%d) %s’,[GetLastError,SysErrorMessage(GetLastError)]));
end;

// Delphi
// Calls UAC Dialog Window
uses
  SysUtils, Windows, ShellApi, ShlObj, ComObj;
type
    ...
function RunAsAdmin(strFilename, strParam, strPath: string; opt: integer; handle: HWND; isVista: boolean);
var
    sellExecuteInfo: TShellExecuteInfo;
begin
    if( isVista ) then begin
sellExecuteInfo.lpVerb := 'runas';
if( handle <> 0 ) then sellExecuteInfo.Wnd := handle;
    end;

    sellExecuteInfo.lpFile := PChar( strFileName );
    sellExecuteInfo.lpParameters := PChar( strParam );
    sellExecuteInfo.lpDirectory := PChar( strPath );
    sellExecuteInfo.nShow := opt; // SW_MINIMIZE, ...

    Result := ShellExecuteEx( @sellExecuteInfo );
end;

RunAsAdmin( 'regsvr32', '/s', '.\' + 'test.ocx', SW_NORMAL, self.handle );


-----
i don't like above ways. i think just show UAC dialog window if needed it,
but why bypass this process?
if you learn more about the permission then i recommended you SHOULD use *NIX system.
so, i hate Windows series.
hmm... but i should work under the Windows for my job. shit...

Cheers,
June

댓글 없음:

댓글 쓰기