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