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.

483 lines
14 KiB

  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <memory.h>
  6. #include <ddeml.h>
  7. #include <strsafe.h>
  8. #include "common.h"
  9. #include "clipfile.h"
  10. #include "clipsrv.h"
  11. #include "ddeutil.h"
  12. #include "callback.h"
  13. #include "debugout.h"
  14. /*
  15. * GetTopicListA
  16. *
  17. * Purpose: Creata a DDE handle to a block containing a tab-delimited
  18. * list of the available topics with a NULL at the end.
  19. *
  20. * Parameters:
  21. * fAllTopicReq - TRUE to get all topics, FALSE to just get shared.
  22. *
  23. * Returns: The data handle.
  24. *
  25. * Notes: AW variants
  26. */
  27. HDDEDATA GetTopicListA(
  28. HCONV hConv,
  29. BOOL fAllTopicReq)
  30. {
  31. LPSTR lpszTopics;
  32. LPSTR pTmp;
  33. HDDEDATA hData;
  34. DWORD cbData = 0L;
  35. pShrInfo pshrinfo;
  36. for ( pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next )
  37. {
  38. /*
  39. * Keep enough buffer for MBCS string,
  40. */
  41. cbData += ( ( lstrlenW( pshrinfo->szName ) + 1 ) * sizeof(WORD) );
  42. }
  43. cbData += sizeof(szUpdateName) +1;
  44. // if there are no entries, must send a "" string, not 0!
  45. if ( !cbData )
  46. return (DdeCreateDataHandle (idInst, TEXT(""), 1, 0L, hszTopicList, CF_TEXT, 0));
  47. hData = DdeCreateDataHandle (idInst, NULL, cbData, 0L, hszTopicList, CF_TEXT, 0);
  48. if ( !hData )
  49. {
  50. SetXactErr (hConv, XERRT_DDE, DdeGetLastError (idInst));
  51. PERROR(TEXT("error creating hddedata for topic list\n\r"));
  52. }
  53. else
  54. {
  55. if ( ( pTmp = lpszTopics = DdeAccessData(hData, NULL) ) == (LPSTR)NULL )
  56. {
  57. SetXactErr (hConv, XERRT_DDE, DdeGetLastError (idInst));
  58. PERROR(TEXT("error accessing data handle for topic list\n\r"));
  59. DdeFreeDataHandle(hData);
  60. hData = 0L;
  61. }
  62. else
  63. {
  64. // put the updated name first
  65. #ifdef UNICODE
  66. StringCchPrintfA (pTmp, cbData, "%lc%ls\t", BOGUS_CHAR, szUpdateName);
  67. #else
  68. StringCchPrintfA (pTmp, cbData, "%hc%hs\t", BOGUS_CHAR, szUpdateName);
  69. #endif
  70. pTmp += lstrlenA (pTmp);
  71. // Create a tab-delimited list of topics in CF_TEXT format.
  72. for ( pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next )
  73. {
  74. // Only list SHARED topics if this isn't a "[alltopiclist]" req
  75. if (SHR_CHAR == pshrinfo->szName[0] ||
  76. fAllTopicReq)
  77. {
  78. WideCharToMultiByte (CP_ACP,
  79. 0,
  80. pshrinfo->szName,
  81. -1,
  82. pTmp,
  83. (int)(cbData - (size_t)(pTmp - lpszTopics)),
  84. NULL,
  85. NULL);
  86. pTmp += lstrlenA(pTmp);
  87. *pTmp++ = '\t';
  88. }
  89. }
  90. // Turn the last tab into a NULL.
  91. if ( pTmp != lpszTopics )
  92. *--pTmp = '\0';
  93. DdeUnaccessData ( hData );
  94. }
  95. }
  96. return hData;
  97. }
  98. /*
  99. * GetTopicListW
  100. */
  101. HDDEDATA GetTopicListW(
  102. HCONV hConv,
  103. BOOL fAllTopicsReq)
  104. {
  105. LPWSTR lpszTopics;
  106. LPWSTR pTmp;
  107. HDDEDATA hData;
  108. DWORD cbData = 0L;
  109. pShrInfo pshrinfo;
  110. for (pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next)
  111. {
  112. /*
  113. * Keep enough buffer for MBCS string,
  114. */
  115. cbData += ( ( lstrlenW( pshrinfo->szName ) + 1 ) * sizeof(WORD) );
  116. }
  117. cbData += sizeof(szUpdateName) + sizeof(WORD);
  118. // if there are no entries, must send a "" string, not 0!
  119. if ( !cbData )
  120. return DdeCreateDataHandle (idInst, TEXT(""), 1, 0L, hszTopicList, CF_UNICODETEXT, 0);
  121. hData = DdeCreateDataHandle (idInst, NULL, cbData, 0L, hszTopicList, CF_UNICODETEXT, 0);
  122. if ( !hData )
  123. {
  124. SetXactErr (hConv, XERRT_DDE, DdeGetLastError(idInst));
  125. PERROR(TEXT("error creating hddedata for topic list\n\r"));
  126. }
  127. else
  128. {
  129. if ((pTmp = lpszTopics = (LPWSTR)DdeAccessData( hData, NULL ))
  130. == (LPWSTR)NULL)
  131. {
  132. SetXactErr (hConv, XERRT_DDE, DdeGetLastError(idInst));
  133. PERROR(TEXT("error accessing data handle for topic list\n\r"));
  134. DdeFreeDataHandle(hData);
  135. hData = 0L;
  136. }
  137. else
  138. {
  139. // put the updated name first
  140. #ifdef UNICODE
  141. StringCbPrintfW (pTmp, cbData, L"%lc%ls\t", BOGUS_CHAR, szUpdateName);
  142. #else
  143. StringCbPrintfW (pTmp, cbData, L"%hc%hs\t", BOGUS_CHAR, szUpdateName);
  144. #endif
  145. pTmp += lstrlenW (pTmp);
  146. // Create a tab-delimited list of topics in CF_TEXT format.
  147. for (pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next )
  148. {
  149. if (SHR_CHAR == pshrinfo->szName[0] ||
  150. fAllTopicsReq)
  151. {
  152. StringCbCopyW( pTmp, cbData - (pTmp-lpszTopics), pshrinfo->szName );
  153. pTmp += lstrlenW(pTmp);
  154. *pTmp++ = '\t';
  155. }
  156. }
  157. // Turn the last tab into a NULL.
  158. if ( pTmp != lpszTopics )
  159. *--pTmp = '\0';
  160. DdeUnaccessData ( hData );
  161. }
  162. }
  163. return hData;
  164. }
  165. /*
  166. * GetFormatListA
  167. *
  168. * Purpose: Create a DDE handle containing a tab-delimited list of the
  169. * formats available for the given topic -- it's assumed to be a share.
  170. *
  171. * Parameters:
  172. * hszTopic - String handle to the topic name.
  173. *
  174. * Returns:
  175. * DDE handle to the list.
  176. *
  177. * Notes:
  178. * AW variants
  179. */
  180. HDDEDATA GetFormatListA(
  181. HCONV hConv,
  182. HSZ hszTopic )
  183. {
  184. LPSTR lpszFormats;
  185. LPSTR lpcsTmp;
  186. HDDEDATA hData = 0L;
  187. DWORD cbData = 0L;
  188. pShrInfo pshrinfo;
  189. unsigned cFormats;
  190. FORMATHEADER FormatHeader;
  191. unsigned i;
  192. HANDLE fh;
  193. PINFO(TEXT("GetFormatList:"));
  194. for ( pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next )
  195. {
  196. if ( DdeCmpStringHandles ( hszTopic, pshrinfo->hszName ) == 0 )
  197. {
  198. #ifdef CACHEFORMATLIST
  199. if (pshrinfo->hFormatList)
  200. return pshrinfo->hFormatList;
  201. #endif
  202. fh = CreateFileW (pshrinfo->szFileName,
  203. GENERIC_READ,
  204. 0,
  205. NULL,
  206. OPEN_EXISTING,
  207. 0,
  208. NULL);
  209. if ( INVALID_HANDLE_VALUE == fh)
  210. {
  211. SetXactErr (hConv, XERRT_SYS, GetLastError());
  212. PERROR(TEXT("ERROR opening %s\n\r"), pshrinfo->szFileName);
  213. }
  214. else
  215. {
  216. cFormats = ReadFileHeader(fh);
  217. // allocate max data - some will be wasted.
  218. // Keep enought buffer for MBCS string,
  219. cbData = cFormats * CCHFMTNAMEMAX * sizeof(WORD);
  220. hData = DdeCreateDataHandle (idInst,
  221. NULL,
  222. cbData,
  223. 0L,
  224. hszFormatList,
  225. CF_TEXT,
  226. #ifdef CACHEFORMATLIST
  227. HDATA_APPOWNED );
  228. #else
  229. 0 );
  230. #endif
  231. if (!hData)
  232. {
  233. SetXactErr (hConv, XERRT_DDE, DdeGetLastError (idInst));
  234. PERROR(TEXT("DdeCreateDataHandle failed!!!\n\r"));
  235. }
  236. else
  237. {
  238. lpszFormats = DdeAccessData(hData, NULL);
  239. lpcsTmp = lpszFormats;
  240. if (NULL == lpcsTmp)
  241. {
  242. SetXactErr (hConv, XERRT_DDE, DdeGetLastError (idInst));
  243. DdeFreeDataHandle ( hData );
  244. hData = 0L;
  245. PERROR(TEXT("DdeAccessData failed!!!\n\r"));
  246. }
  247. else
  248. {
  249. PINFO(TEXT("%d formats found\n\r"), cFormats);
  250. // form tab-separated list
  251. for (i=0; i < cFormats; i++)
  252. {
  253. ReadFormatHeader(fh, &FormatHeader, i);
  254. PINFO(TEXT("getformat: read >%ws<\n\r"), FormatHeader.Name);
  255. WideCharToMultiByte (CP_ACP,
  256. 0,
  257. FormatHeader.Name,
  258. -1,
  259. lpcsTmp,
  260. cbData - (UINT)(lpcsTmp-lpszFormats),
  261. NULL,
  262. NULL);
  263. lpcsTmp += lstrlenA(lpcsTmp);
  264. *lpcsTmp++ = '\t';
  265. }
  266. *--lpcsTmp = '\0';
  267. PINFO(TEXT("clipsrv: returning format list >%cs<\n\r"), lpszFormats );
  268. DdeUnaccessData ( hData );
  269. #ifdef CACHEFORMATLIST
  270. pshrinfo->hFormatList = hData;
  271. #endif
  272. }
  273. }
  274. CloseHandle(fh);
  275. }
  276. }
  277. }
  278. if (!hData)
  279. {
  280. PERROR (TEXT("GetFormatList: Topic not found\n\r"));
  281. }
  282. return hData;
  283. }
  284. /*
  285. * GetFormatListW
  286. */
  287. HDDEDATA GetFormatListW(
  288. HCONV hConv,
  289. HSZ hszTopic )
  290. {
  291. LPWSTR lpszFormats;
  292. LPWSTR lpwsTmp;
  293. HDDEDATA hData = 0L;
  294. DWORD cbData = 0L;
  295. pShrInfo pshrinfo;
  296. unsigned cFormats;
  297. FORMATHEADER FormatHeader;
  298. unsigned i;
  299. HANDLE fh;
  300. PINFO(TEXT("GetFormatList:"));
  301. for ( pshrinfo=SIHead; pshrinfo; pshrinfo = pshrinfo->Next )
  302. {
  303. if ( DdeCmpStringHandles ( hszTopic, pshrinfo->hszName ) == 0 )
  304. {
  305. #ifdef CACHEFORMATLIST
  306. if ( pshrinfo->hFormatList )
  307. return pshrinfo->hFormatList;
  308. #endif
  309. fh = CreateFileW (pshrinfo->szFileName,
  310. GENERIC_READ,
  311. 0,
  312. NULL,
  313. OPEN_EXISTING,
  314. 0,
  315. NULL);
  316. if ( INVALID_HANDLE_VALUE == fh)
  317. {
  318. SetXactErr (hConv, XERRT_SYS, GetLastError());
  319. PERROR(TEXT("ERROR opening %s\n\r"), pshrinfo->szFileName);
  320. }
  321. else
  322. {
  323. cFormats = ReadFileHeader(fh);
  324. // allocate max data - some will be wasted.
  325. // Keep enought buffer for MBCS string,
  326. cbData = cFormats * CCHFMTNAMEMAX * sizeof(WORD);
  327. hData = DdeCreateDataHandle (idInst,
  328. NULL,
  329. cbData,
  330. 0L,
  331. hszFormatList,
  332. CF_TEXT,
  333. #ifdef CACHEFORMATLIST
  334. HDATA_APPOWNED );
  335. #else
  336. 0);
  337. #endif
  338. if ( !hData )
  339. {
  340. SetXactErr (hConv, XERRT_DDE, DdeGetLastError(idInst));
  341. PERROR(TEXT("DdeCreateDataHandle failed!!!\n\r"));
  342. }
  343. else
  344. {
  345. lpszFormats = (LPWSTR)DdeAccessData(hData, NULL);
  346. lpwsTmp = lpszFormats;
  347. if (NULL == lpwsTmp)
  348. {
  349. SetXactErr (hConv, XERRT_DDE, DdeGetLastError(idInst));
  350. DdeFreeDataHandle ( hData );
  351. hData = 0L;
  352. PERROR(TEXT("DdeAccessData failed!!!\n\r"));
  353. }
  354. else
  355. {
  356. PINFO(TEXT("%d formats found\n\r"), cFormats);
  357. // form tab-separated list
  358. for (i=0; i < cFormats; i++)
  359. {
  360. ReadFormatHeader (fh, &FormatHeader, i);
  361. PINFO(TEXT("getformat: read >%ws<\n\r"), FormatHeader.Name);
  362. StringCbCopyW (lpwsTmp, cbData-(lpwsTmp-lpszFormats), FormatHeader.Name);
  363. lpwsTmp += lstrlenW (FormatHeader.Name);
  364. *lpwsTmp++ = '\t';
  365. }
  366. *--lpwsTmp = '\0';
  367. PINFO(TEXT("clipsrv: returning format list >%ws<\n\r"), lpszFormats );
  368. DdeUnaccessData ( hData );
  369. #ifdef CACHEFORMATLIST
  370. pshrinfo->hFormatList = hData;
  371. #endif
  372. }
  373. }
  374. CloseHandle(fh);
  375. }
  376. }
  377. }
  378. if (!hData)
  379. {
  380. PERROR (TEXT("GetFormatList: Topic not found\n\r"));
  381. }
  382. return hData;
  383. }