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