ReactOS 0.4.17-dev-357-ga8f14ff
istream.c
Go to the documentation of this file.
1/*
2 * SHLWAPI IStream functions
3 *
4 * Copyright 2002 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20#include <stdarg.h>
21#include <string.h>
22
23#define COBJMACROS
24#include "windef.h"
25#include "winbase.h"
26#include "winerror.h"
27#include "winnls.h"
28#define NO_SHLWAPI_REG
29#define NO_SHLWAPI_PATH
30#include "shlwapi.h"
31#ifdef __REACTOS__
32#include "shlobj.h"
33#endif
34#include "wine/debug.h"
35
37
38/*************************************************************************
39 *
40 * Call IStream_Read() on a stream.
41 *
42 * PARAMS
43 * lpStream [I] IStream object
44 * lpvDest [O] Destination for data read
45 * ulSize [I] Size of data to read
46 *
47 * RETURNS
48 * Success: S_OK. ulSize bytes have been read from the stream into lpvDest.
49 * Failure: An HRESULT error code, or E_FAIL if the read succeeded but the
50 * number of bytes read does not match.
51 */
52HRESULT WINAPI SHIStream_Read(IStream *lpStream, LPVOID lpvDest, ULONG ulSize)
53{
54 ULONG ulRead;
55 HRESULT hRet;
56
57 TRACE("(%p,%p,%d)\n", lpStream, lpvDest, ulSize);
58
59 hRet = IStream_Read(lpStream, lpvDest, ulSize, &ulRead);
60
61 if (SUCCEEDED(hRet) && ulRead != ulSize)
62 hRet = E_FAIL;
63 return hRet;
64}
65
66/*************************************************************************
67 * @ [SHLWAPI.166]
68 *
69 * Determine if a stream has 0 length.
70 *
71 * PARAMS
72 * lpStream [I] IStream object
73 *
74 * RETURNS
75 * TRUE: If the stream has 0 length
76 * FALSE: Otherwise.
77 */
79{
80 STATSTG statstg;
81 BOOL bRet = TRUE;
82
83 TRACE("(%p)\n", lpStream);
84
85 memset(&statstg, 0, sizeof(statstg));
86
87 if(SUCCEEDED(IStream_Stat(lpStream, &statstg, 1)))
88 {
89 if(statstg.cbSize.QuadPart)
90 bRet = FALSE; /* Non-Zero */
91 }
92 else
93 {
94 DWORD dummy, read_len;
95
96 /* Try to read from the stream */
97 if (SUCCEEDED(IStream_Read(lpStream, &dummy, sizeof(dummy), &read_len)) && read_len == sizeof(dummy))
98 {
100 zero.QuadPart = 0;
101
102 IStream_Seek(lpStream, zero, 0, NULL);
103 bRet = FALSE; /* Non-Zero */
104 }
105 }
106 return bRet;
107}
108
109/*************************************************************************
110 *
111 * Call IStream_Write() on a stream.
112 *
113 * PARAMS
114 * lpStream [I] IStream object
115 * lpvSrc [I] Source for data to write
116 * ulSize [I] Size of data
117 *
118 * RETURNS
119 * Success: S_OK. ulSize bytes have been written to the stream from lpvSrc.
120 * Failure: An HRESULT error code, or E_FAIL if the write succeeded but the
121 * number of bytes written does not match.
122 */
124{
125 ULONG ulWritten;
126 HRESULT hRet;
127
128 TRACE("(%p,%p,%d)\n", lpStream, lpvSrc, ulSize);
129
130 hRet = IStream_Write(lpStream, lpvSrc, ulSize, &ulWritten);
131
132 if (SUCCEEDED(hRet) && ulWritten != ulSize)
133 hRet = E_FAIL;
134
135 return hRet;
136}
137
138#ifdef __REACTOS__
139/*************************************************************************
140 * IStream_ReadPidl [SHLWAPI.512]
141 *
142 * https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/util/istream/readpidl.htm
143 */
146{
147 LPITEMIDLIST pidl, pidlEnd;
148 LPSHITEMID pItem;
149 UINT cbSize;
150 HRESULT hr;
151
152 *ppidlOut = NULL;
153
154 hr = SHIStream_Read(pstm, &cbSize, sizeof(cbSize));
155 if (FAILED(hr))
156 return hr;
157
158 if (cbSize < sizeof(USHORT))
159 return E_INVALIDARG;
160
161 pidl = CoTaskMemAlloc(cbSize);
162 if (!pidl)
163 return E_OUTOFMEMORY;
164
165 hr = SHIStream_Read(pstm, pidl, cbSize);
166 if (FAILED(hr))
167 {
168 CoTaskMemFree(pidl);
169 return hr;
170 }
171
172 /* Validate that the PIDL is well-formed */
173 pidlEnd = (LPITEMIDLIST)((PBYTE)pidl + cbSize - sizeof(USHORT));
174 for (pItem = &pidl->mkid; pItem <= (LPSHITEMID)pidlEnd;
175 pItem = (LPSHITEMID)((PBYTE)pItem + pItem->cb))
176 {
177 if (!pItem->cb)
178 break;
179 }
180
181 if ((LPITEMIDLIST)pItem == pidlEnd && !pItem->cb)
182 {
183 *ppidlOut = pidl;
184 hr = S_OK;
185 }
186 else
187 {
188 CoTaskMemFree(pidl);
190 }
191
192 return hr;
193}
194
195/*************************************************************************
196 * IStream_WritePidl [SHLWAPI.513]
197 *
198 * https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/util/istream/writepidl.htm
199 */
202{
203 UINT cbSize = ILGetSize(pidlWrite);
204 HRESULT hr = SHIStream_Write(pstm, &cbSize, sizeof(cbSize));
205 if (FAILED(hr))
206 return hr;
207 return SHIStream_Write(pstm, pidlWrite, cbSize);
208}
209#endif /* def __REACTOS__ */
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
BOOL WINAPI SHIsEmptyStream(IStream *lpStream)
Definition: istream.c:78
HRESULT WINAPI SHIStream_Write(IStream *lpStream, LPCVOID lpvSrc, ULONG ulSize)
Definition: istream.c:123
HRESULT WINAPI SHIStream_Read(IStream *lpStream, LPVOID lpvDest, ULONG ulSize)
Definition: istream.c:52
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
CONST void * LPCVOID
Definition: minwindef.h:164
unsigned int UINT
Definition: ndis.h:50
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
Definition: pidl.c:941
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
HRESULT WINAPI IStream_WritePidl(_In_ IStream *pstm, _In_ LPCITEMIDLIST pidlWrite)
HRESULT WINAPI IStream_ReadPidl(_In_ IStream *pstm, _Out_ LPITEMIDLIST *ppidlOut)
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
struct SHITEMID * LPSHITEMID
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
WORD cb
Definition: shtypes.idl:27
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6