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.

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