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,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
|
@ -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);
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue