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:
Pierre Mageau 2000-02-25 20:58:25 +00:00 committed by Alexandre Julliard
parent 1c57a3ba2d
commit 89aa86165f
6 changed files with 1220 additions and 52 deletions

View File

@ -58,7 +58,8 @@ static ICOM_VTABLE(IStream) StgStreamImpl_Vtbl =
*/ */
StgStreamImpl* StgStreamImpl_Construct( StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage, StorageBaseImpl* parentStorage,
ULONG ownerProperty) DWORD grfMode,
ULONG ownerProperty)
{ {
StgStreamImpl* newStream; StgStreamImpl* newStream;
@ -78,7 +79,8 @@ StgStreamImpl* StgStreamImpl_Construct(
*/ */
newStream->parentStorage = parentStorage; newStream->parentStorage = parentStorage;
IStorage_AddRef((IStorage*)newStream->parentStorage); IStorage_AddRef((IStorage*)newStream->parentStorage);
newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty; newStream->ownerProperty = ownerProperty;
/* /*
@ -427,6 +429,12 @@ HRESULT WINAPI StgStreamImpl_Write(
*/ */
*pcbWritten = 0; *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) if (cb == 0)
{ {
return S_OK; return S_OK;
@ -529,29 +537,56 @@ HRESULT WINAPI StgStreamImpl_Seek(
return STG_E_INVALIDFUNCTION; 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 * Check if we end-up before the beginning of the file. That should
* error. * trigger an error.
*/ */
if ( (dlibMove.s.LowPart<0) && (plibNewPosition->s.LowPart < (ULONG)(-dlibMove.s.LowPart)) ) if (plibNewPosition->s.HighPart < 0) {
{ return STG_E_INVALIDPOINTER;
/*
* I don't know what error to send there.
*/
return E_FAIL;
} }
/*
* 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
/* /*
* Move the actual file pointer * tell the caller what we calculated
* 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.
*/ */
plibNewPosition->s.LowPart += dlibMove.s.LowPart;
This->currentPosition = *plibNewPosition; This->currentPosition = *plibNewPosition;
return S_OK; return S_OK;
@ -582,7 +617,13 @@ HRESULT WINAPI StgStreamImpl_SetSize(
*/ */
if (libNewSize.s.HighPart != 0) if (libNewSize.s.HighPart != 0)
return STG_E_INVALIDFUNCTION; 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) if (This->streamSize.s.LowPart == libNewSize.s.LowPart)
return S_OK; return S_OK;
@ -823,6 +864,8 @@ HRESULT WINAPI StgStreamImpl_Stat(
StorageUtl_CopyPropertyToSTATSTG(pstatstg, StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty, &curProperty,
grfStatFlag); grfStatFlag);
pstatstg->grfMode = This->grfMode;
return S_OK; return S_OK;
} }

File diff suppressed because it is too large Load Diff

View File

@ -375,11 +375,12 @@ void StorageImpl_Destroy(
StorageImpl* This); StorageImpl* This);
HRESULT StorageImpl_Construct( HRESULT StorageImpl_Construct(
StorageImpl* This, StorageImpl* This,
HANDLE hFile, HANDLE hFile,
ILockBytes* pLkbyt, ILockBytes* pLkbyt,
DWORD openFlags, DWORD openFlags,
BOOL fileBased); BOOL fileBased,
BOOL fileCreate);
BOOL StorageImpl_ReadBigBlock( BOOL StorageImpl_ReadBigBlock(
StorageImpl* This, StorageImpl* This,
@ -604,6 +605,11 @@ struct StgStreamImpl
*/ */
StorageBaseImpl* parentStorage; StorageBaseImpl* parentStorage;
/*
* Access mode of this stream.
*/
DWORD grfMode;
/* /*
* Index of the property that owns (points to) this stream. * Index of the property that owns (points to) this stream.
*/ */
@ -626,7 +632,6 @@ struct StgStreamImpl
*/ */
BlockChainStream* bigBlockChain; BlockChainStream* bigBlockChain;
SmallBlockChainStream* smallBlockChain; SmallBlockChainStream* smallBlockChain;
DWORD grfMode;
}; };
/* /*
@ -634,7 +639,8 @@ struct StgStreamImpl
*/ */
StgStreamImpl* StgStreamImpl_Construct( StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage, StorageBaseImpl* parentStorage,
ULONG ownerProperty); DWORD grfMode,
ULONG ownerProperty);
void StgStreamImpl_Destroy( void StgStreamImpl_Destroy(
StgStreamImpl* This); StgStreamImpl* This);

View File

@ -105,6 +105,24 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid,
LPVOID* ppvObj); LPVOID* ppvObj);
HRESULT WINAPI CreateOleAdviseHolder (LPOLEADVISEHOLDER *ppOAHolder); 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 #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */

View File

@ -67,6 +67,9 @@ HRESULT WINAPI CLSIDFromString(LPCOLESTR, CLSID *);
HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid); HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid);
HRESULT WINAPI CLSIDFromProgID(LPCOLESTR 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); INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax);
BOOL16 WINAPI IsEqualGUID16(GUID* g1,GUID* g2); BOOL16 WINAPI IsEqualGUID16(GUID* g1,GUID* g2);

View File

@ -1608,6 +1608,14 @@ extern int WIN32_LastError;
#define STG_E_NOTFILEBASEDSTORAGE 0x80030107 #define STG_E_NOTFILEBASEDSTORAGE 0x80030107
#define STG_E_EXTANTMARSHALLINGS 0x80030108 #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 /* alten versionen
#define E_NOTIMPL 0x80000001 #define E_NOTIMPL 0x80000001
#define E_OUTOFMEMORY 0x80000002 #define E_OUTOFMEMORY 0x80000002