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.

546 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. 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. ErrQueryReleaseMethod,
  67. ErrRequestData, // requestdata
  68. ErrObjectLong, // objectLong
  69. GenChangeData // change data of the existing object
  70. };
  71. OLESTATUS FARINTERNAL GenRelease (LPOLEOBJECT lpoleobj)
  72. {
  73. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  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 (
  91. LPOLEOBJECT lpoleobj,
  92. LPOLESTREAM lpstream
  93. ){
  94. DWORD dwFileVer = GetFileVersion(lpoleobj);
  95. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  96. LPSTR lpData;
  97. OLESTATUS retVal = OLE_OK;
  98. DWORD dwClipFormat = 0;
  99. char formatName[MAX_STR];
  100. if (!lpobj->hData)
  101. return OLE_ERROR_BLANK;
  102. if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG)))
  103. return OLE_ERROR_STREAM;
  104. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  105. return OLE_ERROR_STREAM;
  106. if (PutAtomIntoStream (lpstream, lpobj->aClass))
  107. return OLE_ERROR_STREAM;
  108. if (lpobj->cfFormat < 0xC000)
  109. // then it is a predefined format
  110. dwClipFormat = lpobj->cfFormat;
  111. if (PutBytes (lpstream, (LPSTR) &dwClipFormat, sizeof(DWORD)))
  112. return OLE_ERROR_STREAM;
  113. if (!dwClipFormat) {
  114. if (!GetClipboardFormatName (lpobj->cfFormat, (LPSTR) formatName,
  115. sizeof(formatName)))
  116. return OLE_ERROR_FORMAT;
  117. if (PutStrWithLen (lpstream, formatName))
  118. return OLE_ERROR_STREAM;
  119. }
  120. if (!lpobj->sizeBytes)
  121. return OLE_ERROR_BLANK;
  122. if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  123. return OLE_ERROR_STREAM;
  124. if (!(lpData = GlobalLock (lpobj->hData)))
  125. return OLE_ERROR_MEMORY;
  126. if (PutBytes (lpstream, lpData, lpobj->sizeBytes))
  127. retVal = OLE_ERROR_STREAM;
  128. GlobalUnlock (lpobj->hData);
  129. return retVal;
  130. }
  131. OLESTATUS FARINTERNAL GenClone (
  132. LPOLEOBJECT lpoleobjsrc,
  133. LPOLECLIENT lpclient,
  134. LHCLIENTDOC lhclientdoc,
  135. OLE_LPCSTR lpobjname,
  136. LPOLEOBJECT FAR * lplpoleobj
  137. ){
  138. LPOBJECT_GEN lpobjsrc = (LPOBJECT_GEN)lpoleobjsrc;
  139. if (!lpobjsrc->hData)
  140. return OLE_ERROR_BLANK;
  141. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  142. return OLE_ERROR_HANDLE;
  143. if (!(*lplpoleobj = (LPOLEOBJECT)GenCreateObject (lpobjsrc->hData, lpclient,
  144. FALSE, lhclientdoc,
  145. (LPSTR)lpobjname, lpobjsrc->head.ctype)))
  146. return OLE_ERROR_MEMORY;
  147. else {
  148. ((LPOBJECT_GEN)(*lplpoleobj))->cfFormat = lpobjsrc->cfFormat;
  149. ((LPOBJECT_GEN)(*lplpoleobj))->aClass = DuplicateAtom (lpobjsrc->aClass);
  150. return OLE_OK;
  151. }
  152. }
  153. OLESTATUS FARINTERNAL GenEqual (
  154. LPOLEOBJECT lpoleobj1,
  155. LPOLEOBJECT lpoleobj2
  156. ){
  157. LPOBJECT_GEN lpobj1 = (LPOBJECT_GEN)lpoleobj1;
  158. LPOBJECT_GEN lpobj2 = (LPOBJECT_GEN)lpoleobj2;
  159. if (CmpGlobals (lpobj1->hData, lpobj2->hData))
  160. return OLE_OK;
  161. return OLE_ERROR_NOT_EQUAL;
  162. }
  163. OLESTATUS FARINTERNAL GenCopy (LPOLEOBJECT lpoleobj)
  164. {
  165. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  166. HANDLE hData;
  167. if (!lpobj->hData)
  168. return OLE_ERROR_BLANK;
  169. if (!(hData = DuplicateGlobal (lpobj->hData, GMEM_MOVEABLE)))
  170. return OLE_ERROR_MEMORY;
  171. SetClipboardData (lpobj->cfFormat, hData);
  172. return OLE_OK;
  173. }
  174. OLESTATUS FARINTERNAL GenLoadFromStream (
  175. LPOLESTREAM lpstream,
  176. LPOLECLIENT lpclient,
  177. LHCLIENTDOC lhclientdoc,
  178. LPSTR lpobjname,
  179. LPOLEOBJECT FAR * lplpobj,
  180. LONG objType,
  181. ATOM aClass,
  182. OLECLIPFORMAT cfFormat
  183. ){
  184. LPOBJECT_GEN lpobj = NULL;
  185. OLESTATUS retVal = OLE_ERROR_STREAM;
  186. HANDLE hData;
  187. LPSTR lpData;
  188. DWORD dwClipFormat;
  189. char formatName[MAX_STR];
  190. LONG length;
  191. if (!(*lplpobj = (LPOLEOBJECT) (lpobj = GenCreateBlank(lhclientdoc,
  192. lpobjname, objType,
  193. aClass)))) {
  194. if (aClass)
  195. GlobalDeleteAtom(aClass);
  196. return OLE_ERROR_MEMORY;
  197. }
  198. if (GetBytes (lpstream, (LPSTR) &dwClipFormat, sizeof (DWORD)))
  199. goto errLoad;
  200. // If object is from MAC then we will keep the data intact if the data
  201. // format is either TEXT or RTF
  202. if (HIWORD(dwVerFromFile) == OS_MAC) {
  203. if (dwClipFormat == *((DWORD *) aMacText))
  204. lpobj->cfFormat = CF_TEXT;
  205. else if (dwClipFormat == *((DWORD *) aMacRtf))
  206. lpobj->cfFormat = (OLECLIPFORMAT)RegisterClipboardFormat ((LPSTR) "Rich Text Format");
  207. else
  208. lpobj->cfFormat = 0;
  209. }
  210. else {
  211. // object is created on windows
  212. if (!dwClipFormat) {
  213. // this is new file format. format name string follows
  214. if (GetBytes (lpstream, (LPSTR) &length, sizeof (LONG))
  215. || GetBytes (lpstream, (LPSTR)formatName, length)
  216. || (!(lpobj->cfFormat = (OLECLIPFORMAT)RegisterClipboardFormat ((LPSTR) formatName))))
  217. goto errLoad;
  218. }
  219. else if ((lpobj->cfFormat = (WORD) dwClipFormat) >= 0xc000) {
  220. // if format is not predefined and file format is old, then use
  221. // what value is passed to you through "cfFormat" argument
  222. lpobj->cfFormat = cfFormat;
  223. }
  224. }
  225. if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof (DWORD)))
  226. goto errLoad;
  227. lpobj->head.lpclient = lpclient;
  228. retVal = OLE_ERROR_MEMORY;
  229. if (!(hData = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)))
  230. goto errLoad;
  231. if (!(lpData = GlobalLock (hData)))
  232. goto errMem;
  233. if (GetBytes (lpstream, lpData, lpobj->sizeBytes)) {
  234. retVal = OLE_ERROR_STREAM;
  235. GlobalUnlock (hData);
  236. goto errMem;
  237. }
  238. lpobj->hData = hData;
  239. GlobalUnlock (hData);
  240. // if the object is from MAC then we want delete this and create blank
  241. // metafile object, which draws a rectangle
  242. if ((HIWORD(dwVerFromFile) == OS_MAC) && !lpobj->cfFormat) {
  243. LPOBJECT_MF lpobjMf;
  244. OleDelete ((LPOLEOBJECT)lpobj); // delete generic object
  245. // Now create a dummy metafile object which draws a rectangle of size
  246. // 1" x 1". Note that 1" = 2540 HIMETRIC units
  247. lpobjMf = MfCreateBlank (lhclientdoc, lpobjname, objType);
  248. lpobjMf->head.cx = lpobjMf->mfp.xExt = 2540;
  249. lpobjMf->head.cy = - (lpobjMf->mfp.yExt = 2540);
  250. if ((retVal = wCreateDummyMetaFile (lpobjMf, lpobjMf->mfp.xExt,
  251. lpobjMf->mfp.yExt)) != OLE_OK) {
  252. OleDelete ((LPOLEOBJECT) lpobjMf);
  253. return retVal;
  254. }
  255. }
  256. return OLE_OK;
  257. errMem:
  258. GlobalFree (hData);
  259. errLoad:
  260. OleDelete ((LPOLEOBJECT)lpobj);
  261. *lplpobj = NULL;
  262. return OLE_ERROR_STREAM;
  263. }
  264. LPOBJECT_GEN INTERNAL GenCreateObject (
  265. HANDLE hData,
  266. LPOLECLIENT lpclient,
  267. BOOL fDelete,
  268. LHCLIENTDOC lhclientdoc,
  269. LPCSTR lpobjname,
  270. LONG objType
  271. ){
  272. LPOBJECT_GEN lpobj;
  273. if (!hData)
  274. return NULL;
  275. if (lpobj = GenCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType, (ATOM)0)) {
  276. if (GenChangeData ((LPOLEOBJECT)lpobj, hData, lpclient, fDelete) != OLE_OK) {
  277. GenRelease ((LPOLEOBJECT)lpobj);
  278. lpobj = NULL;
  279. }
  280. }
  281. return lpobj;
  282. }
  283. // If the routine fails then the object will be left with it's old data.
  284. // If fDelete is TRUE, then hNewData will be deleted whether the routine
  285. // is successful or not.
  286. OLESTATUS FARINTERNAL GenChangeData (
  287. LPOLEOBJECT lpoleobj,
  288. HANDLE hSrcData,
  289. LPOLECLIENT lpclient,
  290. BOOL fDelete
  291. ){
  292. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  293. HANDLE hDestData;
  294. if (!fDelete) {
  295. if (!(hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE)))
  296. return OLE_ERROR_MEMORY;
  297. }
  298. else {
  299. // change the ownership to yourself
  300. if (!(hDestData = GlobalReAlloc(hSrcData,0L,GMEM_MODIFY|GMEM_SHARE))){
  301. hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE);
  302. GlobalFree (hSrcData);
  303. if (!hDestData)
  304. return OLE_ERROR_MEMORY;
  305. }
  306. }
  307. lpobj->head.lpclient = lpclient;
  308. if (lpobj->hData)
  309. GlobalFree (lpobj->hData);
  310. lpobj->hData = hDestData;
  311. lpobj->sizeBytes = (DWORD)GlobalSize (hDestData);
  312. return OLE_OK;
  313. }
  314. LPOBJECT_GEN FARINTERNAL GenCreateBlank(
  315. LHCLIENTDOC lhclientdoc,
  316. LPSTR lpobjname,
  317. LONG objType,
  318. ATOM aClass
  319. ){
  320. HOBJECT hobj;
  321. LPOBJECT_GEN lpobj;
  322. if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_GEN)))
  323. == NULL)
  324. return NULL;
  325. if (!(lpobj = (LPOBJECT_GEN) GlobalLock (hobj))){
  326. GlobalFree (hobj);
  327. return NULL;
  328. }
  329. lpobj->head.objId[0] = 'L';
  330. lpobj->head.objId[1] = 'E';
  331. lpobj->head.mm = MM_TEXT;
  332. lpobj->head.ctype = objType;
  333. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblGEN;
  334. lpobj->head.iTable = INVALID_INDEX;
  335. lpobj->head.hobj = hobj;
  336. lpobj->aClass = aClass;
  337. if (objType == CT_STATIC)
  338. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  339. (LPOLEOBJECT) lpobj, lpobjname);
  340. return lpobj;
  341. }
  342. OLESTATUS FARINTERNAL GenPaste (
  343. LPOLECLIENT lpclient,
  344. LHCLIENTDOC lhclientdoc,
  345. LPSTR lpobjname,
  346. LPOLEOBJECT FAR * lplpobj,
  347. LPSTR lpClass,
  348. OLECLIPFORMAT cfFormat,
  349. LONG objType
  350. ){
  351. HANDLE hData = NULL;
  352. *lplpobj = NULL;
  353. if (!cfFormat)
  354. return OLE_ERROR_FORMAT;
  355. if (!(hData = GetClipboardData(cfFormat)))
  356. return OLE_ERROR_MEMORY;
  357. if (!(*lplpobj = (LPOLEOBJECT) GenCreateObject (hData, lpclient,
  358. FALSE, lhclientdoc,
  359. lpobjname, objType)))
  360. return OLE_ERROR_MEMORY;
  361. ((LPOBJECT_GEN)(*lplpobj))->cfFormat = cfFormat;
  362. ((LPOBJECT_GEN)(*lplpobj))->aClass = GlobalAddAtom (lpClass);
  363. return OLE_OK;
  364. }
  365. OLESTATUS FARINTERNAL GenQueryType (
  366. LPOLEOBJECT lpobj,
  367. LPLONG lptype
  368. ){
  369. UNREFERENCED_PARAMETER(lpobj);
  370. UNREFERENCED_PARAMETER(lptype);
  371. return OLE_ERROR_GENERIC;;
  372. }
  373. OLESTATUS FARINTERNAL GenSetData (
  374. LPOLEOBJECT lpoleobj,
  375. OLECLIPFORMAT cfFormat,
  376. HANDLE hData
  377. ){
  378. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  379. if (lpobj->cfFormat != cfFormat)
  380. return OLE_ERROR_FORMAT;
  381. if (!hData)
  382. return OLE_ERROR_BLANK;
  383. GlobalFree (lpobj->hData);
  384. lpobj->hData = hData;
  385. lpobj->sizeBytes = (DWORD)GlobalSize (hData);
  386. return OLE_OK;
  387. }
  388. OLESTATUS FARINTERNAL GenGetData (
  389. LPOLEOBJECT lpoleobj,
  390. OLECLIPFORMAT cfFormat,
  391. LPHANDLE lphandle
  392. ){
  393. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  394. if (cfFormat != lpobj->cfFormat)
  395. return OLE_ERROR_FORMAT;
  396. if (!(*lphandle = lpobj->hData))
  397. return OLE_ERROR_BLANK;
  398. return OLE_OK;
  399. }
  400. OLECLIPFORMAT FARINTERNAL GenEnumFormat (
  401. LPOLEOBJECT lpoleobj,
  402. OLECLIPFORMAT cfFormat
  403. ){
  404. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  405. if (!cfFormat)
  406. return lpobj->cfFormat;
  407. return 0;
  408. }
  409. OLESTATUS FARINTERNAL GenQueryBounds (
  410. LPOLEOBJECT lpoleobj,
  411. LPRECT lpRc
  412. ){
  413. LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
  414. lpRc->right = 0;
  415. lpRc->left = 0;
  416. lpRc->top = 0;
  417. lpRc->bottom = 0;
  418. return OLE_ERROR_GENERIC;
  419. }