使用ATL建立支援IClassFactory2的COM元件 (轉)
使用ATL建立支援IClasactory2的COM
關鍵字:COM、IClassFactory2、建立、License、License Key
本文詳細描述瞭如何使用ATL自身的功能建立具有建立許可權功能的COM物件。最後還講述瞭如何建立具有固定和臨時許可權的COM物件,以及如何獲取註冊碼。
1 概述
IClassFactory2介面的作用是為給COM物件增加限制控制的功能。透過這個介面,只能在有合法使用權的上才可以建立COM物件的例項。
COM物件的許可權有兩種,一種是固定許可權,在建立COM物件之前就存在電腦中,建立COM物件時不需要提供附加的資訊。另一種是臨時的許可權,在建立物件的時候必須提供表明具有許可權的註冊碼,臨時許可權不能保留在電腦中,所以,每次建立例項的時候都需要提供註冊碼。每個COM物件可以選擇使用固定許可權方式、臨時許可權方式或兩者都使用。
COM物件可以提供取得註冊碼的功能。透過這個功能,可以在具有固定許可權的電腦上獲取的註冊碼。
在COM物件被建立的時候,應該檢查註冊碼或者固定許可權的資訊,如果COM物件判定沒有使用許可權,可以返回CLASS_E_NOTLICENSED。
2 ATL對IClassFactory2的支援
ATL完全支援IClassFactory2。透過宏DECLARE_CLASSFACTORY2宣告COM物件支援IClassFactory2介面。DECLARE_CLASSFACTORY2宏需要一個License類實現具體的許可許可權驗證演算法和註冊碼驗證演算法。License類可以使用任何名字,其中必須定義如下的幾個成員。License類的形式如下:
class CLicenseCls
{
protected:
static BOOL VerifyLicenseKey(BSTR bstr);
static BOOL GetLicenseKey(D dwReserved, BSTR* pBstr);
static BOOL IsLicenseValid();
};
VerifyLicenseKey函式用於驗證註冊碼的合法性。GetLicenseKey用於獲取註冊碼。IsLicenseValid函式用於驗證是否存在固定的使用許可權。
使用者可以根據需要,提供這三個函式的實現。如下表:
所需功能
VerifyLicenseKey
GetLicenseKey
IsLicenseValid
不檢查許可權
FALSE
FALSE
TRUE
固定許可權
FALSE
FALSE
檢查固定許可權
臨時許可權
檢測註冊碼
FALSE
FALSE
固定許可權和
臨時許可權
檢測註冊碼
FALSE
檢查固定許可權
固定許可權和
臨時許可權和
獲取註冊碼
檢測註冊碼
返回註冊碼
檢查固定許可權
3 實現方式
3.1 License類
實現License類的成員函式:
class CMyLicense
{
protected:
static BOOL VerifyLicenseKey(BSTR bstrLicenseKey)
{
if (wcscmp(bstrLicenseKey, OLESTR("Template License Key")) == 0)
{
return TRUE;
}
return FALSE;
}
static BOOL GetLicenseKey(DWORD dwReserved, BSTR* pBstrLicenseKey)
{
if (pBstrLicenseKey)
{
* pBstrLicenseKey = SysAllocString(OLESTR("Template License Key "));
}
return TRUE;
}
static BOOL IsLicenseValid() { return TRUE; }
};
以上例子中,IsLicenseValid函式永遠返回真。在實際使用中,要驗證電腦中是否存在固定許可權。如果存在固定許可權則返回真,否則返回假。這個例子中使用的是固定註冊碼,也可以根據需要使用偽隨機註冊碼。
3.2 實現IClassFactory2介面
在ATL的COM物件類中透過DECLARE_CLASSFACTORY2宏宣告在類物件中使用IClassFactory2介面。DECLARE_CLASSFACTORY2宏的定義如下:
DECLARE_CLASSFACTORY2(lic)
其中lic是License類的名稱,本例中為CMyLicense。
4 建立需要License的COM物件
4.1 具有固定許可權的COM物件
建立具有固定許可權的COM物件的方法和建立普通COM物件是相同的。不需要提供任何附加的資訊。
使用CoCreateInstance可以方便的創見固定許可權的COM物件。CoCreateInstance的定義如下:
STD CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClntext,
REFIID riid,
LPVOID * ppv
);
rclsid是要建立物件的CLSID。
pUnkOuter用於聚合的情況,不使用聚合的時候,使用NULL。
dwClsContext指定COM物件的執行環境,一般情況使用CLSCTX_ALL表示可以在任何環境執行。
riid是需要返回的介面的IID。
ppv是返回的介面指標的地址。
具體程式碼如下:
Iyyy * pObj;
HRESULT hr;
hr = CoCreateInstance(CLSID_xxx, NULL, CLSCTX_ALL, IID_yyy, &pObj);
if (FAILED(hr))
{
...
}
4.2 使用臨時許可權
使用臨時許可權建立COM物件,需要一個註冊碼。註冊碼可以從COM物件本身獲取,也可以透過其它方式取得(如購買等)。使用臨時許可權建立COM物件需要兩個步驟:取得COM類物件和建立COM物件。
透過CoGetClass函式,可以獲取類物件。CoGetClassObject的定義如下:
STDAPI CoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
COSERVERINFO * pServerInfo,
REFIID riid,
LPVOID * ppv
);
rclsid是要建立COM物件的CLSID。
dwClsContext是COM物件的執行方式,一般情況使用CLSCTX_ALL表示可以在任何環境執行。
pServerInfo用於在另一臺電腦上建立COM物件,在本地建立時用NULL。
riid是所需要的介面的IID,這裡使用IID_IClassFactory2。
ppv是返回介面指標的地址。
可以看出,前兩個引數和在CoCreateInstance中的定義是相同的。
具體程式碼:
IClassFactory2 * pCF2;
HRESULT hr;
hr = CoGetClassObject(CLSID_xxx, CLSCTX_ALL, NULL,
IID_IClassFactory2, (void **)&pCF2);
if (FAILED(hr))
{
...
}
...
4.2.2 建立物件
透過IClassFactory2的CreateInstanceLic方法,可以使用臨時許可權建立物件。在取得了COM類物件之後,CreateInstanceLic方法,並且把註冊碼作為引數,就可以得到新建的COM物件的介面指標。
CreateInstanceLic的定義如下:
HRESULT CreateInstanceLic(
IUnknown* pUnkOuter,
IUnknown* pUnkReserved,
REFIID riid,
BSTR bstrKey,
void** ppvObject
);
pUnkOuter是聚合的外部物件指標,在不使用聚合的時候,用NULL。
pUnkReserved是保留的引數,用NULL。
riid是所需要返回的介面IID。
bstrKey是註冊碼。
ppvObject是儲存返回的介面指標的地址。
具體程式碼:
Ixxx * pObj;
hr = pCF2->CreateInstanceLic(NULL, NULL, IID_Ixxx,
bstrLicenseKey, (void**) &pObj);
if (FAILED(hr))
{
...
}
建立之後就可以像使用普通COM物件一樣使用新建的COM物件。
4.3 獲取註冊碼
首先要取得類物件的指標,詳見第4.2.1節。
在取得了IClassFactory2的指標之後,透過RequestLicKey方法可以取得註冊碼。
RequestLicKey的定義如下:
HRESULT RequestLicKey(
DWORD dwReserved,
BSTR* pbstrKey
);
dwReserved是保留引數,用0。
pbstrKey是儲存返回的註冊碼的地址。呼叫方負責釋放返回值的地址。
具體程式碼:
BSTR bstrLicKey;
hr = pCF2->RequestLicKey(0, &bstrLicKey);
if (FAILED(hr))
{
...
}
...
SysFreeString(bstrLicKey);
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-958422/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 不使用ATL嚮導,建立一個簡單的ATL對話方塊程式. (轉)
- Developing COM Components using VC-ATL(1) (轉)dev
- 使用VC++ ATL實現iStylePDF的COM外掛C++
- ATL元件中文路徑註冊問題 (轉)元件
- Developing COM Components using VC-ATL(2-3) (轉)dev
- Developing COM Components using VC-ATL(2-2) (轉)dev
- Developing COM Components using VC-ATL(3-3) (轉)dev
- Developing COM Components using VC-ATL(3-5) (轉)dev
- Developing COM Components using VC-ATL(3-4) (轉)dev
- Developing COM Components using VC-ATL(3-6) (轉)dev
- Developing COM Components using VC-ATL(3-7) (轉)dev
- combo box控制元件的使用 (轉)控制元件
- 利用ATL製作程式多媒體封面元件 (轉)元件
- VC++、MFC、COM和ATL的區別C++
- 使用C#開發COM+元件 (轉)C#元件
- MSComm串列埠控制元件使用詳解(轉)串列埠控制元件
- 《深入解析ATL》學習手札 -- 第一天 (ATL #1) (轉)
- ATL中的Thunk機制學習 (轉)
- 元件能否支援動態建立庫及表元件
- react建立的元件中bind的使用React元件
- 自制支援檔案拖放的VCL元件 (轉)元件
- 建立和使用 WebAssembly 元件Web元件
- COM元件中的執行緒模式 (轉)元件執行緒模式
- MFC對COM介面編寫的支援分析 (轉)
- Cookie的建立使用 (轉)Cookie
- 使用 composer 建立專案
- c# 中呼叫COM元件 (轉)C#元件
- 用C#建立COM物件 (轉)C#物件
- 《Inside ATL/COM》第二期電子雜誌隆重發布 (轉)IDE
- 使用 Hooks 建立非同步元件Hook非同步元件
- WebSphere Message Broker -JavaCompute元件的使用WebJava元件
- 使用c# 開發 php的com元件C#PHP元件
- 在VB.Net中建立使用控制元件陣列 (轉)控制元件陣列
- 不用ATL框架純手工實現COM程式外回撥框架
- 對話方塊的選單、控制元件使用COMMAND_UI (轉)控制元件UI
- uniapp——元件的建立使用和元件的生命週期函式APP元件函式
- 使用 defineNuxtComponent`定義 Vue 元件UXVue元件
- B/S系統中我知道使用ATL作的Com元件可以獲得客戶端計算機的串列埠資料,java技術如何實現?元件客戶端計算機串列埠Java