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.

571 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: clipformat.cxx
  7. //
  8. // Contents: Support for Windows/OLE data types for oleprx32.dll.
  9. // Used to be transmit_as routines, now user_marshal routines.
  10. //
  11. // This file contains support for CLIPFORMAT.
  12. //
  13. // Functions:
  14. // CLIPFORMAT_UserSize
  15. // CLIPFORMAT_UserMarshal
  16. // CLIPFORMAT_UserUnmarshal
  17. // CLIPFORMAT_UserFree
  18. // CLIPFORMAT_UserSize64
  19. // CLIPFORMAT_UserMarshal64
  20. // CLIPFORMAT_UserUnmarshal64
  21. // CLIPFORMAT_UserFree64
  22. //
  23. // History: 13-Dec-00 JohnDoty Migrated from transmit.cxx
  24. //
  25. //--------------------------------------------------------------------------
  26. #include "stdrpc.hxx"
  27. #pragma hdrstop
  28. #include <oleauto.h>
  29. #include <objbase.h>
  30. #include "transmit.hxx"
  31. #include <rpcwdt.h>
  32. #include <storext.h>
  33. #include "widewrap.h"
  34. #include <valid.h>
  35. #include <obase.h>
  36. #include <stream.hxx>
  37. #include <winsta.h>
  38. #include <allproc.h>
  39. typedef HANDLE __stdcall FN_WinStationOpenServerW(LPWSTR);
  40. typedef BOOLEAN __stdcall FN_WinStationGetTermSrvCountersValue(HANDLE, ULONG, PVOID);
  41. typedef BOOLEAN __stdcall FN_WinStationCloseServer(HANDLE);
  42. static DWORD g_cTSSessions = -1;
  43. #include "carefulreader.hxx"
  44. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  45. void CountTSSessions()
  46. {
  47. DWORD cTSSessions = 0;
  48. HINSTANCE hTSLib = LoadLibraryW(L"winsta.dll");
  49. if (hTSLib)
  50. {
  51. FN_WinStationOpenServerW *pFNOpen = (FN_WinStationOpenServerW *)GetProcAddress(hTSLib, "WinStationOpenServerW");
  52. FN_WinStationGetTermSrvCountersValue *pFNCount = (FN_WinStationGetTermSrvCountersValue *)GetProcAddress(hTSLib, "WinStationGetTermSrvCountersValue");
  53. FN_WinStationCloseServer *pFNClose = (FN_WinStationCloseServer *)GetProcAddress(hTSLib, "WinStationCloseServer");
  54. if (pFNOpen && pFNCount && pFNClose)
  55. {
  56. HANDLE hServer = pFNOpen(reinterpret_cast<WCHAR*>(SERVERNAME_CURRENT));
  57. if (hServer != NULL)
  58. {
  59. TS_COUNTER tsCounters[2] = {0};
  60. tsCounters[0].counterHead.dwCounterID = TERMSRV_CURRENT_DISC_SESSIONS;
  61. tsCounters[1].counterHead.dwCounterID = TERMSRV_CURRENT_ACTIVE_SESSIONS;
  62. if (pFNCount(hServer, ARRAYSIZE(tsCounters), tsCounters))
  63. {
  64. int i;
  65. for (i = 0; i < ARRAYSIZE(tsCounters); i++)
  66. {
  67. if (tsCounters[i].counterHead.bResult)
  68. {
  69. cTSSessions += tsCounters[i].dwValue;
  70. }
  71. }
  72. }
  73. pFNClose(hServer);
  74. }
  75. }
  76. FreeLibrary(hTSLib);
  77. }
  78. g_cTSSessions = cTSSessions;
  79. }
  80. //+-------------------------------------------------------------------------
  81. //
  82. // Function: CLIPFORMAT_UserSize
  83. //
  84. // Synopsis: Sizes a CLIPFORMAT.
  85. //
  86. // Derivation: A union of a long and a string.
  87. //
  88. // history: Feb-96 Ryszardk Created
  89. //
  90. //--------------------------------------------------------------------------
  91. unsigned long __RPC_USER
  92. CLIPFORMAT_UserSize(
  93. unsigned long * pFlags,
  94. unsigned long Offset,
  95. CLIPFORMAT * pObject )
  96. {
  97. if ( !pObject )
  98. return( Offset );
  99. if (g_cTSSessions == -1)
  100. {
  101. CountTSSessions();
  102. }
  103. // userCLIPFORMAT is an encapsulated union with a string.
  104. LENGTH_ALIGN( Offset, 3);
  105. Offset += sizeof(long) + sizeof(void *);
  106. if ( (NON_STANDARD_CLIPFORMAT(pObject)) && ((REMOTE_CLIPFORMAT( pFlags) )
  107. || (g_cTSSessions > 1 ))) // ignore console session
  108. {
  109. wchar_t temp[CLIPFORMAT_BUFFER_MAX];
  110. int ret = GetClipboardFormatName( *pObject,
  111. temp,
  112. CLIPFORMAT_BUFFER_MAX - 1 );
  113. if ( ret )
  114. {
  115. Offset += 3 * sizeof(long) + (ret+1) * sizeof(wchar_t);
  116. }
  117. else
  118. RAISE_RPC_EXCEPTION( DV_E_CLIPFORMAT );
  119. }
  120. return( Offset );
  121. }
  122. //+-------------------------------------------------------------------------
  123. //
  124. // Function: CLIPFORMAT_UserMarshal
  125. //
  126. // Synopsis: Marshals a CLIPFORMAT.
  127. //
  128. // Derivation: A union of a long and a string.
  129. //
  130. // history: Feb-96 Ryszardk Created
  131. //
  132. //--------------------------------------------------------------------------
  133. unsigned char __RPC_FAR * __RPC_USER
  134. CLIPFORMAT_UserMarshal(
  135. unsigned long * pFlags,
  136. unsigned char * pBuffer,
  137. CLIPFORMAT * pObject )
  138. {
  139. if ( !pObject )
  140. return pBuffer;
  141. // userCLIPFORMAT is an encapsulated union with a string.
  142. ALIGN( pBuffer, 3);
  143. if ( (NON_STANDARD_CLIPFORMAT(pObject)) && ((REMOTE_CLIPFORMAT( pFlags) )
  144. || (g_cTSSessions > 1 ))) // ignore console session
  145. {
  146. // sending a wide string
  147. unsigned long ret;
  148. *(PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  149. *(PULONG_LV_CAST pBuffer)++ = (ulong) *pObject;
  150. // On Chicago this is GetClipboardFormatNameX.
  151. // When the buffer is too short, this call would still
  152. // return a decent, null terminated, truncated string.
  153. //
  154. ret = (ulong) GetClipboardFormatName( *pObject,
  155. (wchar_t *)(pBuffer + 12),
  156. CLIPFORMAT_BUFFER_MAX - 1
  157. );
  158. if ( ret )
  159. {
  160. ret++;
  161. // conformat size etc. for string.
  162. *(PULONG_LV_CAST pBuffer)++ = ret;
  163. *(PULONG_LV_CAST pBuffer)++ = 0;
  164. *(PULONG_LV_CAST pBuffer)++ = ret;
  165. // skip the string in the bbuffer, including the terminator
  166. pBuffer += ret * sizeof(wchar_t);
  167. }
  168. else
  169. RpcRaiseException( DV_E_CLIPFORMAT );
  170. }
  171. else
  172. {
  173. // sending the number itself
  174. *(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  175. *(PULONG_LV_CAST pBuffer)++ = (ulong) *pObject;
  176. }
  177. return( pBuffer );
  178. }
  179. //+-------------------------------------------------------------------------
  180. //
  181. // Function: CLIPFORMAT_UserUnmarshal
  182. //
  183. // Synopsis: Unmarshals a CLIPFORMAT; registers if needed.
  184. //
  185. // Derivation: A union of a long and a string.
  186. //
  187. // history: Feb-96 Ryszardk Created
  188. // Aug-99 JohnStra Added consistency checks
  189. //
  190. //--------------------------------------------------------------------------
  191. unsigned char __RPC_FAR * __RPC_USER
  192. CLIPFORMAT_UserUnmarshal(
  193. unsigned long * pFlags,
  194. unsigned char * pBuffer,
  195. CLIPFORMAT * pObject )
  196. {
  197. ulong UnionDisc;
  198. UINT cf;
  199. // Get the buffer size and the start of the buffer.
  200. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  201. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  202. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  203. // Align the buffer and save the fixup size.
  204. ALIGN( pBuffer, 3 );
  205. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  206. // Check for EOB before accessing buffer.
  207. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) );
  208. UnionDisc = *(PULONG_LV_CAST pBuffer)++;
  209. cf = (WORD) *(PULONG_LV_CAST pBuffer)++;
  210. if ( WDT_DATA_MARKER == UnionDisc )
  211. {
  212. // CLIPFORMAT value must be in valid range.
  213. if ( cf < 0xc000 || cf > 0xffff )
  214. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  215. // Check for EOB before accessing string header.
  216. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (5 * sizeof( ULONG )) );
  217. // Get the string header from the buffer and subtract the string
  218. // header from the BufferSize.
  219. ULONG ConfSize = *(PULONG_LV_CAST pBuffer)++;
  220. ULONG Offset = *(PULONG_LV_CAST pBuffer)++;
  221. ULONG ActualSize = *(PULONG_LV_CAST pBuffer)++;
  222. // Verify the header: Offset must always be zero, length must match
  223. // size, and size can't be zero since that would mean no NULL
  224. // terminator.
  225. if ( 0 != Offset || ActualSize != ConfSize || 0 == ActualSize )
  226. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  227. // Check for EOB before accessing string.
  228. CHECK_BUFFER_SIZE(
  229. BufferSize,
  230. cbFixup + (5 * sizeof(ULONG)) + (ActualSize * sizeof(WCHAR)) );
  231. // Last two bytes of the buffer must be unicode terminator
  232. if ( *(WCHAR*)(pBuffer + ((ActualSize-1) * sizeof(WCHAR))) != 0x0000 )
  233. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  234. // Must be only 1 unicode terminator.
  235. if ( (ULONG)(lstrlenW( (WCHAR*)pBuffer ) + 1) != ActualSize )
  236. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  237. // Register the clipboard format.
  238. cf = RegisterClipboardFormat( (wchar_t *)pBuffer );
  239. if ( cf == 0 )
  240. RAISE_RPC_EXCEPTION( DV_E_CLIPFORMAT );
  241. // Advance buffer pointer past string.
  242. pBuffer += ActualSize * sizeof(wchar_t);
  243. }
  244. else if ( WDT_HANDLE_MARKER != UnionDisc )
  245. {
  246. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  247. }
  248. *pObject = (CLIPFORMAT) cf;
  249. return( pBuffer );
  250. }
  251. //+-------------------------------------------------------------------------
  252. //
  253. // Function: CLIPFORMAT_UserFree
  254. //
  255. // Synopsis: Frees remnants of CLIPFORMAT.
  256. //
  257. // Derivation: A union of a long and a string.
  258. //
  259. // history: Feb-96 Ryszardk Created
  260. //
  261. //--------------------------------------------------------------------------
  262. void __RPC_USER
  263. CLIPFORMAT_UserFree(
  264. unsigned long * pFlags,
  265. CLIPFORMAT * pObject )
  266. {
  267. // Nothing to free, as nothing gets allocated when we unmarshal.
  268. }
  269. #if defined(_WIN64)
  270. //+-------------------------------------------------------------------------
  271. //
  272. // Function: CLIPFORMAT_UserSize64
  273. //
  274. // Synopsis: Sizes a CLIPFORMAT.
  275. //
  276. // Derivation: A union of a long and a string.
  277. //
  278. // history: Dec-00 JohnDoty Created from 32bit function
  279. //
  280. //--------------------------------------------------------------------------
  281. unsigned long __RPC_USER
  282. CLIPFORMAT_UserSize64 (
  283. unsigned long * pFlags,
  284. unsigned long Offset,
  285. CLIPFORMAT * pObject )
  286. {
  287. if ( !pObject )
  288. return( Offset );
  289. // userCLIPFORMAT is an encapsulated union with a string.
  290. // max align of the union is size of 64b pointer.
  291. LENGTH_ALIGN( Offset, 7 );
  292. Offset += 8; // 4 byte discriminant, 4 byte alignment
  293. if ( (NON_STANDARD_CLIPFORMAT(pObject)) && ((REMOTE_CLIPFORMAT( pFlags) )
  294. || (g_cTSSessions > 1 ))) // ignore console session
  295. {
  296. // Writing another pointer...
  297. Offset += 8; // 64b pointer
  298. wchar_t temp[CLIPFORMAT_BUFFER_MAX + 1];
  299. int ret = GetClipboardFormatName( *pObject,
  300. temp,
  301. CLIPFORMAT_BUFFER_MAX );
  302. if ( ret )
  303. {
  304. // This string has 3 conformance fields (64b) followed by an
  305. // array of 16b chars.
  306. Offset += (3 * 8) + ((ret + 1) * 2);
  307. }
  308. else
  309. RAISE_RPC_EXCEPTION( DV_E_CLIPFORMAT );
  310. }
  311. else
  312. {
  313. // Writing a DWORD
  314. Offset += 4;
  315. }
  316. return( Offset );
  317. }
  318. //+-------------------------------------------------------------------------
  319. //
  320. // Function: CLIPFORMAT_UserMarshal64
  321. //
  322. // Synopsis: Marshals a CLIPFORMAT.
  323. //
  324. // Derivation: A union of a long and a string.
  325. //
  326. // history: Dec-00 JohnDoty Created from 32bit function
  327. //
  328. //--------------------------------------------------------------------------
  329. unsigned char __RPC_FAR * __RPC_USER
  330. CLIPFORMAT_UserMarshal64 (
  331. unsigned long * pFlags,
  332. unsigned char * pBuffer,
  333. CLIPFORMAT * pObject )
  334. {
  335. if ( !pObject )
  336. return pBuffer;
  337. // userCLIPFORMAT is an encapsulated union with a string.
  338. ALIGN( pBuffer, 7 );
  339. if ( (NON_STANDARD_CLIPFORMAT(pObject)) && ((REMOTE_CLIPFORMAT( pFlags) )
  340. || (g_cTSSessions > 1 ))) // ignore console session
  341. {
  342. // sending a wide string
  343. unsigned long ret;
  344. *(PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  345. ALIGN( pBuffer, 7 );
  346. *(PHYPER_LV_CAST pBuffer)++ = (hyper) *pObject;
  347. // On Chicago this is GetClipboardFormatNameX.
  348. // When the buffer is too short, this call would still
  349. // return a decent, null terminated, truncated string.
  350. //
  351. ret = (ulong) GetClipboardFormatName( *pObject,
  352. (wchar_t *)(pBuffer + (3 * 8)),
  353. CLIPFORMAT_BUFFER_MAX
  354. );
  355. if ( ret )
  356. {
  357. // Account for the trailing NULL.
  358. ret ++;
  359. // conformat size etc. for string.
  360. *(PHYPER_LV_CAST pBuffer)++ = ret; // Conformance
  361. *(PHYPER_LV_CAST pBuffer)++ = 0; // Offset
  362. *(PHYPER_LV_CAST pBuffer)++ = ret; // Actual Size
  363. // skip the string in the buffer, including the terminator
  364. pBuffer += (ret * 2);
  365. }
  366. else
  367. RpcRaiseException( DV_E_CLIPFORMAT );
  368. }
  369. else
  370. {
  371. // sending the number itself
  372. *(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  373. ALIGN( pBuffer, 7 );
  374. *(PULONG_LV_CAST pBuffer)++ = (ulong) *pObject;
  375. }
  376. return( pBuffer );
  377. }
  378. //+-------------------------------------------------------------------------
  379. //
  380. // Function: CLIPFORMAT_UserUnmarshal64
  381. //
  382. // Synopsis: Unmarshals a CLIPFORMAT; registers if needed.
  383. //
  384. // Derivation: A union of a long and a string.
  385. //
  386. // history: Dec-00 JohnDoty Created from 32bit function
  387. //
  388. //--------------------------------------------------------------------------
  389. unsigned char __RPC_FAR * __RPC_USER
  390. CLIPFORMAT_UserUnmarshal64 (
  391. unsigned long * pFlags,
  392. unsigned char * pBuffer,
  393. CLIPFORMAT * pObject )
  394. {
  395. ulong UnionDisc;
  396. hyper cf;
  397. // Get the buffer size and the start of the buffer.
  398. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  399. CarefulBufferReader stream( pBuffer, MarshalInfo.GetBufferSize() );
  400. stream.Align( 8 ); // Must align on 8, union rules.
  401. UnionDisc = stream.ReadULONGNA(); // ...so no need to align on 4 here...
  402. stream.Align( 8 ); // ...but must explicitly align to 8 here again.
  403. if ( WDT_DATA_MARKER == UnionDisc )
  404. {
  405. cf = stream.ReadHYPERNA(); // Just aligned 8, so don't align again.
  406. // CLIPFORMAT value must be in valid range.
  407. if ( cf < 0xc000 || cf > 0xffff )
  408. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  409. // Get the string header from the buffer and subtract the string
  410. // header from the BufferSize.
  411. hyper ConfSize = stream.ReadHYPERNA();
  412. hyper Offset = stream.ReadHYPERNA();
  413. hyper ActualSize = stream.ReadHYPERNA();
  414. // Verify the header: Offset must always be zero, length must match
  415. // size, and size can't be zero since that would mean no NULL
  416. // terminator.
  417. if ( 0 != Offset || ActualSize != ConfSize || 0 == ActualSize )
  418. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  419. // Check for EOB before accessing string.
  420. stream.CheckSize((unsigned long)(ActualSize * sizeof(WCHAR)));
  421. // Last two bytes of the buffer must be unicode terminator
  422. WCHAR *pCheck = (WCHAR *)stream.GetBuffer();
  423. if ( pCheck[ActualSize-1] != 0x0000 )
  424. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  425. // Must be only 1 unicode terminator.
  426. if ( (ULONG)(lstrlenW( pCheck ) + 1) != ActualSize )
  427. RAISE_RPC_EXCEPTION( RPC_X_INVALID_BOUND );
  428. // Register the clipboard format.
  429. cf = RegisterClipboardFormat( pCheck );
  430. if ( cf == 0 )
  431. RAISE_RPC_EXCEPTION( DV_E_CLIPFORMAT );
  432. // Advance buffer pointer past string.
  433. stream.Advance((unsigned long)(ActualSize * sizeof(WCHAR)));
  434. }
  435. else if ( WDT_HANDLE_MARKER == UnionDisc )
  436. {
  437. cf = (hyper)stream.ReadULONGNA(); // Just aligned on 8...
  438. }
  439. else
  440. {
  441. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  442. }
  443. *pObject = (CLIPFORMAT) cf;
  444. return( stream.GetBuffer() );
  445. }
  446. //+-------------------------------------------------------------------------
  447. //
  448. // Function: CLIPFORMAT_UserFree64
  449. //
  450. // Synopsis: Frees remnants of CLIPFORMAT.
  451. //
  452. // Derivation: A union of a long and a string.
  453. //
  454. // history: Dec-00 JohnDoty Created from 32bit function
  455. //
  456. //--------------------------------------------------------------------------
  457. void __RPC_USER
  458. CLIPFORMAT_UserFree64 (
  459. unsigned long * pFlags,
  460. CLIPFORMAT * pObject )
  461. {
  462. // Nothing to free, as nothing gets allocated when we unmarshal.
  463. }
  464. #endif // win64