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:   Generic DocFile support functions
9 //
10 //  Functions:  ModeToTFlags
11 //              CheckName
12 //              wcsdup
13 //              VerifyPerms
14 //
15 //---------------------------------------------------------------
16 
17 #include "dfhead.cxx"
18 
19 //+--------------------------------------------------------------
20 //
21 //  Function:   ModeToDFlags, private
22 //
23 //  Synopsis:   Translates STGM flags to DF flags
24 //
25 //  Arguments:  [dwModeFlags]
26 //
27 //  Returns:    DF_*
28 //
29 //---------------------------------------------------------------
30 
ModeToDFlags(DWORD const dwModeFlags)31 DFLAGS ModeToDFlags(DWORD const dwModeFlags)
32 {
33     DFLAGS df;
34 
35     olDebugOut((DEB_ITRACE, "In  ModeToDFlags(%lX)\n", dwModeFlags));
36     if ((dwModeFlags & STGM_TRANSACTED) == 0)
37         df = DF_DIRECT;
38     else
39         df = DF_TRANSACTED;
40     if ((dwModeFlags & STGM_TRANSACTED) &&
41         (dwModeFlags & STGM_PRIORITY) == 0 &&
42         (dwModeFlags & STGM_DENY) != STGM_SHARE_DENY_WRITE &&
43         (dwModeFlags & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
44         df |= DF_INDEPENDENT;
45     switch(dwModeFlags & STGM_RDWR)
46     {
47     case STGM_READ:
48         df |= DF_READ;
49         break;
50     case STGM_WRITE:
51         df |= DF_WRITE;
52         break;
53     case STGM_READWRITE:
54         df |= DF_READWRITE;
55         break;
56     default:
57         olAssert(FALSE);
58         break;
59     }
60     switch(dwModeFlags & STGM_DENY)
61     {
62     case STGM_SHARE_DENY_READ:
63         df |= DF_DENYREAD;
64         break;
65     case STGM_SHARE_DENY_WRITE:
66         df |= DF_DENYWRITE;
67         break;
68     case STGM_SHARE_EXCLUSIVE:
69         df |= DF_DENYALL;
70         break;
71         // Default is deny none
72     }
73     if (dwModeFlags & STGM_PRIORITY)
74         df |= DF_PRIORITY;
75     olDebugOut((DEB_ITRACE, "Out ModeToDFlags => %lX\n", df));
76     return df;
77 }
78 
79 //+--------------------------------------------------------------
80 //
81 //  Function:   DFlagsToMode, private
82 //
83 //  Synopsis:   Converts the read/write/denials/transacted/priority
84 //              to STGM flags
85 //
86 //  Arguments:  [df] - DFlags
87 //
88 //  Returns:    STGM flags
89 //
90 //---------------------------------------------------------------
91 
DFlagsToMode(DFLAGS const df)92 DWORD DFlagsToMode(DFLAGS const df)
93 {
94     DWORD dwMode;
95 
96     olDebugOut((DEB_ITRACE, "In  DFlagsToMode(%X)\n", df));
97     if (P_READ(df))
98         if (P_WRITE(df))
99             dwMode = STGM_READWRITE;
100         else
101             dwMode = STGM_READ;
102     else if (P_WRITE(df))
103         dwMode = STGM_WRITE;
104     // Must have either read or write, so no else
105 
106     if (P_DENYREAD(df))
107         if (P_DENYWRITE(df))
108             dwMode |= STGM_SHARE_EXCLUSIVE;
109         else
110             dwMode |= STGM_SHARE_DENY_READ;
111     else if (P_DENYWRITE(df))
112         dwMode |= STGM_SHARE_DENY_WRITE;
113     else
114         dwMode |= STGM_SHARE_DENY_NONE;
115 
116     if (P_TRANSACTED(df))
117         dwMode |= STGM_TRANSACTED;
118 
119     if (P_PRIORITY(df))
120         dwMode |= STGM_PRIORITY;
121 
122     olDebugOut((DEB_ITRACE, "Out DFlagsToMode\n"));
123     return dwMode;
124 }
125 
126 //+--------------------------------------------------------------
127 //
128 //  Function:   VerifyPerms, private
129 //
130 //  Synopsis:   Checks flags to see if they are valid
131 //
132 //  Arguments:  [grfMode] - Permissions
133 //
134 //  Returns:    Appropriate status code
135 //
136 //---------------------------------------------------------------
137 
VerifyPerms(DWORD grfMode)138 SCODE VerifyPerms(DWORD grfMode)
139 {
140     SCODE sc = S_OK;
141 
142     olDebugOut((DEB_ITRACE, "In  VerifyPerms(%lX)\n", grfMode));
143 
144     // Check for valid flags
145     if ((grfMode & STGM_RDWR) > STGM_READWRITE ||
146         (grfMode & STGM_DENY) > STGM_SHARE_DENY_NONE ||
147         (grfMode & ~(STGM_RDWR | STGM_DENY | STGM_DIRECT | STGM_TRANSACTED |
148                      STGM_PRIORITY | STGM_CREATE | STGM_CONVERT |
149                      STGM_FAILIFTHERE | STGM_DELETEONRELEASE)))
150         olErr(EH_Err, STG_E_INVALIDFLAG);
151 
152     // We don't support these modes
153     if (grfMode & (STGM_PRIORITY|STGM_TRANSACTED|STGM_SIMPLE))
154     {
155         olAssert( FALSE &&
156             aMsg("Unsupported feature of reference implemention called"));
157         return STG_E_INVALIDFUNCTION;
158     }
159 
160     // Check to make sure only one existence flag is specified
161     // FAILIFTHERE is zero so it can't be checked
162     if ((grfMode & (STGM_CREATE | STGM_CONVERT)) ==
163         (STGM_CREATE | STGM_CONVERT))
164         olErr(EH_Err, STG_E_INVALIDFLAG);
165 
166     // If not transacted and not priority, you can either be
167     // read-only deny write or read-write deny all
168     if ((grfMode & (STGM_TRANSACTED | STGM_PRIORITY)) == 0)
169     {
170         if ((grfMode & STGM_RDWR) == STGM_READ)
171         {
172             //  we're asking for read-only access
173 
174             if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE &&
175                 (grfMode & STGM_DENY) != STGM_SHARE_DENY_WRITE)
176             {
177                 //  Can't allow others to have write access
178                 olErr(EH_Err, STG_E_INVALIDFLAG);
179             }
180         }
181         else
182         {
183             //  we're asking for write access
184 
185             if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
186             {
187                 //  Can't allow others to have any access
188                 olErr(EH_Err, STG_E_INVALIDFLAG);
189             }
190         }
191     }
192     olDebugOut((DEB_ITRACE, "Out VerifyPerms\n"));
193     // Fall through
194 EH_Err:
195     return sc;
196 }
197 
198 
199 
200 //+--------------------------------------------------------------
201 //
202 //  Function:   wcsdup, public
203 //
204 //  Synopsis:   Duplicates a WCHAR string
205 //
206 //  Arguments:  [pwcs] - String
207 //
208 //  Returns:    Pointer to new string or Appropriate status code
209 //
210 //---------------------------------------------------------------
211 
wcsdup(WCHAR const * pwcs)212 WCHAR * _CRTAPI1 wcsdup(WCHAR const *pwcs)
213 {
214     WCHAR *pwcsNew;
215 
216     olDebugOut((DEB_ITRACE, "In  wcsdup(%ws)\n", pwcs));
217     pwcsNew = new WCHAR[wcslen(pwcs)+1];
218     if (pwcsNew == NULL)
219         return NULL;
220     wcscpy(pwcsNew, pwcs);
221     olDebugOut((DEB_ITRACE, "Out wcsdup => %p\n", pwcsNew));
222     return pwcsNew;
223 }
224 
225 
226 
227 //+--------------------------------------------------------------
228 //
229 //  Function:   ValidateSNBW
230 //
231 //  Synopsis:   Validates SNB memory
232 //
233 //  Arguments:  [snb] - SNB
234 //
235 //  Returns:    Appropriate status code
236 //
237 //---------------------------------------------------------------
238 #ifdef _UNICODE
ValidateSNBW(SNBW snb)239 SCODE ValidateSNBW(SNBW snb)
240 {
241     SCODE sc;
242 
243     olDebugOut((DEB_ITRACE, "In  ValidateSNB(%p)\n", snb));
244     for (;;)
245     {
246         olChk(ValidatePtrBuffer(snb));
247         if (*snb == NULL)
248             break;
249         olChk(ValidateNameW(*snb, CWCMAXPATHCOMPLEN));
250         snb++;
251     }
252     olDebugOut((DEB_ITRACE, "Out ValidateSNB\n"));
253     return S_OK;
254 EH_Err:
255     return sc;
256 }
257 #endif // ifdef _UNICODE
258 //+--------------------------------------------------------------
259 //
260 //  Function:   CheckWName, public
261 //
262 //  Synopsis:   Checks name for illegal characters and length
263 //
264 //  Arguments:  [pwcsName] - Name
265 //
266 //  Returns:    Appropriate status code
267 //
268 //---------------------------------------------------------------
269 
270 #ifdef _UNICODE
271 WCHAR wcsInvalid[] = { '\\', '/', ':', '!','\0' };
272 
CheckWName(WCHAR const * pwcsName)273 SCODE CheckWName(WCHAR const *pwcsName)
274 {
275     SCODE sc;
276     olDebugOut((DEB_ITRACE, "In  CheckWName(%s)\n", pwcsName));
277     if (FAILED(sc = ValidateNameW(pwcsName, CBMAXPATHCOMPLEN)))
278         return sc;
279     // >= is used because the max len includes the null terminator
280     if (wcslen(pwcsName) >= CWCMAXPATHCOMPLEN)
281         return STG_E_INVALIDNAME;
282     for (; *pwcsName; pwcsName++)
283     {
284         if ( wcschr(wcsInvalid, *pwcsName) )
285             return STG_E_INVALIDNAME;
286     }
287     olDebugOut((DEB_ITRACE, "Out CheckWName\n"));
288     return S_OK;
289 }
290 #else  // validation done in ascii layer already
291 
292 #define CheckWName(pwcsName) (S_OK)
293 
294 #endif // ifdef _UNICODE
295 
296 //+--------------------------------------------------------------
297 //
298 //  Function:   CopyDStreamToDStream
299 //
300 //  Synopsis:   Copies the contents of a stream to another stream
301 //
302 //  Arguments:  [pstFrom] - Stream to copy from
303 //              [pstTo] - Stream to copy to
304 //
305 //  Returns:    Appropriate status code
306 //
307 //  Notes:      This function may fail due to out of memory.  It
308 //              may not be used by callers who must not fail due
309 //              to out of memory.
310 //
311 //              This function does not check permissions
312 //              for write in the to streams.
313 //
314 //---------------------------------------------------------------
315 
CopyStreamToStream(CDirectStream * pstFrom,CDirectStream * pstTo)316 SCODE CopyStreamToStream(CDirectStream *pstFrom,
317                          CDirectStream *pstTo)
318 {
319     BYTE *pbBuffer;
320     SCODE sc;
321     ULONG cbRead, cbWritten, cbSize, cbPos;
322 
323     // Set destination size for contiguity
324     pstFrom->GetSize(&cbSize);
325     olChk(pstTo->SetSize(cbSize));
326 
327     // We're allowed to fail due to out of memory
328     olMem(pbBuffer = new BYTE[STREAMBUFFERSIZE]);
329 
330     // Copy between streams
331     cbPos = 0;
332     for (;;)
333     {
334         olChkTo(EH_pbBuffer,
335                 pstFrom->ReadAt(cbPos, pbBuffer, STREAMBUFFERSIZE,
336                                  (ULONG STACKBASED *)&cbRead));
337         if (cbRead == 0) // EOF
338             break;
339         olChkTo(EH_pbBuffer,
340                 pstTo->WriteAt(cbPos, pbBuffer, cbRead,
341                                 (ULONG STACKBASED *)&cbWritten));
342         if (cbRead != cbWritten)
343             olErr(EH_Err, STG_E_WRITEFAULT);
344         cbPos += cbWritten;
345     }
346     delete pbBuffer;
347     return S_OK;
348 
349 EH_pbBuffer:
350     delete pbBuffer;
351 EH_Err:
352     return sc;
353 }
354 
355 //+--------------------------------------------------------------
356 //
357 //  Function:   NameInSNB, private
358 //
359 //  Synopsis:   Determines whether the given name is in the SNB
360 //
361 //  Arguments:  [dfn] - Name
362 //              [snb] - SNB
363 //
364 //  Returns:    S_OK or S_FALSE
365 //
366 //---------------------------------------------------------------
367 
NameInSNB(CDfName const * dfn,SNBW snb)368 SCODE NameInSNB(CDfName const *dfn, SNBW snb)
369 {
370     SCODE sc = S_FALSE;
371 
372     olDebugOut((DEB_ITRACE, "In  NameInSNB(%ws, %p)\n", dfn, snb));
373 
374     for (; *snb; snb++) {
375         if (dfwcsnicmp((WCHAR *)dfn->GetBuffer(), (WCHAR *)*snb,
376             dfn->GetLength()) == 0)
377         {
378             sc = S_OK;
379             break;
380         }
381     }
382 
383     olDebugOut((DEB_ITRACE, "Out NameInSNB\n"));
384     return sc;
385 }
386