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.

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