青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 126,  comments - 73,  trackbacks - 0
摘要:數(shù)字簽名SIGN保證控件在下載時(shí)候的安全性。如果你的代碼已經(jīng)經(jīng)過數(shù)字簽名,即使用戶IE的安全設(shè)置很高也能下載,安裝并登記。但是在頁面上初始化,或者用腳本運(yùn)行這個(gè)控件,為了保證安全性,還需要進(jìn)行MARK。  
   
  數(shù)字簽名SIGN  
  曹曉峰  
   
  摘要:數(shù)字簽名保證控件的安全性。數(shù)字簽名使用證書。證書一般有個(gè)人證書和授信公司證書。個(gè)人證書是對個(gè)人的信任,由個(gè)人承擔(dān)責(zé)任,控件每次下載時(shí)需要進(jìn)行確認(rèn)。公司證書是由第三方公司發(fā)布的,保證控件的安全性,公司證書需要付費(fèi)。Windows授信的證書公司有VeriSign,SecureSign等等。由這些公司證書簽名的控件在下載的時(shí)候不需要確認(rèn)。  
   
  一.工具  
  工具包括以下幾個(gè)軟件:  
  makecert.exe     制作cer格式的證書,即X.509證書,同時(shí)可以創(chuàng)建私鑰(防止抵賴)  
  cert2spc.exe     將cer格式證書轉(zhuǎn)換成spc格式證書,即PKCS   #7證書  
  signcode.exe     將證書簽署到ocx上去  
  chktrust.exe     檢查簽署證書后的ocx是否正確  
  certmgr.exe,是管理證書用的,可以從這里面導(dǎo)出root.cer來,不過沒有私鑰用不上。  
   
  二.步驟  
  下面是具體的步驟:  
  1、創(chuàng)建一個(gè)自己的證書文件:  
  makecert   /sv   "Record.PVK"   /n   "CN=SinoWave"   dream.cer  
  這里,Record.PVK表示新創(chuàng)建的私人密鑰保存文件名  
              SinoWave是你想顯示的公司名  
              dream.cer是你創(chuàng)建最后的證書文件名  
  這些根據(jù)你自己的要求填寫,最后得到Record.PVK和dream.cer兩個(gè)文件。其中,運(yùn)行過程中需要輸入私人密鑰的保護(hù)密碼(sw),一定要輸入一致,不要出錯。  
   
  2、轉(zhuǎn)換cer格式為spc格式(可以省略),得到dream.spc文件。  
   
  cert2spc   dream.cer   dream.spc  
   
  3、用VS6工具中的   cabarc生成internet分發(fā)的CAB包,  
  cabarc.exe   N   DataTransfer.cab   DataTransfer.ocx  
   
  4、同時(shí)制作分發(fā)代碼(.htm,其中包含使IE可以自動下載安裝包的代碼)。  
  現(xiàn)在得到了2個(gè)文件DataTransfer.CAB和DataTransfer.htm。  
  .htm中包含類似如下的代碼:  
  <OBJECT   ID="   DataTransfer   "   CLASSID="CLSID:   CA466D54-0684-49D2-B0C3-DD7E09EA76D3"   CODEBASE="http://192.9.200.8/DataTransfer.CAB#version=1,0,0,0"></OBJECT>  
  注意:一定要寫上"http://   192.9.200.8/",真正發(fā)行時(shí)最好使用url。  
   
  5、給CAB文件簽名  
  運(yùn)行signcode,命令行的我沒有試驗(yàn)通過,我是通過界面實(shí)現(xiàn)的。signcode運(yùn)行后會出現(xiàn)數(shù)字簽名向?qū)В紫冗x擇DataTransfer.CAB,下一步后會出現(xiàn)簽名選項(xiàng),一種是典型,一種是自定義。選擇自定義,這樣才能從文件選擇證書,選擇前面制作的dream.spc,再下一步是選擇私鑰文件,選擇Record.PVK,輸入私人密鑰的保護(hù)密碼,選擇散列算法,一般用md5就可以了,下一步是選擇其他證書,直接下一步,填寫一下這個(gè)控件的聲明,用戶用ie瀏覽的時(shí)候,會彈出證書說明,再下一步是加蓋時(shí)間戳,例如http://timestamp.sheca.com/timestamp  
     
  6、用chktrust檢查是否正確  
  chktrust   -v   DataTransfer.CAB  
   
  7、將簽名后的DataTransfer.CAB和DataTransfer.htm復(fù)制到IIS的某個(gè)目錄下。并在IE中打開DataTransfer.htm文件進(jìn)行測試。  

ActiveX控件的安全初始化和腳本操作MARK  
  曹曉峰  
   
  簡介  
  很多微軟的ActiveX控件(本地/遠(yuǎn)程)都需要使用持久性數(shù)據(jù)進(jìn)行初始化,而且它們大多數(shù)都是可以通過腳本進(jìn)行操作的   (支持一個(gè)方法,事件和屬性的集合提供腳本語言操作)。初始化(使用持久性數(shù)據(jù))和腳本操作都需要一個(gè)確定的安全性機(jī)制保證其安全性不被違背。  
   
  初始化安全性  
  當(dāng)一個(gè)控件初始化時(shí),可以從一個(gè)   IPersist*   接口獲得數(shù)據(jù)   (來自一個(gè)本地/遠(yuǎn)端的URL)提供初始化狀態(tài)。這是一個(gè)潛在的安全隱患,因?yàn)閿?shù)據(jù)可能來自一個(gè)不可信的數(shù)據(jù)源。不提供安全性保證的控件將無視數(shù)據(jù)源的安全性。  
  有兩種方法可以檢測控件的初始化安全性。第一種使用組件分組管理器(Component   Categories   Manager)創(chuàng)建一個(gè)正確的入口到系統(tǒng)注冊表。IE檢測注冊表之后才調(diào)用你的控件決定是否這些入口存在。第二種方法實(shí)現(xiàn)一個(gè)名稱為IObjectSafe的接口到你的控件。如果IE發(fā)現(xiàn)你的控件支持IObjectSafety,它調(diào)用   IObjectSafety::SetInterfaceSafetyOptions   方法然后才載入你的控件。  
  注意,第一種方法是基于組件的安全性,也就是如果設(shè)置了注冊表,那么整個(gè)組件的所有的接口都被標(biāo)注為安全的;而第二種方法(實(shí)現(xiàn)IObjectSafety)是基于接口的,也就是它的作用范圍是接口,必須一個(gè)接口一個(gè)接口地標(biāo)注。第二種方法的運(yùn)行性能要優(yōu)于第一種。在保證安全的情況下,兩種方法同時(shí)使用更好。  
   
  腳本操作安全性  
  代碼簽字可以保證用戶其代碼的可信度。但是運(yùn)行一個(gè)   ActiveX   控件可以被腳本訪問將帶來幾個(gè)新的安全性問題。即使控件被認(rèn)為是可靠的,如果使用不可信腳本代碼訪問也不能保證其安全性。比如,微軟的   Word   被認(rèn)為是一個(gè)安全的程序,但是一個(gè)宏可以使用自動化模型的腳本刪除用戶計(jì)算機(jī)上的文件,載入宏病毒或者蠕蟲病毒。  
  有兩種方法提供你的控件的腳本操作安全性保證。第一種是使用組件分組管理器   (Component   Categories   Manager)   ——在組件導(dǎo)入以后在注冊表上面創(chuàng)建正確的入口。IE在腳本操作之前檢查注冊表確認(rèn)安全性。第二種是實(shí)現(xiàn)一個(gè)   IObjectSafety   接口到你的控件。如果IE發(fā)現(xiàn)你的控件支持   IObjectSafety,就在導(dǎo)入控件之前調(diào)用   IObjectSafety::SetInterfaceSafetyOptions   方法來確保安全性腳本操作。  
  注意,第一種方法是基于組件的安全性,也就是如果設(shè)置了注冊表,那么整個(gè)組件的所有的接口都被標(biāo)注為安全的;而第二種方法是基于接口的,也就是它的作用范圍是接口,必須一個(gè)接口一個(gè)接口地標(biāo)注。第二種方法的運(yùn)行性能要優(yōu)于第一種。在保證安全的情況下,兩種方法同時(shí)使用更好。  
   
  方法一:IObjectSafety方法:  
  MFC:實(shí)現(xiàn)接口IObjectSafety  
  ATL:繼承接口IObjectSafetyImpl<CPolyCtl,   INTERFACESAFE_FOR_UNTRUSTED_CALLER|   INTERFACESAFE_FOR_UNTRUSTED_DATA   >  
   
  具體方法:  
  一. MFC  
  1. 在控件類的頭文件里  
  (1)加入文件#include   <objsafe.h>  
  (2)在類的定義里,聲明接口映射表,并加入接口定義(以嵌套類的形式)  
  DECLARE_INTERFACE_MAP()  
  BEGIN_INTERFACE_PART(ObjSafe,   IObjectSafety)  
  STDMETHOD_(HRESULT,   GetInterfaceSafetyOptions)   (    
                          /*   [in]   */   REFIID   riid,  
                          /*   [out]   */   DWORD   __RPC_FAR   *pdwSupportedOptions,  
                          /*   [out]   */   DWORD   __RPC_FAR   *pdwEnabledOptions  
  );  
                   
                  STDMETHOD_(HRESULT,   SetInterfaceSafetyOptions)   (    
                          /*   [in]   */   REFIID   riid,  
                          /*   [in]   */   DWORD   dwOptionSetMask,  
                          /*   [in]   */   DWORD   dwEnabledOptions  
  );  
  END_INTERFACE_PART(ObjSafe);  
   
  2. 在控件類的CPP文件里  
  (1)建立接口映射表  
  BEGIN_INTERFACE_MAP(   CMyCtrl,   COleControl   )  
  INTERFACE_PART(CMyCtrl,   IID_IObjectSafety,   ObjSafe)  
  END_INTERFACE_MAP()  
  (2)加入接口類的實(shí)現(xiàn)  
  ULONG   FAR   EXPORT   CMyCtrl::XObjSafe::AddRef()  
  {  
          METHOD_PROLOGUE(CMyCtrl,   ObjSafe)  
          return   pThis->ExternalAddRef();  
  }  
   
  ULONG   FAR   EXPORT   CMyCtrl::XObjSafe::Release()  
  {  
          METHOD_PROLOGUE(CMyCtrl,   ObjSafe)  
          return   pThis->ExternalRelease();  
  }  
   
  HRESULT   FAR   EXPORT   CMyCtrl::XObjSafe::QueryInterface(  
          REFIID   iid,   void   FAR*   FAR*   ppvObj)  
  {  
          METHOD_PROLOGUE(CMyCtrl,   ObjSafe)  
          return   (HRESULT)pThis->ExternalQueryInterface(&iid,   ppvObj);  
  }  
   
  const   DWORD   dwSupportedBits   =    
  INTERFACESAFE_FOR_UNTRUSTED_CALLER   |  
  INTERFACESAFE_FOR_UNTRUSTED_DATA;  
  const   DWORD   dwNotSupportedBits   =   ~   dwSupportedBits;  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions  
  //   Allows   container   to   query   what   interfaces   are   safe   for   what.   We're  
  //   optimizing   significantly   by   ignoring   which   interface   the   caller   is  
  //   asking   for.  
  HRESULT   STDMETHODCALLTYPE    
  CMyCtrl::XObjSafe::GetInterfaceSafetyOptions(    
  /*   [in]   */   REFIID   riid,  
                  /*   [out]   */   DWORD   __RPC_FAR   *pdwSupportedOptions,  
                  /*   [out]   */   DWORD   __RPC_FAR   *pdwEnabledOptions)  
  {  
  METHOD_PROLOGUE(CMyCtrl,   ObjSafe)  
   
  HRESULT   retval   =   ResultFromScode(S_OK);  
   
  //   does   interface   exist?  
  IUnknown   FAR*   punkInterface;  
  retval   =   pThis->ExternalQueryInterface(&riid,    
  (void   *   *)&punkInterface);  
  if   (retval   !=   E_NOINTERFACE)   { //   interface   exists  
  punkInterface->Release();   //   release   it--just   checking!  
  }  
   
  //   we   support   both   kinds   of   safety   and   have   always   both   set,  
  //   regardless   of   interface  
  *pdwSupportedOptions   =   *pdwEnabledOptions   =   dwSupportedBits;  
   
  return   retval;   //   E_NOINTERFACE   if   QI   failed  
  }  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions  
  //   Since   we're   always   safe,   this   is   a   no-brainer--but   we   do   check   to   make  
  //   sure   the   interface   requested   exists   and   that   the   options   we're   asked   to  
  //   set   exist   and   are   set   on   (we   don't   support   unsafe   mode).  
  HRESULT   STDMETHODCALLTYPE    
  CMyCtrl::XObjSafe::SetInterfaceSafetyOptions(    
                  /*   [in]   */   REFIID   riid,  
                  /*   [in]   */   DWORD   dwOptionSetMask,  
                  /*   [in]   */   DWORD   dwEnabledOptions)  
  {  
          METHOD_PROLOGUE(CMyCtrl,   ObjSafe)  
   
  //   does   interface   exist?  
  IUnknown   FAR*   punkInterface;  
  pThis->ExternalQueryInterface(&riid,   (void   *   *)&punkInterface);  
  if   (punkInterface)   { //   interface   exists  
  punkInterface->Release();   //   release   it--just   checking!  
  }  
  else   {   //   interface   doesn't   exist  
  return   ResultFromScode(E_NOINTERFACE);  
  }  
   
  //   can't   set   bits   we   don't   support  
  if   (dwOptionSetMask   &   dwNotSupportedBits)   {    
  return   ResultFromScode(E_FAIL);  
  }  
   
  //   can't   set   bits   we   do   support   to   zero  
  dwEnabledOptions   &=   dwSupportedBits;  
  //   (we   already   know   there   are   no   extra   bits   in   mask   )  
  if   ((dwOptionSetMask   &   dwEnabledOptions)   !=  
    dwOptionSetMask)   {  
  return   ResultFromScode(E_FAIL);  
  }  
  //   don't   need   to   change   anything   since   we're   always   safe  
  return   ResultFromScode(S_OK);  
  }  
  二. ATL  
  在控件類加一個(gè)繼承接口即可  
  public   IObjectSafetyImpl<CAtlCtrl,   INTERFACESAFE_FOR_UNTRUSTED_CALLER    
                                                      |   INTERFACESAFE_FOR_UNTRUSTED_DATA>  
方法二:使用組件分組管理器  
  前面提到,IE通過檢測注冊表決定一個(gè)控件是否是可以安全性初始化和腳本操作的。IE通過調(diào)用   ICatInformation::IsClassOfCategories   方法決定是否控件支持給出的安全性分組。  
  如果一個(gè)控件使用組件分組管理器將自己注冊為安全的,該控件的注冊表入口就包含一個(gè)實(shí)現(xiàn)的分組關(guān)鍵字,該關(guān)鍵字含有一個(gè)或者兩個(gè)子鍵。一個(gè)子鍵設(shè)置控件支持安全性初始化,另一個(gè)設(shè)置支持安全性腳本操作。安全性初始化子鍵依賴于   CATID_SafeForInitializing;   安全性腳本操作子鍵依賴于   CATID_SafeForScripting。(其他組件分組子鍵定義在   Comcat.h   文件,而安全性初始化和腳本操作子鍵定義在   Objsafe.h   文件。)    
  下列演示顯示了一個(gè)注冊表入口(Tabular   Data   Control),該ActiveX控件同IE綁定支持創(chuàng)建數(shù)據(jù)驅(qū)動的網(wǎng)頁。因?yàn)榭丶强梢园踩阅_本操作和初始化的,注冊表中將其標(biāo)記為安全性腳本操作  
  (7DD95801-9882-11CF-9FA9-00AA006C42C4)   和安全性初始化  
  (7DD95802-9882-11CF-9FA9-00AA006C42C4)。  
  注意,這兩個(gè)GUID值是固定的。  
  將一個(gè)控件注冊為安全的  
  系統(tǒng)注冊表含有一個(gè)組件分組鍵來羅列每一個(gè)安裝在系統(tǒng)中的組件的功能性分組。下面演示了一個(gè)組件分組鍵。假設(shè)   CATID_SafeForScripting   (7DD95801-9882-11CF-9FA9-00AA006C42C4)   和   CATID_SafeForInitializing   (7DD95802-9882-11CF-9FA9-00AA006C42C4)   在列表之中。    
  要創(chuàng)建一個(gè)組件分組的子鍵,你的控件必須包含以下步驟:  
  1.創(chuàng)建一個(gè)組件分組管理器(Component   Categories   Manager)實(shí)例來接收   ICatRegister   接口的地址。  
  2.設(shè)置正確的   CATEGORYINFO   結(jié)構(gòu)分量。  
  3.調(diào)用   ICatRegister::RegisterCategories   方法,將初始化的   CATEGORYINFO   結(jié)構(gòu)變量傳遞給這個(gè)方法。  
     
  下面的例子演示如何使用這些步驟來完成一個(gè)名稱為   CreateComponentCategory全局函數(shù),生成組件分組。  
  #include   "comcat.h"  
  HRESULT   CreateComponentCategory(CATID   catid,WCHAR*   catDescription)  
  {  
  ICatRegister*   pcr   =   NULL   ;  
  HRESULT   hr   =   S_OK   ;  
       
  //創(chuàng)建一個(gè)組件管理器實(shí)例(進(jìn)程內(nèi))  
  hr   =   CoCreateInstance(CLSID_StdComponentCategoriesMgr,  
  NULL,CLSCTX_INPROC_SERVER,IID_ICatRegister,(void**)&pcr);  
  if   (FAILED(hr))  
  return   hr;  
       
  //   確信   HKCR\Component   Categories\{..catid...}   鍵已經(jīng)被注冊  
  CATEGORYINFO   catinfo;  
  catinfo.catid   =   catid;  
  catinfo.lcid   =   0x0409   ;   //   英語  
       
  //   確信提供的描述在127個(gè)字符以內(nèi)  
  int   len   =   wcslen(catDescription);  
  if   (len>127)  
  len   =   127;  
  wcsncpy(catinfo.szDescription,catDescription,len);  
  //   確信描述使用'\0'結(jié)束  
  catinfo.szDescription[len]   =   '\0';  
       
  hr   =   pcr->RegisterCategories(1,&catinfo);  
  pcr->Release();  
       
  return   hr;  
  }  
   
  當(dāng)一個(gè)子鍵被創(chuàng)建到需要的分組,控件應(yīng)該注冊到該分組,需要以下步驟:  
  1.創(chuàng)建一個(gè)組件分組管理器實(shí)例接收   ICatRegister   接口地址。  
  2.調(diào)用   ICatRegister::RegisterClassImplCategories   方法,將控件的   CLSID   和需要的   category   ID   作為參數(shù)傳遞給函數(shù)。  
       
  下面的例子演示如何將一個(gè)名稱為   RegisterCLSIDInCategory   加入實(shí)例控件。  
       
  #include   "comcat.h"  
  HRESULT   RegisterCLSIDInCategory(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))  
  {  
  //   注冊已實(shí)現(xiàn)的類到分組  
  CATID   rgcatid[1]   ;  
  rgcatid[0]   =   catid;  
  hr   =   pcr->RegisterClassImplCategories(clsid,1,rgcatid);  
  }  
       
  if   (pcr   !=   NULL)  
  pcr->Release();  
       
  return   hr;  
  }  
       
  一個(gè)控件應(yīng)該在調(diào)用   DLLRegisterServer   函數(shù)是注冊安全性初始化和腳本操作。(DLLRegisterServer   由組件對象模型   [COM]   調(diào)用創(chuàng)建注冊表入口)   在實(shí)例組件中   DLLRegisterServer   函數(shù)調(diào)用了   CreateComponentCategory   和   RegisterCLSIDInCategory   函數(shù)   (它們保證控件的安全性初始化和腳本操作)。下面的就是   DLLRegisterServer   的實(shí)現(xiàn)。  
       
  STDAPI   DllRegisterServer(void)  
  {  
  HRESULT   hr;   //   return   for   safety   functions  
       
  AFX_MANAGE_STATE(_afxModuleAddrThis);  
       
  if   (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(),_tlid))    
  return   ResultFromScode(SELFREG_E_TYPELIB);  
       
  if   (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))  
  return   ResultFromScode(SELFREG_E_CLASS);  
       
  RegisterTwo(CLSID_SafeItem);  
       
  return   NOERROR;  
  }  
       
  HRESULT   RegisterTwo(REFCLSID   clsid)  
  {  
  //   注冊控件是安全性初始化的  
  /////////////////////////////////////////////////  
  HRESULT   hr;  
  hr   =   CreateComponentCategory(CATID_SafeForInitializing,   L"Controls   safely   initializable   from   persistent   data!");  
  if   (FAILED(hr))  
  return   hr;  
   
  hr   =   RegisterCLSIDInCategory(clsid,   CATID_SafeForInitializing);  
  if   (FAILED(hr))  
  return   hr;  
  //   注冊控件是安全性腳本操作的  
   
  hr   =   CreateComponentCategory(CATID_SafeForScripting,   L"Controls   safely   scriptable!");  
  if   (FAILED(hr))  
  return   hr;  
   
  hr   =   RegisterCLSIDInCategory(clsid,   CATID_SafeForScripting);  
  if   (FAILED(hr))  
  return   hr;  
   
  return   S_OK;  
  }  
  作為一個(gè)創(chuàng)建所有安全性分組入口到注冊表的控件,它也應(yīng)該負(fù)責(zé)卸載所有的分組信息。COM   調(diào)用控件的   DLLUnRegisterServer   函數(shù)刪除相應(yīng)的注冊表入口然后卸載該控件。  
       
  要卸載一個(gè)安全性初始化和腳本操作控件,控件應(yīng)該完成以下任務(wù):  
  1   創(chuàng)建一個(gè)組件分類管理器實(shí)例接收   ICatRegister   接口地址。  
  2   調(diào)用   ICatRegister::UnRegisterClassImplCategories   方法,將控件的   CLSID   和必要的   category   ID   作為參數(shù)傳遞  
       
  下面的例子演示如何完成一個(gè)   UnRegisterCLSIDInCategory   。  
       
  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;  
  }  
       
  我們前面提過,一個(gè)控件負(fù)責(zé)刪除安全性初始化和腳本操作入口,下面演示如何完成這兩個(gè)步驟:    
       
  STDAPI   DllUnregisterServer(void)  
  {  
  AFX_MANAGE_STATE(_afxModuleAddrThis);  
   
  if   (!AfxOleUnregisterTypeLib(_tlid,   _wVerMajor,   _wVerMinor))  
  return   ResultFromScode(SELFREG_E_TYPELIB);  
   
  if   (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))  
  return   ResultFromScode(SELFREG_E_CLASS);  
   
  UnRegisterTwo(CLSID_SafeItem);  
   
  return   NOERROR;  
  }  
   
  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;  
  }  
  附件,   CXFMARK.h  
  以上函數(shù)形成一個(gè)文件,  
  #include   "comcat.h"  
   
  const   GUID   CATID_SafeForInitializing   =    
  {0x7DD95802,0x9882,0x11CF,{0x9F,0xA9,0x00,0xAA,0x00,0x6C,0x42,0xC4}};  
  const   GUID   CATID_SafeForScripting   =    
  {0x7DD95801,0x9882,0x11CF,{0x9F,0xA9,0x00,0xAA,0x00,0x6C,0x42,0xC4}};  

HRESULT   CreateComponentCategory(CATID   catid,WCHAR*   catDescription)  
  {  
  ICatRegister*   pcr   =   NULL   ;  
  HRESULT   hr   =   S_OK;  
   
  //創(chuàng)建一個(gè)組件管理器實(shí)例(進(jìn)程內(nèi))  
  hr   =   CoCreateInstance(CLSID_StdComponentCategoriesMgr,  
  NULL,CLSCTX_INPROC_SERVER,IID_ICatRegister,(void**)&pcr);  
  if   (FAILED(hr))  
  return   hr;  
   
  //   確信   HKCR\Component   Categories\{..catid...}   鍵已經(jīng)被注冊  
  CATEGORYINFO   catinfo;  
  catinfo.catid   =   catid;  
  catinfo.lcid   =   0x0409   ;   //   英語  
   
  //   確信提供的描述在127個(gè)字符以內(nèi)  
  int   len   =   wcslen(catDescription);  
  if   (len>127)  
  len   =   127;  
  wcsncpy(catinfo.szDescription,catDescription,len);  
  //   確信描述使用'\0'結(jié)束  
  catinfo.szDescription[len]   =   '\0';  
   
  hr   =   pcr->RegisterCategories(1,&catinfo);  
  pcr->Release();  
   
  return   hr;  
  }  
   
  HRESULT   RegisterCLSIDInCategory(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))  
  {  
  //   注冊已實(shí)現(xiàn)的類到分組  
  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;  
  }  
   
  //下面來兩個(gè)函數(shù)分別在DllRegisterServer和DllUnregisterServer中使用,參數(shù)均為控件的GUID。  
  HRESULT   RegisterTwo(REFCLSID   clsid)//   注意clsid就是控件的GUID  
  {  
  //   注冊控件是安全性初始化的  
  /////////////////////////////////////////////////  
  HRESULT   hr;  
  hr   =   CreateComponentCategory(CATID_SafeForInitializing,   L"Controls   safely   initializable   from   persistent   data!");  
  if   (FAILED(hr))  
  return   hr;  
   
  hr   =   RegisterCLSIDInCategory(clsid,   CATID_SafeForInitializing);  
  if   (FAILED(hr))  
  return   hr;  
  //   注冊控件是安全性腳本操作的  
   
  hr   =   CreateComponentCategory(CATID_SafeForScripting,   L"Controls   safely   scriptable!");  
  if   (FAILED(hr))  
  return   hr;  
   
  hr   =   RegisterCLSIDInCategory(clsid,   CATID_SafeForScripting);  
  if   (FAILED(hr))  
  return   hr;  
   
  return   S_OK;  
  }  
   
  HRESULT   UnRegisterTwo(REFCLSID   clsid)   //   注意clsid就是控件的GUID  
  {  
  //   刪除注冊表入口  
  HRESULT   hr;  
  hr   =   UnRegisterCLSIDInCategory(clsid,   CATID_SafeForInitializing);  
  if   (FAILED(hr))  
  return   hr;  
  //REFCLSID  
  hr   =   UnRegisterCLSIDInCategory(clsid,   CATID_SafeForScripting);  
  if   (FAILED(hr))  
  return   hr;  
   
  return   S_OK;  
  }  


from:http://topic.csdn.net/t/20030704/00/1988641.html
posted on 2007-07-04 10:01 我風(fēng) 閱讀(1312) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

C++

MyFavorite

搜索

  •  

積分與排名

  • 積分 - 329000
  • 排名 - 75

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久91精品国产一区二区精品| 国产亚洲欧美另类一区二区三区| 一本一本久久a久久精品综合妖精| 欧美黄色片免费观看| 久久久999精品| 国产三级欧美三级日产三级99| 欧美日本在线观看| 欧美激情中文不卡| 欧美日韩精品在线视频| 欧美日韩国产黄| 国产精品久久久久一区二区| 国产精品入口尤物| 一区在线播放| 亚洲伦理久久| 欧美亚洲视频| 免费在线亚洲欧美| 亚洲国产天堂久久综合| 亚洲激情影视| 亚洲在线不卡| 美女网站在线免费欧美精品| 欧美日韩情趣电影| 国产综合色产| 在线视频中文亚洲| 久久久蜜桃精品| 亚洲精品国产系列| 久久er精品视频| 欧美国产在线电影| 国产视频亚洲精品| 亚洲精品久久久久久久久| 亚洲欧美日韩国产| 亚洲福利在线视频| 欧美一区二区三区成人| 欧美人与性动交α欧美精品济南到| 国产日韩精品一区二区三区| 亚洲人成亚洲人成在线观看图片 | 日韩视频永久免费观看| 久久精品国产第一区二区三区最新章节| 欧美成人午夜影院| 韩国三级电影久久久久久| 夜夜爽99久久国产综合精品女不卡| 久久国内精品自在自线400部| 亚洲人成亚洲人成在线观看图片| 欧美亚洲日本网站| 国产精品久久久久久久久婷婷| 最新国产乱人伦偷精品免费网站| 久久精品国产免费看久久精品| 日韩视频在线观看| 欧美成人免费视频| 在线日本成人| 蜜桃伊人久久| 久久久久国产精品一区| 国产伦精品一区二区三区高清版 | 亚洲欧美久久久久一区二区三区| 免费看av成人| …久久精品99久久香蕉国产| 久久久噜噜噜久久| 午夜精品久久久久久久蜜桃app| 欧美成人蜜桃| 久久免费高清| 在线亚洲观看| 欧美三级视频在线观看| 99国产精品久久久久久久久久| 欧美大尺度在线观看| 久久综合给合久久狠狠狠97色69| 国产综合色在线| 狂野欧美激情性xxxx欧美| 欧美一区日韩一区| 狠狠色丁香久久综合频道| 久久精品最新地址| 欧美一区二区三区免费视| 国内外成人在线| 蜜桃av一区二区| 免费国产自线拍一欧美视频| 9l国产精品久久久久麻豆| 日韩一级在线观看| 国产精品萝li| 久久久久久亚洲综合影院红桃 | 亚洲性线免费观看视频成熟| 一区二区三区视频在线| 国产精品日韩在线观看| 久久高清福利视频| 久久精品国产77777蜜臀| 亚洲成人自拍视频| 亚洲国产一区在线| 欧美三级视频在线| 久久精品国产亚洲aⅴ| 久久综合国产精品| 这里只有精品丝袜| 欧美一区=区| 最新日韩欧美| 亚洲一区二区在线| 亚洲福利国产精品| 99视频日韩| 国产午夜亚洲精品理论片色戒| 久久久久久久网站| 美女久久一区| 欧美亚洲尤物久久| 麻豆成人综合网| 欧美一区二区在线免费播放| 久久综合九色欧美综合狠狠| 亚洲一区中文| 欧美v日韩v国产v| 欧美一区成人| 欧美精品一区三区在线观看| 久久精品视频一| 欧美日韩一区二区国产| 猛男gaygay欧美视频| 国产精品日产欧美久久久久| 亚洲国产一成人久久精品| 国产午夜久久| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲午夜影视影院在线观看| 久久精品国产77777蜜臀| 亚洲一区免费网站| 免费成人你懂的| 伊人色综合久久天天| 亚洲一区二区伦理| 久久婷婷国产综合精品青草| 亚洲与欧洲av电影| 欧美激情视频一区二区三区在线播放 | 亚洲视屏在线播放| 亚洲电影免费观看高清完整版| 亚洲美女中文字幕| 最新国产成人av网站网址麻豆| 欧美在线免费观看| 亚洲免费视频一区二区| 欧美激情精品| 亚洲黄色精品| 亚洲精品乱码久久久久久按摩观| 久久久精品五月天| 久久这里有精品视频| 国产亚洲视频在线| 亚洲欧美成人网| 午夜精品一区二区在线观看 | 欧美日韩八区| 91久久精品国产91久久| 亚洲二区在线观看| 久久久青草婷婷精品综合日韩| 久久精品一区二区三区不卡| 国产亚洲a∨片在线观看| 亚洲欧美日韩综合| 久久精品国产在热久久| 国产一区二区欧美| 久久福利精品| 欧美福利视频在线| 日韩视频免费看| 欧美体内谢she精2性欧美| 一区二区免费看| 欧美一区二区视频网站| 国产一区二区三区日韩欧美| 久久精品中文字幕一区二区三区 | 欧美福利视频一区| 亚洲久久在线| 国产精品第一页第二页第三页| 亚洲一区二区三区精品在线观看 | 亚洲欧美日韩综合国产aⅴ| 欧美中文字幕视频| 一区国产精品| 欧美片第一页| 亚洲免费人成在线视频观看| 久久女同精品一区二区| 亚洲国产精品一区在线观看不卡| 欧美/亚洲一区| 中国日韩欧美久久久久久久久| 久久aⅴ国产紧身牛仔裤| 在线观看三级视频欧美| 欧美激情一区二区| 亚洲欧美日韩精品久久亚洲区| 久久综合久色欧美综合狠狠 | 亚洲视频福利| 国产一区二区精品久久| 翔田千里一区二区| 国产亚洲欧美日韩日本| 亚洲综合精品一区二区| 欧美成人午夜| 午夜欧美不卡精品aaaaa| 国产真实精品久久二三区| 欧美高清你懂得| 性做久久久久久免费观看欧美| 亚洲第一搞黄网站| 欧美在线观看网站| 99国产一区| 伊人久久大香线蕉综合热线| 欧美日韩国语| 快播亚洲色图| 欧美一区二区大片| 一本色道久久88精品综合| 美玉足脚交一区二区三区图片| 午夜精品久久久久久| 亚洲精品资源| 亚洲成人在线网站| 国产自产v一区二区三区c| 国产精品久久波多野结衣| 欧美国产精品久久| 狼人社综合社区| 欧美一区在线直播| 亚洲综合色激情五月| 亚洲视频在线看| 99成人在线| 99pao成人国产永久免费视频|