|
델마당에서 구한 Vista ActiveX UAC 해결 방법에 대한 자료를 보고 C++ 빌더로 작업을 하고있습니다.
하지만 권한상승시켜 실행한 ActiveXObject 를 리턴하는 부분에서 Variant 형태로 리턴하려니 C++ 빌더에서는
에러가 발생하더군여 형을 맞춰주어야 할것 같은데 조언부탁드립니다. 에러발생지점은 [C++빌더로 변환작업한 소스2] 에서 *ret = pObj 부분입니다.
[델파이 참고 소스1]
unit uActiveXElevation;
interface
uses windows, Sysutils, ActiveX;
type
PBindOpts3 = ^TBindOpts3;
{$EXTERNALSYM tagBIND_OPTS3}
tagBIND_OPTS3 = record
cbStruct: DWORD;
grfFlags: DWORD;
grfMode: DWORD;
dwTickCountDeadline: DWORD;
dwTrackFlags: DWORD;
dwClassContext: DWORD;
locale: LCID;
pServerInfo: Pointer;
hwnd: HWND;
end;
TBindOpts3 = tagBIND_OPTS3;
{$EXTERNALSYM BIND_OPTS3}
BIND_OPTS3 = TBindOpts3;
function CoCreateInstanceAsAdmin(WndHandle: HWND; clsid: TCLSID;
iid: TIID; out ppv): HRESULT;
implementation
function ElevationCoGetObject(pazName: PWideChar; pBindOptions: PBindOpts3;
const iid: TIID; out ppv): HResult; stdcall; external 'ole32.dll'
name 'CoGetObject';
function CoCreateInstanceAsAdmin(WndHandle: HWND; clsid: TCLSID; iid: TIID; out ppv): HRESULT;
var
BindOpts: TBindOpts3;
Moniker : PWideChar;
begin
Moniker := PWideChar(WideString('Elevation:Administrator!new:' + GuidToString(clsid)));
FillChar(BindOpts, SizeOf(BindOpts), #0);
BindOpts.hwnd := WndHandle;
BindOpts.cbStruct := SizeOf(BindOpts);
BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER;
Result := ElevationCoGetObject(Moniker, @BindOpts, iid, ppv);
end;
end.
[C++빌더로 변환작업한 소스1]
//---------------------------------------------------------------------------
#ifndef uActiveXElevationH
#define uActiveXElevationH
//---------------------------------------------------------------------------
#include <windows.h>
#include <objidl.h>
#include <strsafe.h>
typedef struct tagBIND_OPTS3 : tagBIND_OPTS2
{
HWND hwnd;
} BIND_OPTS3, * LPBIND_OPTS3;
BOOL IsVISTA()
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return FALSE;
}
// Windows Vista or Windows Server "Longhorn" : 6
if ( osvi.dwMajorVersion >= 6 )
{
return TRUE;
}
else
{
return FALSE;
}
}
HRESULT CoCreateInstanceAsAdmin(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 = StringCchPrintfW(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);
}
#endif
[델파이 참고 소스2]
function TDelphiZzangXElevator.ElevateDelphiZzang: OleVariant;
var
FCOMObject : IDelphiZzangX;
begin
OleCheck(CoCreateInstanceAsAdmin(Self.Handle, CLASS_DelphiZzangX, IID_IDelphiZzangX, FCOMObject));
result := FCOMObject;
end;
[C++빌더로 변환작업한 소스2]
STDMETHODIMP TPtmElevatorFormImpl::ElevatePtmRunner(VARIANT *ret)
{
IPtmElevatorForm *pObj = NULL;
HRESULT hr;
try
{
if(IsVISTA())
{
hr = CoCreateInstanceAsAdmin(NULL, CLSID_PtmElevatorForm,
IID_IPtmElevatorForm, (void**)&pObj);
} else {
hr = CoCreateInstance(CLSID_PtmElevatorForm,
NULL, CLSCTX_INPROC_SERVER, IID_IPtmElevatorForm, (void**)&pObj);
}
if (SUCCEEDED(hr))
{
*ret = pObj; // <----문제 발생부분
}
else
{
//ShowMessage("IPtmElevatorForm is NULL"));
*ret = pObj; // <----문제 발생부분
}
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IPtmElevatorForm);
}
return S_OK;
};
|