Application에 Manifest 를 이용하는 방법 외에 Application Level에서 특정한 Process를 Administrator 권한을 갖고 실행하려면 다음과 같은 방법이 존재합니다.
1. ShellExecute
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;
}
2. COM Elevation Moniker
typedef struct tagBIND_OPTS3 : tagBIND_OPTS2
{
HWND hwnd;
} BIND_OPTS3, * LPBIND_OPTS3;
HRESULT CreateElevatedComObject(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}
여기서 언급할 내용은 parent HWND을 해당 함수로 넘기는 것에 대한 부분입니다. Background Application이 Elevation될 때는 Secure desktop으로 switch 하여 Prompt가 Open되지 않고, Taskbar에 Elevation prompt 가 minimize 되어 나타나며(깜박이게 됩니다.), 이를 사용자 interaction을 통해서, 확인할 수 있도록 하는 구성입니다. 만일, Foreground application을 Program 상에서 임의로 Elevation 할 경우에, parent HWND 를 넘기지 않고, NULL로 전달되었을 때는 Background application elevation 현상처럼 발생하게 됩니다. 고려하시구요..
그렇다면, LorIE 처럼, Low Level로 Process를 실행시키는 방법은? 다음과 같이 합니다.
BOOL bRet;
HANDLE hToken;
HANDLE hNewToken;
// Notepad is used as an example
WCHAR wszProcessName[MAX_PATH] = L"C:\\Windows\\System32\\Notepad.exe";
// Low integrity SID
WCHAR wszIntegritySid[20] = L"S-1-16-4096";
PSID pIntegritySid = NULL;
TOKEN_MANDATORY_LABEL TIL = {0};
PROCESS_INFORMATION ProcInfo = {0};
STARTUPINFO StartupInfo = {0};
ULONG ExitCode = 0;
if (OpenProcessToken(GetCurrentProcess(),MAXIMUM_ALLOWED, &hToken))
{
if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hNewToken))
{
if (ConvertStringSidToSid(wszIntegritySid, &pIntegritySid))
{
TIL.Label.Attributes = SE_GROUP_INTEGRITY;
TIL.Label.Sid = pIntegritySid;
// Set the process integrity level
if (SetTokenInformation(hNewToken, TokenIntegrityLevel, &TIL,
sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
{
// Create the new process at Low/High integrity
bRet = CreateProcessAsUser(hNewToken, NULL,
wszProcessName, NULL, NULL, FALSE,
0, NULL, NULL, &StartupInfo, &ProcInfo);
}
LocalFree(pIntegritySid);
}
CloseHandle(hNewToken);
}
CloseHandle(hToken);
코드를 보시는 분들은 궁금한 점이 생기시겠지요. Low Integrity SID로 S-1-16-4096를 사용하는 데, 그렇다면, High Integrity SID를 넣어주면, High right process가 실행될 수도 있지 않을 까.. 하실 텐데, 제가 Test 한 결과로는 안되더군요. 안될 것이란 생각을 갖고 혹시나 했지만 말이죠.
** 상위의 Code 및 내용은 아래의 문서에서 찾아보실 수 있습니다.
Windows Vista Application Development Requirements for User Account Control Compatibility
Understanding and Working in Protected Mode Internet Explorer (Windows IETechCol)



덧글
charmzine 2007/02/23 12:30 # 삭제 답글
안녕하세요. 게임개발에 몸 담고 있는 청년입니다.현재 제가 기존 웹에서 게임을 런쳐하는 ActiveX를 Vista 관련 수정하고 있습니다.
ActiveX 자체를 Admin 권한으로 상승하기 위한 방법이 궁금합니다...
SehYoon 2007/02/23 20:10 # 답글
IE가 Protected Mode에서 Low Rights IE로 돌기때문에 그 위에 올라가 있는 ActiveX Control도 역시 Low Rights 일 것으로 보입니다. 보통 이와같은 Extension은 Admin으로 실행되지 못하도록 Vista에서 구성되었다고 보시면 됩니다. IE자체를 Admin으로 돌도록 한다면 모르겠지만 말이죠.