{
ILockBytes ILockBytes_iface;
LONG ref;
- ULARGE_INTEGER filesize;
HANDLE hfile;
DWORD flProtect;
LPWSTR pwcsName;
This->ILockBytes_iface.lpVtbl = &FileLockBytesImpl_Vtbl;
This->ref = 1;
This->hfile = hFile;
- This->filesize.u.LowPart = GetFileSize(This->hfile,
- &This->filesize.u.HighPart);
This->flProtect = GetProtectMode(openFlags);
if(pwcsName) {
else
This->pwcsName = NULL;
- TRACE("file len %u\n", This->filesize.u.LowPart);
-
*pLockBytes = &This->ILockBytes_iface;
return S_OK;
ULONG* pcbWritten) /* [out] */
{
FileLockBytesImpl* This = impl_from_ILockBytes(iface);
- ULONG size_needed = ulOffset.u.LowPart + cb;
ULONG bytes_left = cb;
const BYTE *writePtr = pv;
BOOL ret;
if (pcbWritten)
*pcbWritten = 0;
- if (size_needed > This->filesize.u.LowPart)
- {
- ULARGE_INTEGER newSize;
- newSize.u.HighPart = 0;
- newSize.u.LowPart = size_needed;
- ILockBytes_SetSize(iface, newSize);
- }
-
offset.QuadPart = ulOffset.QuadPart;
ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN);
if (!ret)
- return STG_E_READFAULT;
+ return STG_E_WRITEFAULT;
while (bytes_left)
{
ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL);
if (!ret)
- return STG_E_READFAULT;
+ return STG_E_WRITEFAULT;
if (pcbWritten)
*pcbWritten += cbWritten;
HRESULT hr = S_OK;
LARGE_INTEGER newpos;
- if (This->filesize.u.LowPart == newSize.u.LowPart)
- return hr;
-
- TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
+ TRACE("new size %u\n", newSize.u.LowPart);
newpos.QuadPart = newSize.QuadPart;
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
SetEndOfFile(This->hfile);
}
- This->filesize = newSize;
return hr;
}
+static HRESULT get_lock_error(void)
+{
+ switch (GetLastError())
+ {
+ case ERROR_LOCK_VIOLATION: return STG_E_LOCKVIOLATION; break;
+ case ERROR_ACCESS_DENIED: return STG_E_ACCESSDENIED; break;
+ case ERROR_NOT_SUPPORTED: return STG_E_INVALIDFUNCTION; break;
+ default:
+ FIXME("no mapping for error %d\n", GetLastError());
+ return STG_E_INVALIDFUNCTION;
+ }
+}
+
static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
- FIXME("stub\n");
- return E_NOTIMPL;
+ FileLockBytesImpl* This = impl_from_ILockBytes(iface);
+ OVERLAPPED ol;
+ DWORD lock_flags = LOCKFILE_FAIL_IMMEDIATELY;
+
+ TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
+
+ if (dwLockType & LOCK_WRITE)
+ return STG_E_INVALIDFUNCTION;
+
+ if (dwLockType & (LOCK_EXCLUSIVE|LOCK_ONLYONCE))
+ lock_flags |= LOCKFILE_EXCLUSIVE_LOCK;
+
+ ol.hEvent = 0;
+ ol.u.s.Offset = libOffset.u.LowPart;
+ ol.u.s.OffsetHigh = libOffset.u.HighPart;
+
+ if (LockFileEx(This->hfile, lock_flags, 0, cb.u.LowPart, cb.u.HighPart, &ol))
+ return S_OK;
+ return get_lock_error();
+}
+
+HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface,
+ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb)
+{
+ FileLockBytesImpl* This = impl_from_ILockBytes(iface);
+ OVERLAPPED ol;
+
+ if (iface->lpVtbl != &FileLockBytesImpl_Vtbl)
+ return E_NOTIMPL;
+
+ ol.hEvent = 0;
+ ol.u.s.Offset = libOffset.u.LowPart;
+ ol.u.s.OffsetHigh = libOffset.u.HighPart;
+
+ if (LockFileEx(This->hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, cb.u.LowPart, cb.u.HighPart, &ol))
+ return S_OK;
+ return get_lock_error();
}
static HRESULT WINAPI FileLockBytesImpl_UnlockRegion(ILockBytes* iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
- FIXME("stub\n");
- return E_NOTIMPL;
+ FileLockBytesImpl* This = impl_from_ILockBytes(iface);
+ OVERLAPPED ol;
+
+ TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
+
+ if (dwLockType & LOCK_WRITE)
+ return STG_E_INVALIDFUNCTION;
+
+ ol.hEvent = 0;
+ ol.u.s.Offset = libOffset.u.LowPart;
+ ol.u.s.OffsetHigh = libOffset.u.HighPart;
+
+ if (UnlockFileEx(This->hfile, 0, cb.u.LowPart, cb.u.HighPart, &ol))
+ return S_OK;
+ return get_lock_error();
}
static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_LOCKBYTES;
- pstatstg->cbSize = This->filesize;
+
+ pstatstg->cbSize.u.LowPart = GetFileSize(This->hfile, &pstatstg->cbSize.u.HighPart);
/* FIXME: If the implementation is exported, we'll need to set other fields. */
return S_OK;