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.

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