Leaked source code of windows server 2003
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

// @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;
}