ReactOS 0.4.15-dev-7918-g2a2556c
filelockbytes.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * File-based ILockBytes implementation
4 *
5 * Copyright 1999 Thuy Nguyen
6 * Copyright 2010 Vincent Povirk for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#include <assert.h>
24#include <stdlib.h>
25#include <stdarg.h>
26#include <stdio.h>
27#include <string.h>
28#include <limits.h>
29
30#define COBJMACROS
31#define NONAMELESSUNION
32#define NONAMELESSSTRUCT
33
34#include "windef.h"
35#include "winbase.h"
36#include "winuser.h"
37#include "winerror.h"
38#include "objbase.h"
39#include "ole2.h"
40
41#include "storage32.h"
42
43#include "wine/debug.h"
44
46
47typedef struct FileLockBytesImpl
48{
55
56static const ILockBytesVtbl FileLockBytesImpl_Vtbl;
57
59{
60 return CONTAINING_RECORD(iface, FileLockBytesImpl, ILockBytes_iface);
61}
62
63/***********************************************************
64 * Prototypes for private methods
65 */
66
67/****************************************************************************
68 * GetProtectMode
69 *
70 * This function will return a protection mode flag for a file-mapping object
71 * from the open flags of a file.
72 */
73static DWORD GetProtectMode(DWORD openFlags)
74{
75 switch(STGM_ACCESS_MODE(openFlags))
76 {
77 case STGM_WRITE:
78 case STGM_READWRITE:
79 return PAGE_READWRITE;
80 }
81 return PAGE_READONLY;
82}
83
84/******************************************************************************
85 * FileLockBytesImpl_Construct
86 *
87 * Initialize a big block object supported by a file.
88 */
90{
92 WCHAR fullpath[MAX_PATH];
93
95 return E_FAIL;
96
98
99 if (!This)
100 return E_OUTOFMEMORY;
101
102 This->ILockBytes_iface.lpVtbl = &FileLockBytesImpl_Vtbl;
103 This->ref = 1;
104 This->hfile = hFile;
105 This->flProtect = GetProtectMode(openFlags);
106
107 if(pwcsName) {
108 if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL))
109 {
110 lstrcpynW(fullpath, pwcsName, MAX_PATH);
111 }
112 This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
113 (lstrlenW(fullpath)+1)*sizeof(WCHAR));
114 if (!This->pwcsName)
115 {
117 return E_OUTOFMEMORY;
118 }
119 lstrcpyW(This->pwcsName, fullpath);
120 }
121 else
122 This->pwcsName = NULL;
123
124 *pLockBytes = &This->ILockBytes_iface;
125
126 return S_OK;
127}
128
129/* ILockByte Interfaces */
130
132 void **ppvObject)
133{
134 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ILockBytes))
135 *ppvObject = iface;
136 else
137 {
138 *ppvObject = NULL;
139 return E_NOINTERFACE;
140 }
141
142 IUnknown_AddRef((IUnknown*)*ppvObject);
143
144 return S_OK;
145}
146
148{
150 return InterlockedIncrement(&This->ref);
151}
152
154{
156 ULONG ref;
157
159
160 if (ref == 0)
161 {
162 CloseHandle(This->hfile);
163 HeapFree(GetProcessHeap(), 0, This->pwcsName);
165 }
166
167 return ref;
168}
169
170/******************************************************************************
171 * This method is part of the ILockBytes interface.
172 *
173 * It reads a block of information from the byte array at the specified
174 * offset.
175 *
176 * See the documentation of ILockBytes for more info.
177 */
179 ILockBytes* iface,
180 ULARGE_INTEGER ulOffset, /* [in] */
181 void* pv, /* [length_is][size_is][out] */
182 ULONG cb, /* [in] */
183 ULONG* pcbRead) /* [out] */
184{
186 ULONG bytes_left = cb;
187 LPBYTE readPtr = pv;
188 BOOL ret;
190 ULONG cbRead;
191
192 TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead);
193
194 /* verify a sane environment */
195 if (!This) return E_FAIL;
196
197 if (pcbRead)
198 *pcbRead = 0;
199
200 offset.QuadPart = ulOffset.QuadPart;
201
203
204 if (!ret)
205 return STG_E_READFAULT;
206
207 while (bytes_left)
208 {
209 ret = ReadFile(This->hfile, readPtr, bytes_left, &cbRead, NULL);
210
211 if (!ret || cbRead == 0)
212 return STG_E_READFAULT;
213
214 if (pcbRead)
215 *pcbRead += cbRead;
216
217 bytes_left -= cbRead;
218 readPtr += cbRead;
219 }
220
221 TRACE("finished\n");
222 return S_OK;
223}
224
225/******************************************************************************
226 * This method is part of the ILockBytes interface.
227 *
228 * It writes the specified bytes at the specified offset.
229 * position. If the file is too small, it will be resized.
230 *
231 * See the documentation of ILockBytes for more info.
232 */
234 ILockBytes* iface,
235 ULARGE_INTEGER ulOffset, /* [in] */
236 const void* pv, /* [size_is][in] */
237 ULONG cb, /* [in] */
238 ULONG* pcbWritten) /* [out] */
239{
241 ULONG bytes_left = cb;
242 const BYTE *writePtr = pv;
243 BOOL ret;
245 ULONG cbWritten;
246
247 TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten);
248
249 /* verify a sane environment */
250 if (!This) return E_FAIL;
251
252 if (This->flProtect != PAGE_READWRITE)
253 return STG_E_ACCESSDENIED;
254
255 if (pcbWritten)
256 *pcbWritten = 0;
257
258 offset.QuadPart = ulOffset.QuadPart;
259
261
262 if (!ret)
263 return STG_E_WRITEFAULT;
264
265 while (bytes_left)
266 {
267 ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL);
268
269 if (!ret)
270 return STG_E_WRITEFAULT;
271
272 if (pcbWritten)
273 *pcbWritten += cbWritten;
274
275 bytes_left -= cbWritten;
276 writePtr += cbWritten;
277 }
278
279 TRACE("finished\n");
280 return S_OK;
281}
282
284{
285 return S_OK;
286}
287
288/******************************************************************************
289 * ILockBytes_SetSize
290 *
291 * Sets the size of the file.
292 *
293 */
295{
297 HRESULT hr = S_OK;
298 LARGE_INTEGER newpos;
299
300 TRACE("new size %u\n", newSize.u.LowPart);
301
302 newpos.QuadPart = newSize.QuadPart;
303 if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
304 {
305 SetEndOfFile(This->hfile);
306 }
307
308 return hr;
309}
310
312{
313 switch (GetLastError())
314 {
315 case ERROR_LOCK_VIOLATION: return STG_E_LOCKVIOLATION; break;
316 case ERROR_ACCESS_DENIED: return STG_E_ACCESSDENIED; break;
317 case ERROR_NOT_SUPPORTED: return STG_E_INVALIDFUNCTION; break;
318 default:
319 FIXME("no mapping for error %d\n", GetLastError());
321 }
322}
323
325 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
326{
328 OVERLAPPED ol;
329 DWORD lock_flags = LOCKFILE_FAIL_IMMEDIATELY;
330
331 TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
332
333 if (dwLockType & LOCK_WRITE)
335
336 if (dwLockType & (LOCK_EXCLUSIVE|LOCK_ONLYONCE))
337 lock_flags |= LOCKFILE_EXCLUSIVE_LOCK;
338
339 ol.hEvent = 0;
340 ol.u.s.Offset = libOffset.u.LowPart;
341 ol.u.s.OffsetHigh = libOffset.u.HighPart;
342
343 if (LockFileEx(This->hfile, lock_flags, 0, cb.u.LowPart, cb.u.HighPart, &ol))
344 return S_OK;
345 return get_lock_error();
346}
347
349 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
350{
352 OVERLAPPED ol;
353
354 TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
355
356 if (dwLockType & LOCK_WRITE)
358
359 ol.hEvent = 0;
360 ol.u.s.Offset = libOffset.u.LowPart;
361 ol.u.s.OffsetHigh = libOffset.u.HighPart;
362
363 if (UnlockFileEx(This->hfile, 0, cb.u.LowPart, cb.u.HighPart, &ol))
364 return S_OK;
365 return get_lock_error();
366}
367
369 STATSTG *pstatstg, DWORD grfStatFlag)
370{
372
373 if (!(STATFLAG_NONAME & grfStatFlag) && This->pwcsName)
374 {
375 pstatstg->pwcsName =
376 CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR));
377
378 lstrcpyW(pstatstg->pwcsName, This->pwcsName);
379 }
380 else
381 pstatstg->pwcsName = NULL;
382
383 pstatstg->type = STGTY_LOCKBYTES;
384
385 pstatstg->cbSize.u.LowPart = GetFileSize(This->hfile, &pstatstg->cbSize.u.HighPart);
386 /* FIXME: If the implementation is exported, we'll need to set other fields. */
387
388 pstatstg->grfLocksSupported = LOCK_EXCLUSIVE|LOCK_ONLYONCE|WINE_LOCK_READ;
389
390 return S_OK;
391}
392
393static const ILockBytesVtbl FileLockBytesImpl_Vtbl = {
404};
#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 E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
BOOL WINAPI UnlockFileEx(IN HANDLE hFile, IN DWORD dwReserved, IN DWORD nNumberOfBytesToUnLockLow, IN DWORD nNumberOfBytesToUnLockHigh, IN LPOVERLAPPED lpOverlapped)
Definition: lock.c:183
BOOL WINAPI LockFileEx(IN HANDLE hFile, IN DWORD dwFlags, IN DWORD dwReserved, IN DWORD nNumberOfBytesToLockLow, IN DWORD nNumberOfBytesToLockHigh, IN LPOVERLAPPED lpOverlapped)
Definition: lock.c:82
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
static ULONG WINAPI FileLockBytesImpl_Release(ILockBytes *iface)
static HRESULT WINAPI FileLockBytesImpl_UnlockRegion(ILockBytes *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
static HRESULT get_lock_error(void)
static ULONG WINAPI FileLockBytesImpl_AddRef(ILockBytes *iface)
static HRESULT WINAPI FileLockBytesImpl_WriteAt(ILockBytes *iface, ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
static HRESULT WINAPI FileLockBytesImpl_Flush(ILockBytes *iface)
static const ILockBytesVtbl FileLockBytesImpl_Vtbl
Definition: filelockbytes.c:56
static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes *iface, STATSTG *pstatstg, DWORD grfStatFlag)
static HRESULT WINAPI FileLockBytesImpl_ReadAt(ILockBytes *iface, ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes *iface, ULARGE_INTEGER newSize)
static DWORD GetProtectMode(DWORD openFlags)
Definition: filelockbytes.c:73
HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes)
Definition: filelockbytes.c:89
static FileLockBytesImpl * impl_from_ILockBytes(ILockBytes *iface)
Definition: filelockbytes.c:58
static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
static HRESULT WINAPI FileLockBytesImpl_QueryInterface(ILockBytes *iface, REFIID riid, void **ppvObject)
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLintptr offset
Definition: glext.h:5920
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
_In_ HANDLE hFile
Definition: mswsock.h:90
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_WRITE
Definition: objbase.h:918
long LONG
Definition: pedump.c:60
#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
#define WINE_LOCK_READ
Definition: storage32.h:523
#define STGM_ACCESS_MODE(stgm)
Definition: storage32.h:115
ILockBytes ILockBytes_iface
Definition: filelockbytes.c:49
DWORD OffsetHigh
Definition: winbase.h:816
DWORD Offset
Definition: winbase.h:815
HANDLE hEvent
Definition: winbase.h:820
struct _ULARGE_INTEGER::@4140 u
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: send.c:48
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
int ret
#define LOCKFILE_FAIL_IMMEDIATELY
Definition: winbase.h:385
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOCKFILE_EXCLUSIVE_LOCK
Definition: winbase.h:386
_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_LOCKVIOLATION
Definition: winerror.h:2578
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_READFAULT
Definition: winerror.h:2576
#define ERROR_LOCK_VIOLATION
Definition: winerror.h:136
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
#define STG_E_WRITEFAULT
Definition: winerror.h:2575
#define STG_E_INVALIDFUNCTION
Definition: winerror.h:2564
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193