달력

102018  이전 다음

  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  


ActiveX의 안정성 코드에 대해 좋은글 링크

http://ancdesign.tistory.com/18

Posted by 알이씨


최근 시간이 없는 관계로..

포스팅이 늦었다. ㅜㅜ; 그래서 간단하게 정리해보고자 한다.

이후 질문 답 형식으로 완성해야겠다. ㅜㅜ; 요즘 넘 바뻐서. 흑.. ㅜㅜ;

프로젝트 생성이나 컨트롤 추가를 모르시는 분이 계시려나... 혹시 모른다면

나중에 올려드리겠습니다.

워드로 정리 해놓은 것을 옮기느라 보기가 안좋을 수 있습니다. 이해해주세요~

그리고 대부분의 내용은 Devpia나 웹상에서 제가 검색한 내용을 토대로 재작성 하였습니다.

==================================================================

1. ATL Project 생성 (필자는 ApLauncher로 생성)
  - 옵션에서 Support MFC를 체크 하도록 한다.

2. ATL Control 추가 (필자는 ApBroker로 생성)
  - 옵션은 걍 다음 다음으로 넘겨버렸다. -ㅁ-;

3. 레지스트리 수정

ApBroker.rgs 파일 수정


 

HKCR

{

             ApLauncher.ApBroker.1 = s 'ApBroker Class'

             {

                           CLSID = s '{FC9E01FE-A5E6-43FD-A925-9D5F6803E779}'

             }

             ApLauncher.ApBroker = s 'ApBroker Class'

             {

                           CLSID = s '{FC9E01FE-A5E6-43FD-A925-9D5F6803E779}'

                           CurVer = s 'ApLauncher.ApBroker.1'

             }

             NoRemove CLSID

             {

                           ForceRemove {FC9E01FE-A5E6-43FD-A925-9D5F6803E779} = s 'ApBroker Class'

                           {

                                        ProgID = s 'ApLauncher.ApBroker.1'

                                        VersionIndependentProgID = s 'ApLauncher.ApBroker'

                                        ForceRemove 'Programmable'

                                        InprocServer32 = s '%MODULE%'

                                        {

                                                     val ThreadingModel = s 'Apartment'

                                        }

                                        val AppID = s '%APPID%'

                                       

                                        Elevation

                                {

                                          val Enabled = d 1

                                }

                                val LocalizedString = s '@%MODULE%,-101'

                                       

                                        ForceRemove 'Control'

                                        ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 103'

                                        'MiscStatus' = s '0'

                                        {

                                            '1' = s '%OLEMISC%'

                                        }

                                        'TypeLib' = s '{B0EA13FC-8B95-4C3E-9627-D8937BFEDBCD}'

                                        'Version' = s '1.0'

                           }

             }

}


 

주의 : String Table 101번에 대한 String 추가할 것


빨간색으로 된 부분이 추가 되어야 하는 부분이다. 이 때 101번 String은 권한 상승시에 사용된다. (각자 확인 해보세요~)


ApLauncher.rgs 수정

HKCR

{

             NoRemove AppID

             {

                           '%APPID%' = s 'ApLauncher'

                           {

                                val DllSurrogate = s ''

                     }

                           'ApLauncher.DLL'

                           {

                                        val AppID = s '%APPID%'

                           }

             }

}

4. Broker 함수 추가


이제 권한 상승 함수와 실제 다이얼로그를 띄우는 부분을 추가해야 겠다.

프로젝스 프로퍼티창에서
  - IApBroker – Add – Add Method - RunBroker
함수 추가

  - IApBroker – Add – Add Method - RunProgram 함수 추가
  - IsVistaOS 함수와 CoCreateInstanceAsAdmin 함수 추가(어디든 CApBroker 클래스가 참조할 수 있으면 됩니다.
     클래스 함수로 포함시키면 좋겠지요...

 
isVistaOS 함수 착성

BOOL IsVistaOS(void)
{
 BOOL bIsVista = FALSE;
 OSVERSIONINFO sInfo;
 sInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 
 //
 // OS VERSION CHECK.
 //
 if(::GetVersionEx(&sInfo)) {
  if( sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
   sInfo.dwMajorVersion >= 6 &&
   sInfo.dwMinorVersion >= 0) { // Windows VISTA
   bIsVista = TRUE;

  }
 }

 return bIsVista;
}



CoCreateInstanceAsAdmin 함수 작성

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv, BOOL bAdministrator)

{

             BIND_OPTS3 bo;

             WCHAR  wszCLSID[50];

             WCHAR  wszMonikerName[300];

 

             StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));

             HRESULT hr = S_OK ;

 

             if( bAdministrator)

                           hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);

             else

                           hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:HighestAvailable!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);

}

 


 

RunBroker 함수 작성

STDMETHODIMP CApBroker::RunBroker(void)

{

             AFX_MANAGE_STATE(AfxGetStaticModuleState());

 

             HRESULT                                                                  hr;

             HWND                                                          hwnd = NULL;

             IApBroker*            objElevator = NULL;           

             const GUID                                                   guidCurrentObject = CLSID_ApBroker;

             const IID                                         iidCurrentObject = IID_IApBroker;

 

             CoInitialize(NULL);

            

             if(!IsVistaOS()) {

                           //

                           // VISTA 가아닌경우.

                           //

                           RunProgram();

 

                           return S_OK;

             }

 

             //

             // 권한상승(ELEVATION)

             //

             hr = CoCreateInstanceAsAdmin(NULL, guidCurrentObject, iidCurrentObject, (void**)(&objElevator), TRUE);

 

             //

             // EXECUTE

             //

 

             if(SUCCEEDED(hr)) {

                           // do work.

                           objElevator->RunProgram();

 

                           // release.                       

                           objElevator->Release();

 

                           return S_OK;

             } else {

                           //

                           // Elevation 실패.

                           //

                           CString sErr;

                           sErr.Format(_T("CoCreateInstanceAsAdmin failed! HResult: %x"), hr);

                           ::MessageBox(NULL, sErr, _T("ApBroker") , MB_OK);

             }

            

             return S_OK;

}


위에서 Vista인 경우와 아닌 경우로 나뉘어 Vista인 경우 권한 상승 후 프로그램을

실행하고 있습니다. 이부분을 유의해서 보시면 됩니다.
 

RunProgram 함수 작성

STDMETHODIMP CApBroker::RunProgram(void)

{

             AFX_MANAGE_STATE(AfxGetStaticModuleState());

             // TODO: Add your implementation code here

             CDlgMain m_DlgMain;

             m_DlgMain.DoModal();

 

             return S_OK;

}

 

자 지금까진 공통적인 부분이었고 저기 CDlgMain m_DlGmain; 부분을 봅시다.
필자는 다이얼로그를 하나 추가해서 연결해 두었습니다.

그리고 CApBroker::RunProgram 안에서 호출하고 있습니다.

따라서 기존 MFC 프로그래밍 하는 것처럼 코딩하시고 권한 상승 부분만 ATL을 이용합니다.

필자는 ATL을 해본적도 없고 MFC를 좀 하던차에 ActiveX를 만들어야 했기 때문에

좀 편하게 코딩해보가 이런 꼼수를 사용했습니다.
(더 확실한 것은 아예 모두 MFC로 만드는 것이겠지요. 필자는 하다하다 포기했습니다.
 방법을 아시는 분은 링크좀.. ㅡㅡ;)


5. 안정성 코드 추가

안정성 코드는 이 엑티브 엑스를 정말로 실행해도 됩니까? 하는 것을 빼게 해줍니다.
그냥 빨간 부분 추가만 해주시면 됩니다.

ApLauncher.cpp 수정

  - CreateComponentCategory 함수 추가
  - RegisterCLSIDInCategory 함수 추가

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{

    ICatRegister* pcr = NULL ; // interface pointer
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
 if (FAILED(hr)) {
  return hr;
 }

    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // english

 // Make sure the provided description is not too long.
 // Only copy the first 127 characters if it is
 int len = (int)wcslen(catDescription);
 if (len>127)
  len = 127;
    wcsncpy_s(catinfo.szDescription, catDescription, len);
 // Make sure the description is null terminated
 catinfo.szDescription[len] = '\0';

    hr = pcr->RegisterCategories(1, &catinfo);
 pcr->Release();
 
 return hr;
}


 

HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Register this category as being "implemented" by
       // the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();
 
 return hr;
}


 빨간 부분 추가

STDAPI DllRegisterServer(void)

{

    // registers object, typelib and all interfaces in typelib

    HRESULT hr = _AtlModule.DllRegisterServer();

#ifdef _MERGE_PROXYSTUB

    if (FAILED(hr))

        return hr;

    hr = PrxDllRegisterServer();

#endif

 

             /////////////////////////////////////////////////////////////////////////////   

             // 안전성코드추가SAFE FOR SCRIPTING.

             /////////////////////////////////////////////////////////////////////////////   

             const CATID CATID_SafeForScripting =

             { 0x7dd95801, 0x9882, 0x11cf, { 0x9f, 0xa9, 0x00, 0xaa, 0x00, 0x6c, 0x42, 0xc4 } };

             const CATID CATID_SafeForInitializing =

             { 0x7dd95802, 0x9882, 0x11cf, { 0x9f, 0xa9, 0x00, 0xaa, 0x00, 0x6c, 0x42, 0xc4 } };

             REFCLSID clsidCurrentActiveX = CLSID_ApBroker;

            

 

             CoInitialize( NULL );

 

             if (FAILED( CreateComponentCategory(CATID_SafeForScripting, L"Controls that are safely scriptable") )) {

                           return ResultFromScode(SELFREG_E_CLASS);

             }

 

             if (FAILED( CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data") )) {

                           return ResultFromScode(SELFREG_E_CLASS);

             }

 

             if (FAILED( RegisterCLSIDInCategory(clsidCurrentActiveX, CATID_SafeForScripting) )) {

                           return ResultFromScode(SELFREG_E_CLASS);

             }

 

             if (FAILED( RegisterCLSIDInCategory(clsidCurrentActiveX, CATID_SafeForInitializing) )) {

                           return ResultFromScode(SELFREG_E_CLASS);

             }

 

             return hr;

}

================================================================
에고에고 힘들다.  있는거 가져다 붙이는 것도 힘드네요.

다시 말씀드리자면 이 방법은 MFC 이용하여 권한 상승을 하지는 않습니다.

정확히는 ATL 기반에서 권한 상승하고 MFC를 쓰는 것이지요.

포스팅이 너무 늦어버렸네요..
Posted by 알이씨


ActiveX를 이용하여 런처를 만들어야 하는 프로젝트가 떨어졌다.

MFC만 주구장창 해오다가 ActiveX라니... 난감하다..

ActiveX를 알아보니 MFC로도 만들 수 있다고 한다. 그래서 열심히 만들었다.

다이얼로그 하나 추가해서 뚝딱뚝딱 만들었다. 뭐 술술 진행되는 듯 했다.

윈도 xp, 2003에서 테스트를 마치고... Vista에서 돌려보았다.

털썩... 되질 않는다... 파일을 가져와서 복사를 못한다..

그것도 그럴것이 c:\ 밑에 프로젝트 이름으로 해서 디렉토리를 만들고 파일을 넣었으니..

Vista에서는 UAC(User Account Control)라는 보안 기능에 의해 익스플로어는 로우 레벨이란다.

로우 레벨은 c:\ 밑에 디렉토리 못만든단다. 파일복사도 안되고.... 아... 난감하다.

그래서 여기저기 자료를 뒤적거리기 시작했다. 그런데 죄다 ATL로 만든 ActiveX다.

난 또 생각했다. MFC로도 할 수 있을거야.. 그럴거야...

그러다가 포기했다. Registe 건들이는 부분이 ATL에는 rgs파일에 친절히 나와 있는데

MFC에서는 당최 모르겠다. (저와 같은 생각하는 초보 ActiveX 제작자는 없으려나 -_-)

그래서 생각했다 ATL에서 MFC처럼 하겠노라고...

작업 과정은 다음과 같다.

1. ATL 에서 권한 상승에 관련된 작업을 한다.
2. Dialog를 하나 띄워서 그곳에 런처에 관련된 기능을 구현한다.

위와 같이 하면 쉽게 해결될거 같다.

다음 Article에 ATL에서 권한 상승을 시키는 방법을 말해보고자 한다. 씨이익~
Posted by 알이씨


Visual Studio 2005에서 ActiveX에 관련된 자료를 찾고 있다.

현재 이 시점에서 개념 조차 모르는 상황인데.. 자 이제 또 달려야한다.

ActiveX에 Smart Client까지 다 알게 되면 어느정도 웹어플들을 손쉽게 만들 수 있지 않을까.

일단은 MFC위주로 자료를 찾아보았다.

아래는 그 링크들~



http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/vccore/html/_core_activex_control_topics.asp


ATL은 나중에 찾아봐야겠다.

M$ 애들은 참 여러가지 많이도 만들어놔서 골치아프게.. ㅡㅡ^


참고 : 위 링크는 계속해서 추가 됩니다. (최종 업데이트 07년 8월 29일)
Posted by 알이씨

티스토리 툴바