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.

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