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

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module USEWheelEffectDriverEntryPoints.cpp |
  5. *
  6. * Contains DLL Entry points
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Matthew L. Coill (mlc) Original Jul-7-1999
  11. *
  12. * (c) 1999 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic DLL Entry points |
  15. * DllMain - Main Entry Point for DLL (Process/Thread Attach/Detach)
  16. * DllCanUnloadNow - Can the DLL be removed from memory
  17. * DllGetClassObject - Retreive the Class Factory
  18. * DllRegisterServer - Insert keys into the system registry
  19. * DLLUnRefisterServer - Remove keys from the system registry
  20. *
  21. **********************************************************************/
  22. #include <windows.h>
  23. #include "IDirectInputEffectDriverClassFactory.h"
  24. #include "IDirectInputEffectDriver.h"
  25. #include "Registry.h"
  26. #include <crtdbg.h>
  27. // From objbase.h
  28. WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
  29. CIDirectInputEffectDriverClassFactory* g_pClassFactoryObject = NULL;
  30. LONG g_lObjectCount = 0;
  31. HINSTANCE g_hLocalInstance = NULL;
  32. GUID g_guidSystemPIDDriver = { // EEC6993A-B3FD-11D2-A916-00C04FB98638
  33. 0xEEC6993A,
  34. 0xB3FD,
  35. 0x11D2,
  36. { 0xA9, 0x16, 0x00, 0xC0, 0x4F, 0xB9, 0x86, 0x38 }
  37. };
  38. extern TCHAR CLSID_SWPIDDriver_String[] = TEXT("{db11d351-3bf6-4f2c-a82b-b26cb9676d2b}");
  39. #define DRIVER_OBJECT_NAME TEXT("Microsoft SideWinder PID Filter Object")
  40. #define THREADING_MODEL_STRING TEXT("Both")
  41. /***********************************************************************************
  42. **
  43. ** BOOL DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  44. **
  45. ** @func Process/Thread is Attaching/Detaching
  46. **
  47. ** @rdesc TRUE always
  48. **
  49. *************************************************************************************/
  50. BOOL __stdcall DllMain
  51. (
  52. HINSTANCE hInstance, //@parm [IN] Instance of the DLL
  53. DWORD dwReason, //@parm [IN] Reason for this call
  54. LPVOID lpReserved //@parm [IN] Reserved - Ignored
  55. )
  56. {
  57. if (dwReason == DLL_PROCESS_ATTACH)
  58. {
  59. g_hLocalInstance = hInstance;
  60. }
  61. return TRUE;
  62. }
  63. /***********************************************************************************
  64. **
  65. ** HRESULT DllCanUnloadNow()
  66. **
  67. ** @func Query the DLL for Unloadability
  68. **
  69. ** @rdesc If there are any object S_FALSE, else S_OK
  70. **
  71. *************************************************************************************/
  72. extern "C" HRESULT __stdcall DllCanUnloadNow()
  73. {
  74. if (g_lObjectCount > 0)
  75. {
  76. return S_FALSE;
  77. }
  78. return S_OK;
  79. }
  80. /***********************************************************************************
  81. **
  82. ** HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  83. **
  84. ** @func Retrieve the requested Factory
  85. **
  86. ** @rdesc E_INVALIDARG: if (ppv == NULL)
  87. ** E_NOMEMORY: if can't create the object
  88. ** S_OK: if all is well
  89. ** E_NOINTERFACE: if interface is not supported
  90. **
  91. *************************************************************************************/
  92. extern "C" HRESULT __stdcall DllGetClassObject
  93. (
  94. REFCLSID rclsid,
  95. REFIID riid, //@parm [IN] ID of requested interface on retrieved object
  96. LPVOID* ppv //@parm [OUT] Address of location for returned interface
  97. )
  98. {
  99. if (ppv == NULL)
  100. {
  101. return E_INVALIDARG;
  102. }
  103. *ppv = NULL;
  104. if (g_pClassFactoryObject == NULL)
  105. {
  106. ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  107. // Need to get the PID Class Factory
  108. IClassFactory* pIClassFactory = NULL;
  109. HRESULT hrGetPIDFactory = ::CoGetClassObject(g_guidSystemPIDDriver, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pIClassFactory);
  110. if (FAILED(hrGetPIDFactory) || (pIClassFactory == NULL))
  111. {
  112. return hrGetPIDFactory;
  113. }
  114. g_pClassFactoryObject = new CIDirectInputEffectDriverClassFactory(pIClassFactory);
  115. pIClassFactory->Release(); // CIDirectInputEffectDriverClassFactory adds a reference
  116. if (g_pClassFactoryObject == NULL)
  117. {
  118. return E_OUTOFMEMORY;
  119. }
  120. }
  121. else
  122. {
  123. g_pClassFactoryObject->AddRef();
  124. }
  125. HRESULT hrQuery = g_pClassFactoryObject->QueryInterface(riid, ppv);
  126. g_pClassFactoryObject->Release(); // Force a release (we start with 1)
  127. return hrQuery;
  128. }
  129. /***********************************************************************************
  130. **
  131. ** HRESULT DllRegisterServer()
  132. **
  133. ** @func
  134. **
  135. ** @rdesc
  136. **
  137. *************************************************************************************/
  138. HRESULT __stdcall DllRegisterServer()
  139. {
  140. RegistryKey classesRootKey(HKEY_CLASSES_ROOT);
  141. RegistryKey clsidKey = classesRootKey.OpenSubkey(TEXT("CLSID"), KEY_READ | KEY_WRITE);
  142. if (clsidKey == c_InvalidKey)
  143. {
  144. return E_UNEXPECTED; // No CLSID key????
  145. }
  146. // -- If the key is there get it (else Create)
  147. RegistryKey driverKey = clsidKey.OpenCreateSubkey(CLSID_SWPIDDriver_String);
  148. // -- Set value (if valid key)
  149. if (driverKey != c_InvalidKey) {
  150. driverKey.SetValue(NULL, (BYTE*)DRIVER_OBJECT_NAME, sizeof(DRIVER_OBJECT_NAME)/sizeof(TCHAR), REG_SZ);
  151. RegistryKey inproc32Key = driverKey.OpenCreateSubkey(TEXT("InProcServer32"));
  152. if (inproc32Key != c_InvalidKey) {
  153. TCHAR rgtcFileName[MAX_PATH];
  154. DWORD dwNameSize = ::GetModuleFileName(g_hLocalInstance, rgtcFileName, MAX_PATH);
  155. if (dwNameSize > 0) {
  156. rgtcFileName[dwNameSize] = '\0';
  157. inproc32Key.SetValue(NULL, (BYTE*)rgtcFileName, sizeof(rgtcFileName)/sizeof(TCHAR), REG_SZ);
  158. }
  159. inproc32Key.SetValue(TEXT("ThreadingModel"), (BYTE*)THREADING_MODEL_STRING, sizeof(THREADING_MODEL_STRING)/sizeof(TCHAR), REG_SZ);
  160. }
  161. }
  162. return S_OK;
  163. }
  164. /***********************************************************************************
  165. **
  166. ** HRESULT DllUnregisterServer()
  167. **
  168. ** @func
  169. **
  170. ** @rdesc
  171. **
  172. *************************************************************************************/
  173. HRESULT __stdcall DllUnregisterServer()
  174. {
  175. // Unregister CLSID for DIEffectDriver
  176. // -- Get HKEY_CLASSES_ROOT\CLSID key
  177. RegistryKey classesRootKey(HKEY_CLASSES_ROOT);
  178. RegistryKey clsidKey = classesRootKey.OpenSubkey(TEXT("CLSID"), KEY_READ | KEY_WRITE);
  179. if (clsidKey == c_InvalidKey) {
  180. return E_UNEXPECTED; // No CLSID key????
  181. }
  182. DWORD numSubKeys = 0;
  183. { // driverKey Destructor will close the key
  184. // -- If the key is there get it, else we don't have to remove it
  185. RegistryKey driverKey = clsidKey.OpenSubkey(CLSID_SWPIDDriver_String);
  186. if (driverKey != c_InvalidKey) { // Is it there
  187. driverKey.RemoveSubkey(TEXT("InProcServer32"));
  188. numSubKeys = driverKey.GetNumSubkeys();
  189. } else { // Key is not there (I guess removal was successful)
  190. return S_OK;
  191. }
  192. }
  193. if (numSubKeys == 0) {
  194. return clsidKey.RemoveSubkey(CLSID_SWPIDDriver_String);
  195. }
  196. // Made it here valid driver key
  197. return S_OK;
  198. }
  199. LONG DllAddRef()
  200. {
  201. _RPT1(_CRT_WARN, "(DllAddRef)g_lObjectCount: %d\n", g_lObjectCount);
  202. return ::InterlockedIncrement(&g_lObjectCount);
  203. }
  204. LONG DllRelease()
  205. {
  206. _RPT1(_CRT_WARN, "(DllRelease)g_lObjectCount: %d\n", g_lObjectCount);
  207. DWORD dwCount = ::InterlockedDecrement(&g_lObjectCount);
  208. if (dwCount == 0)
  209. {
  210. g_pClassFactoryObject = NULL;
  211. ::CoUninitialize();
  212. }
  213. return dwCount;
  214. }