ReactOS 0.4.16-dev-2354-g16de117
stg_stream.c
Go to the documentation of this file.
1/*
2 * Compound Storage (32 bit version)
3 * Stream implementation
4 *
5 * This file contains the implementation of the stream interface
6 * for streams contained in a compound storage.
7 *
8 * Copyright 1999 Francis Beaudet
9 * Copyright 1999 Thuy Nguyen
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <stdlib.h>
27#include <stdarg.h>
28#include <stdio.h>
29#include <string.h>
30
31#define COBJMACROS
32#include "windef.h"
33#include "winbase.h"
34#include "winerror.h"
35#include "winternl.h"
36#include "wine/debug.h"
37
38#include "storage32.h"
39
41
42/***
43 * This implements the IUnknown method QueryInterface for this
44 * class
45 */
47 IStream* iface,
48 REFIID riid, /* [in] */
49 void** ppvObject) /* [iid_is][out] */
50{
52
53 if (ppvObject==0)
54 return E_INVALIDARG;
55
56 *ppvObject = 0;
57
59 IsEqualIID(&IID_ISequentialStream, riid) ||
60 IsEqualIID(&IID_IStream, riid))
61 {
62 *ppvObject = &This->IStream_iface;
63 }
64 else
65 return E_NOINTERFACE;
66
67 IStream_AddRef(iface);
68
69 return S_OK;
70}
71
72/***
73 * This implements the IUnknown method AddRef for this
74 * class
75 */
77 IStream* iface)
78{
80 return InterlockedIncrement(&This->ref);
81}
82
83/***
84 * This implements the IUnknown method Release for this
85 * class
86 */
88 IStream* iface)
89{
92
93 if (!ref)
94 {
95 TRACE("(%p)\n", This);
96
97 /*
98 * Release the reference we are holding on the parent storage.
99 * IStorage_Release(&This->parentStorage->IStorage_iface);
100 *
101 * No, don't do this. Some apps call IStorage_Release without
102 * calling IStream_Release first. If we grab a reference the
103 * file is not closed, and the app fails when it tries to
104 * reopen the file (Easy-PC, for example). Just inform the
105 * storage that we have closed the stream
106 */
107
108 if (This->parentStorage)
109 StorageBaseImpl_RemoveStream(This->parentStorage, This);
110 This->parentStorage = 0;
112 }
113
114 return ref;
115}
116
117/***
118 * This method is part of the ISequentialStream interface.
119 *
120 * It reads a block of information from the stream at the current
121 * position. It then moves the current position at the end of the
122 * read block
123 *
124 * See the documentation of ISequentialStream for more info.
125 */
127 IStream* iface,
128 void* pv, /* [length_is][size_is][out] */
129 ULONG cb, /* [in] */
130 ULONG* pcbRead) /* [out] */
131{
133
134 ULONG bytesReadBuffer;
135 HRESULT res;
136
137 TRACE("%p, %p, %lu, %p.\n", iface, pv, cb, pcbRead);
138
139 if (!This->parentStorage)
140 {
141 WARN("storage reverted\n");
142 return STG_E_REVERTED;
143 }
144
145 /*
146 * If the caller is not interested in the number of bytes read,
147 * we use another buffer to avoid "if" statements in the code.
148 */
149 if (pcbRead==0)
150 pcbRead = &bytesReadBuffer;
151
152 res = StorageBaseImpl_StreamReadAt(This->parentStorage,
153 This->dirEntry,
154 This->currentPosition,
155 cb,
156 pv,
157 pcbRead);
158
159 if (SUCCEEDED(res))
160 {
161 /*
162 * Advance the pointer for the number of positions read.
163 */
164 This->currentPosition.QuadPart += *pcbRead;
165 }
166
167 TRACE("<-- %#lx\n", res);
168 return res;
169}
170
171/***
172 * This method is part of the ISequentialStream interface.
173 *
174 * It writes a block of information to the stream at the current
175 * position. It then moves the current position at the end of the
176 * written block. If the stream is too small to fit the block,
177 * the stream is grown to fit.
178 *
179 * See the documentation of ISequentialStream for more info.
180 */
182 IStream* iface,
183 const void* pv, /* [size_is][in] */
184 ULONG cb, /* [in] */
185 ULONG* pcbWritten) /* [out] */
186{
188
190 HRESULT res;
191
192 TRACE("%p, %p, %lu, %p.\n", iface, pv, cb, pcbWritten);
193
194 /*
195 * Do we have permission to write to this stream?
196 */
197 switch(STGM_ACCESS_MODE(This->grfMode))
198 {
199 case STGM_WRITE:
200 case STGM_READWRITE:
201 break;
202 default:
203 WARN("access denied by flags: %#lx\n", STGM_ACCESS_MODE(This->grfMode));
204 return STG_E_ACCESSDENIED;
205 }
206
207 if (!pv)
209
210 if (!This->parentStorage)
211 {
212 WARN("storage reverted\n");
213 return STG_E_REVERTED;
214 }
215
216 /*
217 * If the caller is not interested in the number of bytes written,
218 * we use another buffer to avoid "if" statements in the code.
219 */
220 if (pcbWritten == 0)
221 pcbWritten = &bytesWritten;
222
223 /*
224 * Initialize the out parameter
225 */
226 *pcbWritten = 0;
227
228 if (cb == 0)
229 {
230 TRACE("<-- S_OK, written 0\n");
231 return S_OK;
232 }
233
234 res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
235 This->dirEntry,
236 This->currentPosition,
237 cb,
238 pv,
239 pcbWritten);
240
241 /*
242 * Advance the position pointer for the number of positions written.
243 */
244 This->currentPosition.QuadPart += *pcbWritten;
245
246 if (SUCCEEDED(res))
247 res = StorageBaseImpl_Flush(This->parentStorage);
248
249 TRACE("<-- %#lx, written %lu\n", res, *pcbWritten);
250 return res;
251}
252
253/***
254 * This method is part of the IStream interface.
255 *
256 * It will move the current stream pointer according to the parameters
257 * given.
258 *
259 * See the documentation of IStream for more info.
260 */
262 IStream* iface,
263 LARGE_INTEGER dlibMove, /* [in] */
264 DWORD dwOrigin, /* [in] */
265 ULARGE_INTEGER* plibNewPosition) /* [out] */
266{
268
269 ULARGE_INTEGER newPosition;
270 DirEntry currentEntry;
271 HRESULT hr;
272
273 TRACE("%p, %ld, %ld, %p.\n", iface, dlibMove.LowPart, dwOrigin, plibNewPosition);
274
275 /*
276 * fail if the stream has no parent (as does windows)
277 */
278
279 if (!This->parentStorage)
280 {
281 WARN("storage reverted\n");
282 return STG_E_REVERTED;
283 }
284
285 /*
286 * The caller is allowed to pass in NULL as the new position return value.
287 * If it happens, we assign it to a dynamic variable to avoid special cases
288 * in the code below.
289 */
290 if (plibNewPosition == 0)
291 {
292 plibNewPosition = &newPosition;
293 }
294
295 /*
296 * The file pointer is moved depending on the given "function"
297 * parameter.
298 */
299 switch (dwOrigin)
300 {
301 case STREAM_SEEK_SET:
302 plibNewPosition->u.HighPart = 0;
303 plibNewPosition->u.LowPart = 0;
304 break;
305 case STREAM_SEEK_CUR:
306 *plibNewPosition = This->currentPosition;
307 break;
308 case STREAM_SEEK_END:
309 hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, &currentEntry);
310 if (FAILED(hr)) return hr;
311 *plibNewPosition = currentEntry.size;
312 break;
313 default:
314 WARN("invalid dwOrigin %ld\n", dwOrigin);
316 }
317
318 plibNewPosition->QuadPart += dlibMove.QuadPart;
319
320 /*
321 * tell the caller what we calculated
322 */
323 This->currentPosition = *plibNewPosition;
324
325 return S_OK;
326}
327
328/***
329 * This method is part of the IStream interface.
330 *
331 * It will change the size of a stream.
332 *
333 * See the documentation of IStream for more info.
334 */
336 IStream* iface,
337 ULARGE_INTEGER libNewSize) /* [in] */
338{
340
341 HRESULT hr;
342
343 TRACE("%p, %ld.\n", iface, libNewSize.LowPart);
344
345 if(!This->parentStorage)
346 {
347 WARN("storage reverted\n");
348 return STG_E_REVERTED;
349 }
350
351 /*
352 * As documented.
353 */
354 if (libNewSize.HighPart != 0)
355 {
356 WARN("invalid value for libNewSize.HighPart %ld\n", libNewSize.HighPart);
358 }
359
360 /*
361 * Do we have permission?
362 */
363 if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
364 {
365 WARN("access denied\n");
366 return STG_E_ACCESSDENIED;
367 }
368
369 hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
370
371 if (SUCCEEDED(hr))
372 hr = StorageBaseImpl_Flush(This->parentStorage);
373
374 return hr;
375}
376
377/***
378 * This method is part of the IStream interface.
379 *
380 * It will copy the 'cb' Bytes to 'pstm' IStream.
381 *
382 * See the documentation of IStream for more info.
383 */
385 IStream* iface,
386 IStream* pstm, /* [unique][in] */
387 ULARGE_INTEGER cb, /* [in] */
388 ULARGE_INTEGER* pcbRead, /* [out] */
389 ULARGE_INTEGER* pcbWritten) /* [out] */
390{
392 HRESULT hr = S_OK;
393 BYTE tmpBuffer[128];
394 ULONG bytesRead, bytesWritten, copySize;
395 ULARGE_INTEGER totalBytesRead;
396 ULARGE_INTEGER totalBytesWritten;
397
398 TRACE("%p, %p, %ld, %p, %p.\n", iface, pstm, cb.LowPart, pcbRead, pcbWritten);
399
400 /*
401 * Sanity check
402 */
403
404 if (!This->parentStorage)
405 {
406 WARN("storage reverted\n");
407 return STG_E_REVERTED;
408 }
409
410 if ( pstm == 0 )
412
413 totalBytesRead.QuadPart = 0;
414 totalBytesWritten.QuadPart = 0;
415
416 while ( cb.QuadPart > 0 )
417 {
418 if ( cb.QuadPart >= sizeof(tmpBuffer) )
419 copySize = sizeof(tmpBuffer);
420 else
421 copySize = cb.LowPart;
422
423 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
424
425 totalBytesRead.QuadPart += bytesRead;
426
427 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
428
429 totalBytesWritten.QuadPart += bytesWritten;
430
431 /*
432 * Check that read & write operations were successful
433 */
434 if (bytesRead != bytesWritten)
435 {
437 WARN("medium full\n");
438 break;
439 }
440
441 if (bytesRead!=copySize)
442 cb.QuadPart = 0;
443 else
444 cb.QuadPart -= bytesRead;
445 }
446
447 if (pcbRead) pcbRead->QuadPart = totalBytesRead.QuadPart;
448 if (pcbWritten) pcbWritten->QuadPart = totalBytesWritten.QuadPart;
449
450 return hr;
451}
452
453/***
454 * This method is part of the IStream interface.
455 *
456 * For streams contained in structured storages, this method
457 * does nothing. This is what the documentation tells us.
458 *
459 * See the documentation of IStream for more info.
460 */
462 IStream* iface,
463 DWORD grfCommitFlags) /* [in] */
464{
466
467 if (!This->parentStorage)
468 {
469 WARN("storage reverted\n");
470 return STG_E_REVERTED;
471 }
472
473 return StorageBaseImpl_Flush(This->parentStorage);
474}
475
476/***
477 * This method is part of the IStream interface.
478 *
479 * For streams contained in structured storages, this method
480 * does nothing. This is what the documentation tells us.
481 *
482 * See the documentation of IStream for more info.
483 */
485 IStream* iface)
486{
487 return S_OK;
488}
489
491 IStream* iface,
492 ULARGE_INTEGER libOffset, /* [in] */
493 ULARGE_INTEGER cb, /* [in] */
494 DWORD dwLockType) /* [in] */
495{
497
498 if (!This->parentStorage)
499 {
500 WARN("storage reverted\n");
501 return STG_E_REVERTED;
502 }
503
504 FIXME("not implemented!\n");
505 return E_NOTIMPL;
506}
507
509 IStream* iface,
510 ULARGE_INTEGER libOffset, /* [in] */
511 ULARGE_INTEGER cb, /* [in] */
512 DWORD dwLockType) /* [in] */
513{
515
516 if (!This->parentStorage)
517 {
518 WARN("storage reverted\n");
519 return STG_E_REVERTED;
520 }
521
522 FIXME("not implemented!\n");
523 return E_NOTIMPL;
524}
525
526/***
527 * This method is part of the IStream interface.
528 *
529 * This method returns information about the current
530 * stream.
531 *
532 * See the documentation of IStream for more info.
533 */
535 IStream* iface,
536 STATSTG* pstatstg, /* [out] */
537 DWORD grfStatFlag) /* [in] */
538{
540
541 DirEntry currentEntry;
542 HRESULT hr;
543
544 TRACE("%p, %p, %#lx.\n", This, pstatstg, grfStatFlag);
545
546 /*
547 * if stream has no parent, return STG_E_REVERTED
548 */
549
550 if (!This->parentStorage)
551 {
552 WARN("storage reverted\n");
553 return STG_E_REVERTED;
554 }
555
556 /*
557 * Read the information from the directory entry.
558 */
559 hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
560 This->dirEntry,
561 &currentEntry);
562
563 if (SUCCEEDED(hr))
564 {
566 pstatstg,
567 &currentEntry,
568 grfStatFlag);
569
570 pstatstg->grfMode = This->grfMode;
571
572 /* In simple create mode cbSize is the current pos */
573 if((This->parentStorage->openFlags & STGM_SIMPLE) && This->parentStorage->create)
574 pstatstg->cbSize = This->currentPosition;
575
576 return S_OK;
577 }
578
579 WARN("failed to read entry\n");
580 return hr;
581}
582
583/***
584 * This method is part of the IStream interface.
585 *
586 * This method returns a clone of the interface that allows for
587 * another seek pointer
588 *
589 * See the documentation of IStream for more info.
590 *
591 * I am not totally sure what I am doing here but I presume that this
592 * should be basically as simple as creating a new stream with the same
593 * parent etc and positioning its seek cursor.
594 */
596 IStream* iface,
597 IStream** ppstm) /* [out] */
598{
600 StgStreamImpl* new_stream;
601 LARGE_INTEGER seek_pos;
602
603 TRACE("%p %p\n", This, ppstm);
604
605 /*
606 * Sanity check
607 */
608
609 if (!This->parentStorage)
610 return STG_E_REVERTED;
611
612 if ( ppstm == 0 )
614
615 new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->dirEntry);
616
617 if (!new_stream)
618 return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
619
620 *ppstm = &new_stream->IStream_iface;
621 IStream_AddRef(*ppstm);
622
623 seek_pos.QuadPart = This->currentPosition.QuadPart;
624
625 return IStream_Seek(*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
626}
627
628/*
629 * Virtual function table for the StgStreamImpl class.
630 */
631static const IStreamVtbl StgStreamVtbl =
632{
647};
648
649/******************************************************************************
650** StgStreamImpl implementation
651*/
652
653/***
654 * This is the constructor for the StgStreamImpl class.
655 *
656 * Params:
657 * parentStorage - Pointer to the storage that contains the stream to open
658 * dirEntry - Index of the directory entry that points to this stream.
659 */
661 StorageBaseImpl* parentStorage,
662 DWORD grfMode,
663 DirRef dirEntry)
664{
665 StgStreamImpl* newStream;
666
667 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(StgStreamImpl));
668
669 if (newStream)
670 {
671 /*
672 * Set-up the virtual function table and reference count.
673 */
674 newStream->IStream_iface.lpVtbl = &StgStreamVtbl;
675 newStream->ref = 0;
676
677 newStream->parentStorage = parentStorage;
678
679 /*
680 * We want to nail-down the reference to the storage in case the
681 * stream out-lives the storage in the client application.
682 *
683 * -- IStorage_AddRef(&newStream->parentStorage->IStorage_iface);
684 *
685 * No, don't do this. Some apps call IStorage_Release without
686 * calling IStream_Release first. If we grab a reference the
687 * file is not closed, and the app fails when it tries to
688 * reopen the file (Easy-PC, for example)
689 */
690
691 newStream->grfMode = grfMode;
692 newStream->dirEntry = dirEntry;
693
694 /*
695 * Start the stream at the beginning.
696 */
697 newStream->currentPosition.HighPart = 0;
698 newStream->currentPosition.LowPart = 0;
699
700 /* add us to the storage's list of active streams */
701 StorageBaseImpl_AddStream(parentStorage, newStream);
702 }
703
704 return newStream;
705}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
static struct hglobal_stream * impl_from_IStream(IStream *iface)
Definition: hglobalstream.c:84
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
void StorageBaseImpl_RemoveStream(StorageBaseImpl *stg, StgStreamImpl *strm)
Definition: storage32.c:2708
void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage, STATSTG *destination, const DirEntry *source, int statFlags)
Definition: storage32.c:6979
void StorageBaseImpl_AddStream(StorageBaseImpl *stg, StgStreamImpl *strm)
Definition: storage32.c:2702
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLenum GLsizei GLuint GLint * bytesWritten
Definition: glext.h:11123
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define STGM_READWRITE
Definition: objbase.h:936
#define STGM_SIMPLE
Definition: objbase.h:933
#define STGM_WRITE
Definition: objbase.h:935
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
StgStreamImpl * StgStreamImpl_Construct(StorageBaseImpl *parentStorage, DWORD grfMode, DirRef dirEntry)
Definition: stg_stream.c:660
static HRESULT WINAPI StgStreamImpl_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
Definition: stg_stream.c:46
static HRESULT WINAPI StgStreamImpl_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: stg_stream.c:126
static HRESULT WINAPI StgStreamImpl_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: stg_stream.c:490
static ULONG WINAPI StgStreamImpl_Release(IStream *iface)
Definition: stg_stream.c:87
static HRESULT WINAPI StgStreamImpl_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: stg_stream.c:261
static HRESULT WINAPI StgStreamImpl_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: stg_stream.c:461
static HRESULT WINAPI StgStreamImpl_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: stg_stream.c:508
static HRESULT WINAPI StgStreamImpl_Revert(IStream *iface)
Definition: stg_stream.c:484
static HRESULT WINAPI StgStreamImpl_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: stg_stream.c:335
static HRESULT WINAPI StgStreamImpl_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: stg_stream.c:181
static const IStreamVtbl StgStreamVtbl
Definition: stg_stream.c:631
static HRESULT WINAPI StgStreamImpl_Clone(IStream *iface, IStream **ppstm)
Definition: stg_stream.c:595
static HRESULT WINAPI StgStreamImpl_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: stg_stream.c:534
static ULONG WINAPI StgStreamImpl_AddRef(IStream *iface)
Definition: stg_stream.c:76
static HRESULT WINAPI StgStreamImpl_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: stg_stream.c:384
static HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, DirRef index, ULARGE_INTEGER newsize)
Definition: storage32.h:317
static HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
Definition: storage32.h:303
static HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
Definition: storage32.h:311
ULONG DirRef
Definition: storage32.h:139
#define STGM_ACCESS_MODE(stgm)
Definition: storage32.h:115
static HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This)
Definition: storage32.h:268
static HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This, DirRef index, DirEntry *data)
Definition: storage32.h:290
ULARGE_INTEGER size
Definition: storage32.h:157
IStream IStream_iface
Definition: storage32.h:429
StorageBaseImpl * parentStorage
Definition: storage32.h:440
DWORD grfMode
Definition: storage32.h:445
ULARGE_INTEGER currentPosition
Definition: storage32.h:455
DirRef dirEntry
Definition: storage32.h:450
$ULONG LowPart
Definition: ntbasedef.h:581
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
$ULONG HighPart
Definition: ntbasedef.h:582
struct _ULARGE_INTEGER::@4458 u
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
#define WINAPI
Definition: msvc.h:6
#define STG_E_INVALIDPOINTER
Definition: winerror.h:3666
#define STG_E_REVERTED
Definition: winerror.h:3686
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_ACCESSDENIED
Definition: winerror.h:3663
#define STG_E_MEDIUMFULL
Definition: winerror.h:3676
#define STG_E_INVALIDFUNCTION
Definition: winerror.h:3659
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:3665
unsigned char BYTE
Definition: xxhash.c:193