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.

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