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.

248 lines
7.4 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1996
  5. //
  6. // File: chinst.cxx
  7. //
  8. // Contents: DocFile child instance management code
  9. //
  10. //---------------------------------------------------------------
  11. #include "dfhead.cxx"
  12. #include "h/chinst.hxx"
  13. #include "h/revert.hxx"
  14. // Permissions checked in the less-restrictive rule
  15. #define TCANTSET DF_READ
  16. #define DCANTSET (DF_READ | DF_WRITE)
  17. #define CANTCLEAR (DF_DENYREAD | DF_DENYWRITE)
  18. //+--------------------------------------------------------------
  19. //
  20. // Method: CChildInstanceList::Add, private
  21. //
  22. // Synopsis: Registers an instance of a child
  23. //
  24. // Arguments: [prv] - Child
  25. //
  26. //---------------------------------------------------------------
  27. void CChildInstanceList::Add(PRevertable *prv)
  28. {
  29. olDebugOut((DEB_ITRACE, "In CChildInstanceList::Add(%p)\n", prv));
  30. prv->_prvNext = _prvHead;
  31. _prvHead = prv;
  32. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::Add\n"));
  33. }
  34. //+---------------------------------------------------------------------------
  35. //
  36. // Member: CChildInstanceList::FindByName, private
  37. //
  38. // Synopsis: Finds a child instance by name
  39. //
  40. // Arguments: [pdfn] - Name
  41. //
  42. // Returns: Pointer to instance or NULL
  43. //
  44. //----------------------------------------------------------------------------
  45. PRevertable *CChildInstanceList::FindByName(CDfName const *pdfn)
  46. {
  47. PRevertable *prv;
  48. olDebugOut((DEB_ITRACE, "In CChildInstanceList::FindByName:%p(%ws)\n",
  49. this, pdfn->GetBuffer()));
  50. for (prv = _prvHead; prv; prv = prv->_prvNext)
  51. if (prv->_dfn.IsEqual(pdfn))
  52. return prv;
  53. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::FindByName\n"));
  54. return NULL;
  55. }
  56. //+--------------------------------------------------------------
  57. //
  58. // Method: CChildInstanceList::DeleteByName, private
  59. //
  60. // Synopsis: Removes an instance from the instance list
  61. // and reverts it
  62. //
  63. // Arguments: [pdfn] - Name or NULL
  64. //
  65. // Notes: The entry does not have to exist
  66. // There can be multiple entries
  67. // If name is NULL, all entries match
  68. //
  69. //---------------------------------------------------------------
  70. void CChildInstanceList::DeleteByName(CDfName const *pdfn)
  71. {
  72. PRevertable **pprv;
  73. olDebugOut((DEB_ITRACE, "In CChildInstanceList::DeleteByName(%ws)\n",
  74. pdfn->GetBuffer()));
  75. for (pprv = &_prvHead; *pprv; )
  76. if (NULL == pdfn || (*pprv)->_dfn.IsEqual(pdfn))
  77. {
  78. (*pprv)->RevertFromAbove();
  79. *pprv = (*pprv)->_prvNext;
  80. }
  81. else
  82. pprv = &(*pprv)->_prvNext;
  83. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::DeleteByName\n"));
  84. }
  85. //+--------------------------------------------------------------
  86. //
  87. // Method: CChildInstanceList::RemoveRv, private
  88. //
  89. // Synopsis: Removes a specific instance from the instance list
  90. //
  91. // Arguments: [prv] - Instance
  92. //
  93. // Notes: The entry does not have to exist
  94. //
  95. //---------------------------------------------------------------
  96. void CChildInstanceList::RemoveRv(PRevertable *prvRv)
  97. {
  98. PRevertable **prv;
  99. olDebugOut((DEB_ITRACE, "In CChildInstanceList::RemoveRv(%p)\n", prvRv));
  100. for (prv = &_prvHead; *prv; prv = &(*prv)->_prvNext)
  101. if (*prv == prvRv)
  102. {
  103. *prv = (*prv)->_prvNext;
  104. break;
  105. }
  106. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::RemoveRv\n"));
  107. }
  108. //+--------------------------------------------------------------
  109. //
  110. // Method: CChildInstanceList::IsDenied, private
  111. //
  112. // Synopsis: Checks the parent instantiation list for a previous
  113. // instance of the given child with DENY flags on
  114. // Also determines whether child mode flags are
  115. // less restrictive than the parent's
  116. //
  117. // Arguments: [pdfn] - Instance name
  118. // [dfCheck] - Access modes to check for denial
  119. // [dfAgainst] - Access modes to check against
  120. //
  121. // Returns: Appropriate status code
  122. //
  123. // Notes: The instance doesn't have to be in the list.
  124. // If it isn't, it's not denied
  125. //
  126. //---------------------------------------------------------------
  127. SCODE CChildInstanceList::IsDenied(CDfName const *pdfn,
  128. DFLAGS const dfCheck,
  129. DFLAGS const dfAgainst)
  130. {
  131. PRevertable *prv;
  132. SCODE sc = S_OK;
  133. olDebugOut((DEB_ITRACE, "In CChildInstanceList::IsDenied("
  134. "%p, %lX, %lX)\n", pdfn, dfCheck, dfAgainst));
  135. olAssert(pdfn != NULL && aMsg("IsDenied, null name"));
  136. // Check to see if permissions are less restrictive than
  137. // parent permissions
  138. // This checks to see that a child isn't specifying
  139. // a permission that its parent doesn't
  140. // For example, giving read permission when the parent
  141. // doesn't
  142. if ((~dfAgainst & dfCheck & DCANTSET)
  143. ||
  144. (dfAgainst & ~dfCheck & CANTCLEAR))
  145. olErr(EH_Err, STG_E_INVALIDFLAG);
  146. // Check for DENY_*
  147. olAssert((DF_DENYALL >> DF_DENIALSHIFT) == DF_READWRITE);
  148. for (prv = _prvHead; prv != NULL; prv = prv->GetNext())
  149. {
  150. if (prv->_dfn.IsEqual(pdfn))
  151. {
  152. // Check for existing instance with DENY_* mode
  153. if ((((prv->GetDFlags() & DF_DENYALL) >> DF_DENIALSHIFT) &
  154. dfCheck) != 0 ||
  155. // Check for instance with permission already given that
  156. // new instance wants to deny
  157. (((dfCheck & DF_DENYALL) >> DF_DENIALSHIFT) &
  158. prv->GetDFlags()) != 0)
  159. {
  160. sc = STG_E_ACCESSDENIED;
  161. break;
  162. }
  163. }
  164. }
  165. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::IsDenied\n"));
  166. // Fall through
  167. EH_Err:
  168. return sc;
  169. }
  170. //+--------------------------------------------------------------
  171. //
  172. // Method: CChildInstanceList::RenameChild, public
  173. //
  174. // Synopsis: Renames the child
  175. //
  176. // Arguments: [pdfn] - old name
  177. // [pdfnName] - new name
  178. //
  179. // Notes: The entry might exist
  180. //
  181. //---------------------------------------------------------------
  182. void CChildInstanceList::RenameChild(
  183. CDfName const *pdfn,
  184. CDfName const *pdfnNewName)
  185. {
  186. PRevertable *prv;
  187. olDebugOut((DEB_ITRACE, "In CChildInstanceList::RenameChild(%p, %p)\n",
  188. pdfn, pdfnNewName));
  189. for (prv = _prvHead; prv; prv = prv->_prvNext)
  190. {
  191. if (prv->_dfn.IsEqual(pdfn))
  192. {
  193. prv->_dfn.Set(pdfnNewName->GetLength(), pdfnNewName->GetBuffer());
  194. break;
  195. }
  196. }
  197. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::RenameChild\n"));
  198. }
  199. #ifdef NEWPROPS
  200. //+---------------------------------------------------------------------------
  201. //
  202. // Member: CChildInstanceList::FlushBufferedData, private
  203. //
  204. // Synopsis: Calls each child, instructing it to flush property data.
  205. //
  206. // Returns: SCODE
  207. //
  208. //----------------------------------------------------------------------------
  209. SCODE CChildInstanceList::FlushBufferedData(void)
  210. {
  211. PRevertable *prv;
  212. SCODE sc = S_OK;
  213. olDebugOut((DEB_ITRACE, "In CChildInstanceList::FlushBufferedData:%p\n",
  214. this));
  215. for (prv = _prvHead; prv && sc == S_OK; prv = prv->_prvNext)
  216. {
  217. sc = prv->FlushBufferedData();
  218. }
  219. olDebugOut((DEB_ITRACE, "Out CChildInstanceList::FlushBufferedData\n"));
  220. return sc;
  221. }
  222. #endif