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.

2646 lines
91 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 1996 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dinputi.h
  6. * Content: DirectInput internal include file
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 1996.05.07 raymondc Lost a bet
  12. *
  13. *@@END_MSINTERNAL
  14. *
  15. ***************************************************************************/
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. /***************************************************************************
  20. *
  21. * Debug / RDebug / Retail
  22. *
  23. * If either DEBUG or RDEBUG, set XDEBUG.
  24. *
  25. * Retail defines nothing.
  26. *
  27. ***************************************************************************/
  28. #if defined(DEBUG) || defined(RDEBUG)
  29. #define XDEBUG
  30. #endif
  31. /***************************************************************************
  32. *
  33. * Turning off stuff...
  34. *
  35. * Turn off these things, because they confuse the bilingualism macros.
  36. * Instead, we call then IMumbleT.
  37. *
  38. ***************************************************************************/
  39. #undef IDirectInput
  40. #undef IDirectInput2
  41. #undef IDirectInput7
  42. #undef IDirectInputDevice
  43. #undef IDirectInputDevice2
  44. #undef IDirectInputDevice7
  45. /*
  46. * And <mmsystem.h> defines JOY_POVCENTERED incorrectly...
  47. */
  48. #undef JOY_POVCENTERED
  49. #define JOY_POVCENTERED 0xFFFFFFFF
  50. /*
  51. * And older versions of windows.h don't have this definition.
  52. */
  53. #ifndef HasOverlappedIoCompleted
  54. #define HasOverlappedIoCompleted(lpOverlapped) \
  55. ((lpOverlapped)->Internal != STATUS_PENDING)
  56. #endif
  57. /***************************************************************************
  58. *
  59. * Abbreviations....
  60. *
  61. * Give shorter names to things we talk about frequently.
  62. *
  63. ***************************************************************************/
  64. typedef LPDIRECTINPUT PDI , *PPDI ;
  65. typedef LPDIRECTINPUTA PDIA, *PPDIA;
  66. typedef LPDIRECTINPUTW PDIW, *PPDIW;
  67. typedef LPDIRECTINPUTDEVICE PDID , *PPDID ;
  68. typedef LPDIRECTINPUTDEVICEA PDIDA, *PPDIDA;
  69. typedef LPDIRECTINPUTDEVICEW PDIDW, *PPDIDW;
  70. typedef LPDIRECTINPUTEFFECT PDIE , *PPDIE ;
  71. typedef DIOBJECTDATAFORMAT ODF, *PODF;
  72. typedef const ODF *PCODF;
  73. typedef LPUNKNOWN PUNK;
  74. typedef LPVOID PV, *PPV;
  75. typedef CONST VOID *PCV;
  76. typedef REFIID RIID;
  77. typedef CONST GUID *PCGUID;
  78. /***************************************************************************
  79. *
  80. * GetProcAddress'd KERNEL32 and USER32 functions.
  81. *
  82. ***************************************************************************/
  83. typedef DWORD (WINAPI *OPENVXDHANDLE)(HANDLE);
  84. typedef BOOL (WINAPI *CANCELIO)(HANDLE);
  85. typedef DWORD (WINAPI *MSGWAITFORMULTIPLEOBJECTSEX)
  86. (DWORD, LPHANDLE, DWORD, DWORD, DWORD);
  87. typedef BOOL (WINAPI *TRYENTERCRITICALSECTION)(LPCRITICAL_SECTION);
  88. extern OPENVXDHANDLE _OpenVxDHandle;
  89. extern CANCELIO _CancelIO;
  90. extern MSGWAITFORMULTIPLEOBJECTSEX _MsgWaitForMultipleObjectsEx;
  91. #ifdef XDEBUG
  92. extern TRYENTERCRITICALSECTION _TryEnterCritSec;
  93. BOOL WINAPI FakeTryEnterCriticalSection(LPCRITICAL_SECTION lpCrit_sec);
  94. #endif
  95. DWORD WINAPI
  96. FakeMsgWaitForMultipleObjectsEx(DWORD, LPHANDLE, DWORD, DWORD, DWORD);
  97. BOOL WINAPI FakeCancelIO(HANDLE h);
  98. /***************************************************************************
  99. *
  100. * Our global variables - see dinput.c for documentation
  101. *
  102. ***************************************************************************/
  103. extern HINSTANCE g_hinst;
  104. #ifndef WINNT
  105. extern HANDLE g_hVxD;
  106. #endif
  107. extern DWORD g_flEmulation;
  108. extern LPDWORD g_pdwSequence;
  109. #ifdef USE_SLOW_LL_HOOKS
  110. extern HHOOK g_hhkLLHookCheck;
  111. #define g_fUseLLHooks ((BOOL)(UINT_PTR)g_hhkLLHookCheck)
  112. #endif
  113. extern HANDLE g_hmtxGlobal;
  114. extern HANDLE g_hfm;
  115. extern struct SHAREDOBJECTPAGE *g_psop;
  116. extern UINT g_wmJoyChanged;
  117. extern HANDLE g_hmtxJoy;
  118. extern HINSTANCE g_hinstRPCRT4;
  119. extern HINSTANCE g_hinstSetupapi;
  120. extern LONG g_lWheelGranularity;
  121. extern BOOL fWinnt; //whether we are running in Winnt
  122. extern BOOL g_fRawInput;
  123. #ifdef USE_WM_INPUT
  124. extern HWND g_hwndThread;
  125. extern HANDLE g_hEventAcquire;
  126. extern HANDLE g_hEventThread;
  127. extern HANDLE g_hEventHid;
  128. #endif
  129. #if (DIRECTINPUT_VERSION > 0x061A)
  130. typedef struct _DIAPPHACKS
  131. {
  132. BOOL fReacquire;
  133. BOOL fNoSubClass;
  134. BOOL fNativeAxisOnly;
  135. BOOL fNoPollUnacquire;
  136. BOOL fSucceedAcquire;
  137. int nMaxDeviceNameLength;
  138. DWORD dwDevType;
  139. } DIAPPHACKS, *LPDIAPPHACKS;
  140. #endif
  141. /*****************************************************************************
  142. *
  143. * Baggage
  144. *
  145. * Stuff I carry everywhere.
  146. *
  147. *****************************************************************************/
  148. #define INTERNAL NTAPI /* Called only within a translation unit */
  149. #define EXTERNAL NTAPI /* Called from other translation units */
  150. #define INLINE static __inline
  151. #define BEGIN_CONST_DATA data_seg(".text", "CODE")
  152. #define END_CONST_DATA data_seg(".data", "DATA")
  153. /*
  154. * Arithmetic on pointers.
  155. */
  156. #define pvSubPvCb(pv, cb) ((PV)((PBYTE)pv - (cb)))
  157. #define pvAddPvCb(pv, cb) ((PV)((PBYTE)pv + (cb)))
  158. #define cbSubPvPv(p1, p2) ((PBYTE)(p1) - (PBYTE)(p2))
  159. /*
  160. * Convert an object (X) to a count of bytes (cb).
  161. */
  162. #define cbX(X) sizeof(X)
  163. /*
  164. * Convert an array name (A) to a generic count (c).
  165. */
  166. #define cA(a) (cbX(a)/cbX(a[0]))
  167. /*
  168. * Convert a count of X's (cx) into a count of bytes
  169. * and vice versa.
  170. */
  171. #define cbCxX(cx, X) ((cx) * cbX(X))
  172. #define cxCbX(cb, X) ((cb) / cbX(X))
  173. /*
  174. * Convert a count of chars (cch), tchars (ctch), wchars (cwch),
  175. * or dwords (cdw) into a count of bytes, and vice versa.
  176. */
  177. #define cbCch(cch) cbCxX( cch, CHAR)
  178. #define cbCwch(cwch) cbCxX(cwch, WCHAR)
  179. #define cbCtch(ctch) cbCxX(ctch, TCHAR)
  180. #define cbCdw(cdw) cbCxX( cdw, DWORD)
  181. #define cchCb(cb) cxCbX(cb, CHAR)
  182. #define cwchCb(cb) cxCbX(cb, WCHAR)
  183. #define ctchCb(cb) cxCbX(cb, TCHAR)
  184. #define cdwCb(cb) cxCbX(cb, DWORD)
  185. /*
  186. * Zero an arbitrary buffer. It is a common error to get the second
  187. * and third parameters to memset backwards.
  188. */
  189. #define ZeroBuf(pv, cb) memset(pv, 0, cb)
  190. /*
  191. * Zero an arbitrary object.
  192. */
  193. #define ZeroX(x) ZeroBuf(&(x), cbX(x))
  194. /*
  195. * land -- Logical and. Evaluate the first. If the first is zero,
  196. * then return zero. Otherwise, return the second.
  197. */
  198. #define fLandFF(f1, f2) ((f1) ? (f2) : 0)
  199. /*
  200. * lor -- Logical or. Evaluate the first. If the first is nonzero,
  201. * return it. Otherwise, return the second.
  202. *
  203. * Unfortunately, due to the nature of the C language, this can
  204. * be implemented only with a GNU extension. In the non-GNU case,
  205. * we return 1 if the first is nonzero.
  206. */
  207. #if defined(__GNUC__)
  208. #define fLorFF(f1, f2) ((f1) ?: (f2))
  209. #else
  210. #define fLorFF(f1, f2) ((f1) ? 1 : (f2))
  211. #endif
  212. /*
  213. * limp - logical implication. True unless the first is nonzero and
  214. * the second is zero.
  215. */
  216. #define fLimpFF(f1, f2) (!(f1) || (f2))
  217. /*
  218. * leqv - logical equivalence. True if both are zero or both are nonzero.
  219. */
  220. #define fLeqvFF(f1, f2) (!(f1) == !(f2))
  221. /*
  222. * fInOrder - checks that i1 <= i2 < i3.
  223. */
  224. #define fInOrder(i1, i2, i3) ((unsigned)((i2)-(i1)) < (unsigned)((i3)-(i1)))
  225. /*
  226. * fHasAllBitsFlFl - checks that all bits in fl2 are set in fl1.
  227. */
  228. BOOL INLINE
  229. fHasAllBitsFlFl(DWORD fl1, DWORD fl2)
  230. {
  231. return (fl1 & fl2) == fl2;
  232. }
  233. /*
  234. * fEqualMask - checks that all masked bits are equal
  235. */
  236. BOOL INLINE
  237. fEqualMaskFlFl(DWORD flMask, DWORD fl1, DWORD fl2)
  238. {
  239. return ((fl1 ^ fl2) & flMask) == 0;
  240. }
  241. /*
  242. * Words to keep preprocessor happy.
  243. */
  244. #define comma ,
  245. #define empty
  246. /*
  247. * Atomically exchange one value for another.
  248. */
  249. #if defined(_M_IA64) || defined(_M_AMD64)
  250. #define InterlockedExchange64 _InterlockedExchange64
  251. #ifndef RC_INVOKED
  252. #pragma intrinsic(_InterlockedExchange64)
  253. #endif /*RC_INVOKED*/
  254. #define pvExchangePpvPv(ppv, pv) \
  255. InterlockedExchange((ppv), (pv))
  256. #define pvExchangePpvPv64(ppv, pv) \
  257. InterlockedExchange64((ppv), (pv))
  258. #else /*_M_IA64*/
  259. #define pvExchangePpvPv(ppv, pv) \
  260. (PV)InterlockedExchange((PLONG)(ppv), (LONG)(pv))
  261. #define pvExchangePpvPv64(ppv, pv) \
  262. (PV)InterlockedExchange((PLONG)(ppv), (LONG)(pv))
  263. #endif /*_M_IA64*/
  264. /*
  265. * Creating HRESULTs from a USHORT or from a LASTERROR.
  266. */
  267. #define hresUs(us) MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(us))
  268. #define hresLe(le) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, (USHORT)(le))
  269. /*
  270. * or a registry function return code
  271. */
  272. HRESULT INLINE
  273. hresReg( LONG lRc )
  274. {
  275. return( (lRc) ? MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, (USHORT)(lRc))
  276. : S_OK );
  277. }
  278. /***************************************************************************
  279. *
  280. * Debugging macros needed by inline functions
  281. *
  282. * The build of debugging goo is in debug.h
  283. *
  284. ***************************************************************************/
  285. int EXTERNAL AssertPtszPtszLn(LPCTSTR ptszExpr, LPCTSTR ptszFile, int iLine);
  286. #ifdef DEBUG
  287. #define AssertFPtsz(c, ptsz) \
  288. ((c) ? 0 : AssertPtszPtszLn(ptsz, TEXT(__FILE__), __LINE__))
  289. #define ValidateF(c, arg) \
  290. ((c) ? 0 : (RPF arg, ValidationException(), 0))
  291. #define ConfirmF(c) \
  292. ((c) ? 0 : AssertPtszPtszLn(TEXT(#c), TEXT(__FILE__), __LINE__))
  293. #else /* !DEBUG */
  294. #define AssertFPtsz(c, ptsz)
  295. #define ValidateF(c, arg)
  296. #define ConfirmF(c) (c)
  297. #endif
  298. /*
  299. * CAssertF - compile-time assertion.
  300. */
  301. #define CAssertF(c) switch(0) case c: case 0:
  302. #define AssertF(c) AssertFPtsz(c, TEXT(#c))
  303. /***************************************************************************
  304. *
  305. * Validation Code....
  306. *
  307. * "If it crashes in retail, it must crash in debug."
  308. *
  309. * What we don't want is an app that works fine under debug, but crashes
  310. * under retail.
  311. *
  312. * So if we find an invalid parameter in debug that would not have been
  313. * detected by retail, let it pass through after a warning. That way,
  314. * the invalid parameter continues onward through the system and creates
  315. * as much (or more) havoc in debug as it would under retail.
  316. *
  317. * There used to be _fFastValidXxx functions, but the decision was made
  318. * to do full validation always, except in inner-loop methods.
  319. *
  320. * The hresFullValidXxx functions return HRESULTs instead of BOOLs.
  321. *
  322. * Values for Xxx:
  323. *
  324. * Hwnd - hwnd = window handle
  325. * Pdw - pdw = pointer to a dword
  326. * PdwOut - pdw = pointer to a dword that will be set initially to 0
  327. * Pfn - pfn = function pointer
  328. * riid - riid = pointer to IID
  329. * guid - pguid = pointer to GUID
  330. * Esc - pesc = pointer to DIEFFESCAPE
  331. *
  332. * ReadPx - p -> structure for reading, X = structure name
  333. * WritePx - p -> structure for writing, X = structure name
  334. *
  335. * ReadPxCb - p -> structure for reading, X = structure name
  336. * first field of structure is dwSize which must be
  337. * equal to cbX(X).
  338. *
  339. * WritePxCb - p -> structure for writing, X = structure name
  340. * first field of structure is dwSize which must be
  341. * equal to cbX(X).
  342. *
  343. * WritePxCb2 - p -> structure for writing, X = structure name
  344. * first field of structure is dwSize which must be
  345. * equal to cbX(X) or cbX(X2).
  346. *
  347. * ReadPvCb - p -> buffer, cb = size of buffer
  348. * WritePvCb - p -> buffer, cb = size of buffer
  349. *
  350. * Pobj - p -> internal interface
  351. *
  352. * fl - fl = incoming flags, flV = valid flags
  353. *
  354. ***************************************************************************/
  355. #ifndef XDEBUG
  356. /*
  357. * Wrappers that throw away the szProc and iarg info.
  358. */
  359. #define hresFullValidHwnd_(hwnd, z, i) \
  360. _hresFullValidHwnd_(hwnd) \
  361. #define hresFullValidPcbOut_(pdw, cb, z, i) \
  362. _hresFullValidPcbOut_(pdw, cb) \
  363. #define hresFullValidReadPxCb_(pv, cb, pszProc, iarg) \
  364. _hresFullValidReadPxCb_(pv, cb) \
  365. #define hresFullValidReadPvCb_(pv, cb, pszProc, iarg) \
  366. _hresFullValidReadPvCb_(pv, cb) \
  367. #define hresFullValidWritePxCb_(pv, cb, pszProc, iarg) \
  368. _hresFullValidWritePxCb_(pv, cb) \
  369. #define hresFullValidWriteNoScramblePxCb_(pv, cb, pszProc, iarg)\
  370. _hresFullValidWriteNoScramblePxCb_(pv, cb) \
  371. #define hresFullValidWritePvCb_(pv, cb, pszProc, iarg) \
  372. _hresFullValidWritePvCb_(pv, cb) \
  373. #define hresFullValidFl_(fl, flV, pszProc, iarg) \
  374. _hresFullValidFl_(fl, flV) \
  375. #define hresFullValidPfn_(pfn, pszProc, iarg) \
  376. _hresFullValidPfn_(pfn) \
  377. #define hresFullValidPitf_(punk, pszProc, iarg) \
  378. _hresFullValidPitf_(punk) \
  379. #define hresFullValidReadStrA_(psz, cch, pszProc, iarg) \
  380. _hresFullValidReadStrA_(psz, cch) \
  381. #define hresFullValidReadStrW_(pwsz, cwch, pszProc, iarg) \
  382. _hresFullValidReadStrW_(pwsz, cwch) \
  383. #define hresFullValidHwnd0_(hwnd, pszProc, iarg) \
  384. _hresFullValidHwnd0_(hwnd) \
  385. #define hresFullValidPitf0_(punk, pszProc, iarg) \
  386. _hresFullValidPitf0_(punk) \
  387. #define hresFullValidPesc_(pesc, pszProc, iarg) \
  388. _hresFullValidPesc_(pesc) \
  389. #endif
  390. /*
  391. * The actual functions.
  392. */
  393. STDMETHODIMP hresFullValidHwnd_(HWND hwnd, LPCSTR pszProc, int iarg);
  394. STDMETHODIMP hresFullValidPcbOut_(PV pdw, UINT cb, LPCSTR pszProc, int iarg);
  395. STDMETHODIMP hresFullValidReadPxCb_(PCV pv, UINT cb, LPCSTR pszProc, int iarg);
  396. STDMETHODIMP hresFullValidReadPvCb_(PCV pv, UINT cb, LPCSTR pszProc, int iarg);
  397. STDMETHODIMP hresFullValidWritePxCb_(PV pv, UINT cb, LPCSTR pszProc, int iarg);
  398. STDMETHODIMP hresFullValidWritePvCb_(PV pv, UINT cb, LPCSTR pszProc, int iarg);
  399. STDMETHODIMP hresFullValidFl_(DWORD fl, DWORD flV, LPCSTR pszProc, int iarg);
  400. STDMETHODIMP hresFullValidPfn_(FARPROC pfn, LPCSTR pszProc, int iarg);
  401. STDMETHODIMP hresFullValidPitf_(PUNK punk, LPCSTR pszProc, int iarg);
  402. STDMETHODIMP hresFullValidReadStrA_(LPCSTR psz, UINT cch,
  403. LPCSTR s_szProc, int iarg);
  404. STDMETHODIMP hresFullValidReadStrW_(LPCWSTR pwsz, UINT cwch,
  405. LPCSTR pszProc, int iarg);
  406. STDMETHODIMP hresFullValidPesc_(LPDIEFFESCAPE pesc, LPCSTR pszProc, int iarg);
  407. #ifdef XDEBUG
  408. STDMETHODIMP
  409. hresFullValidWriteNoScramblePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg);
  410. #define hresFullValidWriteNoScramblePvCb_(pv, cb, pszProc, iarg) \
  411. hresFullValidWritePvCb_(pv, cb, pszProc, MAKELONG(iarg, 1)) \
  412. #else
  413. /*
  414. * Retail doesn't scramble.
  415. */
  416. #define _hresFullValidWriteNoScramblePxCb_ \
  417. _hresFullValidWritePxCb_ \
  418. #define hresFullValidWriteNoScramblePvCb_ \
  419. hresFullValidWritePvCb_ \
  420. #endif
  421. HRESULT INLINE
  422. hresFullValidHwnd0_(HWND hwnd, LPCSTR pszProc, int iarg)
  423. {
  424. HRESULT hres;
  425. if(hwnd)
  426. {
  427. hres = hresFullValidHwnd_(hwnd, pszProc, iarg);
  428. } else
  429. {
  430. hres = S_OK;
  431. }
  432. return hres;
  433. }
  434. HRESULT INLINE
  435. hresFullValidPitf0_(PUNK punk, LPCSTR pszProc, int iarg)
  436. {
  437. HRESULT hres;
  438. if(punk)
  439. {
  440. hres = hresFullValidPitf_(punk, pszProc, iarg);
  441. } else
  442. {
  443. hres = S_OK;
  444. }
  445. return hres;
  446. }
  447. /*
  448. * Wrappers for derived types.
  449. */
  450. #define hresFullValidRiid_(riid, s_szProc, iarg) \
  451. hresFullValidReadPvCb_(riid, cbX(IID), s_szProc, iarg) \
  452. /*
  453. * Wrapers that add the szProc and iarg info.
  454. */
  455. #define hresFullValidHwnd(hwnd, iarg) \
  456. hresFullValidHwnd_(hwnd, s_szProc, iarg) \
  457. #define hresFullValidPcbOut(pdw, cb, i) \
  458. hresFullValidPcbOut_(pdw, cb, s_szProc, i) \
  459. #define hresFullValidReadPdw_(pdw, z, i) \
  460. hresFullValidReadPvCb_(pdw, cbX(DWORD), z, i) \
  461. #define hresFullValidRiid(riid, iarg) \
  462. hresFullValidRiid_(riid, s_szProc, iarg) \
  463. #define hresFullValidGuid(pguid, iarg) \
  464. hresFullValidReadPvCb_(pguid, cbX(GUID), s_szProc, iarg) \
  465. #define hresFullValidReadPxCb(pv, X, iarg) \
  466. hresFullValidReadPxCb_(pv, cbX(X), s_szProc, iarg) \
  467. #define hresFullValidReadPxCb2(pv, X, X2, iarg) \
  468. hresFullValidReadPxCb_(pv, MAKELONG(cbX(X), cbX(X2)), \
  469. s_szProc, iarg) \
  470. #define hresFullValidReadPvCb(pv, cb, iarg) \
  471. hresFullValidReadPvCb_(pv, cb, s_szProc, iarg) \
  472. #define hresFullValidReadPx(pv, X, iarg) \
  473. hresFullValidReadPvCb_(pv, cbX(X), s_szProc, iarg) \
  474. #define hresFullValidWritePxCb(pv, X, iarg) \
  475. hresFullValidWritePxCb_(pv, cbX(X), s_szProc, iarg) \
  476. #define hresFullValidWritePxCb2(pv, X, X2, iarg) \
  477. hresFullValidWritePxCb_(pv, MAKELONG(cbX(X), cbX(X2)), \
  478. s_szProc, iarg) \
  479. #define hresFullValidWriteNoScramblePxCb(pv, X, iarg) \
  480. hresFullValidWriteNoScramblePxCb_(pv, cbX(X), s_szProc, iarg)\
  481. #define hresFullValidWriteNoScramblePxCb2(pv, X, X2, iarg) \
  482. hresFullValidWriteNoScramblePxCb_(pv, MAKELONG(cbX(X), cbX(X2)),\
  483. s_szProc, iarg)\
  484. #define hresFullValidWritePvCb(pv, cb, iarg) \
  485. hresFullValidWritePvCb_(pv, cb, s_szProc, iarg) \
  486. #define hresFullValidWriteNoScramblePvCb(pv, cb, iarg) \
  487. hresFullValidWriteNoScramblePvCb_(pv, cb, s_szProc, iarg) \
  488. #define hresFullValidWritePx(pv, X, iarg) \
  489. hresFullValidWritePvCb_(pv, cbX(X), s_szProc, iarg) \
  490. #define hresFullValidReadPdw(pdw, iarg) \
  491. hresFullValidReadPdw_(pdw, s_szProc, iarg) \
  492. #define hresFullValidWritePguid(pguid, iarg) \
  493. hresFullValidWritePx(pguid, GUID, iarg) \
  494. #define hresFullValidFl(fl, flV, iarg) \
  495. hresFullValidFl_(fl, flV, s_szProc, iarg) \
  496. #define hresFullValidPfn(pfn, iarg) \
  497. hresFullValidPfn_((FARPROC)(pfn), s_szProc, iarg) \
  498. #define hresFullValidPitf(pitf, iarg) \
  499. hresFullValidPitf_((PUNK)(pitf), s_szProc, iarg) \
  500. #define hresFullValidReadStrA(psz, cch, iarg) \
  501. hresFullValidReadStrA_(psz, cch, s_szProc, iarg) \
  502. #define hresFullValidReadStrW(pwsz, cwch, iarg) \
  503. hresFullValidReadStrW_(pwsz, cwch, s_szProc, iarg) \
  504. #define hresFullValidHwnd0(hwnd, iarg) \
  505. hresFullValidHwnd0_(hwnd, s_szProc, iarg) \
  506. #define hresFullValidPitf0(pitf, iarg) \
  507. hresFullValidPitf0_((PUNK)(pitf), s_szProc, iarg) \
  508. #define hresFullValidPesc(pesc, iarg) \
  509. hresFullValidPesc_(pesc, s_szProc, iarg) \
  510. /*****************************************************************************
  511. *
  512. * @doc INTERNAL
  513. *
  514. * @func void | ValidationException |
  515. *
  516. * Raises a parameter validation exception in XDEBUG.
  517. *
  518. *****************************************************************************/
  519. #define ecValidation (ERROR_SEVERITY_ERROR | hresLe(ERROR_INVALID_PARAMETER))
  520. #ifdef XDEBUG
  521. #define ValidationException() RaiseException(ecValidation, 0, 0, 0)
  522. #else
  523. #define ValidationException()
  524. #endif
  525. /*****************************************************************************
  526. *
  527. * Bilingualism
  528. *
  529. * Special macros that help writing ANSI and UNICODE versions of
  530. * the same underlying interface.
  531. *
  532. *****************************************************************************/
  533. /*
  534. * _THAT is something you tack onto the end of a "bilingual" interface.
  535. * In debug, it expands to the magic third argument which represents
  536. * the vtbl the object should have. In retail, it expands to nothing.
  537. */
  538. #ifdef XDEBUG
  539. #define _THAT , PV vtblExpected
  540. #define THAT_ , vtblExpected
  541. #else
  542. #define _THAT
  543. #define THAT_
  544. #endif
  545. /*
  546. * CSET_STUBS creates stubs for ANSI and UNICODE versions of the
  547. * same procedure that is not character set-sensitive.
  548. *
  549. * mf - method function name
  550. * arg1 - argument list in prototype form
  551. * arg2 - argument list for calling (with _riid appended).
  552. *
  553. * It is assumed that the caller has already defined the symbols
  554. * ThisClass and ThisInterface[AWT]. If a "2" interface is involved,
  555. * then also define ThisInterface2.
  556. *
  557. * This macro should be used only in DEBUG. In retail, the common
  558. * procedure handles both character sets directly.
  559. */
  560. #ifdef XDEBUG
  561. #define CSET_STUBS(mf, arg1, arg2) \
  562. CSET_STUB(TFORM, mf, arg1, arg2) \
  563. CSET_STUB(SFORM, mf, arg1, arg2) \
  564. #define CSET_STUB(FORM, mf, arg1, arg2) \
  565. _CSET_STUB(FORM, mf, arg1, arg2, ThisClass, ThisInterface) \
  566. #define _CSET_STUB(FORM, mf, arg1, arg2, cls, itf) \
  567. __CSET_STUB(FORM, mf, arg1, arg2, cls, itf) \
  568. #define __CSET_STUB(FORM, mf, arg1, arg2, cls, itf) \
  569. STDMETHODIMP \
  570. FORM(cls##_##mf) arg1 \
  571. { \
  572. PV vtblExpected = Class_Vtbl(ThisClass, FORM(ThisInterfaceT)); \
  573. return cls##_##mf arg2; \
  574. } \
  575. #define CSET_STUBS2(mf, arg1, arg2) \
  576. CSET_STUB2(TFORM, mf, arg1, arg2) \
  577. CSET_STUB2(SFORM, mf, arg1, arg2) \
  578. #define CSET_STUB2(FORM, mf, arg1, arg2) \
  579. _CSET_STUB2(FORM, mf, arg1, arg2, ThisClass, ThisInterface2) \
  580. #define _CSET_STUB2(FORM, mf, arg1, arg2, cls, itf) \
  581. __CSET_STUB2(FORM, mf, arg1, arg2, cls, itf) \
  582. #define __CSET_STUB2(FORM, mf, arg1, arg2, cls, itf) \
  583. STDMETHODIMP \
  584. FORM(cls##_##mf##2) arg1 \
  585. { \
  586. PV vtblExpected = Class_Vtbl(ThisClass, FORM(ThisInterface2T)); \
  587. return cls##_##mf arg2; \
  588. } \
  589. #endif
  590. /*
  591. * TFORM(x) expands to x##A if ANSI or x##W if UNICODE.
  592. * This T-izes a symbol, in the sense of TCHAR or PTSTR.
  593. *
  594. * SFORM(x) expands to x##W if ANSI or x##A if UNICODE.
  595. * This anti-T-izes a symbol.
  596. */
  597. #ifdef UNICODE
  598. #define _TFORM(x) x##W
  599. #define _SFORM(x) x##A
  600. #else
  601. #define _TFORM(x) x##A
  602. #define _SFORM(x) x##W
  603. #endif
  604. #define TFORM(x) _TFORM(x)
  605. #define SFORM(x) _SFORM(x)
  606. #ifdef UNICODE
  607. typedef CHAR SCHAR;
  608. #else
  609. typedef WCHAR SCHAR;
  610. #endif
  611. typedef SCHAR * LPSSTR;
  612. typedef const SCHAR * LPCSSTR;
  613. /*
  614. * SToT(dst, cchDst, src) - convert S to T
  615. * TToS(dst, cchDst, src) - convert T to S
  616. *
  617. * Remember, "T" means "ANSI if ANSI, or UNICODE if UNICODE",
  618. * and "S" is the anti-T.
  619. *
  620. * So SToT converts to the preferred character set, and TToS converts
  621. * to the alternate character set.
  622. *
  623. */
  624. #define AToU(dst, cchDst, src) \
  625. MultiByteToWideChar(CP_ACP, 0, src, -1, dst, cchDst)
  626. #define UToA(dst, cchDst, src) \
  627. WideCharToMultiByte(CP_ACP, 0, src, -1, dst, cchDst, 0, 0)
  628. #ifdef UNICODE
  629. #define SToT AToU
  630. #define TToS UToA
  631. #define AToT AToU
  632. #define TToU(dst, cchDst, src) lstrcpyn(dst, src, cchDst)
  633. #define UToT(dst, cchDst, src) lstrcpyn(dst, src, cchDst)
  634. #else
  635. #define SToT UToA
  636. #define TToS AToU
  637. #define AToT(dst, cchDst, src) lstrcpyn(dst, src, cchDst)
  638. #define TToU AToU
  639. #define UToT UToA
  640. #endif
  641. /*****************************************************************************
  642. *
  643. * Unicode wrappers for Win95
  644. *
  645. *****************************************************************************/
  646. #ifndef UNICODE
  647. #define LoadStringW _LoadStringW
  648. int EXTERNAL LoadStringW(HINSTANCE hinst, UINT ids, LPWSTR pwsz, int cwch);
  649. #define RegDeleteKeyW _RegDeleteKeyW
  650. LONG EXTERNAL RegDeleteKeyW(HKEY hk, LPCWSTR pwsz);
  651. #endif
  652. /*****************************************************************************
  653. *
  654. * Registry access functions
  655. *
  656. *****************************************************************************/
  657. //our own version of KEY_ALL_ACCESS, that does not use WRITE_DAC and WRITE_OWNER (see Whistler bug 318865)
  658. #define DI_DAC_OWNER (WRITE_DAC | WRITE_OWNER)
  659. #define DI_KEY_ALL_ACCESS (KEY_ALL_ACCESS & ~DI_DAC_OWNER)
  660. LONG EXTERNAL
  661. RegQueryString(HKEY hk, LPCTSTR ptszValue, LPTSTR ptszBuf, DWORD ctchBuf);
  662. LONG EXTERNAL RegQueryStringValueW(HKEY hk, LPCTSTR ptszValue,
  663. LPWSTR pwszBuf, LPDWORD pcbBuf);
  664. LONG EXTERNAL RegSetStringValueW(HKEY hk, LPCTSTR ptszValue, LPCWSTR pwszBuf);
  665. DWORD EXTERNAL RegQueryDIDword(LPCTSTR ptszPath, LPCTSTR ptszValue, DWORD dwDefault);
  666. STDMETHODIMP
  667. hresMumbleKeyEx(HKEY hk, LPCTSTR ptszKey, REGSAM sam, DWORD dwOptions, PHKEY phk);
  668. STDMETHODIMP
  669. hresRegCopyValues( HKEY hkSrc, HKEY hkDest );
  670. STDMETHODIMP
  671. hresRegCopyKey( HKEY hkSrcRoot, PTCHAR szSrcName, PTCHAR szClass, HKEY hkDestRoot, PTCHAR szDestName, HKEY *phkSub );
  672. STDMETHODIMP
  673. hresRegCopyKeys( HKEY hkSrc, HKEY hkRoot, PDWORD OPTIONAL pMaxNameLen );
  674. STDMETHODIMP
  675. hresRegCopyBranch( HKEY hkSrc, HKEY hkDest );
  676. /*****************************************************************************
  677. *
  678. * Common Object Managers for the Component Object Model
  679. *
  680. * OLE wrapper macros and structures. For more information, see
  681. * the beginning of common.c
  682. *
  683. *****************************************************************************/
  684. /*****************************************************************************
  685. *
  686. * Pre-vtbl structures
  687. *
  688. * Careful! If you change these structures, you must also adjust
  689. * common.c accordingly.
  690. *
  691. *****************************************************************************/
  692. typedef struct PREVTBL
  693. { /* Shared vtbl prefix */
  694. RIID riid; /* Type of this object */
  695. LONG lib; /* offset from start of object */
  696. } PREVTBL, *PPREVTBL;
  697. typedef struct PREVTBLP
  698. { /* Prefix for primary vtbl */
  699. #ifdef DEBUG
  700. LPCTSTR tszClass; /* Class name (for squirties) */
  701. #endif
  702. PPV rgvtbl; /* Array of standard vtbls */
  703. UINT cbvtbl; /* Size of vtbl array in bytes */
  704. STDMETHOD(QIHelper)(PV pv, RIID riid, PPV ppvOut); /* QI helper */
  705. STDMETHOD_(void,AppFinalizeProc)(PV pv);/* App finalization procedure */
  706. STDMETHOD_(void,FinalizeProc)(PV pv);/* Finalization procedure */
  707. PREVTBL prevtbl; /* lib must be zero */
  708. } PREVTBLP, *PPREVTBLP;
  709. /*
  710. * A fuller implementation is in common.c. Out here, we need only
  711. * concern ourselves with getting to the primary interface.
  712. */
  713. #define _thisPv(pitf) \
  714. pvSubPvCb(pitf, (*(PPREVTBL*)(pitf))[-1].lib)
  715. #define _thisPvNm(pitf, nm) \
  716. pvSubPvCb(pitf, FIELD_OFFSET(ThisClass, nm)) \
  717. #ifndef XDEBUG
  718. #define hresPvVtbl_(pv, vtbl, pszProc) \
  719. _hresPvVtbl_(pv, vtbl) \
  720. #define hresPvVtbl2_(pv, vtbl, vtbl2, pszProc) \
  721. _hresPvVtbl2_(pv, vtbl, vtbl2) \
  722. #endif
  723. HRESULT EXTERNAL
  724. hresPvVtbl_(PV pv, PV vtbl, LPCSTR pszProc);
  725. HRESULT EXTERNAL
  726. hresPvVtbl2_(PV pv, PV vtbl, PV vtbl2, LPCSTR pszProc);
  727. #define hresPvVtbl(pv, vtbl) \
  728. hresPvVtbl_(pv, vtbl, s_szProc) \
  729. #define hresPvVtbl2(pv, vtbl, vtbl2) \
  730. hresPvVtbl2_(pv, vtbl, vtbl2, s_szProc) \
  731. #define hresPvI(pv, I) \
  732. hresPvVtbl(pv, Class_Vtbl(ThisClass, I)) \
  733. #define hresPv2I(pv, I, I2) \
  734. hresPvVtbl2(pv, Class_Vtbl(ThisClass, I), Class_Vtbl(ThisClass, I2)) \
  735. #define hresPv(pv) \
  736. hresPvI(pv, ThisInterface) \
  737. #define hresPvA(pv) \
  738. hresPvI(pv, ThisInterfaceA) \
  739. #define hresPvW(pv) \
  740. hresPvI(pv, ThisInterfaceW) \
  741. #define hresPv2A(pv) \
  742. hresPv2I(pv, ThisInterfaceA, ThisInterface2A) \
  743. #define hresPv2W(pv) \
  744. hresPv2I(pv, ThisInterfaceW, ThisInterface2W) \
  745. #ifdef XDEBUG
  746. #define hresPvT(pv) \
  747. hresPvVtbl(pv, vtblExpected) \
  748. #else
  749. #define hresPvT(pv) \
  750. hresPv(pv) \
  751. #endif
  752. /*****************************************************************************
  753. *
  754. * Declaring interfaces
  755. *
  756. * The extra level of indirection on _Primary_Interface et al
  757. * allow the interface name to be a macro which expands to the
  758. * *real* name of the interface.
  759. *
  760. *****************************************************************************/
  761. #define __Class_Vtbl(C, I) &c_##I##_##C##VI.vtbl
  762. #define _Class_Vtbl(C, I) __Class_Vtbl(C, I)
  763. #define Class_Vtbl(C, I) _Class_Vtbl(C, I)
  764. #define Num_Interfaces(C) cA(c_rgpv##C##Vtbl)
  765. #ifdef DEBUG
  766. #define Simple_Interface(C) Primary_Interface(C, IUnknown); \
  767. Default_QueryInterface(C) \
  768. Default_AddRef(C) \
  769. Default_Release(C)
  770. #define Simple_Vtbl(C) Class_Vtbl(C)
  771. #define Simple_Interface_Begin(C) Primary_Interface_Begin(C, IUnknown)
  772. #define Simple_Interface_End(C) Primary_Interface_End(C, IUnknown)
  773. #else
  774. #define Simple_Interface(C) Primary_Interface(C, IUnknown)
  775. #define Simple_Vtbl(C) Class_Vtbl(C)
  776. #define Simple_Interface_Begin(C) \
  777. struct S_##C##Vtbl c_##I##_##C##VI = { { \
  778. c_rgpv##C##Vtbl, \
  779. cbX(c_rgpv##C##Vtbl), \
  780. C##_QIHelper, \
  781. C##_AppFinalize, \
  782. C##_Finalize, \
  783. { &IID_##IUnknown, 0 }, \
  784. }, { \
  785. Common##_QueryInterface, \
  786. Common##_AddRef, \
  787. Common##_Release, \
  788. #define Simple_Interface_End(C) \
  789. } }; \
  790. #endif
  791. #define _Primary_Interface(C, I) \
  792. extern struct S_##C##Vtbl { \
  793. PREVTBLP prevtbl; \
  794. I##Vtbl vtbl; \
  795. } c_##I##_##C##VI \
  796. #define Primary_Interface(C, I) \
  797. _Primary_Interface(C, I) \
  798. #ifdef DEBUG
  799. #define _Primary_Interface_Begin(C, I) \
  800. struct S_##C##Vtbl c_##I##_##C##VI = { { \
  801. TEXT(#C), \
  802. c_rgpv##C##Vtbl, \
  803. cbX(c_rgpv##C##Vtbl), \
  804. C##_QIHelper, \
  805. C##_AppFinalize, \
  806. C##_Finalize, \
  807. { &IID_##I, 0, }, \
  808. }, { \
  809. C##_QueryInterface, \
  810. C##_AddRef, \
  811. C##_Release, \
  812. #else
  813. #define _Primary_Interface_Begin(C, I) \
  814. struct S_##C##Vtbl c_##I##_##C##VI = { { \
  815. c_rgpv##C##Vtbl, \
  816. cbX(c_rgpv##C##Vtbl), \
  817. C##_QIHelper, \
  818. C##_AppFinalize, \
  819. C##_Finalize, \
  820. { &IID_##I, 0, }, \
  821. }, { \
  822. C##_QueryInterface, \
  823. C##_AddRef, \
  824. C##_Release, \
  825. #endif
  826. #define Primary_Interface_Begin(C, I) \
  827. _Primary_Interface_Begin(C, I) \
  828. #define Primary_Interface_End(C, I) \
  829. } }; \
  830. #define _Secondary_Interface(C, I) \
  831. extern struct S_##I##_##C##Vtbl { \
  832. PREVTBL prevtbl; \
  833. I##Vtbl vtbl; \
  834. } c_##I##_##C##VI \
  835. #define Secondary_Interface(C, I) \
  836. _Secondary_Interface(C, I) \
  837. /*
  838. * Secret backdoor for the "private" IUnknown in common.c
  839. */
  840. #define _Secondary_Interface_Begin(C, I, ofs, Pfx) \
  841. struct S_##I##_##C##Vtbl c_##I##_##C##VI = { { \
  842. &IID_##I, \
  843. ofs, \
  844. }, { \
  845. Pfx##QueryInterface, \
  846. Pfx##AddRef, \
  847. Pfx##Release, \
  848. #define Secondary_Interface_Begin(C, I, nm) \
  849. _Secondary_Interface_Begin(C, I, FIELD_OFFSET(C, nm), Common_) \
  850. #define _Secondary_Interface_End(C, I) \
  851. } }; \
  852. #define Secondary_Interface_End(C, I, nm) \
  853. _Secondary_Interface_End(C, I) \
  854. #define Interface_Template_Begin(C) \
  855. PV c_rgpv##C##Vtbl[] = { \
  856. #define Primary_Interface_Template(C, I) \
  857. Class_Vtbl(C, I), \
  858. #define Secondary_Interface_Template(C, I) \
  859. Class_Vtbl(C, I), \
  860. #define Interface_Template_End(C) \
  861. }; \
  862. STDMETHODIMP Common_QueryInterface(PV, RIID, PPV);
  863. STDMETHODIMP_(ULONG) Common_AddRef(PV pv);
  864. STDMETHODIMP_(ULONG) Common_Release(PV pv);
  865. STDMETHODIMP_(void) Common_Hold(PV pv);
  866. STDMETHODIMP_(void) Common_Unhold(PV pv);
  867. STDMETHODIMP Common_QIHelper(PV, RIID, PPV);
  868. void EXTERNAL Common_Finalize(PV);
  869. #define Common_AppFinalize Common_Finalize
  870. #ifndef XDEBUG
  871. #define _Common_New_(cb, punkOuter, vtbl, pvpObj, z) \
  872. __Common_New_(cb, punkOuter, vtbl, pvpObj) \
  873. #define _Common_NewRiid_(cb, vtbl, punkOuter, riid, pvpObj, z) \
  874. __Common_NewRiid_(cb, vtbl, punkOuter, riid, pvpObj) \
  875. #endif
  876. STDMETHODIMP
  877. _Common_New_(ULONG cb, PUNK punkOuter, PV vtbl, PPV ppvObj, LPCSTR s_szProc);
  878. STDMETHODIMP
  879. _Common_NewRiid_(ULONG cb, PV vtbl, PUNK punkOuter, RIID riid, PPV pvpObj,
  880. LPCSTR s_szProc);
  881. #define Common_NewCb(cb, C, punkOuter, ppvObj) \
  882. _Common_New_(cb, punkOuter, Class_Vtbl(C, ThisInterface), ppvObj, s_szProc)
  883. #define Common_New(C, punkOuter, ppvObj) \
  884. Common_NewCb(cbX(C), C, punkOuter, ppvObj) \
  885. #define Common_NewCbRiid(cb, C, punkOuter, riid, ppvObj) \
  886. _Common_NewRiid_(cb, Class_Vtbl(C, ThisInterface), punkOuter, riid, ppvObj, s_szProc)
  887. #define Common_NewRiid(C, punkOuter, riid, ppvObj) \
  888. _Common_NewRiid_(cbX(C), Class_Vtbl(C, ThisInterface), punkOuter, riid, ppvObj, s_szProc)
  889. #ifdef DEBUG
  890. PV EXTERNAL Common_IsType(PV pv);
  891. #else
  892. #define Common_IsType
  893. #endif
  894. #define Assert_CommonType Common_IsType
  895. STDMETHODIMP Forward_QueryInterface(PV pv, RIID riid, PPV ppvObj);
  896. STDMETHODIMP_(ULONG) Forward_AddRef(PV pv);
  897. STDMETHODIMP_(ULONG) Forward_Release(PV pv);
  898. void EXTERNAL Invoke_Release(PV pv);
  899. #define Common_DumpObjects()
  900. /*****************************************************************************
  901. *
  902. * OLE wrappers
  903. *
  904. * These basically do the same as IUnknown_Mumble, except that they
  905. * avoid side-effects in evaluation by being inline functions.
  906. *
  907. *****************************************************************************/
  908. HRESULT INLINE
  909. OLE_QueryInterface(PV pv, RIID riid, PPV ppvObj)
  910. {
  911. PUNK punk = pv;
  912. return punk->lpVtbl->QueryInterface(punk, riid, ppvObj);
  913. }
  914. ULONG INLINE
  915. OLE_AddRef(PV pv)
  916. {
  917. PUNK punk = pv;
  918. return punk->lpVtbl->AddRef(punk);
  919. }
  920. ULONG INLINE
  921. OLE_Release(PV pv)
  922. {
  923. PUNK punk = pv;
  924. return punk->lpVtbl->Release(punk);
  925. }
  926. /*****************************************************************************
  927. *
  928. * Macros that forward to the common handlers after squirting.
  929. * Use these only in DEBUG.
  930. *
  931. * It is assumed that sqfl has been #define'd to the appropriate sqfl.
  932. *
  933. *****************************************************************************/
  934. #ifdef DEBUG
  935. #define Default_QueryInterface(Class) \
  936. STDMETHODIMP \
  937. Class##_QueryInterface(PV pv, RIID riid, PPV ppvObj) \
  938. { \
  939. SquirtSqflPtszV(sqfl, TEXT(#Class) TEXT("_QueryInterface()")); \
  940. return Common_QueryInterface(pv, riid, ppvObj); \
  941. } \
  942. // 7/21/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  943. #define Default_AddRef(Class) \
  944. STDMETHODIMP_(ULONG) \
  945. Class##_AddRef(PV pv) \
  946. { \
  947. ULONG ulRc = Common_AddRef(pv); \
  948. SquirtSqflPtszV(sqfl, TEXT(#Class) \
  949. TEXT("_AddRef(%p) -> %d"), pv, ulRc); \
  950. return ulRc; \
  951. } \
  952. // 7/21/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  953. #define Default_Release(Class) \
  954. STDMETHODIMP_(ULONG) \
  955. Class##_Release(PV pv) \
  956. { \
  957. ULONG ulRc = Common_Release(pv); \
  958. SquirtSqflPtszV(sqfl, TEXT(#Class) \
  959. TEXT("_Release(%p) -> %d"), pv, ulRc); \
  960. return ulRc; \
  961. } \
  962. #endif
  963. /*****************************************************************************
  964. *
  965. * Paranoid callbacks
  966. *
  967. * Callback() performs a callback. The callback must accept exactly
  968. * two parameters, both pointers. (All our callbacks are like this.)
  969. * And it must return a BOOL.
  970. *
  971. *****************************************************************************/
  972. typedef BOOL (FAR PASCAL * DICALLBACKPROC)(LPVOID, LPVOID);
  973. #ifdef XDEBUG
  974. BOOL EXTERNAL Callback(DICALLBACKPROC, PVOID, PVOID);
  975. #else
  976. #define Callback(pec, pv1, pv2) pec(pv1, pv2)
  977. #endif
  978. #if 0
  979. /*****************************************************************************
  980. *
  981. * Groveling into a CONTEXT structure.
  982. *
  983. * This is used to check that a callback procedure is properly
  984. * prototyped. We save the stack register before calling the
  985. * procedure and compare it with the stack register on the way back.
  986. * If they are different, explode!
  987. *
  988. * ctxEsp is the name of the stack pointer register.
  989. *
  990. *****************************************************************************/
  991. typedef struct STACKINFO
  992. {
  993. CONTEXT ctxPre; /* Thread context before call */
  994. CONTEXT ctxPost; /* Thread context after call */
  995. } STACKINFO, *PSTACKINFO;
  996. #ifdef XDEBUG
  997. #if defined(_X86_)
  998. #define ctxEsp Esp
  999. #elif defined(_ALPHA_)
  1000. #define ctxEsp IntSp
  1001. #elif defined(_MIPS_)
  1002. #define ctxEsp IntSp
  1003. #elif defined(_PPC_)
  1004. #define ctxEsp Gpr1
  1005. #else
  1006. #pragma message("I don't know what the stack register is called on this platform")
  1007. #endif
  1008. #endif
  1009. #ifdef ctxEsp
  1010. #define DECLARE_STACKINFO() \
  1011. STACKINFO si \
  1012. #define PRE_CALLBACK() \
  1013. si.ctxPre.ContextFlags = CONTEXT_CONTROL; \
  1014. GetThreadContext(GetCurrentThread(), &si.ctxPre) \
  1015. #define POST_CALLBACK() \
  1016. si.ctxPost.ContextFlags = CONTEXT_CONTROL; \
  1017. if (GetThreadContext(GetCurrentThread(), &si.ctxPost) && \
  1018. si.ctxPre.ctxEsp != si.ctxPost.ctxEsp) { \
  1019. RPF("DINPUT: Incorrectly prototyped callback! Crash soon!"); \
  1020. ValidationException(); \
  1021. } \
  1022. #else
  1023. #define DECLARE_STACKINFO()
  1024. #define PRE_CALLBACK()
  1025. #define POST_CALLBACK()
  1026. #endif
  1027. #endif
  1028. /*****************************************************************************
  1029. *
  1030. * Alternative message cracker macros
  1031. *
  1032. * Basically the same as HANDLE_MSG, except that it stashes the
  1033. * answer into hres.
  1034. *
  1035. *****************************************************************************/
  1036. #define HRES_MSG(this, msg, fn) \
  1037. case msg: hres = HANDLE_##msg(this, wParam, lParam, fn); break
  1038. /*****************************************************************************
  1039. *
  1040. * Registry keys and value names
  1041. *
  1042. *****************************************************************************/
  1043. #define REGSTR_PATH_DINPUT TEXT("Software\\Microsoft\\DirectInput")
  1044. #define REGSTR_PATH_LASTAPP REGSTR_PATH_DINPUT TEXT("\\MostRecentApplication\\")
  1045. #define REGSTR_PATH_DITYPEPROP REGSTR_PATH_PRIVATEPROPERTIES TEXT("\\DirectInput")
  1046. #define REGSTR_KEY_APPHACK TEXT("Compatibility")
  1047. #define REGSTR_KEY_TEST TEXT("Test")
  1048. #define REGSTR_KEY_KEYBTYPE REGSTR_KEY_TEST TEXT("\\KeyboardType")
  1049. #define REGSTR_VAL_EMULATION TEXT("Emulation")
  1050. #define REGSTR_VAL_GAMEPADDELAY TEXT("GamepadDelay")
  1051. #define REGSTR_VAL_JOYNFFCONFIG TEXT("Joystick%dFFConfiguration")
  1052. #define REGSTR_VAL_JOYGAMEPORTEMULATOR TEXT("OEMEmulator")
  1053. #define REGSTR_VAL_CPLCLSID TEXT("ConfigCLSID")
  1054. #define REGSTR_KEY_JOYPREDEFN TEXT("predef%d")
  1055. #define REGSTR_VAL_JOYOEMCALLOUT TEXT("OEMCallout")
  1056. #define REGSTR_VAL_JOYOEMHARDWAREID TEXT("OEMHardwareID")
  1057. #define REGSTR_VAL_FLAGS1 TEXT("Flags1")
  1058. #define REGSTR_VAL_FLAGS2 TEXT("Flags2")
  1059. /*****************************************************************************
  1060. *
  1061. * Registered window messages
  1062. *
  1063. *****************************************************************************/
  1064. #define MSGSTR_JOYCHANGED TEXT("MSJSTICK_VJOYD_MSGSTR")
  1065. /*****************************************************************************
  1066. *
  1067. * mem.c - Memory management
  1068. *
  1069. * Be extremely careful with FreePv, because it doesn't work if
  1070. * the pointer is null.
  1071. *
  1072. *****************************************************************************/
  1073. #define NEED_REALLOC
  1074. STDMETHODIMP EXTERNAL ReallocCbPpv(UINT cb, PV ppvObj);
  1075. STDMETHODIMP EXTERNAL AllocCbPpv(UINT cb, PV ppvObj);
  1076. #ifdef NEED_REALLOC
  1077. #define FreePpv(ppv) (void)ReallocCbPpv(0, ppv)
  1078. #else
  1079. void EXTERNAL FreePpv(PV ppv);
  1080. #define FreePpv(ppv) FreePpv(ppv)
  1081. #endif
  1082. #define FreePv(pv) LocalFree((HLOCAL)(pv))
  1083. /*****************************************************************************
  1084. *
  1085. * diutil.c - Misc utilities
  1086. *
  1087. *****************************************************************************/
  1088. extern GUID GUID_Null;
  1089. #define ctchGuid (1 + 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
  1090. BOOL EXTERNAL ParseGUID(LPGUID pGUID, LPCTSTR ptsz);
  1091. BOOL EXTERNAL ParseVIDPID(PUSHORT puVID, PUSHORT puPID , LPCWSTR ptsz);
  1092. #define ctchNamePrefix 12 /* 12 = strlen("DirectInput.") */
  1093. #define ctchNameGuid (ctchNamePrefix + ctchGuid)
  1094. void EXTERNAL NameFromGUID(LPTSTR ptszBuf, PCGUID pGUID);
  1095. typedef STDMETHOD(CREATEDCB)(PUNK, REFGUID, RIID, PPV);
  1096. typedef struct DIOBJECTSTATICDATA
  1097. {
  1098. union
  1099. {
  1100. PCGUID rguidInstance; /* If a static device */
  1101. UINT uiButtons; /* If a HID mouse */
  1102. };
  1103. DWORD dwDevType;
  1104. union
  1105. {
  1106. CREATEDCB CreateDcb; /* If a static device */
  1107. UINT uiAxes; /* If a HID mouse */
  1108. };
  1109. } DIOBJECTSTATICDATA, *PDIOBJECTSTATICDATA, **PPDIOBJECTSTATICDATA;
  1110. HRESULT EXTERNAL hresRunControlPanel(LPCTSTR ptszCpl);
  1111. void EXTERNAL DeviceInfoWToA(LPDIDEVICEINSTANCEA pdiA,
  1112. LPCDIDEVICEINSTANCEW pdiW);
  1113. void EXTERNAL ObjectInfoWToA(LPDIDEVICEOBJECTINSTANCEA pdoiA,
  1114. LPCDIDEVICEOBJECTINSTANCEW pdoiW);
  1115. #ifdef IDirectInputDevice2Vtbl
  1116. void EXTERNAL EffectInfoWToA(LPDIEFFECTINFOA pdeiA,
  1117. LPCDIEFFECTINFOW pdeiW);
  1118. #endif
  1119. #ifndef XDEBUG
  1120. #define hresFindInstanceGUID_(pGUID, pcdcb, z, i) \
  1121. _hresFindInstanceGUID_(pGUID, pcdcb) \
  1122. #define hresValidInstanceVer_(hinst, dwVer, z) \
  1123. _hresValidInstanceVer_(hinst, dwVer) \
  1124. #endif
  1125. HRESULT EXTERNAL hresFindInstanceGUID_(PCGUID pGUID, CREATEDCB *pcdcb,
  1126. LPCSTR s_szProc, int iarg);
  1127. HRESULT EXTERNAL
  1128. hresValidInstanceVer_(HINSTANCE hinst, DWORD dwVersion, LPCSTR s_szProc);
  1129. #define hresFindInstanceGUID(pGuid, pcdcb, iarg) \
  1130. hresFindInstanceGUID_(pGuid, pcdcb, s_szProc, iarg) \
  1131. #define hresValidInstanceVer(hinst, dwVer) \
  1132. hresValidInstanceVer_(hinst, dwVer, s_szProc) \
  1133. HRESULT EXTERNAL DupEventHandle(HANDLE h, LPHANDLE phOut);
  1134. DWORD EXTERNAL GetWindowPid(HWND hwnd);
  1135. PV EXTERNAL pvFindResource(HINSTANCE hinst, DWORD id, LPCTSTR rt);
  1136. void EXTERNAL GetNthString(LPWSTR pwsz, UINT ids, UINT ui);
  1137. #define GetNthButtonString(pwsz, ui) \
  1138. GetNthString(pwsz, IDS_BUTTONTEMPLATE, ui)
  1139. #define GetNthAxisString(pwsz, ui) \
  1140. GetNthString(pwsz, IDS_AXISTEMPLATE, ui)
  1141. #define GetNthPOVString(pwsz, ui) \
  1142. GetNthString(pwsz, IDS_POVTEMPLATE, ui)
  1143. HRESULT EXTERNAL hresDupPtszPptsz(LPCTSTR ptszSrc, LPTSTR *pptszDst);
  1144. BOOL EXTERNAL fInitializeCriticalSection(LPCRITICAL_SECTION pCritSec);
  1145. void EXTERNAL DiCharUpperW(LPWSTR pwsz);
  1146. #define WIN_UNKNOWN_OS 0
  1147. #define WIN95_OS 1
  1148. #define WIN98_OS 2
  1149. #define WINME_OS 3
  1150. #define WINNT_OS 4
  1151. #define WINWH_OS 5
  1152. DWORD INTERNAL DIGetOSVersion();
  1153. /*****************************************************************************
  1154. *
  1155. * dilist.c
  1156. *
  1157. *****************************************************************************/
  1158. /*****************************************************************************
  1159. *
  1160. * @doc INTERNAL
  1161. *
  1162. * @struct GPA |
  1163. *
  1164. * Growable pointer array.
  1165. *
  1166. * @field PPV | rgpv |
  1167. *
  1168. * The base of the array of pointers.
  1169. *
  1170. * @field int | cpv |
  1171. *
  1172. * The number of pointers in use in the array.
  1173. *
  1174. * @field int | cpvAlloc |
  1175. *
  1176. * The number of pointers allocated in the array.
  1177. *
  1178. *****************************************************************************/
  1179. typedef struct GPA
  1180. {
  1181. PPV rgpv;
  1182. int cpv;
  1183. int cpvAlloc;
  1184. } GPA, *HGPA;
  1185. void EXTERNAL GPA_Init(HGPA hgpa);
  1186. void EXTERNAL GPA_Term(HGPA hgpa);
  1187. STDMETHODIMP GPA_Append(HGPA hgpa, PV pv);
  1188. BOOL EXTERNAL GPA_FindPtr(HGPA hgpa, PV pv);
  1189. STDMETHODIMP GPA_DeletePtr(HGPA hgpa, PV pv);
  1190. STDMETHODIMP GPA_Clone(HGPA hgpaDst, HGPA hgpaSrc);
  1191. /*****************************************************************************
  1192. *
  1193. * @doc INTERNAL
  1194. *
  1195. * @func void | GPA_InitFromZero |
  1196. *
  1197. * Initialize a GPA structure that is already zero-initialized.
  1198. *
  1199. * @parm HGPA | hgpa |
  1200. *
  1201. * Handle to pointer array.
  1202. *
  1203. *****************************************************************************/
  1204. /*
  1205. * Nothing needs to be done; zero-init is just fine.
  1206. *
  1207. * Note: didev.c also has a global GPA, and it assumes that zero-init
  1208. * is just fine.
  1209. */
  1210. #define GPA_InitFromZero(hgpa)
  1211. /*****************************************************************************
  1212. *
  1213. * dioledup.c
  1214. *
  1215. *****************************************************************************/
  1216. STDMETHODIMP
  1217. DICoCreateInstance(LPTSTR ptszClsid, LPUNKNOWN punkOuter,
  1218. RIID riid, PPV ppvOut, HINSTANCE *phinst);
  1219. /*****************************************************************************
  1220. *
  1221. * diexcl.c - Exclusive access management
  1222. *
  1223. * We also keep GUID uniqueness goo up here, because it is
  1224. * diexcl.c that manages shared memory.
  1225. *
  1226. *****************************************************************************/
  1227. STDMETHODIMP Excl_Acquire(PCGUID pguid, HWND hwnd, DWORD discl);
  1228. void EXTERNAL Excl_Unacquire(PCGUID pguid, HWND hwnd, DWORD discl);
  1229. STDMETHODIMP Excl_Init(void);
  1230. LONG EXTERNAL Excl_UniqueGuidInteger(void);
  1231. DWORD EXTERNAL Excl_GetConfigChangedTime();
  1232. void EXTERNAL Excl_SetConfigChangedTime(DWORD tm);
  1233. /*****************************************************************************
  1234. *
  1235. * @doc INTERNAL
  1236. *
  1237. * @struct GLOBALJOYSTATE |
  1238. *
  1239. * Structure that records global joystick state information.
  1240. *
  1241. * @field DWORD | dwTag |
  1242. *
  1243. * Counter used to keep track of how many times each joystick's
  1244. * force feedback driver has been reset. This is used to make
  1245. * sure that nobody messes with a joystick that he doesn't own.
  1246. *
  1247. * Each time the joystick is reset, the corresponding counter
  1248. * is incremented. Before we do anything to a device, we check
  1249. * if the reset counter matches the value stored in the
  1250. * object. If not, then it means that the device has been
  1251. * reset in the meantime and no longer belongs to the caller.
  1252. *
  1253. * @field DWORD | dwCplGain |
  1254. *
  1255. * Control panel (global) gain setting for the joystick.
  1256. *
  1257. * @field DWORD | dwDevGain |
  1258. *
  1259. * Most recent device (local) gain applied to the joystick.
  1260. *
  1261. * This is cached so that when the global gain changes,
  1262. * we know what physical gain to apply as a result.
  1263. *
  1264. *****************************************************************************/
  1265. typedef struct GLOBALJOYSTATE
  1266. {
  1267. DWORD dwTag;
  1268. DWORD dwCplGain;
  1269. DWORD dwDevGain;
  1270. } GLOBALJOYSTATE, *PGLOBALJOYSTATE;
  1271. /*****************************************************************************
  1272. *
  1273. * @doc INTERNAL
  1274. *
  1275. * @struct SHAREDOBJECTHEADER |
  1276. *
  1277. * A simple header comes in front of the array of objects.
  1278. *
  1279. * WARNING! This structure may not change between DEBUG and
  1280. * RETAIL. Otherwise, you have problems if one DirectInput
  1281. * app is using DEBUG and another is using RETAIL.
  1282. *
  1283. * The global <c g_gsop> variable points to one of these things,
  1284. * suitably cast.
  1285. *
  1286. * @field int | cso |
  1287. *
  1288. * Number of <t SHAREDOBJECT>s currently in use. The array
  1289. * is kept packed for simplicity.
  1290. *
  1291. * @field DWORD | dwSequence |
  1292. *
  1293. * Global sequence number used during data collection.
  1294. * (Not used if we have a VxD to manage a "really global"
  1295. * sequence number.)
  1296. *
  1297. * @field int | cguid |
  1298. *
  1299. * Unique integer for GUID generation.
  1300. *
  1301. * @field DWORD | rgdwJoy[cMaxJoy] |
  1302. *
  1303. * Counter used to keep track of how many times each joystick's
  1304. * force feedback driver has been reset. This is used to make
  1305. * sure that nobody messes with a joystick that they don't own.
  1306. *
  1307. * Each time the joystick is reset, the corresponding counter
  1308. * is incremented. Before we do anything to a device, we check
  1309. * if the reset counter matches the value stored in the
  1310. * object. If not, then it means that the device has been
  1311. * reset in the meantime and no longer belongs to the caller.
  1312. *
  1313. * Note! We support up to 16 joysticks. Hope that'll be enough
  1314. * for a while.
  1315. *
  1316. * @field GLOBALJOYSTATE | rggjs[cMaxJoy] |
  1317. *
  1318. * Global settings for each joystick.
  1319. *
  1320. * @field DWORD | tmConfigChanged
  1321. *
  1322. * The tick count of last config changed.
  1323. *
  1324. *****************************************************************************/
  1325. #define cJoyMax 16 /* Up to 16 joysticks */
  1326. typedef struct SHAREDOBJECTHEADER
  1327. {
  1328. int cso;
  1329. DWORD dwSequence;
  1330. int cguid;
  1331. GLOBALJOYSTATE rggjs[cJoyMax];
  1332. DWORD tmConfigChanged;
  1333. } SHAREDOBJECTHEADER, *PSHAREDOBJECTHEADER;
  1334. #define g_psoh ((PSHAREDOBJECTHEADER)g_psop)
  1335. /*****************************************************************************
  1336. *
  1337. * @doc INTERNAL
  1338. *
  1339. * @topic The Worker Thread |
  1340. *
  1341. * Some emulation behaviors (low-level hooks, HID) require
  1342. * a worker thread to do the data collection. We multiplex
  1343. * all such work onto a single worker thread (known as
  1344. * simple "the" worker thread).
  1345. *
  1346. * The thread is spun up when the first client needs it
  1347. * and is taken down when the last client has been released.
  1348. *
  1349. * To prevent race conditions from crashing us, we addref
  1350. * our DLL when the thread exists and have the thread
  1351. * perform a FreeLibrary as its final act.
  1352. *
  1353. *****************************************************************************/
  1354. #if defined(USE_SLOW_LL_HOOKS) || defined(HID_SUPPORT)
  1355. #define WORKER_THREAD
  1356. #endif
  1357. /*****************************************************************************
  1358. *
  1359. * diem.c - Emulation
  1360. *
  1361. *****************************************************************************/
  1362. HRESULT EXTERNAL CEm_AcquireInstance(PVXDINSTANCE *ppvi);
  1363. HRESULT EXTERNAL CEm_UnacquireInstance(PVXDINSTANCE *ppvi);
  1364. HRESULT EXTERNAL CEm_SetBufferSize(PVXDDWORDDATA pvdd);
  1365. HRESULT EXTERNAL CEm_DestroyInstance(PVXDINSTANCE *ppvi);
  1366. HRESULT EXTERNAL CEm_SetDataFormat(PVXDDATAFORMAT pvdf);
  1367. HRESULT EXTERNAL CEm_Mouse_CreateInstance(PVXDDEVICEFORMAT pdevf,
  1368. PVXDINSTANCE *ppviOut);
  1369. HRESULT EXTERNAL CEm_Mouse_InitButtons(PVXDDWORDDATA pvdd);
  1370. HRESULT EXTERNAL CEm_Kbd_CreateInstance(PVXDDEVICEFORMAT pdevf,
  1371. PVXDINSTANCE *ppviOut);
  1372. HRESULT EXTERNAL CEm_Kbd_InitKeys(PVXDDWORDDATA pvdd);
  1373. HRESULT EXTERNAL CEm_Joy_CreateInstance(PVXDDEVICEFORMAT pdevf,
  1374. PVXDINSTANCE *ppviOut);
  1375. HRESULT EXTERNAL CEm_Joy_Ping(PVXDINSTANCE *ppvi);
  1376. HRESULT EXTERNAL CEm_HID_CreateInstance(PVXDDEVICEFORMAT pdevf,
  1377. PVXDINSTANCE *ppviOut);
  1378. /*****************************************************************************
  1379. *
  1380. * diemm.c - Mouse Emulation
  1381. *
  1382. *****************************************************************************/
  1383. void EXTERNAL CEm_Mouse_AddState(LPDIMOUSESTATE_INT pms, DWORD tm);
  1384. /*****************************************************************************
  1385. *
  1386. * dinput.c - Basic DLL stuff
  1387. *
  1388. *****************************************************************************/
  1389. void EXTERNAL DllEnterCrit_(LPCTSTR lptszFile, UINT line);
  1390. void EXTERNAL DllLeaveCrit_(LPCTSTR lptszFile, UINT line);
  1391. #ifdef DEBUG
  1392. BOOL EXTERNAL DllInCrit(void);
  1393. #define DllEnterCrit() DllEnterCrit_(TEXT(__FILE__), __LINE__)
  1394. #define DllLeaveCrit() DllLeaveCrit_(TEXT(__FILE__), __LINE__)
  1395. #else
  1396. #define DllEnterCrit() DllEnterCrit_(NULL, 0x0)
  1397. #define DllLeaveCrit() DllLeaveCrit_(NULL, 0x0)
  1398. #endif
  1399. void EXTERNAL DllAddRef(void);
  1400. void EXTERNAL DllRelease(void);
  1401. void EXTERNAL DllLoadLibrary(void);
  1402. void EXTERNAL DllFreeLibrary(void);
  1403. #ifdef DEBUG
  1404. extern UINT g_thidCrit;
  1405. #define InCrit() (g_thidCrit == GetCurrentThreadId())
  1406. #endif
  1407. /*
  1408. * Describes the CLSIDs we provide to OLE.
  1409. */
  1410. typedef STDMETHOD(CREATEFUNC)(PUNK punkOuter, RIID riid, PPV ppvOut);
  1411. typedef struct CLSIDMAP
  1412. {
  1413. REFCLSID rclsid; /* The clsid */
  1414. CREATEFUNC pfnCreate; /* How to create it */
  1415. UINT ids; /* String that describes it */
  1416. } CLSIDMAP, *PCLSIDMAP;
  1417. #ifdef DEBUG
  1418. #define DEMONSTRATION_FFDRIVER
  1419. #define cclsidmap 3 /* DirectInput, DirectInputDevice, DIEffectDiver */
  1420. #else
  1421. #define cclsidmap 2 /* CLSID_DirectInput, CLSID_DirectInputDevice */
  1422. #endif
  1423. extern CLSIDMAP c_rgclsidmap[cclsidmap];
  1424. /*****************************************************************************
  1425. *
  1426. * dicf.c - IClassFactory implementation
  1427. *
  1428. *****************************************************************************/
  1429. STDMETHODIMP CDIFactory_New(CREATEFUNC pfnCreate, RIID riid, PPV ppvObj);
  1430. /*****************************************************************************
  1431. *
  1432. * didenum.c - IDirectInput device enumeration
  1433. *
  1434. *****************************************************************************/
  1435. typedef struct CDIDEnum CDIDEnum;
  1436. extern GUID rgGUID_Joystick[cJoyMax];
  1437. #define GUID_Joystick (rgGUID_Joystick[0])
  1438. void EXTERNAL CDIDEnum_Release(CDIDEnum *pde);
  1439. STDMETHODIMP CDIDEnum_Next(CDIDEnum *pde, LPDIDEVICEINSTANCEW pddiW);
  1440. STDMETHODIMP
  1441. CDIDEnum_New(PDIW pdiW, DWORD dwDevType, DWORD edfl, DWORD dwVer, CDIDEnum **);
  1442. /*****************************************************************************
  1443. *
  1444. * diobj.c - IDirectInput implementation
  1445. *
  1446. *****************************************************************************/
  1447. HRESULT EXTERNAL CDIObj_TestDeviceFlags(PDIDW pdidW, DWORD diedfl);
  1448. HRESULT EXTERNAL CDIObj_FindDeviceInternal(LPCTSTR ptszName, LPGUID pguidOut);
  1449. STDMETHODIMP CDIObj_New(PUNK punkOuter, RIID riid, PPV ppvOut);
  1450. /*****************************************************************************
  1451. *
  1452. * diaddhw.c - AddNewHardware
  1453. *
  1454. *****************************************************************************/
  1455. HRESULT EXTERNAL AddNewHardware(HWND hwnd, REFGUID rguid);
  1456. /*****************************************************************************
  1457. *
  1458. * dijoycfg.c - IDirectInputJoyConfig implementation
  1459. *
  1460. *****************************************************************************/
  1461. STDMETHODIMP CJoyCfg_New(PUNK punkOuter, RIID riid, PPV ppvOut);
  1462. /*****************************************************************************
  1463. *
  1464. * @doc INLINE
  1465. *
  1466. * @method BOOL | IsWriteSam |
  1467. *
  1468. * Nonzero if the registry security access mask will
  1469. * obtain (or attempt to obtain) write access.
  1470. *
  1471. * @parm REGSAM | regsam |
  1472. *
  1473. * Registry security access mask.
  1474. *
  1475. *****************************************************************************/
  1476. BOOL INLINE
  1477. IsWriteSam(REGSAM sam)
  1478. {
  1479. return sam & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | MAXIMUM_ALLOWED);
  1480. }
  1481. /*****************************************************************************
  1482. *
  1483. * dijoyreg.c - Joystick registry services
  1484. *
  1485. *****************************************************************************/
  1486. extern LPCWSTR c_rghwIdPredef[];
  1487. STDMETHODIMP JoyReg_OpenTypeKey(LPCWSTR pwszType, DWORD sam, DWORD dwOptions, PHKEY phk);
  1488. STDMETHODIMP JoyReg_OpenFFKey(HKEY hkType, REGSAM sam, PHKEY phk);
  1489. STDMETHODIMP
  1490. JoyReg_OpenConfigKey(UINT idJoy, DWORD sam, PJOYCAPS pcaps, DWORD dwOptions, PHKEY phk);
  1491. STDMETHODIMP JoyReg_OpenPropKey(LPCWSTR pwszType, DWORD sam, DWORD dwOptions, PHKEY phk);
  1492. STDMETHODIMP JoyReg_GetTypeInfo(LPCWSTR pwszType,
  1493. LPDIJOYTYPEINFO pjti, DWORD fl);
  1494. STDMETHODIMP JoyReg_SetTypeInfo(HKEY hkTypesW, LPCWSTR pwszType,
  1495. LPCDIJOYTYPEINFO pjti, DWORD fl);
  1496. STDMETHODIMP JoyReg_GetConfig(UINT idJoy, PJOYCAPS pcaps,
  1497. LPDIJOYCONFIG pcfg, DWORD fl);
  1498. STDMETHODIMP JoyReg_SetConfig(UINT idJoy, LPJOYREGHWCONFIG phwc,
  1499. LPCDIJOYCONFIG pcfg, DWORD fl);
  1500. STDMETHODIMP JoyReg_GetUserValues(LPDIJOYUSERVALUES pjuv, DWORD fl);
  1501. STDMETHODIMP JoyReg_SetUserValues(LPCDIJOYUSERVALUES pjuv, DWORD fl);
  1502. STDMETHODIMP
  1503. JoyReg_GetSetConfigValue(HKEY hk, LPCTSTR ptszNValue, UINT idJoy,
  1504. DWORD reg, PV pvBuf, DWORD cb, BOOL fSet);
  1505. #define GSCV_GET 0
  1506. #define GSCV_SET 1
  1507. #define JoyReg_GetConfigValue(hk, ptsz, id, reg, pv, cb) \
  1508. JoyReg_GetSetConfigValue(hk, ptsz, id, reg, pv, cb, GSCV_GET)
  1509. #define JoyReg_SetConfigValue(hk, ptsz, id, reg, pv, cb) \
  1510. JoyReg_GetSetConfigValue(hk, ptsz, id, reg, (PV)(pv), cb, GSCV_SET)
  1511. STDMETHODIMP
  1512. JoyReg_GetValue(HKEY hk, LPCTSTR ptszValue, DWORD reg, PV pvBuf, DWORD cb);
  1513. STDMETHODIMP
  1514. JoyReg_IsWdmGameport(HKEY hk);
  1515. #if 0
  1516. STDMETHODIMP
  1517. JoyReg_IsWdmGameportFromDeviceInstance( LPTSTR ptszDeviceInst );
  1518. #endif
  1519. STDMETHODIMP
  1520. JoyReg_SetValue(HKEY hk, LPCTSTR ptszValue, DWORD reg, PCV pvBuf, DWORD cb);
  1521. LPSTR EXTERNAL
  1522. JoyReg_JoyIdToDeviceInterface_95(UINT idJoy, PVXDINITPARMS pvip, LPSTR ptszBuf);
  1523. HRESULT EXTERNAL
  1524. JoyReg_GetPredefTypeInfo(LPCWSTR pwszType, LPDIJOYTYPEINFO pjti, DWORD fl);
  1525. HRESULT EXTERNAL
  1526. hResIdJoypInstanceGUID_95( UINT idJoy, LPGUID lpguid);
  1527. HRESULT EXTERNAL
  1528. hResIdJoypInstanceGUID_WDM( UINT idJoy, LPGUID lpguid);
  1529. #if 0
  1530. HRESULT EXTERNAL JoyReg_GetIDByOemName( LPTSTR szOemName, PUINT pId );
  1531. #endif
  1532. /*****************************************************************************
  1533. *
  1534. * didev.c - IDirectInputDevice implementation
  1535. *
  1536. *****************************************************************************/
  1537. STDMETHODIMP CDIDev_New(PUNK punkOuter, RIID riid, PPV ppvObj);
  1538. /*****************************************************************************
  1539. *
  1540. * CDIDev_Enter/LeaveCrit are secret backdoors to allow emulation
  1541. * and effects
  1542. * to take the device critical section when updating buffers.
  1543. *
  1544. * CDIDev_InCrit is used for assertion checking.
  1545. *
  1546. * CDIDev_IsExclAcquired is used by effects to make sure the parent
  1547. * is acquired for exclusive before attempting to download.
  1548. *
  1549. * CDIDev_SyncShepHandle is used to get the joystick "tag" which
  1550. * is used by dieshep.c to determine who owns the joystick.
  1551. *
  1552. *****************************************************************************/
  1553. void EXTERNAL CDIDev_EnterCrit_(struct CDIDev *this, LPCTSTR lptszFile, UINT line);
  1554. void EXTERNAL CDIDev_LeaveCrit_(struct CDIDev *this, LPCTSTR lptszFile, UINT line);
  1555. #ifdef DEBUG
  1556. BOOL INTERNAL CDIDev_InCrit(struct CDIDev *this);
  1557. #define CDIDev_EnterCrit(cdidev) CDIDev_EnterCrit_(cdidev, TEXT(__FILE__), __LINE__)
  1558. #define CDIDev_LeaveCrit(cdidev) CDIDev_LeaveCrit_(cdidev, TEXT(__FILE__), __LINE__)
  1559. #else
  1560. #define CDIDev_EnterCrit(cdidev) CDIDev_EnterCrit_(cdidev, NULL, 0x0);
  1561. #define CDIDev_LeaveCrit(cdidev) CDIDev_LeaveCrit_(cdidev, NULL, 0x0);
  1562. #endif
  1563. #ifndef XDEBUG
  1564. #define CDIDev_IsExclAcquired_(pdd, z) \
  1565. _CDiDev_IsExclAcquired_(pdd) \
  1566. #endif
  1567. STDMETHODIMP CDIDev_IsExclAcquired_(struct CDIDev *this, LPCSTR s_szProc);
  1568. #define CDIDev_IsExclAcquired(pdd) \
  1569. CDIDev_IsExclAcquired_(pdd, s_szProc) \
  1570. STDMETHODIMP CDIDev_SyncShepHandle(struct CDIDev *this, PSHEPHANDLE psh);
  1571. /*****************************************************************************
  1572. *
  1573. * CDIDev_SetNotifyEvent is used by the emulation code to
  1574. * notify the application when the state of the device changes.
  1575. *
  1576. *****************************************************************************/
  1577. void EXTERNAL CDIDev_SetNotifyEvent(struct CDIDev *this);
  1578. void EXTERNAL CDIDev_SetForcedUnacquiredFlag(struct CDIDev *this);
  1579. /*****************************************************************************
  1580. *
  1581. * CDIDev_NotifyCreate/DestroyEvent is used by CDIEff to
  1582. * let the parent know when a child effect comes or goes.
  1583. *
  1584. * CDIDev_FindEffectGUID is used by CDIEff to convert an
  1585. * effect GUID into an effect cookie dword.
  1586. *
  1587. * CDIDev_ConvertObjects converts item identifiers in various ways.
  1588. *
  1589. *****************************************************************************/
  1590. HRESULT EXTERNAL
  1591. CDIDev_NotifyCreateEffect(struct CDIDev *this, struct CDIEff *pdeff);
  1592. HRESULT EXTERNAL
  1593. CDIDev_NotifyDestroyEffect(struct CDIDev *this, struct CDIEff *pdeff);
  1594. #ifdef IDirectInputDevice2Vtbl
  1595. /*****************************************************************************
  1596. *
  1597. * @doc INTERNAL
  1598. *
  1599. * @struct EFFECTMAPINFO |
  1600. *
  1601. * Information about an effect, much like a
  1602. * <t DIEFFECTINFO>, but containing the
  1603. * effect ID, too.
  1604. *
  1605. * @field DWORD | dwId |
  1606. *
  1607. * The effect ID. This comes first so we can copy
  1608. * an <t EFFECTMAPINFO> into a <t DIEFFECTINFO>
  1609. * all at one go.
  1610. *
  1611. * @field GUID | guid |
  1612. *
  1613. * The effect GUID.
  1614. *
  1615. * @field DWORD | dwEffType |
  1616. *
  1617. * The effect type and flags.
  1618. *
  1619. * @field WCHAR | wszName[MAX_PATH] |
  1620. *
  1621. * The name for the effect.
  1622. *
  1623. *****************************************************************************/
  1624. typedef struct EFFECTMAPINFO
  1625. {
  1626. DIEFFECTATTRIBUTES attr;
  1627. GUID guid;
  1628. WCHAR wszName[MAX_PATH];
  1629. } EFFECTMAPINFO, *PEFFECTMAPINFO;
  1630. typedef const EFFECTMAPINFO *PCEFFECTMAPINFO;
  1631. #ifndef XDEBUG
  1632. #define CDIDev_FindEffectGUID_(this, rguid, pemi, z, i) \
  1633. _CDIDev_FindEffectGUID_(this, rguid, pemi) \
  1634. #endif
  1635. #define CDIDev_FindEffectGUID(this, rguid, pemi, iarg) \
  1636. CDIDev_FindEffectGUID_(this, rguid, pemi, s_szProc, iarg) \
  1637. STDMETHODIMP
  1638. CDIDev_FindEffectGUID_(struct CDIDev *this, REFGUID rguid,
  1639. PEFFECTMAPINFO pemi, LPCSTR s_szProc, int iarg);
  1640. STDMETHODIMP
  1641. CDIDev_ConvertObjects(struct CDIDev *this, UINT cdw, LPDWORD rgdw, UINT fl);
  1642. /*
  1643. * Note that the bonus DEVCO flags live inside the DIDFT_INSTANCEMASK.
  1644. */
  1645. #define DEVCO_AXIS DIDFT_AXIS
  1646. #define DEVCO_BUTTON DIDFT_BUTTON
  1647. #define DEVCO_TYPEMASK DIDFT_TYPEMASK
  1648. #define DEVCO_FFACTUATOR DIDFT_FFACTUATOR
  1649. #define DEVCO_FFEFFECTTRIGGER DIDFT_FFEFFECTTRIGGER
  1650. #define DEVCO_ATTRMASK DIDFT_ATTRMASK
  1651. #define DEVCO_FROMID 0x00000100
  1652. #define DEVCO_FROMOFFSET 0x00000200
  1653. #define DEVCO_FROMMASK 0x00000300
  1654. #define DEVCO_TOID 0x00001000
  1655. #define DEVCO_TOOFFSET 0x00002000
  1656. #define DEVCO_TOMASK 0x00003000
  1657. #if ((DEVCO_FROMMASK | DEVCO_TOMASK) & DIDFT_INSTANCEMASK) != \
  1658. (DEVCO_FROMMASK | DEVCO_TOMASK)
  1659. #error DEVCO_FROMMASK and DEVCI_TOMASK should not escape DIDFT_INSTANCEMASK.
  1660. #endif
  1661. #define DEVCO_VALID (DEVCO_TYPEMASK | \
  1662. DEVCO_ATTRMASK | \
  1663. DEVCO_FROMMASK | \
  1664. DEVCO_TOMASK)
  1665. #endif
  1666. /*****************************************************************************
  1667. *
  1668. * dieffv.c - IDirectInputEffectDriver for VJoyD joysticks
  1669. *
  1670. *****************************************************************************/
  1671. STDMETHODIMP CEffVxd_New(PUNK punkOuter, RIID riid, PPV ppvOut);
  1672. /*****************************************************************************
  1673. *
  1674. * dieshep.c - IDirectInputEffectShepherd
  1675. *
  1676. *****************************************************************************/
  1677. STDMETHODIMP CEShep_New(HKEY hk, PUNK punkOuter, RIID riid, PPV ppvOut);
  1678. /*****************************************************************************
  1679. *
  1680. * digendef.c - Default IDirectInputDeviceCallback
  1681. *
  1682. *****************************************************************************/
  1683. /*
  1684. * We can't call it a DCB because winbase.h already has one for
  1685. * comm goo.
  1686. */
  1687. typedef IDirectInputDeviceCallback DICB, *PDICB;
  1688. STDMETHODIMP
  1689. CDefDcb_Acquire(PDICB pdcb);
  1690. STDMETHODIMP
  1691. CDefDcb_Unacquire(PDICB pdcb);
  1692. STDMETHODIMP
  1693. CDefDcb_GetProperty(PDICB pdcb, LPCDIPROPINFO ppropi, LPDIPROPHEADER pdiph);
  1694. STDMETHODIMP
  1695. CDefDcb_SetProperty(PDICB pdcb, LPCDIPROPINFO ppropi, LPCDIPROPHEADER pdiph);
  1696. STDMETHODIMP
  1697. CDefDcb_SetEventNotification(PDICB pdcb, HANDLE h);
  1698. STDMETHODIMP
  1699. CDefDcb_SetCooperativeLevel(PDICB pdcb, HWND hwnd, DWORD dwFlags);
  1700. STDMETHODIMP
  1701. CDefDcb_CookDeviceData(PDICB pdcb, UINT cdod, LPDIDEVICEOBJECTDATA rgdod);
  1702. STDMETHODIMP
  1703. CDefDcb_CreateEffect(PDICB pdcb, LPDIRECTINPUTEFFECTSHEPHERD *ppes);
  1704. STDMETHODIMP
  1705. CDefDcb_GetFFConfigKey(PDICB pdcb, DWORD sam, PHKEY phk);
  1706. STDMETHODIMP
  1707. CDefDcb_SendDeviceData(PDICB pdcb, LPCDIDEVICEOBJECTDATA rgdod,
  1708. LPDWORD pdwInOut, DWORD fl);
  1709. STDMETHODIMP
  1710. CDefDcb_Poll(IDirectInputDeviceCallback *pdcb);
  1711. STDMETHODIMP
  1712. CDefDcb_GetVersions(IDirectInputDeviceCallback *pdcb, LPDIDRIVERVERSIONS pvers);
  1713. STDMETHODIMP
  1714. CDefDcb_MapUsage(IDirectInputDeviceCallback *pdcb, DWORD dwUsage, PINT piOut);
  1715. STDMETHODIMP_(DWORD)
  1716. CDefDcb_GetUsage(IDirectInputDeviceCallback *pdcb, int iobj);
  1717. STDMETHODIMP
  1718. CDefDcb_SetDIData(PDICB pdcb, DWORD dwVer, LPVOID lpdihacks);
  1719. /*****************************************************************************
  1720. *
  1721. * digenx.c - IDirectInputDeviceCallback that does nothing
  1722. *
  1723. *****************************************************************************/
  1724. extern IDirectInputDeviceCallback c_dcbNil;
  1725. #define c_pdcbNil &c_dcbNil
  1726. /*****************************************************************************
  1727. *
  1728. * digenm.c - IDirectInputDeviceCallback for mouse
  1729. *
  1730. *****************************************************************************/
  1731. STDMETHODIMP CMouse_New(PUNK punkOuter, REFGUID rguid, RIID riid, PPV ppvOut);
  1732. /*****************************************************************************
  1733. *
  1734. * digenk.c - IDirectInputDeviceCallback for keyboard
  1735. *
  1736. *****************************************************************************/
  1737. STDMETHODIMP CKbd_New(PUNK punkOuter, REFGUID rguid, RIID riid, PPV ppvOut);
  1738. /*****************************************************************************
  1739. *
  1740. * digenj.c - IDirectInputDeviceCallback for joystick
  1741. *
  1742. *****************************************************************************/
  1743. STDMETHODIMP CJoy_New(PUNK punkOuter, REFGUID rguid, RIID riid, PPV ppvOut);
  1744. /*****************************************************************************
  1745. *
  1746. * @doc INTERNAL
  1747. *
  1748. * @func UINT | ibJoyPosAxisFromPosAxis |
  1749. *
  1750. * Returns the offset of the <p iAxis>'th joystick axis
  1751. * in the <t JOYPOS> structure.
  1752. *
  1753. * @parm UINT | uiAxis |
  1754. *
  1755. * The index of the requested axis. X, Y, Z, R, U and V are
  1756. * respctively zero through five.
  1757. *
  1758. * @returns
  1759. *
  1760. * The offset relative to the structure.
  1761. *
  1762. *****************************************************************************/
  1763. #define _ibJoyPosAxisFromPosAxis(uiAxis) \
  1764. (FIELD_OFFSET(JOYPOS, dwX) + cbX(DWORD) * (uiAxis))
  1765. UINT INLINE
  1766. ibJoyPosAxisFromPosAxis(UINT uiPosAxis)
  1767. {
  1768. #define CheckAxis(x) \
  1769. CAssertF(_ibJoyPosAxisFromPosAxis(iJoyPosAxis##x) \
  1770. == FIELD_OFFSET(JOYPOS, dw##x)) \
  1771. CheckAxis(X);
  1772. CheckAxis(Y);
  1773. CheckAxis(Z);
  1774. CheckAxis(R);
  1775. CheckAxis(U);
  1776. CheckAxis(V);
  1777. #undef CheckAxis
  1778. return _ibJoyPosAxisFromPosAxis(uiPosAxis);
  1779. }
  1780. /*****************************************************************************
  1781. *
  1782. * dieffj.c - Dummy IDirectInputEffectDriver for joystick
  1783. *
  1784. *****************************************************************************/
  1785. STDMETHODIMP CJoyEff_New(PUNK punkOuter, RIID riid, PPV ppvOut);
  1786. /*****************************************************************************
  1787. *
  1788. * dihid.c - IDirectInputDeviceCallback for generic HID devices
  1789. *
  1790. *****************************************************************************/
  1791. STDMETHODIMP CHid_New(PUNK punkOuter, REFGUID rguid, RIID riid, PPV ppvOut);
  1792. /*****************************************************************************
  1793. *
  1794. * dieff.c - IDirectInputEffect implementation
  1795. *
  1796. *****************************************************************************/
  1797. STDMETHODIMP
  1798. CDIEff_New(struct CDIDev *pdev, LPDIRECTINPUTEFFECTSHEPHERD pes,
  1799. PUNK punkOuter, RIID riid, PPV ppvObj);
  1800. /*****************************************************************************
  1801. *
  1802. * dihidusg.c - HID usage converters
  1803. *
  1804. *****************************************************************************/
  1805. /*****************************************************************************
  1806. *
  1807. * @doc INTERNAL
  1808. *
  1809. * @struct HIDUSAGEMAP |
  1810. *
  1811. * This structure maps HID usages to GUIDs
  1812. * or legacy joystick axes.
  1813. *
  1814. * @field DWORD | dwUsage |
  1815. *
  1816. * Packed usage via <f DIMAKEUSAGEDWORD>.
  1817. *
  1818. * @field UINT | uiPosAxis |
  1819. *
  1820. * <t JOYPOS> axis number, where 0 = X, 1 = Y, ..., 5 = V.
  1821. *
  1822. * @field PCGUID | pguid |
  1823. *
  1824. * Corresponding <t GUID>.
  1825. *
  1826. *****************************************************************************/
  1827. typedef struct HIDUSAGEMAP
  1828. {
  1829. DWORD dwUsage;
  1830. UINT uiPosAxis;
  1831. PCGUID pguid;
  1832. } HIDUSAGEMAP, *PHIDUSAGEMAP;
  1833. PHIDUSAGEMAP EXTERNAL UsageToUsageMap(DWORD dwUsage);
  1834. DWORD EXTERNAL GuidToUsage(PCGUID pguid);
  1835. UINT EXTERNAL
  1836. GetHIDString(DWORD Usage, DWORD UsagePage, LPWSTR pwszBuf, UINT cwch);
  1837. void EXTERNAL InsertCollectionNumber(UINT icoll, LPWSTR pwszBuf);
  1838. /*****************************************************************************
  1839. *
  1840. * disubcls.c - Subclassing
  1841. *
  1842. *****************************************************************************/
  1843. typedef LRESULT
  1844. (CALLBACK *SUBCLASSPROC)(HWND hwnd, UINT wm, WPARAM wp,
  1845. LPARAM lp, UINT_PTR uId, ULONG_PTR dwRef);
  1846. BOOL EXTERNAL
  1847. SetWindowSubclass(HWND hwnd, SUBCLASSPROC pfnSubclass, UINT_PTR uId, ULONG_PTR dwRef);
  1848. BOOL EXTERNAL
  1849. GetWindowSubclass(HWND hwnd, SUBCLASSPROC pfnSubclass, UINT_PTR uId, ULONG_PTR *pdwRef);
  1850. BOOL EXTERNAL
  1851. RemoveWindowSubclass(HWND hwnd, SUBCLASSPROC pfnSubclass, UINT_PTR uId);
  1852. LRESULT EXTERNAL
  1853. DefSubclassProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
  1854. /*****************************************************************************
  1855. *
  1856. * dical.c - Axis ramps and calibration
  1857. *
  1858. * Structure names begin with "Joy" for historical reasons.
  1859. *
  1860. *****************************************************************************/
  1861. #if defined(_X86_)
  1862. LONG EXTERNAL CCal_MulDiv(LONG lA, LONG lB, LONG lC);
  1863. #else
  1864. #define CCal_MulDiv MulDiv
  1865. #endif
  1866. /*****************************************************************************
  1867. *
  1868. * @doc INTERNAL
  1869. *
  1870. * @struct JOYRAMP |
  1871. *
  1872. * Parameters for a "ramp". A ramp looks like this:
  1873. *
  1874. * r !
  1875. * e dy - *---
  1876. * t ! /
  1877. * u ! /
  1878. * r ! /
  1879. * n y ---*
  1880. * e !
  1881. * d +--!---!---
  1882. * x dx
  1883. *
  1884. * physical position
  1885. *
  1886. *
  1887. * y, dy = baseline and height
  1888. *
  1889. * x, dx = initiation level and width
  1890. *
  1891. * The mapping is
  1892. *
  1893. *
  1894. * (-infty, x ] -> y
  1895. * (x, x+dx ) -> (y, y+dy)
  1896. * [x+dx, infty) -> y+dy
  1897. *
  1898. * It is very important that the middle range not be taken
  1899. * if dx = 0.
  1900. *
  1901. * @field int | x |
  1902. *
  1903. * Horizontal value below which we return the baseline.
  1904. *
  1905. * @field DWORD | dx |
  1906. *
  1907. * Width of the ramp. Beyond this point, we return the
  1908. * full height.
  1909. *
  1910. * @field int | y |
  1911. *
  1912. * Baseline.
  1913. *
  1914. * @field int | dy |
  1915. *
  1916. * Total height.
  1917. *
  1918. *****************************************************************************/
  1919. typedef struct JOYRAMP
  1920. {
  1921. int x;
  1922. int y;
  1923. DWORD dx;
  1924. int dy;
  1925. } JOYRAMP, *PJOYRAMP;
  1926. typedef const JOYRAMP *PCJOYRAMP;
  1927. /*****************************************************************************
  1928. *
  1929. * @doc INTERNAL
  1930. *
  1931. * @struct JOYRANGECONVERT |
  1932. *
  1933. * Parameters for range conversion.
  1934. *
  1935. * The conversion curve is in five sections.
  1936. *
  1937. *
  1938. *
  1939. * !
  1940. * lmax- *----
  1941. * r ! /
  1942. * e ! /
  1943. * t ! /
  1944. * u lc- *------*
  1945. * r ! /
  1946. * n ! /
  1947. * e ! /
  1948. * d lmin-------*
  1949. * !
  1950. * +-!----!---!------!----!----!--
  1951. * pmin smin dmin dmax smax pmax
  1952. *
  1953. * !
  1954. * pc
  1955. *
  1956. *
  1957. * physical position
  1958. *
  1959. *
  1960. * lmin/lmax = logical min/max - This is the smallest/largest
  1961. * position the app will ever see.
  1962. *
  1963. * lc = logical center
  1964. *
  1965. * pmin/pmax = physical min/max - This is the position determined by
  1966. * calibration to be the value which the hardware reports
  1967. * when the device is physically at its bottom/upper limit. Note
  1968. * that the hardware might report values outside this range.
  1969. *
  1970. * pc = physical center - This is the nominal neutral location for
  1971. * the axis
  1972. *
  1973. * dmin/dmax = dead zone min/max - This is the zone around which
  1974. * the center is artificially expanded.
  1975. *
  1976. * smin/smax = saturation min/max - This is the level at which
  1977. * we treat the axis as being at its most extreme position.
  1978. *
  1979. * @field BOOL | fRaw |
  1980. *
  1981. * Is the axis in raw mode? If so, then no cooking is performed.
  1982. *
  1983. * @field JOYRAMP | rmpLow |
  1984. *
  1985. * The ramp for below-center.
  1986. *
  1987. * @field JOYRAMP | rmpHigh |
  1988. *
  1989. * The ramp for above-center.
  1990. *
  1991. * @field DWORD | dwPmin |
  1992. *
  1993. * Physical minimum.
  1994. *
  1995. * @field DWORD | dwPmax |
  1996. *
  1997. * Physical maximum.
  1998. *
  1999. * @field LONG | lMin |
  2000. *
  2001. * Logical minimum.
  2002. *
  2003. * @field LONG | lCenter |
  2004. *
  2005. * Logical center.
  2006. *
  2007. * @field LONG | lMax |
  2008. *
  2009. * Logical maximum.
  2010. *
  2011. * @field DWORD | dwPc |
  2012. *
  2013. * Physical center.
  2014. *
  2015. * @field DWORD | dwDz |
  2016. *
  2017. * Dead zone (in ten thousandths, 10000 = 100%).
  2018. *
  2019. * @field DWORD | dwSat |
  2020. *
  2021. * Saturation level (in ten thousands, 10000 = 100%).
  2022. *
  2023. * @field BOOL | fPolledPOV |
  2024. *
  2025. * Whether the axis is a polled POV. Usable only when the axis is a POV.
  2026. *
  2027. * @field LONG | lMinPOV[5] |
  2028. *
  2029. * Mininum ranges of POV directions. Usable only when the axis is a POV.
  2030. *
  2031. * @field LONG | lMaxPOV[5] |
  2032. *
  2033. * Maxinum ranges of POV directions. Usable only when the axis is a POV.
  2034. *
  2035. *****************************************************************************/
  2036. /*
  2037. * Number of range divisions. We work in ten thousandths.
  2038. */
  2039. #define RANGEDIVISIONS 10000
  2040. typedef struct JOYRANGECONVERT
  2041. {
  2042. BOOL fRaw;
  2043. JOYRAMP rmpLow;
  2044. JOYRAMP rmpHigh;
  2045. DWORD dwPmin;
  2046. DWORD dwPmax;
  2047. DWORD dwPc;
  2048. LONG lMin;
  2049. LONG lMax;
  2050. LONG lC;
  2051. DWORD dwDz;
  2052. DWORD dwSat;
  2053. #ifdef WINNT
  2054. BOOL fFakeRaw;
  2055. BOOL fPolledPOV;
  2056. LONG lMinPOV[5];
  2057. LONG lMaxPOV[5];
  2058. #endif
  2059. } JOYRANGECONVERT, *PJOYRANGECONVERT;
  2060. typedef const JOYRANGECONVERT *PCJOYRANGECONVERT;
  2061. /*****************************************************************************
  2062. *
  2063. * dical.c functions
  2064. *
  2065. *****************************************************************************/
  2066. void EXTERNAL CCal_CookRange(PJOYRANGECONVERT this, LONG UNALIGNED *pl);
  2067. void EXTERNAL CCal_RecalcRange(PJOYRANGECONVERT this);
  2068. STDMETHODIMP
  2069. CCal_GetProperty(PJOYRANGECONVERT this, REFGUID rguid, LPDIPROPHEADER pdiph, DWORD dwVersion);
  2070. STDMETHODIMP
  2071. CCal_SetProperty(PJOYRANGECONVERT this, LPCDIPROPINFO ppropi,
  2072. LPCDIPROPHEADER pdiph, HKEY hkType, DWORD dwVersion);
  2073. /*****************************************************************************
  2074. *
  2075. * @doc INTERNAL
  2076. *
  2077. * @func LONG | CCal_Midpoint |
  2078. *
  2079. * Return the midpoint of two values. Note, however, that
  2080. * we round <y upward> instead of downward. This is important,
  2081. * because many people set the ranges to something like
  2082. * 0 .. 0xFFFF, and we want the midpoint to be 0x8000.
  2083. *
  2084. * Care must be taken that the intermediate sum does not overflow.
  2085. *
  2086. * @parm LONG | lMin |
  2087. *
  2088. * Lower limit.
  2089. *
  2090. * @parm LONG | lMax |
  2091. *
  2092. * Upper limit.
  2093. *
  2094. * @returns
  2095. *
  2096. * The midpoint.
  2097. *
  2098. *****************************************************************************/
  2099. LONG INLINE
  2100. CCal_Midpoint(LONG lMin, LONG lMax)
  2101. {
  2102. /*
  2103. * Can't do "lMax + lMin" because that might overflow.
  2104. */
  2105. AssertF(lMax >= lMin);
  2106. return lMin + (UINT)(lMax - lMin + 1) / 2;
  2107. }
  2108. /*****************************************************************************
  2109. *
  2110. * dijoytyp.c
  2111. *
  2112. *****************************************************************************/
  2113. STDMETHODIMP CType_OpenIdSubkey(HKEY, DWORD, REGSAM, PHKEY);
  2114. void EXTERNAL CType_RegGetObjectInfo(HKEY hkType, DWORD dwId,
  2115. LPDIDEVICEOBJECTINSTANCEW pdidoiW);
  2116. void EXTERNAL CType_RegGetTypeInfo(HKEY hkType, LPDIOBJECTDATAFORMAT podf, BOOL bHid);
  2117. void EXTERNAL CType_MakeGameCtrlName(PWCHAR wszOutput, DWORD dwDevType,
  2118. DWORD dwAxes, DWORD dwButtons, DWORD dwPOVs );
  2119. /*****************************************************************************
  2120. *
  2121. * diaphack.c
  2122. *
  2123. *****************************************************************************/
  2124. HRESULT EXTERNAL AhAppRegister(DWORD dwVer);
  2125. BOOL EXTERNAL AhGetAppHacks(LPDIAPPHACKS);
  2126. /*****************************************************************************
  2127. *
  2128. * diraw.c
  2129. *
  2130. *****************************************************************************/
  2131. #ifdef USE_WM_INPUT
  2132. #define DIRAW_NONEXCL 0
  2133. #define DIRAW_EXCL 1
  2134. #define DIRAW_NOHOTKEYS 2
  2135. HRESULT CDIRaw_RegisterRawInputDevice( UINT uirim, DWORD dwOrd, HWND hwnd);
  2136. HRESULT CDIRaw_UnregisterRawInputDevice( UINT uirim, HWND hwnd );
  2137. BOOL CDIRaw_OnInput(MSG *pmsg);
  2138. HRESULT INTERNAL CDIRaw_Mouse_InitButtons();
  2139. int EXTERNAL DIRaw_GetKeyboardType(int nTypeFlag);
  2140. #endif
  2141. #ifdef __cplusplus
  2142. };
  2143. #endif