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.

531 lines
15 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: GENERIC.C
  3. *
  4. * Handles all API routines for the generic sub-dll of the ole dll.
  5. * Since the data format is unknown, all the routines are written with the
  6. * assumption that all the relevant data is placed in a single global data
  7. * segment. Note that this assumption is not valid for metafiles, bitmaps, and
  8. * and there can always be some other formats with such idiosyncracies. To
  9. * accommodate those cases the rendering dll writer should replace the relevant
  10. * routines after the creation of the generic object. If for a given class this
  11. * assumption (about data format) is valid then the dll writer need to replace
  12. * only the Draw and QueryBounds functions.
  13. *
  14. * Created: November-1990
  15. *
  16. * Copyright (c) 1990, 1991 Microsoft Corporation
  17. *
  18. * History:
  19. *
  20. * Srinik, Raor (11/05/90) Designed, coded
  21. *
  22. \***************************************************************************/
  23. #include <windows.h>
  24. #include "dll.h"
  25. #include "pict.h"
  26. char aMacText[4] = {'T', 'E', 'X', 'T'};
  27. char aMacRtf[4] = "RTF";
  28. extern OLESTATUS FARINTERNAL wCreateDummyMetaFile (LPOBJECT_MF, int, int);
  29. #pragma alloc_text(_TEXT, GenSaveToStream, GenLoadFromStream, GetBytes, PutBytes, PutStrWithLen, PutAtomIntoStream, GenQueryBounds)
  30. OLEOBJECTVTBL vtblGEN = {
  31. ErrQueryProtocol, // check whether the speced protocol is supported
  32. GenRelease, // Release
  33. ErrShow, // Show
  34. ErrPlay, // plat
  35. GenGetData, // Get the object data
  36. GenSetData, // Set the object data
  37. ErrSetTargetDevice, //
  38. ErrSetBounds, // set viewport bounds
  39. GenEnumFormat, // enumerate supported formats
  40. ErrSetColorScheme, //
  41. GenRelease, // delete
  42. ErrSetHostNames, //
  43. GenSaveToStream, // write to file
  44. GenClone, // clone object
  45. ErrCopyFromLink, // Create embedded from Link
  46. GenEqual, // compares the given objects for data equality
  47. GenCopy, // copy to clip
  48. GenDraw, // draw the object
  49. ErrActivate, // open
  50. ErrExecute, // excute
  51. ErrClose, // Stop
  52. ErrUpdate, // Update
  53. ErrReconnect, // Reconnect
  54. ErrObjectConvert, // convert object to specified type
  55. ErrGetUpdateOptions, // update options
  56. ErrSetUpdateOptions, // update options
  57. ObjRename, // Change Object name
  58. ObjQueryName, // Get current object name
  59. GenQueryType, // Object type
  60. GenQueryBounds, // QueryBounds
  61. ObjQuerySize, // Find the size of the object
  62. ErrQueryOpen, // Query open
  63. ErrQueryOutOfDate, // query whether object is current
  64. ErrQueryRelease, // release related stuff
  65. ErrQueryRelease,
  66. ErrQueryRelease,
  67. ErrRequestData, // requestdata
  68. ErrObjectLong, // objectLong
  69. GenChangeData // change data of the existing object
  70. };
  71. OLESTATUS FARINTERNAL GenRelease (lpobj)
  72. LPOBJECT_GEN lpobj;
  73. {
  74. HOBJECT hobj;
  75. if (lpobj->hData) {
  76. GlobalFree (lpobj->hData);
  77. lpobj->hData = NULL;
  78. }
  79. if (lpobj->aClass)
  80. GlobalDeleteAtom (lpobj->aClass);
  81. if (lpobj->head.lhclientdoc)
  82. DocDeleteObject ((LPOLEOBJECT) lpobj);
  83. if (hobj = lpobj->head.hobj){
  84. lpobj->head.hobj = NULL;
  85. GlobalUnlock (hobj);
  86. GlobalFree (hobj);
  87. }
  88. return OLE_OK;
  89. }
  90. OLESTATUS FARINTERNAL GenSaveToStream (lpobj, lpstream)
  91. LPOBJECT_GEN lpobj;
  92. LPOLESTREAM lpstream;
  93. {
  94. LPSTR lpData;
  95. OLESTATUS retVal = OLE_OK;
  96. DWORD dwClipFormat = NULL;
  97. char formatName[MAX_STR];
  98. if (!lpobj->hData)
  99. return OLE_ERROR_BLANK;
  100. if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG)))
  101. return OLE_ERROR_STREAM;
  102. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  103. return OLE_ERROR_STREAM;
  104. if (PutAtomIntoStream (lpstream, lpobj->aClass))
  105. return OLE_ERROR_STREAM;
  106. if (lpobj->cfFormat < 0xC000)
  107. // then it is a predefined format
  108. dwClipFormat = lpobj->cfFormat;
  109. if (PutBytes (lpstream, (LPSTR) &dwClipFormat, sizeof(DWORD)))
  110. return OLE_ERROR_STREAM;
  111. if (!dwClipFormat) {
  112. if (!GetClipboardFormatName (lpobj->cfFormat, (LPSTR) formatName,
  113. sizeof(formatName)))
  114. return OLE_ERROR_FORMAT;
  115. if (PutStrWithLen (lpstream, formatName))
  116. return OLE_ERROR_STREAM;
  117. }
  118. if (!lpobj->sizeBytes)
  119. return OLE_ERROR_BLANK;
  120. if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  121. return OLE_ERROR_STREAM;
  122. if (!(lpData = GlobalLock (lpobj->hData)))
  123. return OLE_ERROR_MEMORY;
  124. if (PutBytes (lpstream, lpData, lpobj->sizeBytes))
  125. retVal = OLE_ERROR_STREAM;
  126. GlobalUnlock (lpobj->hData);
  127. return retVal;
  128. }
  129. OLESTATUS FARINTERNAL GenClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj)
  130. LPOBJECT_GEN lpobjsrc;
  131. LPOLECLIENT lpclient;
  132. LHCLIENTDOC lhclientdoc;
  133. LPSTR lpobjname;
  134. LPOBJECT_GEN FAR * lplpobj;
  135. {
  136. if (!lpobjsrc->hData)
  137. return OLE_ERROR_BLANK;
  138. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  139. return OLE_ERROR_HANDLE;
  140. if (!(*lplpobj = GenCreateObject (lpobjsrc->hData, lpclient,
  141. FALSE, lhclientdoc,
  142. lpobjname, lpobjsrc->head.ctype)))
  143. return OLE_ERROR_MEMORY;
  144. else {
  145. (*lplpobj)->cfFormat = lpobjsrc->cfFormat;
  146. (*lplpobj)->aClass = DuplicateAtom (lpobjsrc->aClass);
  147. return OLE_OK;
  148. }
  149. }
  150. OLESTATUS FARINTERNAL GenEqual (lpobj1, lpobj2)
  151. LPOBJECT_GEN lpobj1;
  152. LPOBJECT_GEN lpobj2;
  153. {
  154. if (CmpGlobals (lpobj1->hData, lpobj2->hData))
  155. return OLE_OK;
  156. return OLE_ERROR_NOT_EQUAL;
  157. }
  158. OLESTATUS FARINTERNAL GenCopy (lpobj)
  159. LPOBJECT_GEN lpobj;
  160. {
  161. HANDLE hData;
  162. if (!lpobj->hData)
  163. return OLE_ERROR_BLANK;
  164. if (!(hData = DuplicateGlobal (lpobj->hData, GMEM_MOVEABLE)))
  165. return OLE_ERROR_MEMORY;
  166. SetClipboardData (lpobj->cfFormat, hData);
  167. return OLE_OK;
  168. }
  169. OLESTATUS FARINTERNAL GenLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat)
  170. LPOLESTREAM lpstream;
  171. LPOLECLIENT lpclient;
  172. LHCLIENTDOC lhclientdoc;
  173. LPSTR lpobjname;
  174. LPOLEOBJECT FAR * lplpobj;
  175. LONG objType;
  176. ATOM aClass;
  177. OLECLIPFORMAT cfFormat;
  178. {
  179. LPOBJECT_GEN lpobj = NULL;
  180. OLESTATUS retVal = OLE_ERROR_STREAM;
  181. HANDLE hData;
  182. LPSTR lpData;
  183. DWORD dwClipFormat;
  184. char formatName[MAX_STR];
  185. LONG length;
  186. if (!(*lplpobj = (LPOLEOBJECT) (lpobj = GenCreateBlank(lhclientdoc,
  187. lpobjname, objType,
  188. aClass)))) {
  189. if (aClass)
  190. GlobalDeleteAtom(aClass);
  191. return OLE_ERROR_MEMORY;
  192. }
  193. if (GetBytes (lpstream, (LPSTR) &dwClipFormat, sizeof (DWORD)))
  194. goto errLoad;
  195. // If object is from MAC then we will keep the data intact if the data
  196. // format is either TEXT or RTF
  197. if (HIWORD(dwVerFromFile) == OS_MAC) {
  198. if (dwClipFormat == *((DWORD *) aMacText))
  199. lpobj->cfFormat = CF_TEXT;
  200. else if (dwClipFormat == *((DWORD *) aMacRtf))
  201. lpobj->cfFormat = RegisterClipboardFormat ((LPSTR) "Rich Text Format");
  202. else
  203. lpobj->cfFormat = NULL;
  204. }
  205. else {
  206. // object is created on windows
  207. if (!dwClipFormat) {
  208. // this is new file format. format name string follows
  209. if (GetBytes (lpstream, (LPSTR) &length, sizeof (LONG))
  210. || GetBytes (lpstream, (LPSTR)formatName, length)
  211. || (!(lpobj->cfFormat = RegisterClipboardFormat ((LPSTR) formatName))))
  212. goto errLoad;
  213. }
  214. else if ((lpobj->cfFormat = (WORD) dwClipFormat) >= 0xc000) {
  215. // if format is not predefined and file format is old, then use
  216. // what value is passed to you through "cfFormat" argument
  217. lpobj->cfFormat = cfFormat;
  218. }
  219. }
  220. if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof (DWORD)))
  221. goto errLoad;
  222. lpobj->head.lpclient = lpclient;
  223. retVal = OLE_ERROR_MEMORY;
  224. if (!(hData = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)))
  225. goto errLoad;
  226. if (!(lpData = GlobalLock (hData)))
  227. goto errMem;
  228. if (GetBytes (lpstream, lpData, lpobj->sizeBytes)) {
  229. retVal = OLE_ERROR_STREAM;
  230. GlobalUnlock (hData);
  231. goto errMem;
  232. }
  233. lpobj->hData = hData;
  234. GlobalUnlock (hData);
  235. // if the object is from MAC then we want delete this and create blank
  236. // metafile object, which draws a rectangle
  237. if ((HIWORD(dwVerFromFile) == OS_MAC) && !lpobj->cfFormat) {
  238. LPOBJECT_MF lpobjMf;
  239. OleDelete ((LPOLEOBJECT)lpobj); // delete generic object
  240. // Now create a dummy metafile object which draws a rectangle of size
  241. // 1" x 1". Note that 1" = 2540 HIMETRIC units
  242. lpobjMf = MfCreateBlank (lhclientdoc, lpobjname, objType);
  243. lpobjMf->head.cx = lpobjMf->mfp.xExt = 2540;
  244. lpobjMf->head.cy = - (lpobjMf->mfp.yExt = 2540);
  245. if ((retVal = wCreateDummyMetaFile (lpobjMf, lpobjMf->mfp.xExt,
  246. lpobjMf->mfp.yExt)) != OLE_OK) {
  247. OleDelete ((LPOLEOBJECT) lpobjMf);
  248. return retVal;
  249. }
  250. *lplpobj = (LPOLEOBJECT) lpobjMf;
  251. }
  252. return OLE_OK;
  253. errMem:
  254. GlobalFree (hData);
  255. errLoad:
  256. OleDelete ((LPOLEOBJECT)lpobj);
  257. *lplpobj = NULL;
  258. return OLE_ERROR_STREAM;
  259. }
  260. LPOBJECT_GEN INTERNAL GenCreateObject (hData, lpclient, fDelete, lhclientdoc, lpobjname, objType)
  261. HANDLE hData;
  262. LPOLECLIENT lpclient;
  263. BOOL fDelete;
  264. LHCLIENTDOC lhclientdoc;
  265. LPSTR lpobjname;
  266. LONG objType;
  267. {
  268. LPOBJECT_GEN lpobj;
  269. if (!hData)
  270. return NULL;
  271. if (lpobj = GenCreateBlank (lhclientdoc, lpobjname, objType, NULL)) {
  272. if (GenChangeData (lpobj, hData, lpclient, fDelete) != OLE_OK) {
  273. GenRelease (lpobj);
  274. lpobj = NULL;
  275. }
  276. }
  277. return lpobj;
  278. }
  279. // If the routine fails then the object will be left with it's old data.
  280. // If fDelete is TRUE, then hNewData will be deleted whether the routine
  281. // is successful or not.
  282. OLESTATUS FARINTERNAL GenChangeData (lpobj, hSrcData, lpclient, fDelete)
  283. LPOBJECT_GEN lpobj;
  284. HANDLE hSrcData;
  285. LPOLECLIENT lpclient;
  286. BOOL fDelete;
  287. {
  288. HANDLE hDestData;
  289. if (!fDelete) {
  290. if (!(hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE)))
  291. return OLE_ERROR_MEMORY;
  292. }
  293. else {
  294. // change the ownership to yourself
  295. if (!(hDestData = GlobalReAlloc(hSrcData,0L,GMEM_MODIFY|GMEM_SHARE))){
  296. hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE);
  297. GlobalFree (hSrcData);
  298. if (!hDestData)
  299. return OLE_ERROR_MEMORY;
  300. }
  301. }
  302. lpobj->head.lpclient = lpclient;
  303. if (lpobj->hData)
  304. GlobalFree (lpobj->hData);
  305. lpobj->hData = hDestData;
  306. lpobj->sizeBytes = GlobalSize (hDestData);
  307. return OLE_OK;
  308. }
  309. LPOBJECT_GEN FARINTERNAL GenCreateBlank(lhclientdoc, lpobjname, objType, aClass)
  310. LHCLIENTDOC lhclientdoc;
  311. LPSTR lpobjname;
  312. LONG objType;
  313. ATOM aClass;
  314. {
  315. HOBJECT hobj;
  316. LPOBJECT_GEN lpobj;
  317. if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_GEN)))
  318. == NULL)
  319. return NULL;
  320. if (!(lpobj = (LPOBJECT_GEN) GlobalLock (hobj))){
  321. GlobalFree (hobj);
  322. return NULL;
  323. }
  324. lpobj->head.objId[0] = 'L';
  325. lpobj->head.objId[1] = 'E';
  326. lpobj->head.mm = MM_TEXT;
  327. lpobj->head.ctype = objType;
  328. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblGEN;
  329. lpobj->head.iTable = INVALID_INDEX;
  330. lpobj->head.hobj = hobj;
  331. lpobj->aClass = aClass;
  332. if (objType == CT_STATIC)
  333. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  334. (LPOLEOBJECT) lpobj, lpobjname);
  335. return lpobj;
  336. }
  337. OLESTATUS FARINTERNAL GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj, lpClass, cfFormat, objType)
  338. LPOLECLIENT lpclient;
  339. LHCLIENTDOC lhclientdoc;
  340. LPSTR lpobjname;
  341. LPOLEOBJECT FAR * lplpobj;
  342. LPSTR lpClass;
  343. OLECLIPFORMAT cfFormat;
  344. LONG objType;
  345. {
  346. HANDLE hData = NULL;
  347. *lplpobj = NULL;
  348. if (!cfFormat)
  349. return OLE_ERROR_FORMAT;
  350. if (!(hData = GetClipboardData(cfFormat)))
  351. return OLE_ERROR_MEMORY;
  352. if (!(*lplpobj = (LPOLEOBJECT) GenCreateObject (hData, lpclient,
  353. FALSE, lhclientdoc,
  354. lpobjname, objType)))
  355. return OLE_ERROR_MEMORY;
  356. ((LPOBJECT_GEN)(*lplpobj))->cfFormat = cfFormat;
  357. ((LPOBJECT_GEN)(*lplpobj))->aClass = GlobalAddAtom (lpClass);
  358. return OLE_OK;
  359. }
  360. OLESTATUS FARINTERNAL GenQueryType (lpobj, lptype)
  361. LPOLEOBJECT lpobj;
  362. LPLONG lptype;
  363. {
  364. return OLE_ERROR_GENERIC;;
  365. }
  366. OLESTATUS FARINTERNAL GenSetData (lpobj, cfFormat, hData)
  367. LPOBJECT_GEN lpobj;
  368. OLECLIPFORMAT cfFormat;
  369. HANDLE hData;
  370. {
  371. if (lpobj->cfFormat != cfFormat)
  372. return OLE_ERROR_FORMAT;
  373. if (!hData)
  374. return OLE_ERROR_BLANK;
  375. GlobalFree (lpobj->hData);
  376. lpobj->hData = hData;
  377. lpobj->sizeBytes = GlobalSize (hData);
  378. return OLE_OK;
  379. }
  380. OLESTATUS FARINTERNAL GenGetData (lpobj, cfFormat, lphandle)
  381. LPOBJECT_GEN lpobj;
  382. OLECLIPFORMAT cfFormat;
  383. LPHANDLE lphandle;
  384. {
  385. if (cfFormat != lpobj->cfFormat)
  386. return OLE_ERROR_FORMAT;
  387. if (!(*lphandle = lpobj->hData))
  388. return OLE_ERROR_BLANK;
  389. return OLE_OK;
  390. }
  391. OLECLIPFORMAT FARINTERNAL GenEnumFormat (lpobj, cfFormat)
  392. LPOBJECT_GEN lpobj;
  393. OLECLIPFORMAT cfFormat;
  394. {
  395. if (!cfFormat)
  396. return lpobj->cfFormat;
  397. return NULL;
  398. }
  399. OLESTATUS FARINTERNAL GenQueryBounds (lpobj, lpRc)
  400. LPOBJECT_GEN lpobj;
  401. LPRECT lpRc;
  402. {
  403. lpRc->right = 0;
  404. lpRc->left = 0;
  405. lpRc->top = 0;
  406. lpRc->bottom = 0;
  407. return OLE_ERROR_GENERIC;
  408. }