Skip to content

Instantly share code, notes, and snippets.

@Lucyfurnice
Created February 26, 2024 22:22
Show Gist options
  • Save Lucyfurnice/bd788672257830d04cad4cc334af50e2 to your computer and use it in GitHub Desktop.
Save Lucyfurnice/bd788672257830d04cad4cc334af50e2 to your computer and use it in GitHub Desktop.
#include "comtest.h"
typedef struct MyInterfaceImpl
{
// IUnknown methods
HRESULT ( WINAPI* QueryInterface )
( IMyInterface* pInterface , REFIID riid , void** ppvObject );
ULONG ( WINAPI* AddRef )
( IMyInterface* pInterface );
ULONG ( WINAPI* Release )
( IMyInterface* pInterface );
ULONG refCount;
// Interface-specific members
TCHAR tcharValue;
int intValue;
} MyInterfaceImpl;
HRESULT WINAPI
QueryInterface ( IMyInterface* pInterface
, REFIID riid , void** ppvObject )
{
// Cast the interface pointer to the actual implementation type
MyInterfaceImpl* pImpl = ( MyInterfaceImpl* )pInterface;
// Check if the requested interface is supported
if ( IsEqualGUID ( riid , &IID_IUnknown )
|| IsEqualGUID ( riid , &IID_IMyInterface ) )
{
// Increment the reference count and return the interface pointer
pImpl->AddRef ( &pImpl );
*ppvObject = pInterface;
return S_OK;
}
else
{
// The requested interface is not supported
*ppvObject = NULL;
return E_NOINTERFACE;
}
}
ULONG WINAPI AddRef ( IMyInterface* pInterface )
{
// Cast the interface pointer to the actual implementation type
MyInterfaceImpl* pImpl = ( MyInterfaceImpl* )pInterface;
// Increment the reference count and return the new count
return InterlockedIncrement ( &( pImpl->refCount ) );
}
// Method to decrement the reference count
ULONG WINAPI Release ( IMyInterface* pInterface )
{
// Cast the interface pointer to the actual implementation type
MyInterfaceImpl* pImpl = ( MyInterfaceImpl* )pInterface;
// Decrement the reference count
ULONG newRefCount = InterlockedDecrement ( &( pImpl->refCount ) );
// If the reference count reaches zero, delete the object
if ( newRefCount == 0 )
{
// dont do this herefree ( pImpl );
// clean up associated resources.
}
// Return the new count
return newRefCount;
}
HRESULT WINAPI
SetTCharValue ( IMyInterface* pInterface , TCHAR value )
{
MyInterfaceImpl* pImpl = ( MyInterfaceImpl* )pInterface;
// Set the value in the implementation
pImpl->tcharValue = value;
// Return success
return S_OK;
}
// Method to get the TCHAR value
HRESULT WINAPI
GetTCharValue ( IMyInterface* pInterface , TCHAR* value )
{
// Implementation code goes here
return S_OK;
}
// Method to set the int value
HRESULT WINAPI
SetIntValue ( IMyInterface* pInterface , int value )
{
// Implementation code goes here
return S_OK;
}
// Method to get the int value
HRESULT WINAPI
GetIntValue ( IMyInterface* pInterface , int* value )
{
// Implementation code goes here
return S_OK;
}
HMODULE g_hModule = NULL;
BOOL APIENTRY
DllMain ( HMODULE hModule
, DWORD ul_reason_for_call , LPVOID lpReserved )
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
break;
case DLL_PROCESS_DETACH:
g_hModule = NULL;
break;
case DLL_THREAD_ATTACH:
// Code to run when a new thread is created in a process
break;
case DLL_THREAD_DETACH:
// Code to run when a thread is terminated in a process
break;
}
return TRUE;
}
HRESULT RegisterProgID ( LPCOLESTR pProgID , REFCLSID clsid );
EXTERN_C __declspec( dllexport ) HRESULT
STDMETHODCALLTYPE DllRegisterServer ( )
{
// Get the path to the DLL
WCHAR szModulePath[ MAX_PATH ];
if ( GetModuleFileName ( g_hModule , szModulePath , MAX_PATH ) == 0 )
{
return HRESULT_FROM_WIN32 ( GetLastError ( ) );
}
// Register the COM component
HRESULT hr = RegisterServer ( szModulePath );
if ( FAILED ( hr ) )
{
return hr;
}
return S_OK;
}
EXTERN_C __declspec( dllexport ) HRESULT
STDMETHODCALLTYPE DllUnregisterServer ( )
{
// Get the path to the DLL
WCHAR szModulePath[ MAX_PATH ];
if ( GetModuleFileName ( g_hModule , szModulePath , MAX_PATH ) == 0 )
{
return HRESULT_FROM_WIN32 ( GetLastError ( ) );
}
// Unregister the COM component
HRESULT hr = UnregisterServer ( szModulePath );
if ( FAILED ( hr ) )
{
return hr;
}
return S_OK;
}
HRESULT RegisterServer ( const WCHAR* pszModulePath )
{
// Get the CLSID of the COM component
CLSID clsid;
//RegisterProgID ( L"net_evilop.MyInterfaceImpl" , &IID_IMyInterface );
HRESULT hr
= CLSIDFromProgID (
L"net_evilop.MyInterfaceImpl"
, &clsid );
if ( FAILED ( hr ) )
{
MessageBeep ( 3 );
MessageBox ( NULL , L"qwert" , L"Title" , MB_OK );
return hr;
}
// Open the HKEY_CLASSES_ROOT\CLSID key for the COM component
HKEY hKeyCLSID;
hr = RegCreateKeyEx ( HKEY_CLASSES_ROOT
, L"CLSID\\{6Ce384844-A2B9-497C-A9A7-BFFAA8FF581D}"
, 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_WRITE
, NULL , &hKeyCLSID , NULL );
if ( FAILED ( hr ) )
{
return hr;
}
// Write the InprocServer32 subkey value
hr = RegSetValueEx ( hKeyCLSID , L"InprocServer32"
, 0 , REG_SZ , ( const BYTE* )pszModulePath
, ( wcslen ( pszModulePath ) + 1 ) * sizeof ( WCHAR ) );
if ( FAILED ( hr ) )
{
RegCloseKey ( hKeyCLSID );
return hr;
}
RegCloseKey ( hKeyCLSID );
return S_OK;
}
// Helper function to unregister the COM component
HRESULT UnregisterServer ( const WCHAR* pszModulePath )
{
// Open the HKEY_CLASSES_ROOT\CLSID key for the COM component
HKEY hKeyCLSID;
HRESULT hr = RegOpenKeyEx ( HKEY_CLASSES_ROOT , L"CLSID\\{6C384844-A2B9-497C-A9A7-BFFAA8FF581D}" , 0 , KEY_WRITE , &hKeyCLSID );
if ( hr != ERROR_SUCCESS )
{
return hr;
}
// Delete the InprocServer32 subkey
hr = RegDeleteKey ( hKeyCLSID , L"InprocServer32" );
if ( hr != ERROR_SUCCESS )
{
RegCloseKey ( hKeyCLSID );
return hr;
}
RegCloseKey ( hKeyCLSID );
return S_OK;
}
HRESULT RegisterProgID ( LPCOLESTR pProgID , REFCLSID clsid )
{
// Open the ProgID key
HKEY hProgIDKey;
HRESULT hr = RegCreateKeyEx ( HKEY_CLASSES_ROOT , pProgID , 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_WRITE , NULL , &hProgIDKey , NULL );
if ( FAILED ( hr ) )
{
return hr;
}
// Set the default value of the ProgID key to the friendly name of your component
hr = RegSetValue ( hProgIDKey , NULL , REG_SZ , L"My Component" , sizeof ( L"My Component" ) );
if ( FAILED ( hr ) )
{
RegCloseKey ( hProgIDKey );
return hr;
}
// Create the CLSID subkey under the ProgID key
HKEY hCLSIDKey;
hr = RegCreateKeyEx ( hProgIDKey , L"CLSID" , 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_WRITE , NULL , &hCLSIDKey , NULL );
if ( FAILED ( hr ) )
{
RegCloseKey ( hProgIDKey );
return hr;
}
// Set the default value of the CLSID subkey to the CLSID of your component
WCHAR szCLSID[ 39 ];
StringFromGUID2 ( clsid , szCLSID , 39 );
hr = RegSetValue ( hCLSIDKey , NULL , REG_SZ , szCLSID , sizeof ( szCLSID ) );
if ( FAILED ( hr ) )
{
RegCloseKey ( hCLSIDKey );
RegCloseKey ( hProgIDKey );
return hr;
}
// Close the registry keys
RegCloseKey ( hCLSIDKey );
RegCloseKey ( hProgIDKey );
return S_OK;
}
__declspec( dllexport ) HRESULT WINAPI DllInstall ( BOOL bInstall , LPCWSTR pszCmdLine )
{
if ( bInstall )
{
if ( pszCmdLine != NULL && wcsstr ( pszCmdLine , L"Install_1" ) != NULL )
{
// Perform installation actions for Install_1
// Register COM classes, create registry entries, etc.
// Example: Call regsvr32
system ( "regsvr32 /s comtest.dll" );
}
else if ( pszCmdLine != NULL && wcsstr ( pszCmdLine , L"Install_2" ) != NULL )
{
// Perform installation actions for Install_2
// Register COM classes, create registry entries, etc.
// Example: Call regsvr32 with additional parameters
system ( "regsvr32 /s /n comtest.dll" );
}
else
{
// Default installation actions
// Perform common installation tasks
}
}
else {
// Perform uninstallation actions
// This could include unregistering COM classes, removing registry entries, etc.
// Example: Unregister COM classes using regsvr32
system ( "regsvr32 /s /u comtest.dll" );
}
return S_OK;
}
#ifndef __IMYINTERFACE_H__
#define __IMYINTERFACE_H__
#include <windows.h>
EXTERN_C const IID IID_IMyInterface;
// Define the interface UUID
static const IID IID_IMyInterface = { 0x6c384844, 0xa2b9, 0x497c, { 0xa9, 0xa7, 0xbf, 0xfa, 0xa8, 0xff, 0x58, 0x1d } };
// Forward declaration of the interface
typedef struct IMyInterface IMyInterface;
// Define the interface methods
typedef HRESULT
( WINAPI* PFN_SetTCharValue )
( IMyInterface* pInterface , TCHAR value );
typedef HRESULT
( WINAPI* PFN_GetTCharValue )
( IMyInterface* pInterface , TCHAR* value );
typedef HRESULT
( WINAPI* PFN_SetIntValue )
( IMyInterface* pInterface , int value );
typedef HRESULT
( WINAPI* PFN_GetIntValue )
( IMyInterface* pInterface , int* value );
// Define the interface structure
struct IMyInterface
{
// IUnknown methods
HRESULT ( WINAPI* QueryInterface )( IMyInterface* pInterface
, REFIID riid , void** ppvObject );
ULONG ( WINAPI* AddRef )( IMyInterface* pInterface );
ULONG ( WINAPI* Release )( IMyInterface* pInterface );
// Interface-specific methods
PFN_SetTCharValue SetTCharValue;
PFN_GetTCharValue GetTCharValue;
PFN_SetIntValue SetIntValue;
PFN_GetIntValue GetIntValue;
};
EXTERN_C __declspec( dllexport )
HRESULT STDMETHODCALLTYPE CreateMyImpl
( IMyInterface * *ppComponent );
EXTERN_C __declspec( dllexport )
HRESULT STDMETHODCALLTYPE DllRegisterServer ( );
EXTERN_C __declspec( dllexport )
HRESULT STDMETHODCALLTYPE DllUnregisterServer ( );
#endif // __IMYINTERFACE_H__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment