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.
This commit is contained in:
parent
1c57a3ba2d
commit
89aa86165f
|
@ -58,6 +58,7 @@ static ICOM_VTABLE(IStream) StgStreamImpl_Vtbl =
|
|||
*/
|
||||
StgStreamImpl* StgStreamImpl_Construct(
|
||||
StorageBaseImpl* parentStorage,
|
||||
DWORD grfMode,
|
||||
ULONG ownerProperty)
|
||||
{
|
||||
StgStreamImpl* newStream;
|
||||
|
@ -79,6 +80,7 @@ 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
|
||||
/*
|
||||
* We don't support files with offsets of 64 bits.
|
||||
* do some multiword arithmetic:
|
||||
* treat HighPart as a signed value
|
||||
* treat LowPart as unsigned
|
||||
* NOTE: this stuff is two's complement specific!
|
||||
*/
|
||||
assert(dlibMove.s.HighPart == 0);
|
||||
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* Check if we end-up before the beginning of the file. That should trigger an
|
||||
* error.
|
||||
* 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.
|
||||
*/
|
||||
return E_FAIL;
|
||||
if (plibNewPosition->s.HighPart < 0) {
|
||||
return STG_E_INVALIDPOINTER;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* We currently don't support files with offsets of >32 bits.
|
||||
* Note that we have checked for a negative offset already
|
||||
*/
|
||||
assert(plibNewPosition->s.HighPart <= 0);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tell the caller what we calculated
|
||||
*/
|
||||
plibNewPosition->s.LowPart += dlibMove.s.LowPart;
|
||||
This->currentPosition = *plibNewPosition;
|
||||
|
||||
return S_OK;
|
||||
|
@ -583,6 +618,12 @@ 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;
|
||||
|
||||
|
@ -824,6 +865,8 @@ HRESULT WINAPI StgStreamImpl_Stat(
|
|||
&curProperty,
|
||||
grfStatFlag);
|
||||
|
||||
pstatstg->grfMode = This->grfMode;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -379,7 +379,8 @@ HRESULT StorageImpl_Construct(
|
|||
HANDLE hFile,
|
||||
ILockBytes* pLkbyt,
|
||||
DWORD openFlags,
|
||||
BOOL fileBased);
|
||||
BOOL fileBased,
|
||||
BOOL fileCreate);
|
||||
|
||||
BOOL StorageImpl_ReadBigBlock(
|
||||
StorageImpl* This,
|
||||
|
@ -604,6 +605,11 @@ struct StgStreamImpl
|
|||
*/
|
||||
StorageBaseImpl* parentStorage;
|
||||
|
||||
/*
|
||||
* Access mode of this stream.
|
||||
*/
|
||||
DWORD grfMode;
|
||||
|
||||
/*
|
||||
* Index of the property that owns (points to) this stream.
|
||||
*/
|
||||
|
@ -626,7 +632,6 @@ struct StgStreamImpl
|
|||
*/
|
||||
BlockChainStream* bigBlockChain;
|
||||
SmallBlockChainStream* smallBlockChain;
|
||||
DWORD grfMode;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -634,6 +639,7 @@ struct StgStreamImpl
|
|||
*/
|
||||
StgStreamImpl* StgStreamImpl_Construct(
|
||||
StorageBaseImpl* parentStorage,
|
||||
DWORD grfMode,
|
||||
ULONG ownerProperty);
|
||||
|
||||
void StgStreamImpl_Destroy(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue