Source code of Windows XP (NT5)
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.

416 lines
11 KiB

  1. /*****************************************************************************
  2. *
  3. * Main.c
  4. * Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  5. *
  6. * Abstract:
  7. *
  8. * Template effect driver that doesn't actually do anything.
  9. *
  10. *****************************************************************************/
  11. #include "PIDpr.h"
  12. /*****************************************************************************
  13. *
  14. * Static globals: Initialized at PROCESS_ATTACH and never modified.
  15. *
  16. *****************************************************************************/
  17. HINSTANCE g_hinst = NULL; /* This DLL's instance handle */
  18. PSHAREDMEMORY g_pshmem = NULL; /* Our shared memory block */
  19. HANDLE g_hfm = NULL; /* Handle to file mapping object */
  20. HANDLE g_hmtxShared = NULL; /* Handle to mutex that protects g_pshmem */
  21. CANCELIO CancelIo_ = FakeCancelIO;
  22. #ifdef DEBUG
  23. LONG g_cCrit = 0;
  24. ULONG g_thidCrit = 0;
  25. PTCHAR g_rgUsageTxt[PIDUSAGETXT_MAX]; // Cheat sheet for PID usages
  26. #endif
  27. TRYENTERCRITICALSECTION TryEnterCriticalSection_ = FakeTryEnterCriticalSection;
  28. /*****************************************************************************
  29. *
  30. * Dynamic Globals. There should be as few of these as possible.
  31. *
  32. * All access to dynamic globals must be thread-safe.
  33. *
  34. *****************************************************************************/
  35. LONG g_cRef = 0; /* Global reference count */
  36. CRITICAL_SECTION g_crst; /* Global critical section */
  37. /*****************************************************************************
  38. *
  39. * DllAddRef / DllRelease
  40. *
  41. * Adjust the DLL reference count.
  42. *
  43. *****************************************************************************/
  44. STDAPI_(ULONG)
  45. DllAddRef(void)
  46. {
  47. return (ULONG)InterlockedIncrement((LPLONG)&g_cRef);
  48. }
  49. STDAPI_(ULONG)
  50. DllRelease(void)
  51. {
  52. return (ULONG)InterlockedDecrement((LPLONG)&g_cRef);
  53. }
  54. /*****************************************************************************
  55. *
  56. * @doc INTERNAL
  57. *
  58. * @func void | DllEnterCrit |
  59. *
  60. * Take the DLL critical section.
  61. *
  62. * The DLL critical section is the lowest level critical section.
  63. * You may not attempt to acquire any other critical sections or
  64. * yield while the DLL critical section is held. Failure to
  65. * comply is a violation of the semaphore hierarchy and will
  66. * lead to deadlocks.
  67. *
  68. *****************************************************************************/
  69. void EXTERNAL
  70. DllEnterCrit_(LPCTSTR lptszFile, UINT line)
  71. {
  72. #ifdef DEBUG
  73. if( ! TryEnterCriticalSection_(&g_crst) )
  74. {
  75. SquirtSqflPtszV(sqflCrit, TEXT("Dll CritSec blocked @%s,%d"), lptszFile, line);
  76. EnterCriticalSection(&g_crst);
  77. }
  78. if (g_cCrit++ == 0) {
  79. g_thidCrit = GetCurrentThreadId();
  80. SquirtSqflPtszV(sqflCrit, TEXT("Dll CritSec Entered @%s,%d"), lptszFile, line);
  81. }
  82. AssertF(g_thidCrit == GetCurrentThreadId());
  83. #else
  84. EnterCriticalSection(&g_crst);
  85. #endif
  86. }
  87. /*****************************************************************************
  88. *
  89. * @doc INTERNAL
  90. *
  91. * @func void | DllLeaveCrit |
  92. *
  93. * Leave the DLL critical section.
  94. *
  95. *****************************************************************************/
  96. void EXTERNAL
  97. DllLeaveCrit_(LPCTSTR lptszFile, UINT line)
  98. {
  99. #ifdef DEBUG
  100. AssertF(g_thidCrit == GetCurrentThreadId());
  101. AssertF(g_cCrit >= 0);
  102. if (--g_cCrit < 0) {
  103. g_thidCrit = 0;
  104. }
  105. SquirtSqflPtszV(sqflCrit, TEXT("Dll CritSec Leaving @%s,%d"), lptszFile, line);
  106. #endif
  107. LeaveCriticalSection(&g_crst);
  108. }
  109. /*****************************************************************************
  110. *
  111. * @doc INTERNAL
  112. *
  113. * @func void | DllInCrit |
  114. *
  115. * Nonzero if we are in the DLL critical section.
  116. *
  117. *****************************************************************************/
  118. #ifdef DEBUG
  119. BOOL INTERNAL
  120. DllInCrit(void)
  121. {
  122. return g_cCrit >= 0 && g_thidCrit == GetCurrentThreadId();
  123. }
  124. #endif
  125. /*****************************************************************************
  126. *
  127. * DllGetClassObject
  128. *
  129. * OLE entry point. Produces an IClassFactory for the indicated GUID.
  130. *
  131. *****************************************************************************/
  132. STDAPI
  133. DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
  134. {
  135. HRESULT hres;
  136. if (IsEqualGUID(rclsid, &IID_IDirectInputPIDDriver)) {
  137. hres = CClassFactory_New(riid, ppvObj);
  138. } else {
  139. *ppvObj = 0;
  140. hres = CLASS_E_CLASSNOTAVAILABLE;
  141. }
  142. return hres;
  143. }
  144. /*****************************************************************************
  145. *
  146. * DllCanUnloadNow
  147. *
  148. * OLE entry point. Fail iff there are outstanding refs.
  149. *
  150. *****************************************************************************/
  151. STDAPI
  152. DllCanUnloadNow(void)
  153. {
  154. return g_cRef ? S_FALSE : S_OK;
  155. }
  156. /*****************************************************************************
  157. *
  158. * DllNameFromGuid
  159. *
  160. * Create the string version of a GUID.
  161. *
  162. *****************************************************************************/
  163. STDAPI_(void)
  164. DllNameFromGuid(LPTSTR ptszBuf, LPCGUID pguid)
  165. {
  166. wsprintf(ptszBuf,
  167. TEXT("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  168. pguid->Data1, pguid->Data2, pguid->Data3,
  169. pguid->Data4[0], pguid->Data4[1],
  170. pguid->Data4[2], pguid->Data4[3],
  171. pguid->Data4[4], pguid->Data4[5],
  172. pguid->Data4[6], pguid->Data4[7]);
  173. }
  174. /*****************************************************************************
  175. *
  176. * @doc INTERNAL
  177. *
  178. * @func BOOL | FakeCancelIO |
  179. *
  180. * Stub function which doesn't do anything but
  181. * keeps us from crashing.
  182. *
  183. * @parm HANDLE | h |
  184. *
  185. * The handle whose I/O is supposed to be cancelled.
  186. *
  187. *****************************************************************************/
  188. BOOL WINAPI
  189. FakeCancelIO(HANDLE h)
  190. {
  191. AssertF(0);
  192. return FALSE;
  193. }
  194. /*****************************************************************************
  195. *
  196. * @doc INTERNAL
  197. *
  198. * @func BOOL | FakeTryEnterCriticalSection |
  199. *
  200. * We use TryEnterCriticalSection in DEBUG to detect deadlock
  201. * If the function does not exist, just enter CritSection and report
  202. * true. This compromises some debug functionality.
  203. *
  204. * @parm LPCRITICAL_SECTION | lpCriticalSection |
  205. *
  206. * Address of Critical Section to be entered.
  207. *
  208. *****************************************************************************/
  209. BOOL WINAPI
  210. FakeTryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
  211. {
  212. EnterCriticalSection(lpCriticalSection);
  213. return TRUE;
  214. }
  215. /*****************************************************************************
  216. *
  217. * DllOnProcessAttach
  218. *
  219. * Initialize the DLL.
  220. *
  221. *****************************************************************************/
  222. STDAPI_(BOOL)
  223. DllOnProcessAttach(HINSTANCE hinst)
  224. {
  225. TCHAR tszName[256];
  226. HINSTANCE hinstK32;
  227. TCHAR c_tszKernel32[] = TEXT("KERNEL32");
  228. // Cache the instance handle
  229. g_hinst = hinst;
  230. hinstK32 = GetModuleHandle( c_tszKernel32 );
  231. if(hinstK32 != INVALID_HANDLE_VALUE)
  232. {
  233. CANCELIO tmp;
  234. TRYENTERCRITICALSECTION tmpCrt;
  235. tmp = (CANCELIO)GetProcAddress(hinstK32, "CancelIo");
  236. if (tmp) {
  237. CancelIo_ = tmp;
  238. } else {
  239. AssertF(CancelIo_ == FakeCancelIO);
  240. }
  241. tmpCrt = (TRYENTERCRITICALSECTION)GetProcAddress(hinstK32, "TryEnterCriticalSection");
  242. if(tmpCrt)
  243. {
  244. TryEnterCriticalSection_ = tmpCrt;
  245. }else
  246. {
  247. AssertF(TryEnterCriticalSection_ == FakeTryEnterCriticalSection);
  248. }
  249. }
  250. #ifdef DEBUG
  251. Sqfl_Init();
  252. #endif
  253. /*
  254. * Performance tweak: We do not need thread notifications.
  255. */
  256. DisableThreadLibraryCalls(hinst);
  257. /*
  258. * !!IHV!! Initialize your DLL here.
  259. */
  260. __try
  261. {
  262. InitializeCriticalSection(&g_crst);
  263. }
  264. __except( EXCEPTION_EXECUTE_HANDLER )
  265. {
  266. return FALSE; // usually out of memory condition
  267. }
  268. /*
  269. * Create our mutex that protects the shared memory block.
  270. * If it already exists, then we get access to the one that
  271. * already exists.
  272. *
  273. * The name of the shared memory block is GUID_MyMutex.
  274. */
  275. DllNameFromGuid(tszName, &GUID_MyMutex);
  276. g_hmtxShared = CreateMutex(NULL, FALSE, tszName);
  277. if (g_hmtxShared == NULL) {
  278. return FALSE;
  279. }
  280. /*
  281. * Create our shared memory block. If it already exists,
  282. * then we get access to the one that already exists.
  283. * If it doesn't already exist, then it gets created
  284. * zero-filled (which is what we want anyway).
  285. *
  286. * The name of the shared memory block is GUID_MySharedMemory.
  287. */
  288. DllNameFromGuid(tszName, &GUID_MySharedMemory);
  289. g_hfm = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
  290. PAGE_READWRITE, 0,
  291. sizeof(SHAREDMEMORY),
  292. tszName);
  293. if (g_hfm == NULL) {
  294. CloseHandle(g_hmtxShared);
  295. g_hmtxShared = NULL;
  296. return FALSE;
  297. }
  298. g_pshmem = MapViewOfFile(g_hfm, FILE_MAP_WRITE | FILE_MAP_READ,
  299. 0, 0, 0);
  300. if (g_pshmem == NULL) {
  301. CloseHandle(g_hmtxShared);
  302. g_hmtxShared = NULL;
  303. CloseHandle(g_hfm);
  304. g_hfm = NULL;
  305. return FALSE;
  306. }
  307. return TRUE;
  308. }
  309. /*****************************************************************************
  310. *
  311. * DllOnProcessDetach
  312. *
  313. * De-initialize the DLL.
  314. *
  315. *****************************************************************************/
  316. STDAPI_(void)
  317. DllOnProcessDetach(void)
  318. {
  319. /*
  320. * !!IHV!! De-initialize your DLL here.
  321. */
  322. if (g_pshmem != NULL) {
  323. UnmapViewOfFile(g_pshmem);
  324. g_pshmem = NULL;
  325. }
  326. if (g_hfm != NULL) {
  327. CloseHandle(g_hfm);
  328. g_hfm = NULL;
  329. }
  330. if (g_hmtxShared != NULL) {
  331. CloseHandle(g_hmtxShared);
  332. g_hmtxShared = NULL;
  333. }
  334. DeleteCriticalSection(&g_crst);
  335. }
  336. /*****************************************************************************
  337. *
  338. * DllEntryPoint
  339. *
  340. * DLL entry point.
  341. *
  342. *****************************************************************************/
  343. STDAPI_(BOOL)
  344. DllEntryPoint(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
  345. {
  346. switch (dwReason) {
  347. case DLL_PROCESS_ATTACH:
  348. return DllOnProcessAttach(hinst);
  349. case DLL_PROCESS_DETACH:
  350. DllOnProcessDetach();
  351. break;
  352. }
  353. return 1;
  354. }