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.

316 lines
7.8 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: doc.c
  3. *
  4. * PURPOSE: Contains client document maipulation routines.
  5. *
  6. * Created: Jan 1991
  7. *
  8. * Copyright (c) 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Srinik 01/11/1191 Orginal
  12. *
  13. \***************************************************************************/
  14. #include <windows.h>
  15. #include "dll.h"
  16. #ifdef FIREWALLS
  17. extern BOOL bShowed;
  18. extern void FARINTERNAL ShowVersion (void);
  19. #endif
  20. LPCLIENTDOC lpHeadDoc = NULL;
  21. LPCLIENTDOC lpTailDoc = NULL;
  22. extern ATOM aClipDoc;
  23. extern int iUnloadableDll;
  24. #pragma alloc_text(_TEXT, CheckClientDoc, CheckPointer)
  25. OLESTATUS FAR PASCAL OleRegisterClientDoc (lpClassName, lpDocName, future, lplhclientdoc)
  26. LPSTR lpClassName;
  27. LPSTR lpDocName;
  28. LONG future;
  29. LHCLIENTDOC FAR * lplhclientdoc;
  30. {
  31. HANDLE hdoc = NULL;
  32. LPCLIENTDOC lpdoc;
  33. OLESTATUS retVal;
  34. ATOM aClass, aDoc;
  35. #ifdef FIREWALLS
  36. if (!bShowed && (ole_flags & DEBUG_MESSAGEBOX))
  37. ShowVersion ();
  38. #endif
  39. Puts ("OleRegisterClientDoc");
  40. PROBE_MODE(bProtMode);
  41. FARPROBE_WRITE(lplhclientdoc);
  42. *lplhclientdoc = NULL;
  43. FARPROBE_READ(lpClassName);
  44. FARPROBE_READ(lpDocName);
  45. if (!lpDocName[0])
  46. return OLE_ERROR_NAME;
  47. aDoc = GlobalAddAtom (lpDocName);
  48. aClass = GlobalAddAtom (lpClassName);
  49. if (!(hdoc = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE,
  50. sizeof(CLIENTDOC)))
  51. || !(lpdoc = (LPCLIENTDOC) GlobalLock (hdoc))) {
  52. retVal = OLE_ERROR_MEMORY;
  53. goto err;
  54. }
  55. lpdoc->docId[0] = 'C';
  56. lpdoc->docId[1] = 'D';
  57. lpdoc->aClass = aClass;
  58. lpdoc->aDoc = aDoc;
  59. lpdoc->hdoc = hdoc;
  60. // Documents are doubly linked
  61. if (!lpHeadDoc) {
  62. #ifdef FIREWALLS
  63. ASSERT(!lpTailDoc, "lpTailDoc is not NULL");
  64. #endif
  65. lpHeadDoc = lpTailDoc = lpdoc;
  66. }
  67. else {
  68. lpTailDoc->lpNextDoc = lpdoc;
  69. lpdoc->lpPrevDoc = lpTailDoc;
  70. lpTailDoc = lpdoc;
  71. }
  72. *lplhclientdoc = (LHCLIENTDOC) lpdoc;
  73. // inform the link manager;
  74. return OLE_OK;
  75. err:
  76. if (aClass)
  77. GlobalDeleteAtom (aClass);
  78. if (aDoc)
  79. GlobalDeleteAtom (aDoc);
  80. if (hdoc)
  81. GlobalFree (hdoc);
  82. return retVal;
  83. }
  84. OLESTATUS FAR PASCAL OleRevokeClientDoc (lhclientdoc)
  85. LHCLIENTDOC lhclientdoc;
  86. {
  87. LPCLIENTDOC lpdoc;
  88. Puts ("OleRevokeClientDoc");
  89. // if there is any handler dll that can be freed up, free it now.
  90. // Otherwise it might become too late if the app quits.
  91. if (iUnloadableDll)
  92. UnloadDll ();
  93. if (!CheckClientDoc (lpdoc = (LPCLIENTDOC) lhclientdoc))
  94. return OLE_ERROR_HANDLE;
  95. if (lpdoc->lpHeadObj) {
  96. ASSERT (0, "OleRevokeClientDoc() called without freeing all objects");
  97. return OLE_ERROR_NOT_EMPTY;
  98. }
  99. if (lpdoc->aClass)
  100. GlobalDeleteAtom (lpdoc->aClass);
  101. if (lpdoc->aDoc)
  102. GlobalDeleteAtom (lpdoc->aDoc);
  103. // if only one doc is in the list then it's prev and next docs are NULL
  104. if (lpdoc == lpHeadDoc)
  105. lpHeadDoc = lpdoc->lpNextDoc;
  106. if (lpdoc == lpTailDoc)
  107. lpTailDoc = lpdoc->lpPrevDoc;
  108. if (lpdoc->lpPrevDoc)
  109. lpdoc->lpPrevDoc->lpNextDoc = lpdoc->lpNextDoc;
  110. if (lpdoc->lpNextDoc)
  111. lpdoc->lpNextDoc->lpPrevDoc = lpdoc->lpPrevDoc;
  112. GlobalUnlock (lpdoc->hdoc);
  113. GlobalFree (lpdoc->hdoc);
  114. // inform link manager
  115. return OLE_OK;
  116. }
  117. OLESTATUS FAR PASCAL OleRenameClientDoc (lhclientdoc, lpNewDocName)
  118. LHCLIENTDOC lhclientdoc;
  119. LPSTR lpNewDocName;
  120. {
  121. LPCLIENTDOC lpdoc;
  122. ATOM aNewDoc;
  123. LPOLEOBJECT lpobj = NULL;
  124. if (!CheckClientDoc (lpdoc = (LPCLIENTDOC) lhclientdoc))
  125. return OLE_ERROR_HANDLE;
  126. FARPROBE_READ(lpNewDocName);
  127. aNewDoc = GlobalAddAtom (lpNewDocName);
  128. if (aNewDoc == lpdoc->aDoc) {
  129. if (aNewDoc)
  130. GlobalDeleteAtom (aNewDoc);
  131. return OLE_OK;
  132. }
  133. // Document name has changed. So, change the topic of all embedded objects
  134. if (lpdoc->aDoc)
  135. GlobalDeleteAtom (lpdoc->aDoc);
  136. lpdoc->aDoc = aNewDoc;
  137. while (lpobj = DocGetNextObject (lpdoc, lpobj)) {
  138. if (lpobj->ctype == CT_EMBEDDED)
  139. if (OleQueryReleaseStatus (lpobj) != OLE_BUSY)
  140. SetEmbeddedTopic ((LPOBJECT_LE) lpobj);
  141. }
  142. return OLE_OK;
  143. }
  144. OLESTATUS FAR PASCAL OleRevertClientDoc (lhclientdoc)
  145. LHCLIENTDOC lhclientdoc;
  146. {
  147. // if there is any handler dll that can be freed up, free it now.
  148. // Otherwise it might become too late if the app quits.
  149. if (iUnloadableDll)
  150. UnloadDll ();
  151. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  152. return OLE_ERROR_HANDLE;
  153. return OLE_OK;
  154. }
  155. OLESTATUS FAR PASCAL OleSavedClientDoc (lhclientdoc)
  156. LHCLIENTDOC lhclientdoc;
  157. {
  158. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  159. return OLE_ERROR_HANDLE;
  160. return OLE_OK;
  161. }
  162. OLESTATUS FAR PASCAL OleEnumObjects (lhclientdoc, lplpobj)
  163. LHCLIENTDOC lhclientdoc;
  164. LPOLEOBJECT FAR * lplpobj;
  165. {
  166. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  167. return OLE_ERROR_HANDLE;
  168. FARPROBE_WRITE(lplpobj);
  169. if (*lplpobj) {
  170. // we are making lhclientdoc field of the object NULL at deletion
  171. // time. The check (*lpobj->lhclientdoc != lhclientdoc) will take care
  172. // of the case where same chunk of memory is allocated again for the
  173. // same pointer and old contents are not erased yet.
  174. if (!FarCheckObject (*lplpobj)
  175. || ((*lplpobj)->lhclientdoc != lhclientdoc))
  176. return OLE_ERROR_OBJECT;
  177. }
  178. *lplpobj = DocGetNextObject ((LPCLIENTDOC) lhclientdoc, *lplpobj);
  179. return OLE_OK;
  180. }
  181. LPOLEOBJECT INTERNAL DocGetNextObject (lpdoc, lpobj)
  182. LPCLIENTDOC lpdoc;
  183. LPOLEOBJECT lpobj;
  184. {
  185. if (!lpobj)
  186. return lpdoc->lpHeadObj;
  187. return lpobj->lpNextObj;
  188. }
  189. BOOL FARINTERNAL CheckClientDoc (lpdoc)
  190. LPCLIENTDOC lpdoc;
  191. {
  192. if (!CheckPointer(lpdoc, WRITE_ACCESS))
  193. return FALSE;
  194. if ((lpdoc->docId[0] == 'C') && (lpdoc->docId[1] == 'D'))
  195. return TRUE;
  196. return FALSE;
  197. }
  198. void FARINTERNAL DocAddObject (lpdoc, lpobj, lpobjname)
  199. LPCLIENTDOC lpdoc;
  200. LPOLEOBJECT lpobj;
  201. LPSTR lpobjname;
  202. {
  203. if (lpobjname)
  204. lpobj->aObjName = GlobalAddAtom (lpobjname);
  205. else
  206. lpobj->aObjName = NULL;
  207. // Objects of a doc are doubly linked
  208. if (!lpdoc->lpHeadObj)
  209. lpdoc->lpHeadObj = lpdoc->lpTailObj = lpobj;
  210. else {
  211. lpdoc->lpTailObj->lpNextObj = lpobj;
  212. lpobj->lpPrevObj = lpdoc->lpTailObj;
  213. lpdoc->lpTailObj = lpobj;
  214. }
  215. lpobj->lhclientdoc = (LHCLIENTDOC)lpdoc;
  216. }
  217. void FARINTERNAL DocDeleteObject (lpobj)
  218. LPOLEOBJECT lpobj;
  219. {
  220. LPCLIENTDOC lpdoc;
  221. if (!(lpdoc = (LPCLIENTDOC) lpobj->lhclientdoc))
  222. return;
  223. if (lpobj->aObjName) {
  224. GlobalDeleteAtom (lpobj->aObjName);
  225. lpobj->aObjName = NULL;
  226. }
  227. // Remove this obj from object chain of the relevant client doc.
  228. // The objects of a doc are doubly linked.
  229. if (lpdoc->lpHeadObj == lpobj)
  230. lpdoc->lpHeadObj = lpobj->lpNextObj;
  231. if (lpdoc->lpTailObj == lpobj)
  232. lpdoc->lpTailObj = lpobj->lpPrevObj;
  233. if (lpobj->lpPrevObj)
  234. lpobj->lpPrevObj->lpNextObj = lpobj->lpNextObj;
  235. if (lpobj->lpNextObj)
  236. lpobj->lpNextObj->lpPrevObj = lpobj->lpPrevObj;
  237. lpobj->lhclientdoc = NULL;
  238. }