Skip to content

Instantly share code, notes, and snippets.

@bg1bgst333
Last active September 13, 2021 13:05
Show Gist options
  • Save bg1bgst333/c827b0e819bc48fee31a to your computer and use it in GitHub Desktop.
Save bg1bgst333/c827b0e819bc48fee31a to your computer and use it in GitHub Desktop.
IUnknown#IUnknown
#include <cstdio> // 標準入出力
#include <tchar.h> // TCHAR対応
static long g_lLock = 0; // ロック
#include "Unknown.h" // Unknownの宣言
static CUnknown g_Unknown; // Unknownオブジェクト
HMODULE g_hModule = NULL;
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
g_hModule = hinstDLL;
return TRUE;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv){
if (rclsid == CLSID_CUnknown){
return g_Unknown.QueryInterface(riid, ppv);
}
else{
*ppv =NULL;
return CLASS_E_CLASSNOTAVAILABLE;
}
}
STDAPI DllCanUnloadNow(void){
return (g_lLock == 0) ? S_OK : S_FALSE;
}
STDAPI DllRegisterServer(void){
TCHAR tszModulePath[MAX_PATH];
HKEY hKey;
long e;
GetModuleFileName(g_hModule, tszModulePath, sizeof(tszModulePath) / sizeof(TCHAR));
e = RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (e != ERROR_SUCCESS){
return S_FALSE;
}
e = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)_T("IUnknown"), (lstrlen(_T("IUnknown")) + 1) * sizeof(TCHAR));
if (e != ERROR_SUCCESS){
RegCloseKey(hKey);
return S_FALSE;
}
e = RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}\\InprocServer32"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (e != ERROR_SUCCESS){
return S_FALSE;
}
e = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)tszModulePath, (lstrlen(tszModulePath) + 1) * sizeof(TCHAR));
if (e != ERROR_SUCCESS){
RegCloseKey(hKey);
return S_FALSE;
}
e = RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}\\InprocServer32"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (e != ERROR_SUCCESS){
return S_FALSE;
}
e = RegSetValueEx(hKey, _T("ThreadingModel"), 0, REG_SZ, (BYTE *)_T("Apartment"), (lstrlen(_T("Apartment")) + 1) * sizeof(TCHAR));
if (e != ERROR_SUCCESS){
RegCloseKey(hKey);
return S_FALSE;
}
e = RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}\\ProgID"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (e != ERROR_SUCCESS){
return S_FALSE;
}
e = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)_T("IUnknown.CUnknown"), (lstrlen(_T("IUnknown.CUnknown")) + 1) * sizeof(TCHAR));
if (e != ERROR_SUCCESS){
RegCloseKey(hKey);
return S_FALSE;
}
return S_OK;
}
STDAPI DllUnregisterServer(void){
RegDeleteKey(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}\\ProgID"));
RegDeleteKey(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}\\InprocServer32"));
RegDeleteKey(HKEY_CLASSES_ROOT, _T("CLSID\\{4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC}"));
return S_OK;
}
LIBRARY "IUnknown.dll"
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllRegisterServer @3 PRIVATE
DllUnregisterServer @4 PRIVATE
// IUnknown_.idl
import "unknwn.idl";
// IUnknown_インターフェイス
[
object,
uuid(A20823A1-5E1E-4019-A688-758944E22C74)
]
interface IUnknown_ : IUnknown // インターフェイス宣言
{
HRESULT Method(void);
};
[
uuid(95070208-E06B-4cd8-811F-D2DE2C4AFEAB),
version(1.0)
]
// UnknownLibタイプライブラリ
library UnknownLib // ライブラリ宣言
{
importlib("stdole32.tlb");
[
uuid(4E0C8ADE-56FA-4d79-9654-8AA2BB27FEFC)
]
coclass CUnknown
{
[default]
interface IUnknown_;
};
};
// ヘッダファイルのインクルード
#include <windows.h> // 標準WindowsAPI
#include <cstdio> // 標準入出力
#include <tchar.h> // TCHAR対応
#include "IUnknown__h.h" // MIDL生成
#include "IUnknown__i.c" // GUID
// _tmain関数の定義
int _tmain(int argc, TCHAR *argv[]){ // main関数のTCHAR版.
CoInitialize(NULL);
IUnknown_* pUnknown = NULL;
HRESULT hr = CoGetClassObject(CLSID_CUnknown, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown_, reinterpret_cast<void**>(&pUnknown));
if (FAILED(hr)){
_tprintf(_T("CoCreateInstance failed!\n"));
CoUninitialize();
return 0;
}
pUnknown->Method();
pUnknown->Release();
CoUninitialize();
// プログラムの終了
return 0;
}
#include <cstdio> // •W€“üo—Í
#include <tchar.h> // TCHAR‘Ήž
#include "Unknown.h" // CUnknown
#include "IUnknown__i.c" // GUID
CUnknown::CUnknown() : m_lRef(0){
m_lRef = 1;
}
CUnknown::~CUnknown(){
}
STDMETHODIMP CUnknown::QueryInterface(REFIID riid, LPVOID *ppv){
*ppv = NULL;
if (riid == IID_IUnknown || riid == IID_IUnknown_){
*ppv = static_cast<IUnknown_ *>(this);
}
else{
return E_NOINTERFACE;
}
_tprintf(_T("QueryInterface!\n"));
static_cast<IUnknown_ *>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CUnknown::AddRef(){
_tprintf(_T("AddRef!\n"));
return InterlockedIncrement(&m_lRef);
}
STDMETHODIMP_(ULONG) CUnknown::Release(){
_tprintf(_T("Release!\n"));
LONG res = InterlockedDecrement(&m_lRef);
if (res == 0){
delete this;
}
return res;
}
STDMETHODIMP CUnknown::Method(void){
_tprintf(_T("Method!\n"));
return S_OK;
}
#pragma once
#include <windows.h>
#include "IUnknown__h.h"
class CUnknown : public IUnknown_
{
public:
CUnknown();
~CUnknown();
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP Method(void);
private:
LONG m_lRef;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment