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:   CExposedIterator implementation
9 //
10 //---------------------------------------------------------------
11 
12 #include "exphead.cxx"
13 
14 #include "expiter.hxx"
15 #include "h/sstream.hxx"
16 
17 //+--------------------------------------------------------------
18 //
19 //  Member:     CExposedIterator::CExposedIterator, public
20 //
21 //  Synopsis:   Constructor
22 //
23 //  Arguments:  [ppdf] - Public Docfile
24 //              [pKey] - Initial cursor (doc file name)
25 //
26 //---------------------------------------------------------------
27 
CExposedIterator(CExposedDocFile * ppdf,CDfName * pKey)28 CExposedIterator::CExposedIterator(CExposedDocFile *ppdf, CDfName *pKey)
29 {
30     olDebugOut((DEB_ITRACE, "In  CExposedIterator::CExposedIterator("
31             "%p, %p)\n", ppdf, pKey));
32     _dfnKey.Set(pKey);
33     _ppdf = ppdf;
34     // keep a ref, so that the pointer is valid throughout life time
35     // of iterator
36     _ppdf->AddRef();
37     _cReferences = 1;
38     _sig = CEXPOSEDITER_SIG;
39     olDebugOut((DEB_ITRACE,
40                 "Out CExposedIterator::CExposedIterator\n"));
41 }
42 
43 //+--------------------------------------------------------------
44 //
45 //  Member:     CExposedIterator::~CExposedIterator, public
46 //
47 //  Synopsis:   Destructor
48 //
49 //---------------------------------------------------------------
50 
~CExposedIterator(void)51 CExposedIterator::~CExposedIterator(void)
52 {
53     olDebugOut((DEB_ITRACE, "In  CExposedIterator::~CExposedIterator\n"));
54     _sig = CEXPOSEDITER_SIGDEL;
55     olAssert(_cReferences == 0);
56     if (_ppdf) _ppdf->Release();
57     olDebugOut((DEB_ITRACE, "Out CExposedIterator::~CExposedIterator\n"));
58 }
59 
60 //+--------------------------------------------------------------
61 //
62 //  Member:     CExposedIterator::Next, public
63 //
64 //  Synopsis:   Gets N entries from an iterator
65 //
66 //  Arguments:  [celt] - Count of elements
67 //              [rgelt] - Array for element return
68 //              [pceltFetched] - If non-NULL, contains the number of
69 //                      elements fetched
70 //
71 //  Returns:    Appropriate status code
72 //
73 //  Modifies:   [rgelt]
74 //              [pceltFetched]
75 //
76 //---------------------------------------------------------------
77 
Next(ULONG celt,STATSTGW FAR * rgelt,ULONG * pceltFetched)78 SCODE CExposedIterator::Next(ULONG celt,
79                              STATSTGW FAR *rgelt,
80                              ULONG *pceltFetched)
81 {
82     SCODE sc;
83     STATSTGW stat, *pelt = rgelt;
84     ULONG celtDone;
85     CDfName dfnInitial;
86 
87     olDebugOut((DEB_ITRACE, "In CExposedIterator::Next(%lu, %p, %p)\n",
88                 celt, rgelt, pceltFetched));
89 
90     if (pceltFetched)
91     {
92         olChk(ValidateBuffer(pceltFetched, sizeof(ULONG)));
93         *pceltFetched = 0;
94     }
95     else if (celt > 1)
96         olErr(EH_Err, STG_E_INVALIDPARAMETER);
97     olAssert(0xffffUL/sizeof(STATSTGW) >= celt);
98     olChkTo(EH_RetSc,
99             ValidateOutBuffer(rgelt, sizeof(STATSTGW)*celt));
100     memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
101     olChk(Validate());
102     olChk(_ppdf->CheckReverted());
103 
104     dfnInitial.Set(&_dfnKey); // preserve initial key to reset on failure
105     for (; pelt<rgelt+celt; pelt++)
106     {
107         sc = _ppdf->FindGreaterEntry(&_dfnKey, NULL, &stat);
108         if (FAILED(sc))
109         {
110             if (sc == STG_E_NOMOREFILES)   sc = S_FALSE;
111             break;
112         }
113         _dfnKey.Set(stat.pwcsName); // advance key
114 
115         stat.grfMode = 0;
116         stat.grfLocksSupported = 0;
117         stat.reserved = 0;
118         *pelt = stat;
119     }
120 
121     // Can't move this down because dfnInitial isn't set for all EH_Err cases
122     if (FAILED(sc)) _dfnKey.Set(&dfnInitial);
123 
124     olDebugOut((DEB_ITRACE, "Out CExposedIterator::Next => %lX\n", sc));
125 EH_Err:
126     celtDone = pelt-rgelt;
127     if (FAILED(sc))
128     {
129         ULONG i;
130 
131         for (i = 0; i<celtDone; i++)
132         delete[] rgelt[i].pwcsName;
133         memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
134     }
135     else if (pceltFetched)
136         *pceltFetched = celtDone;
137 EH_RetSc:
138     return sc;
139 }
140 
141 //+--------------------------------------------------------------
142 //
143 //  Member:     CExposedIterator::Skip, public
144 //
145 //  Synopsis:   Skips N entries from an iterator
146 //
147 //  Arguments:  [celt] - Count of elements
148 //
149 //  Returns:    Appropriate status code
150 //
151 //---------------------------------------------------------------
152 
Skip(ULONG celt)153 STDMETHODIMP CExposedIterator::Skip(ULONG celt)
154 {
155     SCODE sc;
156     CDfName dfnNext;
157 
158     olDebugOut((DEB_ITRACE, "In  CExposedIterator::Skip(%lu)\n", celt));
159 
160     olChk(Validate());
161     olChk(_ppdf->CheckReverted());
162     for (; celt>0; celt--)
163     {
164         sc = _ppdf->FindGreaterEntry(&_dfnKey, &dfnNext, NULL);
165         if (FAILED(sc))
166         {
167             if (sc == STG_E_NOMOREFILES)
168                 sc = S_FALSE;
169             break;
170         }
171         _dfnKey.Set(&dfnNext); // advance the cursor
172     }
173 
174     olDebugOut((DEB_ITRACE, "Out CExposedIterator::Skip\n"));
175 EH_Err:
176     return ResultFromScode(sc);
177 }
178 
179 //+--------------------------------------------------------------
180 //
181 //  Member:     CExposedIterator::Reset, public
182 //
183 //  Synopsis:   Rewinds the iterator
184 //
185 //  Returns:    Appropriate status code
186 //
187 //---------------------------------------------------------------
188 
Reset(void)189 STDMETHODIMP CExposedIterator::Reset(void)
190 {
191     SCODE sc;
192 
193     olDebugOut((DEB_ITRACE, "In  CExposedIterator::Reset()\n"));
194 
195     olChk(Validate());
196     _dfnKey.Set((WORD)0, (BYTE*)NULL);  // set to smallest key
197     sc = _ppdf->CheckReverted();
198 
199     olDebugOut((DEB_ITRACE, "Out CExposedIterator::Reset\n"));
200 EH_Err:
201     return ResultFromScode(sc);
202 }
203 
204 //+--------------------------------------------------------------
205 //
206 //  Member:     CExposedIterator::Clone, public
207 //
208 //  Synopsis:   Clones this iterator
209 //
210 //  Arguments:  [ppenm] - Clone return
211 //
212 //  Returns:    Appropriate status code
213 //
214 //  Modifies:   [ppenm]
215 //
216 //---------------------------------------------------------------
217 
Clone(IEnumSTATSTG ** ppenm)218 STDMETHODIMP CExposedIterator::Clone(IEnumSTATSTG **ppenm)
219 {
220     SCODE sc;
221     CExposedIterator *piExp;
222 
223     olDebugOut((DEB_ITRACE, "In  CExposedIterator::Clone(%p)\n", ppenm));
224 
225     olChk(ValidateOutPtrBuffer(ppenm));
226     *ppenm = NULL;
227     olChk(Validate());
228     olChk(_ppdf->CheckReverted());
229     olMem(piExp = new CExposedIterator(_ppdf, &_dfnKey));
230     *ppenm = piExp;
231 
232     olDebugOut((DEB_ITRACE, "Out CExposedIterator::Clone => %p\n",
233                 SAFE_DREF(ppenm)));
234     // Fall through
235 EH_Err:
236     return ResultFromScode(sc);
237 }
238 
239 //+--------------------------------------------------------------
240 //
241 //  Member:     CExposedIterator::Release, public
242 //
243 //  Synopsis:   Releases resources for the iterator
244 //
245 //  Returns:    Appropriate status code
246 //
247 //---------------------------------------------------------------
248 
STDMETHODIMP_(ULONG)249 STDMETHODIMP_(ULONG) CExposedIterator::Release(void)
250 {
251     ULONG lRet;
252 
253     olDebugOut((DEB_ITRACE, "In  CExposedIterator::Release()\n"));
254     if (FAILED(Validate()))
255         return 0;
256     olAssert(_cReferences > 0);
257     lRet = --(_cReferences);
258     if (_cReferences <= 0)
259         delete this;
260 
261     olDebugOut((DEB_ITRACE, "Out CExposedIterator::Release\n"));
262     return lRet;
263 }
264 
265 //+--------------------------------------------------------------
266 //
267 //  Member:     CExposedIterator::AddRef, public
268 //
269 //  Synopsis:   Increments the ref count
270 //
271 //  Returns:    Appropriate status code
272 //
273 //---------------------------------------------------------------
274 
STDMETHODIMP_(ULONG)275 STDMETHODIMP_(ULONG) CExposedIterator::AddRef(void)
276 {
277     ULONG ulRet;
278 
279     olDebugOut((DEB_ITRACE, "In  CExposedIterator::AddRef()\n"));
280 
281     if (FAILED(Validate())) return 0;
282     ulRet = ++(_cReferences);
283 
284     olDebugOut((DEB_ITRACE, "Out CExposedIterator::AddRef\n"));
285     return ulRet;
286 }
287 
288 //+--------------------------------------------------------------
289 //
290 //  Member:     CExposedIterator::QueryInterface, public
291 //
292 //  Synopsis:   Returns an object for the requested interface
293 //
294 //  Arguments:  [iid] - Interface ID
295 //              [ppvObj] - Object return
296 //
297 //  Returns:    Appropriate status code
298 //
299 //  Modifies:   [ppvObj]
300 //
301 //---------------------------------------------------------------
302 
QueryInterface(REFIID iid,void ** ppvObj)303 STDMETHODIMP CExposedIterator::QueryInterface(REFIID iid, void **ppvObj)
304 {
305     SCODE sc;
306 
307     olDebugOut((DEB_ITRACE, "In  CExposedIterator::QueryInterface(?, %p)\n",
308                 ppvObj));
309 
310     olChk(Validate());
311     olChk(ValidateOutPtrBuffer(ppvObj));
312     *ppvObj = NULL;
313     olChk(_ppdf->CheckReverted());
314     olChk(ValidateIid(iid));
315     if (IsEqualIID(iid, IID_IEnumSTATSTG) || IsEqualIID(iid, IID_IUnknown))
316     {
317         *ppvObj = this;
318         AddRef();
319         sc = S_OK;
320     }
321     else
322     {
323         sc = E_NOINTERFACE;
324     }
325 
326     olDebugOut((DEB_ITRACE, "Out CExposedIterator::QueryInterface => %p\n",
327                 SAFE_DREF(ppvObj)));
328 EH_Err:
329     return ResultFromScode(sc);
330 }
331