You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
7.0 KiB
234 lines
7.0 KiB
// @doc
|
|
/**********************************************************************
|
|
*
|
|
* @module USEWheelEffectDriverEntryPoints.cpp |
|
|
*
|
|
* Contains DLL Entry points
|
|
*
|
|
* History
|
|
* ----------------------------------------------------------
|
|
* Matthew L. Coill (mlc) Original Jul-7-1999
|
|
*
|
|
* (c) 1999 Microsoft Corporation. All right reserved.
|
|
*
|
|
* @topic DLL Entry points |
|
|
* DllMain - Main Entry Point for DLL (Process/Thread Attach/Detach)
|
|
* DllCanUnloadNow - Can the DLL be removed from memory
|
|
* DllGetClassObject - Retreive the Class Factory
|
|
* DllRegisterServer - Insert keys into the system registry
|
|
* DLLUnRefisterServer - Remove keys from the system registry
|
|
*
|
|
**********************************************************************/
|
|
#include <windows.h>
|
|
#include "IDirectInputEffectDriverClassFactory.h"
|
|
#include "IDirectInputEffectDriver.h"
|
|
#include "Registry.h"
|
|
#include <crtdbg.h>
|
|
|
|
// From objbase.h
|
|
WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
|
|
|
|
CIDirectInputEffectDriverClassFactory* g_pClassFactoryObject = NULL;
|
|
LONG g_lObjectCount = 0;
|
|
HINSTANCE g_hLocalInstance = NULL;
|
|
|
|
GUID g_guidSystemPIDDriver = { // EEC6993A-B3FD-11D2-A916-00C04FB98638
|
|
0xEEC6993A,
|
|
0xB3FD,
|
|
0x11D2,
|
|
{ 0xA9, 0x16, 0x00, 0xC0, 0x4F, 0xB9, 0x86, 0x38 }
|
|
};
|
|
|
|
extern TCHAR CLSID_SWPIDDriver_String[] = TEXT("{db11d351-3bf6-4f2c-a82b-b26cb9676d2b}");
|
|
|
|
#define DRIVER_OBJECT_NAME TEXT("Microsoft SideWinder PID Filter Object")
|
|
#define THREADING_MODEL_STRING TEXT("Both")
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** BOOL DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
|
**
|
|
** @func Process/Thread is Attaching/Detaching
|
|
**
|
|
** @rdesc TRUE always
|
|
**
|
|
*************************************************************************************/
|
|
BOOL __stdcall DllMain
|
|
(
|
|
HINSTANCE hInstance, //@parm [IN] Instance of the DLL
|
|
DWORD dwReason, //@parm [IN] Reason for this call
|
|
LPVOID lpReserved //@parm [IN] Reserved - Ignored
|
|
)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
g_hLocalInstance = hInstance;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** HRESULT DllCanUnloadNow()
|
|
**
|
|
** @func Query the DLL for Unloadability
|
|
**
|
|
** @rdesc If there are any object S_FALSE, else S_OK
|
|
**
|
|
*************************************************************************************/
|
|
extern "C" HRESULT __stdcall DllCanUnloadNow()
|
|
{
|
|
if (g_lObjectCount > 0)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
|
**
|
|
** @func Retrieve the requested Factory
|
|
**
|
|
** @rdesc E_INVALIDARG: if (ppv == NULL)
|
|
** E_NOMEMORY: if can't create the object
|
|
** S_OK: if all is well
|
|
** E_NOINTERFACE: if interface is not supported
|
|
**
|
|
*************************************************************************************/
|
|
extern "C" HRESULT __stdcall DllGetClassObject
|
|
(
|
|
REFCLSID rclsid,
|
|
REFIID riid, //@parm [IN] ID of requested interface on retrieved object
|
|
LPVOID* ppv //@parm [OUT] Address of location for returned interface
|
|
)
|
|
{
|
|
if (ppv == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
*ppv = NULL;
|
|
|
|
if (g_pClassFactoryObject == NULL)
|
|
{
|
|
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
|
|
|
// Need to get the PID Class Factory
|
|
IClassFactory* pIClassFactory = NULL;
|
|
HRESULT hrGetPIDFactory = ::CoGetClassObject(g_guidSystemPIDDriver, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pIClassFactory);
|
|
if (FAILED(hrGetPIDFactory) || (pIClassFactory == NULL))
|
|
{
|
|
return hrGetPIDFactory;
|
|
}
|
|
|
|
g_pClassFactoryObject = new CIDirectInputEffectDriverClassFactory(pIClassFactory);
|
|
pIClassFactory->Release(); // CIDirectInputEffectDriverClassFactory adds a reference
|
|
if (g_pClassFactoryObject == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_pClassFactoryObject->AddRef();
|
|
}
|
|
|
|
HRESULT hrQuery = g_pClassFactoryObject->QueryInterface(riid, ppv);
|
|
g_pClassFactoryObject->Release(); // Force a release (we start with 1)
|
|
return hrQuery;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** HRESULT DllRegisterServer()
|
|
**
|
|
** @func
|
|
**
|
|
** @rdesc
|
|
**
|
|
*************************************************************************************/
|
|
HRESULT __stdcall DllRegisterServer()
|
|
{
|
|
RegistryKey classesRootKey(HKEY_CLASSES_ROOT);
|
|
RegistryKey clsidKey = classesRootKey.OpenSubkey(TEXT("CLSID"), KEY_READ | KEY_WRITE);
|
|
if (clsidKey == c_InvalidKey)
|
|
{
|
|
return E_UNEXPECTED; // No CLSID key????
|
|
}
|
|
// -- If the key is there get it (else Create)
|
|
RegistryKey driverKey = clsidKey.OpenCreateSubkey(CLSID_SWPIDDriver_String);
|
|
// -- Set value (if valid key)
|
|
if (driverKey != c_InvalidKey) {
|
|
driverKey.SetValue(NULL, (BYTE*)DRIVER_OBJECT_NAME, sizeof(DRIVER_OBJECT_NAME)/sizeof(TCHAR), REG_SZ);
|
|
RegistryKey inproc32Key = driverKey.OpenCreateSubkey(TEXT("InProcServer32"));
|
|
if (inproc32Key != c_InvalidKey) {
|
|
TCHAR rgtcFileName[MAX_PATH];
|
|
DWORD dwNameSize = ::GetModuleFileName(g_hLocalInstance, rgtcFileName, MAX_PATH);
|
|
if (dwNameSize > 0) {
|
|
rgtcFileName[dwNameSize] = '\0';
|
|
inproc32Key.SetValue(NULL, (BYTE*)rgtcFileName, sizeof(rgtcFileName)/sizeof(TCHAR), REG_SZ);
|
|
}
|
|
inproc32Key.SetValue(TEXT("ThreadingModel"), (BYTE*)THREADING_MODEL_STRING, sizeof(THREADING_MODEL_STRING)/sizeof(TCHAR), REG_SZ);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** HRESULT DllUnregisterServer()
|
|
**
|
|
** @func
|
|
**
|
|
** @rdesc
|
|
**
|
|
*************************************************************************************/
|
|
HRESULT __stdcall DllUnregisterServer()
|
|
{
|
|
// Unregister CLSID for DIEffectDriver
|
|
// -- Get HKEY_CLASSES_ROOT\CLSID key
|
|
RegistryKey classesRootKey(HKEY_CLASSES_ROOT);
|
|
RegistryKey clsidKey = classesRootKey.OpenSubkey(TEXT("CLSID"), KEY_READ | KEY_WRITE);
|
|
if (clsidKey == c_InvalidKey) {
|
|
return E_UNEXPECTED; // No CLSID key????
|
|
}
|
|
|
|
DWORD numSubKeys = 0;
|
|
{ // driverKey Destructor will close the key
|
|
// -- If the key is there get it, else we don't have to remove it
|
|
RegistryKey driverKey = clsidKey.OpenSubkey(CLSID_SWPIDDriver_String);
|
|
if (driverKey != c_InvalidKey) { // Is it there
|
|
driverKey.RemoveSubkey(TEXT("InProcServer32"));
|
|
numSubKeys = driverKey.GetNumSubkeys();
|
|
} else { // Key is not there (I guess removal was successful)
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
if (numSubKeys == 0) {
|
|
return clsidKey.RemoveSubkey(CLSID_SWPIDDriver_String);
|
|
}
|
|
|
|
// Made it here valid driver key
|
|
return S_OK;
|
|
}
|
|
|
|
LONG DllAddRef()
|
|
{
|
|
_RPT1(_CRT_WARN, "(DllAddRef)g_lObjectCount: %d\n", g_lObjectCount);
|
|
return ::InterlockedIncrement(&g_lObjectCount);
|
|
}
|
|
|
|
LONG DllRelease()
|
|
{
|
|
_RPT1(_CRT_WARN, "(DllRelease)g_lObjectCount: %d\n", g_lObjectCount);
|
|
DWORD dwCount = ::InterlockedDecrement(&g_lObjectCount);
|
|
if (dwCount == 0)
|
|
{
|
|
g_pClassFactoryObject = NULL;
|
|
::CoUninitialize();
|
|
}
|
|
return dwCount;
|
|
}
|