Commit 89aa8616 authored by Pierre Mageau's avatar Pierre Mageau Committed by Alexandre Julliard

Implementation of OleConvert routines.

Thuy Nguyen <thuy@macadamian.com> Don't allow to resize stream open in read only mode Allow write access for stream/storage open with STGM_READWRITE. StgOpenStorage return values are now more detailed. Don't rely on STGM_CREATE flag in the Storage constructor. Preventing to write out of date property. Owen Wang <owenw@corel.ca> Allow both positive & negative 32-bit integers as with MFC assumption. This patch improves the 32bit limit on IStream::*_Seek operations. John Li <johnl@corel.ca> When WP opens a linked file, the malloc function in OLECONVERT_LoadOLE10(...) returns a NULL. This causes a later Wine crash. The actual problem is the function reading a large data length.
parent 1c57a3ba
......@@ -58,7 +58,8 @@ static ICOM_VTABLE(IStream) StgStreamImpl_Vtbl =
*/
StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage,
ULONG ownerProperty)
DWORD grfMode,
ULONG ownerProperty)
{
StgStreamImpl* newStream;
......@@ -78,7 +79,8 @@ StgStreamImpl* StgStreamImpl_Construct(
*/
newStream->parentStorage = parentStorage;
IStorage_AddRef((IStorage*)newStream->parentStorage);
newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty;
/*
......@@ -427,6 +429,12 @@ HRESULT WINAPI StgStreamImpl_Write(
*/
*pcbWritten = 0;
/*
* Do we have permission to write to this stream?
*/
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
return STG_E_ACCESSDENIED;
if (cb == 0)
{
return S_OK;
......@@ -529,29 +537,56 @@ HRESULT WINAPI StgStreamImpl_Seek(
return STG_E_INVALIDFUNCTION;
}
#if SIZEOF_LONG_LONG >= 8
plibNewPosition->QuadPart += dlibMove.QuadPart;
#else
/*
* do some multiword arithmetic:
* treat HighPart as a signed value
* treat LowPart as unsigned
* NOTE: this stuff is two's complement specific!
*/
if (dlibMove.s.HighPart < 0) { /* dlibMove is < 0 */
/* calculate the absolute value of dlibMove ... */
dlibMove.s.HighPart = -dlibMove.s.HighPart;
dlibMove.s.LowPart ^= -1;
/* ... and subtract with carry */
if (dlibMove.s.LowPart > plibNewPosition->s.LowPart) {
/* carry needed, This accounts for any underflows at [1]*/
plibNewPosition->s.HighPart -= 1;
}
plibNewPosition->s.LowPart -= dlibMove.s.LowPart; /* [1] */
plibNewPosition->s.HighPart -= dlibMove.s.HighPart;
} else {
/* add directly */
int initialLowPart = plibNewPosition->s.LowPart;
plibNewPosition->s.LowPart += dlibMove.s.LowPart;
if((plibNewPosition->s.LowPart < initialLowPart) ||
(plibNewPosition->s.LowPart < dlibMove.s.LowPart)) {
/* LowPart has rolled over => add the carry digit to HighPart */
plibNewPosition->s.HighPart++;
}
plibNewPosition->s.HighPart += dlibMove.s.HighPart;
}
/*
* We don't support files with offsets of 64 bits.
* Check if we end-up before the beginning of the file. That should
* trigger an error.
*/
assert(dlibMove.s.HighPart == 0);
if (plibNewPosition->s.HighPart < 0) {
return STG_E_INVALIDPOINTER;
}
/*
* Check if we end-up before the beginning of the file. That should trigger an
* error.
*/
if ( (dlibMove.s.LowPart<0) && (plibNewPosition->s.LowPart < (ULONG)(-dlibMove.s.LowPart)) )
{
/*
* I don't know what error to send there.
* We currently don't support files with offsets of >32 bits.
* Note that we have checked for a negative offset already
*/
return E_FAIL;
}
assert(plibNewPosition->s.HighPart <= 0);
#endif
/*
* Move the actual file pointer
* If the file pointer ends-up after the end of the stream, the next Write operation will
* make the file larger. This is how it is documented.
* tell the caller what we calculated
*/
plibNewPosition->s.LowPart += dlibMove.s.LowPart;
This->currentPosition = *plibNewPosition;
return S_OK;
......@@ -582,7 +617,13 @@ HRESULT WINAPI StgStreamImpl_SetSize(
*/
if (libNewSize.s.HighPart != 0)
return STG_E_INVALIDFUNCTION;
/*
* Do we have permission?
*/
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
return STG_E_ACCESSDENIED;
if (This->streamSize.s.LowPart == libNewSize.s.LowPart)
return S_OK;
......@@ -823,6 +864,8 @@ HRESULT WINAPI StgStreamImpl_Stat(
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty,
grfStatFlag);
pstatstg->grfMode = This->grfMode;
return S_OK;
}
......
......@@ -375,11 +375,12 @@ void StorageImpl_Destroy(
StorageImpl* This);
HRESULT StorageImpl_Construct(
StorageImpl* This,
HANDLE hFile,
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased);
StorageImpl* This,
HANDLE hFile,
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased,
BOOL fileCreate);
BOOL StorageImpl_ReadBigBlock(
StorageImpl* This,
......@@ -605,6 +606,11 @@ struct StgStreamImpl
StorageBaseImpl* parentStorage;
/*
* Access mode of this stream.
*/
DWORD grfMode;
/*
* Index of the property that owns (points to) this stream.
*/
ULONG ownerProperty;
......@@ -626,7 +632,6 @@ struct StgStreamImpl
*/
BlockChainStream* bigBlockChain;
SmallBlockChainStream* smallBlockChain;
DWORD grfMode;
};
/*
......@@ -634,7 +639,8 @@ struct StgStreamImpl
*/
StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage,
ULONG ownerProperty);
DWORD grfMode,
ULONG ownerProperty);
void StgStreamImpl_Destroy(
StgStreamImpl* This);
......
......@@ -105,6 +105,24 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid,
LPVOID* ppvObj);
HRESULT WINAPI CreateOleAdviseHolder (LPOLEADVISEHOLDER *ppOAHolder);
/*
* OLE version conversion declarations
*/
typedef struct _OLESTREAM* LPOLESTREAM;
typedef struct _OLESTREAMVTBL {
DWORD (CALLBACK *Get)(LPOLESTREAM,LPSTR,DWORD);
DWORD (CALLBACK *Put)(LPOLESTREAM,LPSTR,DWORD);
} OLESTREAMVTBL;
typedef OLESTREAMVTBL* LPOLESTREAMVTBL;
typedef struct _OLESTREAM {
LPOLESTREAMVTBL lpstbl;
} OLESTREAM;
HRESULT WINAPI OleConvertOLESTREAMToIStorage( LPOLESTREAM lpolestream, LPSTORAGE pstg, const DVTARGETDEVICE* ptd);
HRESULT WINAPI OleConvertIStorageToOLESTREAM( LPSTORAGE pstg, LPOLESTREAM lpolestream);
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
......
......@@ -67,6 +67,9 @@ HRESULT WINAPI CLSIDFromString(LPCOLESTR, CLSID *);
HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid);
HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid);
HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID);
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax);
BOOL16 WINAPI IsEqualGUID16(GUID* g1,GUID* g2);
......
......@@ -1608,6 +1608,14 @@ extern int WIN32_LastError;
#define STG_E_NOTFILEBASEDSTORAGE 0x80030107
#define STG_E_EXTANTMARSHALLINGS 0x80030108
#define CONVERT10_E_OLESTREAM_GET 0x800401C0
#define CONVERT10_E_OLESTREAM_PUT 0x800401C1
#define CONVERT10_E_OLESTREAM_FMT 0x800401C2
#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3
#define CONVERT10_E_STG_FMT 0x800401C4
#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5
#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6
/* alten versionen
#define E_NOTIMPL 0x80000001
#define E_OUTOFMEMORY 0x80000002
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment