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