본문
인터넷 다운 설치를 위한 캐비닛/보증서 만들기
---------------------------------------------
엑티브 컨트롤의 캐비닛/보증서 만들기
준비물 :
컨트롤 test.ocx
캐비닛 보증서만들기 위한 SDK ( cab SDK/ INet SDK )
캐비닛 파일을 만들기
--------------------
캐비닛 파일은 MS에서 만든 Zip방식의 (LZX) 압축 파일이다.
이 압축파일은 MS 윈도 플랫폼의 자동설치를 위해서 쓰인다.
캐비닛 파일을 만들기 위해선 cab SDK를 구해야 한다.
편리하게 cab을 만들기위한 툴인 cab Man (cab Manager, MS )
나 cabPack (프리웨어)를 쓰면 된다.
캐비닛 파일을 단지 압축용으로 쓴다면 inf파일 첨부없이
압축을 하면 되지만 압축이 풀릴 디렉토리 ActiveX컨트롤시
RegisterServer할것인지를 명시할때는 inf파일로 압축 풀기시
풀기 세팅을 맞출수 있다.
다음은 간단한 INF 예제이다.
-------------------[ test.inf ]---------------------------
[version]
signature="SCHICAGOS"
AdvanceINF=2.0
[Add.Code]
test.ocx=test.ocx
[test.ocx]
file-win32-x86=thiscab
classid={D558994B-F7F4-11D2-9559-0060971DB6FE}
FileVersion=1,0,0,0
RegisterServer=yes
;end of file
--------------[ test.ocx만 cab만들기 ]--------------------
file-win32-x86은 x86플랫폼에 이 파일이 있는 곳을 정해주는것으로
thiscab은 이 cab에 있다는 말이고,
file-win43-x86=http://www.bro.com/mydir/test.ocx
로 하면 그 사이트로 가서 다운을 받게 된다.
FileVersion은 해당 파일의 오른클릭후 등록정보메뉴에서 버전탭을
보면 알 수 있다.
만일 ocx 파일 외에 다른 dll 파일도 있다고 한다면
-------------------[ test2.inf ]---------------------------
[version]
signature="SCHICAGOS"
AdvanceINF=2.0
[Add.Code]
test.ocx=test.ocx
test.dll=test.dll
[test.dll]
file-win32-x86=thiscab
FileVersion=1,0,0,0
DestDir=11
RegisterServer=yes
[test.ocx]
file-win32-x86=thiscab
classid={D558994B-F7F4-11D2-9559-0060971DB6FE}
FileVersion=1,0,0,0
RegisterServer=yes
;end of file
-----------[ test.ocx와 test.dll로 cab만들기 ]-----------------
이렇게 해주면 된다. 이때 DestDir은
11은 윈도시스템디렉토리( WINDOWS\SYSTEM 또는 WINNT32\SYSTEM32)
10은 윈도우 디렉토리 (WNIDOWS 또는 WINNT32)
DestDir을 지정안하면 OCCACHE 디레고리로 지정된다.
캐비닛 파일 만들기
inf파일이 필요 없이 그냥 만들때는 cabPack이나 cabMan같은것으로
쉽게 만들고 (물론 안에도 기능으로 inf파일 첨부 할수있다. )
다음은 cab SDK를 써서 할 경우 이다.
cabarc -s 6144 n test.cab test.ocx test.inf
또는
cabarc -s 6144 n test.cab test.ocx test.dll test2.inf
을 하게 되면 test.cab이 생기게 된다.
-s 크기 : 디지털 서명을 위한 영역의 크기(6114는 6K바이트)
n : 새로운 캐비닛 파일을 만듬
이제 test.cab파일이 생겼다.
디지털 서명 보증서 만들기
---------------------------
INet SDK 에 있는 프로그램으로 보증서를 만들게 되는데 이는 원래
VerSign같은 인증기관(CA,Certification Authority)로 부터 SPC
(Software Publisher Ceritificate)를 얻어야 하는데, 상업용 SPC를
얻길 원하면 http://digitalid.versign.com/cdesign.htm을 가보자.
테스트용 SPC를 만들기
1. 보증 확인 과정을 제어하는 레지스트리 키 설정
SETREG 1 TRUE
2. 테스트용 x.509 보증서를 생성하기
MAKESERT -n "CN=조경민 보증서" -sv Test.pvk test.cer
이렇게 하면 test.pvk라는 사적 키(private key)파일과 cer 회사보증
서 파일이 생긴다. 이때 윈도로 암호를 넣으라고 한다. 암호 만들기
3. 테스트 보증서에서 테스트용 SPC를 만들기
CERT2SPC test.cer test.spc
이렇게하면 spc파일이 생긴다.
cab 파일에 디지털 서명 보증서 추가하기
--------------------------------------
SIGNCODE -spc test.spc -v test.pvk -n "test ocx" test.cab
이렇게하면 cab파일에 보증서가 붙게 된다.
물론 보증서는 cab이 아니라 OCX나 DLL파일에 붙일수도 있다.
1999년 5월 15일 PM 07:29
조경민 Visual C++ 6.0 ATL COM,전병선저 참고
실제 인증서 디지털서명하기
오후 2:14 2001-04-25 조경민
========================================================
먼저 cab sdk를 www.microsoft.com 에서 search에서
cab sdk 로 찾아서 cab-sdk.exe를 다운받는다.
ActiveCool.inf
--------------------
[version]
signature="SCHICAGOS"
AdvanceINF=2.0
[Add.Code]
ActiveCool.ocx=ActiveCool.ocx
[ActiveCool.ocx]
file-win32-x86=thiscab
classid={14926478-A07C-49CE-BC69-BD8C8043D07C}
FileVersion=1,0,0,2
RegisterServer=yes
;end of file
----------------------
위 파일과 함께
cabarc -s 6144 n ActiveCool.cab ActiveCool.ocx ActiveCool.inf
이러면 ActiveCool.cab파일이 생기며
versign으로 부터 인증서를 받고 sdk도 받아서
signcode -spc sign.spc -v sign.pvk -t "http://timestamp.verisign.com/scripts/timstamp.dll" -n "AcitveCool 2.0" -i "http://jiran.intracool.co.kr" ActiveCool.cab
이렇게 하면 도중에 암호를 물어보는데 이때 회사 인증서에서 받은 암호를 쓴다.
마지막으로 코드를 바꾸어야한다.
BOOL CActiveCoolCtrl::CActiveCoolCtrlFactory::UpdateRegistry(BOOL bRegister)
이 부분의 코드를 바꾸어야한다.
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_ACTIVECOOL,
IDB_ACTIVECOOL,
afxRegApartmentThreading,
_dwActiveCoolOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
이런 기존의 코드를 아래처럼 바꾼다.
#include "comcat.h"
#include "objsafe.h"
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 = wcslen(catDescription);
if(len>127)
len = 127;
wcsncpy(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;
}
HRESULT UnregisterCLSIDInCategory( REFCLSID clsid, CATID catid )
{
ICatRegister* pcr = NULL;
HRESULT hr = S_OK;
hr = CoCreateInstance( CLSID_StdComponentCategoriesMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICatRegister,
(void**)&pcr );
if( SUCCEEDED(hr) )
{
CATID rgcatid[1];
rgcatid[0] = catid;
hr = pcr->UnRegisterClassImplCategories( clsid, 1, rgcatid );
}
if( pcr != NULL )
pcr->Release();
return hr;
}
BOOL CActiveCoolCtrl::CActiveCoolCtrlFactory::UpdateRegistry(BOOL bRegister)
{
// TODO: Verify that your control follows apartment-model threading rules.
// Refer to MFC TechNote 64 for more information.
// If your control does not conform to the apartment-model rules, then
// you must modify the code below, changing the 6th parameter from
// afxRegApartmentThreading to 0.
/*
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_ACTIVECOOL,
IDB_ACTIVECOOL,
afxRegApartmentThreading,
_dwActiveCoolOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
*/
if(bRegister)
{
BOOL retval = AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_ACTIVECOOL,
IDB_ACTIVECOOL,
afxRegApartmentThreading,
_dwActiveCoolOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
// mark as safe for scripting--failure OK
HRESULT hr = CreateComponentCategory(CATID_SafeForScripting,
L"Controls that are safely scriptable");
if (SUCCEEDED(hr))
// only register if category exists
RegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);
// don't care if this call fails
// mark as safe for data initialization
hr = CreateComponentCategory(CATID_SafeForInitializing,
L"Controls safely initializable from persistent data");
if (SUCCEEDED(hr))
// only register if category exists
RegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);
// don't care if this call fails
return retval;
}
else
{
UnregisterCLSIDInCategory( m_clsid, CATID_SafeForInitializing );
UnregisterCLSIDInCategory( m_clsid, CATID_SafeForScripting );
return AfxOleUnregisterClass( m_clsid, m_lpszProgID );
}
}
그리고 컴파일할때엔
inf의 파일버전과 컴파일때 리소스 StringTable에서 버전과 (파일버전, 프로덕버전)
그리고 웹페이지의 버전을 명시해서 버전이 높으면 자동으로 다운받도록 하게 한다.
<object id="ActiveCool" width=400 height=300
classid="clsid:14926478-A07C-49CE-BC69-BD8C8043D07C"
codebase="http://211.236.68.76/ActiveCool/ActiveCool.cab#version=1,0,0,2">
</object>
관련링크
- http://viper150.cafe24.com/15 467회 연결
댓글목록
등록된 댓글이 없습니다.