Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

422 lines
16 KiB

  1. /****************************************************************************/
  2. // cm.h
  3. //
  4. // Cursor manager header.
  5. //
  6. // Copyright (C) 1997-2000 Microsoft Corp.
  7. /****************************************************************************/
  8. #ifndef _H_CM
  9. #define _H_CM
  10. extern "C" {
  11. #include <adcgdata.h>
  12. }
  13. #include "autil.h"
  14. #include "wui.h"
  15. #include "uh.h"
  16. #include "objs.h"
  17. #include "cd.h"
  18. #define TRC_GROUP TRC_GROUP_CORE
  19. #define TRC_FILE "cm"
  20. #define TSC_HR_FILEID TSC_HR_CM_H
  21. /****************************************************************************/
  22. /* Cursor size constants. These are t.128 specifications. */
  23. /****************************************************************************/
  24. #define CM_CURSOR_WIDTH 32
  25. #define CM_CURSOR_HEIGHT 32
  26. #define CM_NUM_CURSOR_BITMAP_BYTES ((CM_CURSOR_WIDTH * CM_CURSOR_HEIGHT) / 8)
  27. /****************************************************************************/
  28. /* Pointer cache sizes. */
  29. /* */
  30. /* Note: For 'old' style support, the cache includes one entry (never */
  31. /* used!) for the last mono cursor */
  32. /****************************************************************************/
  33. #define CM_COLOR_CACHE_SIZE 20
  34. #define CM_MONO_CACHE_SIZE 1
  35. #define CM_MONO_CACHE_INDEX CM_COLOR_CACHE_SIZE
  36. #define CM_CURSOR_CACHE_SIZE (CM_COLOR_CACHE_SIZE + CM_MONO_CACHE_SIZE)
  37. /**STRUCT+*******************************************************************/
  38. /* Structure: CM_GLOBAL_DATA */
  39. /* */
  40. /* Description: */
  41. /****************************************************************************/
  42. typedef struct tagCM_GLOBAL_DATA
  43. {
  44. HCURSOR cursorCache[CM_CURSOR_CACHE_SIZE];
  45. } CM_GLOBAL_DATA, DCPTR PCM_GLOBAL_DATA;
  46. /**STRUCT-*******************************************************************/
  47. #define CM_DEFAULT_ARROW_CURSOR_HANDLE LoadCursor(NULL, IDC_ARROW)
  48. class CCM
  49. {
  50. public:
  51. CCM(CObjs* objs);
  52. ~CCM();
  53. //
  54. // API
  55. //
  56. /****************************************************************************/
  57. // Functions
  58. /****************************************************************************/
  59. DCVOID DCAPI CM_Init(DCVOID);
  60. DCVOID DCAPI CM_Enable(ULONG_PTR unused);
  61. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CCM, CM_Enable);
  62. DCVOID DCAPI CM_Disable(ULONG_PTR unused);
  63. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CCM, CM_Disable);
  64. void DCAPI CM_NullSystemPointerPDU(void);
  65. void DCAPI CM_DefaultSystemPointerPDU(void);
  66. HRESULT DCAPI CM_MonoPointerPDU(TS_MONOPOINTERATTRIBUTE UNALIGNED FAR *, DCUINT);
  67. void DCAPI CM_PositionPDU(TS_POINT16 UNALIGNED FAR *);
  68. HRESULT DCAPI CM_ColorPointerPDU(TS_COLORPOINTERATTRIBUTE UNALIGNED FAR *, DCUINT);
  69. void DCAPI CM_CachedPointerPDU(unsigned);
  70. HRESULT DCAPI CM_PointerPDU(TS_POINTERATTRIBUTE UNALIGNED FAR *, DCUINT);
  71. /****************************************************************************/
  72. /* Name: CM_Term */
  73. /* */
  74. /* Purpose: Cursor Manager termination */
  75. /****************************************************************************/
  76. inline void DCAPI CM_Term(void)
  77. {
  78. } /* CM_Term */
  79. /****************************************************************************/
  80. // CM_SlowPathPDU
  81. //
  82. // Handles non-fast-path translation to handler function calls.
  83. /****************************************************************************/
  84. // SECURITY - the size of the packet has been checked only to be sure there is
  85. // enough data to read the TS_POINTER_PDU_DATA.messageType field
  86. inline HRESULT DCAPI CM_SlowPathPDU(
  87. TS_POINTER_PDU_DATA UNALIGNED FAR *pPointerPDU,
  88. DCUINT dataLen )
  89. {
  90. DC_BEGIN_FN("CM_SlowPathPDU");
  91. HRESULT hr = S_OK;
  92. switch (pPointerPDU->messageType) {
  93. case TS_PTRMSGTYPE_POSITION:
  94. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  95. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  96. sizeof(TS_POINT16), hr, (TB, _T("Bad TS_PTRMSGTYPE_POSITION")));
  97. CM_PositionPDU(&pPointerPDU->pointerData.pointerPosition);
  98. break;
  99. case TS_PTRMSGTYPE_SYSTEM:
  100. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  101. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  102. sizeof(TSUINT32), hr, (TB, _T("Bad TS_PTRMSGTYPE_SYSTEM")));
  103. switch (pPointerPDU->pointerData.systemPointerType) {
  104. case TS_SYSPTR_NULL:
  105. CM_NullSystemPointerPDU();
  106. break;
  107. case TS_SYSPTR_DEFAULT:
  108. CM_DefaultSystemPointerPDU();
  109. break;
  110. default:
  111. TRC_ERR((TB, _T("Invalid system pointer type")));
  112. break;
  113. }
  114. break;
  115. case TS_PTRMSGTYPE_MONO:
  116. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  117. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  118. sizeof(TS_MONOPOINTERATTRIBUTE), hr, (TB, _T("Bad TS_PTRMSGTYPE_MONO")));
  119. hr = CM_MonoPointerPDU(&pPointerPDU->pointerData.
  120. monoPointerAttribute, dataLen - FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData));
  121. break;
  122. case TS_PTRMSGTYPE_COLOR:
  123. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  124. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  125. sizeof(TS_COLORPOINTERATTRIBUTE), hr, (TB, _T("Bad TS_PTRMSGTYPE_COLOR")));
  126. hr = CM_ColorPointerPDU(&pPointerPDU->pointerData.
  127. colorPointerAttribute, dataLen - FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData));
  128. break;
  129. case TS_PTRMSGTYPE_POINTER:
  130. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  131. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  132. sizeof(TS_POINTERATTRIBUTE), hr, (TB, _T("Bad TS_PTRMSGTYPE_POINTER")));
  133. hr = CM_PointerPDU(&pPointerPDU->pointerData.pointerAttribute,
  134. dataLen - FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData));
  135. break;
  136. case TS_PTRMSGTYPE_CACHED:
  137. CHECK_READ_N_BYTES(pPointerPDU, (PBYTE)pPointerPDU + dataLen,
  138. FIELDOFFSET(TS_POINTER_PDU_DATA,pointerData) +
  139. sizeof(TSUINT16), hr, (TB, _T("Bad TS_PTRMSGTYPE_CACHED")));
  140. CM_CachedPointerPDU(pPointerPDU->pointerData.cachedPointerIndex);
  141. break;
  142. default:
  143. TRC_ERR((TB, _T("Unknown PointerPDU type %#x"),
  144. pPointerPDU->messageType));
  145. hr = E_UNEXPECTED;
  146. break;
  147. }
  148. DC_EXIT_POINT:
  149. DC_END_FN();
  150. return hr;
  151. }
  152. public:
  153. //
  154. // Public data members
  155. //
  156. CM_GLOBAL_DATA _CM;
  157. private:
  158. //
  159. // Internal functions
  160. //
  161. /****************************************************************************/
  162. /* Functions */
  163. /****************************************************************************/
  164. HRESULT DCINTERNAL CMCreateColorCursor(unsigned,
  165. TS_COLORPOINTERATTRIBUTE UNALIGNED FAR *, DCUINT, HCURSOR *);
  166. HRESULT DCINTERNAL CMCreateMonoCursor(
  167. TS_MONOPOINTERATTRIBUTE UNALIGNED FAR *, DCUINT, HCURSOR *);
  168. inline HRESULT DCINTERNAL CMCreateNewCursor(
  169. TS_POINTERATTRIBUTE UNALIGNED FAR *pAttr,
  170. DCUINT dataLen,
  171. HCURSOR FAR *pNewHandle,
  172. HCURSOR * pOldHandle)
  173. {
  174. HRESULT hr = S_OK;
  175. HCURSOR oldHandle = NULL;
  176. HCURSOR newHandle;
  177. unsigned cacheIndex;
  178. unsigned xorLen;
  179. DC_BEGIN_FN("CMCreateNewCursor");
  180. TRC_DATA_DBG("Rx cursor data", pAttr, sizeof(TS_POINTERATTRIBUTE) );
  181. cacheIndex = pAttr->colorPtrAttr.cacheIndex;
  182. // SECURITY: 555587 cursor values must be validated
  183. if (cacheIndex >= CM_CURSOR_CACHE_SIZE) {
  184. TRC_ERR(( TB, _T("Invalid cache index %d"), cacheIndex));
  185. hr = E_TSC_CORE_CACHEVALUE;
  186. DC_QUIT;
  187. }
  188. TRC_DBG((TB, _T("Cached index %d"), cacheIndex));
  189. oldHandle = _CM.cursorCache[cacheIndex];
  190. // SECURITY 555587: CMCreate<XXX>Cursor must validate input
  191. if (FIELDOFFSET(TS_COLORPOINTERATTRIBUTE, colorPointerData) +
  192. pAttr->colorPtrAttr.lengthXORMask + pAttr->colorPtrAttr.lengthANDMask > dataLen) {
  193. TRC_ERR(( TB, _T("Bad CreateNewCursor; dataLen %u"), dataLen));
  194. hr = E_TSC_CORE_LENGTH;
  195. DC_QUIT;
  196. }
  197. // Create the new cursor according to the color depth
  198. if (pAttr->XORBpp == 1) {
  199. TRC_NRM((TB, _T("Create mono cursor")));
  200. // Data contains XOR followed by AND mask.
  201. xorLen = pAttr->colorPtrAttr.lengthXORMask;
  202. TRC_DATA_DBG("AND mask",
  203. pAttr->colorPtrAttr.colorPointerData + xorLen,
  204. xorLen);
  205. TRC_DATA_DBG("XOR bitmap",
  206. pAttr->colorPtrAttr.colorPointerData,
  207. xorLen);
  208. #ifndef OS_WINCE
  209. newHandle = CreateCursor(_pUi->UI_GetInstanceHandle(),
  210. pAttr->colorPtrAttr.hotSpot.x,
  211. pAttr->colorPtrAttr.hotSpot.y,
  212. pAttr->colorPtrAttr.width,
  213. pAttr->colorPtrAttr.height,
  214. pAttr->colorPtrAttr.colorPointerData + xorLen,
  215. pAttr->colorPtrAttr.colorPointerData);
  216. #else
  217. /******************************************************************/
  218. /* In Windows CE environments, we're not guaranteed that */
  219. /* CreateCursor is part of the OS, so we do a GetProcAddress on */
  220. /* it so we can be sure. If it's not there, this usually means */
  221. /* we're on a touch screen device where these cursor doesn't */
  222. /* matter anyway. */
  223. /******************************************************************/
  224. if (g_pCreateCursor)
  225. {
  226. newHandle = g_pCreateCursor(_pUi->UI_GetInstanceHandle(),
  227. pAttr->colorPtrAttr.hotSpot.x,
  228. pAttr->colorPtrAttr.hotSpot.y,
  229. pAttr->colorPtrAttr.width,
  230. pAttr->colorPtrAttr.height,
  231. pAttr->colorPtrAttr.colorPointerData + xorLen,
  232. pAttr->colorPtrAttr.colorPointerData);
  233. }
  234. else
  235. {
  236. newHandle = NULL;
  237. }
  238. #endif // OS_WINCE
  239. }
  240. else {
  241. TRC_NRM((TB, _T("Create %d bpp cursor"), pAttr->XORBpp));
  242. hr = CMCreateColorCursor(pAttr->XORBpp, &(pAttr->colorPtrAttr),
  243. dataLen - FIELDSIZE(TS_POINTERATTRIBUTE, XORBpp), &newHandle);
  244. DC_QUIT_ON_FAIL(hr);
  245. }
  246. _CM.cursorCache[cacheIndex] = newHandle;
  247. if (newHandle != NULL) {
  248. // New cursor created OK.
  249. *pNewHandle = newHandle;
  250. }
  251. else {
  252. // Failed to create the new color cursor - use default
  253. TRC_ALT((TB, _T("Failed to create cursor")));
  254. *pNewHandle = CM_DEFAULT_ARROW_CURSOR_HANDLE;
  255. }
  256. *pOldHandle = oldHandle;
  257. DC_EXIT_POINT:
  258. DC_END_FN();
  259. return hr;
  260. }
  261. inline HRESULT DCINTERNAL CMCreateNewColorCursor(
  262. unsigned cacheIndex,
  263. TS_COLORPOINTERATTRIBUTE UNALIGNED FAR *pAttr,
  264. DCUINT dataLen,
  265. HCURSOR FAR *pNewHandle,
  266. HCURSOR * pOldHandle)
  267. {
  268. HRESULT hr = S_OK;
  269. HCURSOR oldHandle = NULL;
  270. HCURSOR newHandle;
  271. DC_BEGIN_FN("CMCreateNewColorCursor");
  272. // SECURITY: 555587 cursor values must be validated
  273. if (cacheIndex >= CM_CURSOR_CACHE_SIZE) {
  274. TRC_ERR(( TB, _T("Invalid cache index %d"), cacheIndex));
  275. hr = E_TSC_CORE_CACHEVALUE;
  276. DC_QUIT;
  277. }
  278. TRC_DBG((TB, _T("Cached index %d"), cacheIndex));
  279. oldHandle = _CM.cursorCache[cacheIndex];
  280. // Create the new color cursor. Save in the cache.
  281. // This is for the 'old' cursor protocol so we hard coded the color
  282. // depth as 24 bpp.
  283. // SECURITY 559307: CMCreate<XXX>Cursor need size of PDU passed in
  284. hr = CMCreateColorCursor(24, pAttr, dataLen, &newHandle);
  285. DC_QUIT_ON_FAIL(hr);
  286. _CM.cursorCache[cacheIndex] = newHandle;
  287. if (newHandle != NULL) {
  288. // New cursor created OK.
  289. *pNewHandle = newHandle;
  290. }
  291. else {
  292. // Failed to create the new color cursor - use default
  293. TRC_ALT((TB, _T("Failed to create color cursor")));
  294. *pNewHandle = CM_DEFAULT_ARROW_CURSOR_HANDLE;
  295. }
  296. *pOldHandle = oldHandle;
  297. DC_EXIT_POINT:
  298. DC_END_FN();
  299. return hr;
  300. }
  301. inline HCURSOR DCINTERNAL CMGetCachedCursor(unsigned cacheIndex)
  302. {
  303. DC_BEGIN_FN("CMGetCachedCursor");
  304. TRC_NRM((TB, _T("Cached color pointer - index %d"), cacheIndex));
  305. TRC_ASSERT((cacheIndex < CM_CURSOR_CACHE_SIZE),
  306. (TB, _T("Invalid cache index %d"), cacheIndex));
  307. /************************************************************************/
  308. /* Assume NULL means we failed to create the cursor, so use the */
  309. /* default. If the server has not sent this definition, that is not our */
  310. /* fault. */
  311. /************************************************************************/
  312. // SECURITY 550811: Cache index must be verified
  313. if (cacheIndex < CM_CURSOR_CACHE_SIZE &&
  314. _CM.cursorCache[cacheIndex] != NULL) {
  315. DC_END_FN();
  316. return _CM.cursorCache[cacheIndex];
  317. }
  318. else {
  319. TRC_ALT((TB, _T("No cached cursor - use default")));
  320. DC_END_FN();
  321. return CM_DEFAULT_ARROW_CURSOR_HANDLE;
  322. }
  323. }
  324. // Platform specific prototypes.
  325. HBITMAP CMCreateXORBitmap(LPBITMAPINFO,
  326. TS_COLORPOINTERATTRIBUTE UNALIGNED FAR *);
  327. HCURSOR CMCreatePlatformCursor(TS_COLORPOINTERATTRIBUTE UNALIGNED FAR *,
  328. HBITMAP, HBITMAP);
  329. #ifdef OS_WINCE
  330. DCVOID DCINTERNAL CMMakeMonoDIB(HDC, LPBITMAPINFO, PDCUINT8, PDCUINT8);
  331. #endif // OS_WINCE
  332. private:
  333. CUT* _pUt;
  334. CUH* _pUh;
  335. CCD* _pCd;
  336. CIH* _pIh;
  337. CUI* _pUi;
  338. private:
  339. CObjs* _pClientObjects;
  340. };
  341. #undef TRC_FILE
  342. #undef TRC_GROUP
  343. #undef TSC_HR_FILEID
  344. #endif // _H_CM