PATCH: more 16bit ole
Marcus Meissner
marcus at jet.franken.de
Fri Aug 5 15:41:12 CDT 2005
Hi,
Testing a 16bit OLE using application I had to fix some 16bit OLE things.
The 16bit compound storage handling now understands ILockBytes interfaces.
(Actually it should be ported to use the 32bit one instead of doing it the
hack approach it currently is.)
And some stubs / small functions added.
Now it wants to do OLELOAD :/
Changelog:
Implemented ILockBytes16 (memorystream) support for the 16bit compound
storage implementation.
Added ReadClassStg, OleDoAutoConvert, GetConvertStg implementations/stubs.
Index: dlls/ole32/ole2.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole2.c,v
retrieving revision 1.70
diff -u -r1.70 ole2.c
--- dlls/ole32/ole2.c 22 Jul 2005 18:29:19 -0000 1.70
+++ dlls/ole32/ole2.c 5 Aug 2005 20:38:19 -0000
@@ -2328,6 +2328,15 @@
return E_NOTIMPL;
}
+/******************************************************************************
+ * OleDoAutoConvert [OLE2.@]
+ */
+HRESULT WINAPI OleDoAutoConvert16(IStorage *pStg, LPCLSID pClsidNew)
+{
+ FIXME("(%p,%p) : stub\n",pStg,pClsidNew);
+ return E_NOTIMPL;
+}
+
/***********************************************************************
* OLE_FreeClipDataArray [internal]
*
Index: dlls/ole32/ole2.spec
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole2.spec,v
retrieving revision 1.10
diff -u -r1.10 ole2.spec
--- dlls/ole32/ole2.spec 22 Jul 2005 18:29:39 -0000 1.10
+++ dlls/ole32/ole2.spec 5 Aug 2005 20:38:19 -0000
@@ -15,7 +15,7 @@
#15 ___EXPORTEDSTUB
16 stub OLEISRUNNING
17 stub OLELOCKRUNNING
-18 stub READCLASSSTG
+18 pascal ReadClassStg(segptr ptr) ReadClassStg16
19 stub WRITECLASSSTG
20 stub READCLASSSTM
21 stub WRITECLASSSTM
@@ -74,10 +74,10 @@
76 pascal -ret16 OleFlushClipboard() OleFlushClipboard16
77 stub OLEISCURRENTCLIPBOARD
78 stub OLETRANSLATEACCELERATOR
-79 stub OLEDOAUTOCONVERT
+79 pascal OleDoAutoConvert(ptr ptr) OleDoAutoConvert16
80 stub OLEGETAUTOCONVERT
81 stub OLESETAUTOCONVERT
-82 stub GETCONVERTSTG
+82 pascal GETCONVERTSTG(ptr) GetConvertStg16
83 stub SETCONVERTSTG
84 stub CREATESTREAMONHGLOBAL
85 stub GETHGLOBALFROMSTREAM
Index: dlls/ole32/storage.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage.c,v
retrieving revision 1.47
diff -u -r1.47 storage.c
--- dlls/ole32/storage.c 22 Jul 2005 09:03:29 -0000 1.47
+++ dlls/ole32/storage.c 5 Aug 2005 20:38:20 -0000
@@ -89,7 +89,7 @@
#define SMALLBLOCKS_PER_BIGBLOCK (BIGSIZE/SMALLSIZE)
-#define READ_HEADER STORAGE_get_big_block(hf,-1,(LPBYTE)&sth);assert(!memcmp(STORAGE_magic,sth.magic,sizeof(STORAGE_magic)));
+#define READ_HEADER(str) STORAGE_get_big_block(str,-1,(LPBYTE)&sth);assert(!memcmp(STORAGE_magic,sth.magic,sizeof(STORAGE_magic)));
static IStorage16Vtbl stvt16;
static const IStorage16Vtbl *segstvt16 = NULL;
static IStream16Vtbl strvt16;
@@ -319,6 +319,24 @@
* deeper (but never shallower) tree.
*/
+typedef struct {
+ HANDLE hf;
+ SEGPTR lockbytes;
+} stream_access16;
+/* --- IStorage16 implementation struct */
+
+typedef struct
+{
+ /* IUnknown fields */
+ const IStorage16Vtbl *lpVtbl;
+ LONG ref;
+ /* IStorage16 fields */
+ SEGPTR thisptr; /* pointer to this struct as segmented */
+ struct storage_pps_entry stde;
+ int ppsent;
+ stream_access16 str;
+} IStorage16Impl;
+
/******************************************************************************
* STORAGE_get_big_block [Internal]
@@ -326,22 +344,80 @@
* Reading OLE compound storage
*/
static BOOL
-STORAGE_get_big_block(HANDLE hf,int n,BYTE *block)
+STORAGE_get_big_block(stream_access16 *str,int n,BYTE *block)
{
DWORD result;
assert(n>=-1);
- if ((SetFilePointer( hf, (n+1)*BIGSIZE, NULL,
- SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
- {
- WARN(" seek failed (%ld)\n",GetLastError());
- return FALSE;
+ if (str->hf) {
+ if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
+ SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
+ {
+ WARN("(%p,%d,%p), seek failed (%ld)\n",str->hf, n, block, GetLastError());
+ return FALSE;
+ }
+ if (!ReadFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
+ {
+ WARN("(hf=%p, block size %d): read didn't read (%ld)\n",str->hf,n,GetLastError());
+ return FALSE;
+ }
+ } else {
+ DWORD args[6];
+ HRESULT hres;
+ HANDLE16 hsig;
+
+ args[0] = (DWORD)str->lockbytes; /* iface */
+ args[1] = (n+1)*BIGSIZE;
+ args[2] = 0; /* ULARGE_INTEGER offset */
+ args[3] = (DWORD)K32WOWGlobalAllocLock16( 0, BIGSIZE, &hsig ); /* sig */
+ args[4] = BIGSIZE;
+ args[5] = 0;
+
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const ILockBytes16Vtbl*)MapSL(
+ (SEGPTR)((LPLOCKBYTES16)MapSL(str->lockbytes))->lpVtbl)
+ )->ReadAt,
+ WCB16_PASCAL,
+ 6*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ )) {
+ ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
+ return FALSE;
+ }
+ memcpy(block, MapSL(args[3]), BIGSIZE);
+ K32WOWGlobalUnlockFree16(args[3]);
}
- if (!ReadFile( hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
- {
- WARN("(block size %d): read didn't read (%ld)\n",n,GetLastError());
- return FALSE;
+ return TRUE;
+}
+
+static BOOL
+_ilockbytes16_writeat(SEGPTR lockbytes, DWORD offset, DWORD length, void *buffer) {
+ DWORD args[6];
+ HRESULT hres;
+
+ args[0] = (DWORD)lockbytes; /* iface */
+ args[1] = offset;
+ args[2] = 0; /* ULARGE_INTEGER offset */
+ args[3] = (DWORD)MapLS( buffer );
+ args[4] = length;
+ args[5] = 0;
+
+ /* THIS_ ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten); */
+
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const ILockBytes16Vtbl*)MapSL(
+ (SEGPTR)((LPLOCKBYTES16)MapSL(lockbytes))->lpVtbl)
+ )->WriteAt,
+ WCB16_PASCAL,
+ 6*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ )) {
+ ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %lx\n",hres);
+ return FALSE;
}
+ UnMapLS(args[3]);
return TRUE;
}
@@ -349,39 +425,44 @@
* STORAGE_put_big_block [INTERNAL]
*/
static BOOL
-STORAGE_put_big_block(HANDLE hf,int n,BYTE *block)
+STORAGE_put_big_block(stream_access16 *str,int n,BYTE *block)
{
DWORD result;
assert(n>=-1);
- if ((SetFilePointer( hf, (n+1)*BIGSIZE, NULL,
- SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
- {
- WARN("seek failed (%ld)\n",GetLastError());
- return FALSE;
- }
- if (!WriteFile( hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
- {
- WARN(" write failed (%ld)\n",GetLastError());
- return FALSE;
+ if (str->hf) {
+ if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
+ SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
+ {
+ WARN("seek failed (%ld)\n",GetLastError());
+ return FALSE;
+ }
+ if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
+ {
+ WARN(" write failed (%ld)\n",GetLastError());
+ return FALSE;
+ }
+ return TRUE;
+ } else {
+ _ilockbytes16_writeat(str->lockbytes, (n+1)*BIGSIZE, BIGSIZE, block);
+ return TRUE;
}
- return TRUE;
}
/******************************************************************************
* STORAGE_get_next_big_blocknr [INTERNAL]
*/
static int
-STORAGE_get_next_big_blocknr(HANDLE hf,int blocknr) {
+STORAGE_get_next_big_blocknr(stream_access16 *str,int blocknr) {
INT bbs[BIGSIZE/sizeof(INT)];
struct storage_header sth;
- READ_HEADER;
+ READ_HEADER(str);
assert(blocknr>>7<sth.num_of_bbd_blocks);
if (sth.bbd_list[blocknr>>7]==0xffffffff)
return -5;
- if (!STORAGE_get_big_block(hf,sth.bbd_list[blocknr>>7],(LPBYTE)bbs))
+ if (!STORAGE_get_big_block(str,sth.bbd_list[blocknr>>7],(LPBYTE)bbs))
return -5;
assert(bbs[blocknr&0x7f]!=STORAGE_CHAINENTRY_FREE);
return bbs[blocknr&0x7f];
@@ -391,12 +472,13 @@
* STORAGE_get_nth_next_big_blocknr [INTERNAL]
*/
static int
-STORAGE_get_nth_next_big_blocknr(HANDLE hf,int blocknr,int nr) {
+STORAGE_get_nth_next_big_blocknr(stream_access16 *str,int blocknr,int nr) {
INT bbs[BIGSIZE/sizeof(INT)];
int lastblock = -1;
struct storage_header sth;
- READ_HEADER;
+ TRACE("(blocknr=%d, nr=%d)\n", blocknr, nr);
+ READ_HEADER(str);
assert(blocknr>=0);
while (nr--) {
@@ -405,7 +487,7 @@
/* simple caching... */
if (lastblock!=sth.bbd_list[blocknr>>7]) {
- BOOL ret = STORAGE_get_big_block(hf,sth.bbd_list[blocknr>>7],(LPBYTE)bbs);
+ BOOL ret = STORAGE_get_big_block(str,sth.bbd_list[blocknr>>7],(LPBYTE)bbs);
assert(ret);
lastblock = sth.bbd_list[blocknr>>7];
}
@@ -418,16 +500,17 @@
* STORAGE_get_root_pps_entry [Internal]
*/
static BOOL
-STORAGE_get_root_pps_entry(HANDLE hf,struct storage_pps_entry *pstde) {
+STORAGE_get_root_pps_entry(stream_access16* str,struct storage_pps_entry *pstde) {
int blocknr,i;
BYTE block[BIGSIZE];
struct storage_pps_entry *stde=(struct storage_pps_entry*)block;
struct storage_header sth;
- READ_HEADER;
+ READ_HEADER(str);
blocknr = sth.root_startblock;
+ TRACE("startblock is %d\n", blocknr);
while (blocknr>=0) {
- BOOL ret = STORAGE_get_big_block(hf,blocknr,block);
+ BOOL ret = STORAGE_get_big_block(str,blocknr,block);
assert(ret);
for (i=0;i<4;i++) {
if (!stde[i].pps_sizeofname)
@@ -437,7 +520,8 @@
return TRUE;
}
}
- blocknr=STORAGE_get_next_big_blocknr(hf,blocknr);
+ blocknr=STORAGE_get_next_big_blocknr(str,blocknr);
+ TRACE("next block is %d\n", blocknr);
}
return FALSE;
}
@@ -446,18 +530,19 @@
* STORAGE_get_small_block [INTERNAL]
*/
static BOOL
-STORAGE_get_small_block(HANDLE hf,int blocknr,BYTE *sblock) {
+STORAGE_get_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
BYTE block[BIGSIZE];
int bigblocknr;
struct storage_pps_entry root;
BOOL ret;
+ TRACE("(blocknr=%d)\n", blocknr);
assert(blocknr>=0);
- ret = STORAGE_get_root_pps_entry(hf,&root);
+ ret = STORAGE_get_root_pps_entry(str,&root);
assert(ret);
- bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
+ bigblocknr = STORAGE_get_nth_next_big_blocknr(str,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
memcpy(sblock,((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),SMALLSIZE);
@@ -468,23 +553,24 @@
* STORAGE_put_small_block [INTERNAL]
*/
static BOOL
-STORAGE_put_small_block(HANDLE hf,int blocknr,BYTE *sblock) {
+STORAGE_put_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
BYTE block[BIGSIZE];
int bigblocknr;
struct storage_pps_entry root;
BOOL ret;
assert(blocknr>=0);
+ TRACE("(blocknr=%d)\n", blocknr);
- ret = STORAGE_get_root_pps_entry(hf,&root);
+ ret = STORAGE_get_root_pps_entry(str,&root);
assert(ret);
- bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
+ bigblocknr = STORAGE_get_nth_next_big_blocknr(str,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
memcpy(((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),sblock,SMALLSIZE);
- ret = STORAGE_put_big_block(hf,bigblocknr,block);
+ ret = STORAGE_put_big_block(str,bigblocknr,block);
assert(ret);
return TRUE;
}
@@ -493,18 +579,19 @@
* STORAGE_get_next_small_blocknr [INTERNAL]
*/
static int
-STORAGE_get_next_small_blocknr(HANDLE hf,int blocknr) {
+STORAGE_get_next_small_blocknr(stream_access16 *str,int blocknr) {
BYTE block[BIGSIZE];
LPINT sbd = (LPINT)block;
int bigblocknr;
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ TRACE("(blocknr=%d)\n", blocknr);
+ READ_HEADER(str);
assert(blocknr>=0);
- bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128);
+ bigblocknr = STORAGE_get_nth_next_big_blocknr(str,sth.sbd_startblock,blocknr/128);
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
assert(sbd[blocknr & 127]!=STORAGE_CHAINENTRY_FREE);
return sbd[blocknr & (128-1)];
@@ -514,21 +601,22 @@
* STORAGE_get_nth_next_small_blocknr [INTERNAL]
*/
static int
-STORAGE_get_nth_next_small_blocknr(HANDLE hf,int blocknr,int nr) {
+STORAGE_get_nth_next_small_blocknr(stream_access16*str,int blocknr,int nr) {
int lastblocknr=-1;
BYTE block[BIGSIZE];
LPINT sbd = (LPINT)block;
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ TRACE("(blocknr=%d, nr=%d)\n", blocknr, nr);
+ READ_HEADER(str);
assert(blocknr>=0);
while ((nr--) && (blocknr>=0)) {
if (lastblocknr/128!=blocknr/128) {
int bigblocknr;
- bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128);
+ bigblocknr = STORAGE_get_nth_next_big_blocknr(str,sth.sbd_startblock,blocknr/128);
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
lastblocknr = blocknr;
}
@@ -544,18 +632,19 @@
* STORAGE_get_pps_entry [INTERNAL]
*/
static int
-STORAGE_get_pps_entry(HANDLE hf,int n,struct storage_pps_entry *pstde) {
+STORAGE_get_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde) {
int blocknr;
BYTE block[BIGSIZE];
struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ TRACE("(n=%d)\n", n);
+ READ_HEADER(str);
/* we have 4 pps entries per big block */
- blocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.root_startblock,n/4);
+ blocknr = STORAGE_get_nth_next_big_blocknr(str,sth.root_startblock,n/4);
assert(blocknr>=0);
- ret = STORAGE_get_big_block(hf,blocknr,block);
+ ret = STORAGE_get_big_block(str,blocknr,block);
assert(ret);
*pstde=*stde;
@@ -566,22 +655,22 @@
* STORAGE_put_pps_entry [Internal]
*/
static int
-STORAGE_put_pps_entry(HANDLE hf,int n,struct storage_pps_entry *pstde) {
+STORAGE_put_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde) {
int blocknr;
BYTE block[BIGSIZE];
struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));
struct storage_header sth;
BOOL ret;
- READ_HEADER;
-
+ TRACE("(n=%d)\n", n);
+ READ_HEADER(str);
/* we have 4 pps entries per big block */
- blocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.root_startblock,n/4);
+ blocknr = STORAGE_get_nth_next_big_blocknr(str,sth.root_startblock,n/4);
assert(blocknr>=0);
- ret = STORAGE_get_big_block(hf,blocknr,block);
+ ret = STORAGE_get_big_block(str,blocknr,block);
assert(ret);
*stde=*pstde;
- ret = STORAGE_put_big_block(hf,blocknr,block);
+ ret = STORAGE_put_big_block(str,blocknr,block);
assert(ret);
return 1;
}
@@ -590,24 +679,25 @@
* STORAGE_look_for_named_pps [Internal]
*/
static int
-STORAGE_look_for_named_pps(HANDLE hf,int n,LPOLESTR name) {
+STORAGE_look_for_named_pps(stream_access16*str,int n,LPOLESTR name) {
struct storage_pps_entry stde;
int ret;
+ TRACE("(n=%d,name=%s)\n", n, debugstr_w(name));
if (n==-1)
return -1;
- if (1!=STORAGE_get_pps_entry(hf,n,&stde))
+ if (1!=STORAGE_get_pps_entry(str,n,&stde))
return -1;
if (!lstrcmpW(name,stde.pps_rawname))
return n;
if (stde.pps_prev != -1) {
- ret=STORAGE_look_for_named_pps(hf,stde.pps_prev,name);
+ ret=STORAGE_look_for_named_pps(str,stde.pps_prev,name);
if (ret!=-1)
return ret;
}
if (stde.pps_next != -1) {
- ret=STORAGE_look_for_named_pps(hf,stde.pps_next,name);
+ ret=STORAGE_look_for_named_pps(str,stde.pps_next,name);
if (ret!=-1)
return ret;
}
@@ -651,14 +741,15 @@
* STORAGE_init_storage [INTERNAL]
*/
static BOOL
-STORAGE_init_storage(HANDLE hf) {
+STORAGE_init_storage(stream_access16 *str) {
BYTE block[BIGSIZE];
LPDWORD bbs;
struct storage_header *sth;
struct storage_pps_entry *stde;
DWORD result;
- SetFilePointer( hf, 0, NULL, SEEK_SET );
+ if (str->hf)
+ SetFilePointer( str->hf, 0, NULL, SEEK_SET );
/* block -1 is the storage header */
sth = (struct storage_header*)block;
memcpy(sth->magic,STORAGE_magic,8);
@@ -670,13 +761,21 @@
sth->sbd_startblock = 0xffffffff;
memset(sth->bbd_list,0xff,sizeof(sth->bbd_list));
sth->bbd_list[0] = 0;
- if (!WriteFile( hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
+ if (str->hf) {
+ if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
+ } else {
+ if (!_ilockbytes16_writeat(str->lockbytes, 0, BIGSIZE, block)) return FALSE;
+ }
/* block 0 is the big block directory */
bbs=(LPDWORD)block;
memset(block,0xff,sizeof(block)); /* mark all blocks as free */
bbs[0]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for this block */
bbs[1]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for directory entry */
- if (!WriteFile( hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
+ if (str->hf) {
+ if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
+ } else {
+ if (!_ilockbytes16_writeat(str->lockbytes, BIGSIZE, BIGSIZE, block)) return FALSE;
+ }
/* block 1 is the root directory entry */
memset(block,0x00,sizeof(block));
stde = (struct storage_pps_entry*)block;
@@ -689,33 +788,37 @@
stde->pps_prev = -1;
stde->pps_sb = 0xffffffff;
stde->pps_size = 0;
- return (WriteFile( hf, block, BIGSIZE, &result, NULL ) && result == BIGSIZE);
+ if (str->hf) {
+ return (WriteFile( str->hf, block, BIGSIZE, &result, NULL ) && result == BIGSIZE);
+ } else {
+ return _ilockbytes16_writeat(str->lockbytes, BIGSIZE, BIGSIZE, block);
+ }
}
/******************************************************************************
* STORAGE_set_big_chain [Internal]
*/
static BOOL
-STORAGE_set_big_chain(HANDLE hf,int blocknr,INT type) {
+STORAGE_set_big_chain(stream_access16*str,int blocknr,INT type) {
BYTE block[BIGSIZE];
LPINT bbd = (LPINT)block;
int nextblocknr,bigblocknr;
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ READ_HEADER(str);
assert(blocknr!=type);
while (blocknr>=0) {
bigblocknr = sth.bbd_list[blocknr/128];
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
nextblocknr = bbd[blocknr&(128-1)];
bbd[blocknr&(128-1)] = type;
if (type>=0)
return TRUE;
- ret = STORAGE_put_big_block(hf,bigblocknr,block);
+ ret = STORAGE_put_big_block(str,bigblocknr,block);
assert(ret);
type = STORAGE_CHAINENTRY_FREE;
blocknr = nextblocknr;
@@ -727,29 +830,29 @@
* STORAGE_set_small_chain [Internal]
*/
static BOOL
-STORAGE_set_small_chain(HANDLE hf,int blocknr,INT type) {
+STORAGE_set_small_chain(stream_access16*str,int blocknr,INT type) {
BYTE block[BIGSIZE];
LPINT sbd = (LPINT)block;
int lastblocknr,nextsmallblocknr,bigblocknr;
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ READ_HEADER(str);
assert(blocknr!=type);
lastblocknr=-129;bigblocknr=-2;
while (blocknr>=0) {
/* cache block ... */
if (lastblocknr/128!=blocknr/128) {
- bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128);
+ bigblocknr = STORAGE_get_nth_next_big_blocknr(str,sth.sbd_startblock,blocknr/128);
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
}
lastblocknr = blocknr;
nextsmallblocknr = sbd[blocknr&(128-1)];
sbd[blocknr&(128-1)] = type;
- ret = STORAGE_put_big_block(hf,bigblocknr,block);
+ ret = STORAGE_put_big_block(str,bigblocknr,block);
assert(ret);
if (type>=0)
return TRUE;
@@ -763,7 +866,7 @@
* STORAGE_get_free_big_blocknr [Internal]
*/
static int
-STORAGE_get_free_big_blocknr(HANDLE hf) {
+STORAGE_get_free_big_blocknr(stream_access16 *str) {
BYTE block[BIGSIZE];
LPINT sbd = (LPINT)block;
int lastbigblocknr,i,bigblocknr;
@@ -771,21 +874,21 @@
struct storage_header sth;
BOOL ret;
- READ_HEADER;
+ READ_HEADER(str);
curblock = 0;
lastbigblocknr = -1;
bigblocknr = sth.bbd_list[curblock];
while (curblock<sth.num_of_bbd_blocks) {
assert(bigblocknr>=0);
- ret = STORAGE_get_big_block(hf,bigblocknr,block);
+ ret = STORAGE_get_big_block(str,bigblocknr,block);
assert(ret);
for (i=0;i<128;i++)
if (sbd[i]==STORAGE_CHAINENTRY_FREE) {
sbd[i] = STORAGE_CHAINENTRY_ENDOFCHAIN;
- ret = STORAGE_put_big_block(hf,bigblocknr,block);
+ ret = STORAGE_put_big_block(str,bigblocknr,block);
assert(ret);
memset(block,0x42,sizeof(block));
- ret = STORAGE_put_big_block(hf,i+curblock*128,block);
+ ret = STORAGE_put_big_block(str,i+curblock*128,block);
assert(ret);
return i+curblock*128;
}
@@ -800,30 +903,30 @@
memset(block,0xff,sizeof(block));
/* mark the block allocated and returned by this function */
sbd[1] = STORAGE_CHAINENTRY_ENDOFCHAIN;
- ret = STORAGE_put_big_block(hf,bigblocknr,block);
+ ret = STORAGE_put_big_block(str,bigblocknr,block);
assert(ret);
/* if we had a bbd block already (mostlikely) we need
* to link the new one into the chain
*/
if (lastbigblocknr!=-1) {
- ret = STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr);
+ ret = STORAGE_set_big_chain(str,lastbigblocknr,bigblocknr);
assert(ret);
}
sth.bbd_list[curblock]=bigblocknr;
sth.num_of_bbd_blocks++;
assert(sth.num_of_bbd_blocks==curblock+1);
- ret = STORAGE_put_big_block(hf,-1,(LPBYTE)&sth);
+ ret = STORAGE_put_big_block(str,-1,(LPBYTE)&sth);
assert(ret);
/* Set the end of the chain for the bigblockdepots */
- ret = STORAGE_set_big_chain(hf,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN);
+ ret = STORAGE_set_big_chain(str,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN);
assert(ret);
/* add 1, for the first entry is used for the additional big block
* depot. (means we already used bigblocknr) */
memset(block,0x42,sizeof(block));
/* allocate this block (filled with 0x42) */
- ret = STORAGE_put_big_block(hf,bigblocknr+1,block);
+ ret = STORAGE_put_big_block(str,bigblocknr+1,block);
assert(ret);
return bigblocknr+1;
}
@@ -833,20 +936,20 @@
* STORAGE_get_free_small_blocknr [Internal]
*/
static int
-STORAGE_get_free_small_blocknr(HANDLE hf) {
+STORAGE_get_free_small_blocknr(stream_access16 *str) {
BYTE block[BIGSIZE];
LPINT sbd = (LPINT)block;
int lastbigblocknr,newblocknr,i,curblock,bigblocknr;
struct storage_pps_entry root;
struct storage_header sth;
- READ_HEADER;
+ READ_HEADER(str);
bigblocknr = sth.sbd_startblock;
curblock = 0;
lastbigblocknr = -1;
newblocknr = -1;
while (bigblocknr>=0) {
- if (!STORAGE_get_big_block(hf,bigblocknr,block))
+ if (!STORAGE_get_big_block(str,bigblocknr,block))
return -1;
for (i=0;i<128;i++)
if (sbd[i]==STORAGE_CHAINENTRY_FREE) {
@@ -857,56 +960,56 @@
if (i!=128)
break;
lastbigblocknr = bigblocknr;
- bigblocknr = STORAGE_get_next_big_blocknr(hf,bigblocknr);
+ bigblocknr = STORAGE_get_next_big_blocknr(str,bigblocknr);
curblock++;
}
if (newblocknr==-1) {
- bigblocknr = STORAGE_get_free_big_blocknr(hf);
+ bigblocknr = STORAGE_get_free_big_blocknr(str);
if (bigblocknr<0)
return -1;
- READ_HEADER;
+ READ_HEADER(str);
memset(block,0xff,sizeof(block));
sbd[0]=STORAGE_CHAINENTRY_ENDOFCHAIN;
- if (!STORAGE_put_big_block(hf,bigblocknr,block))
+ if (!STORAGE_put_big_block(str,bigblocknr,block))
return -1;
if (lastbigblocknr==-1) {
sth.sbd_startblock = bigblocknr;
- if (!STORAGE_put_big_block(hf,-1,(LPBYTE)&sth)) /* need to write it */
+ if (!STORAGE_put_big_block(str,-1,(LPBYTE)&sth)) /* need to write it */
return -1;
} else {
- if (!STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr))
+ if (!STORAGE_set_big_chain(str,lastbigblocknr,bigblocknr))
return -1;
}
- if (!STORAGE_set_big_chain(hf,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(str,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return -1;
newblocknr = curblock*128;
}
/* allocate enough big blocks for storing the allocated small block */
- if (!STORAGE_get_root_pps_entry(hf,&root))
+ if (!STORAGE_get_root_pps_entry(str,&root))
return -1;
if (root.pps_sb==-1)
lastbigblocknr = -1;
else
- lastbigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,(root.pps_size-1)/BIGSIZE);
+ lastbigblocknr = STORAGE_get_nth_next_big_blocknr(str,root.pps_sb,(root.pps_size-1)/BIGSIZE);
while (root.pps_size < (newblocknr*SMALLSIZE+SMALLSIZE-1)) {
/* we need to allocate more stuff */
- bigblocknr = STORAGE_get_free_big_blocknr(hf);
+ bigblocknr = STORAGE_get_free_big_blocknr(str);
if (bigblocknr<0)
return -1;
- READ_HEADER;
+ READ_HEADER(str);
if (root.pps_sb==-1) {
root.pps_sb = bigblocknr;
root.pps_size += BIGSIZE;
} else {
- if (!STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr))
+ if (!STORAGE_set_big_chain(str,lastbigblocknr,bigblocknr))
return -1;
root.pps_size += BIGSIZE;
}
lastbigblocknr = bigblocknr;
}
- if (!STORAGE_set_big_chain(hf,lastbigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(str,lastbigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return -1;
- if (!STORAGE_put_pps_entry(hf,0,&root))
+ if (!STORAGE_put_pps_entry(str,0,&root))
return -1;
return newblocknr;
}
@@ -915,38 +1018,38 @@
* STORAGE_get_free_pps_entry [Internal]
*/
static int
-STORAGE_get_free_pps_entry(HANDLE hf) {
+STORAGE_get_free_pps_entry(stream_access16*str) {
int blocknr, i, curblock, lastblocknr=-1;
BYTE block[BIGSIZE];
struct storage_pps_entry *stde = (struct storage_pps_entry*)block;
struct storage_header sth;
- READ_HEADER;
+ READ_HEADER(str);
blocknr = sth.root_startblock;
assert(blocknr>=0);
curblock=0;
while (blocknr>=0) {
- if (!STORAGE_get_big_block(hf,blocknr,block))
+ if (!STORAGE_get_big_block(str,blocknr,block))
return -1;
for (i=0;i<4;i++)
if (stde[i].pps_sizeofname==0) /* free */
return curblock*4+i;
lastblocknr = blocknr;
- blocknr = STORAGE_get_next_big_blocknr(hf,blocknr);
+ blocknr = STORAGE_get_next_big_blocknr(str,blocknr);
curblock++;
}
assert(blocknr==STORAGE_CHAINENTRY_ENDOFCHAIN);
- blocknr = STORAGE_get_free_big_blocknr(hf);
+ blocknr = STORAGE_get_free_big_blocknr(str);
/* sth invalidated */
if (blocknr<0)
return -1;
- if (!STORAGE_set_big_chain(hf,lastblocknr,blocknr))
+ if (!STORAGE_set_big_chain(str,lastblocknr,blocknr))
return -1;
- if (!STORAGE_set_big_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return -1;
memset(block,0,sizeof(block));
- STORAGE_put_big_block(hf,blocknr,block);
+ STORAGE_put_big_block(str,blocknr,block);
return curblock*4;
}
@@ -961,8 +1064,8 @@
SEGPTR thisptr; /* pointer to this struct as segmented */
struct storage_pps_entry stde;
int ppsent;
- HANDLE hf;
ULARGE_INTEGER offset;
+ stream_access16 str;
} IStream16Impl;
/******************************************************************************
@@ -989,20 +1092,82 @@
return InterlockedIncrement(&This->ref);
}
+static void
+_ilockbytes16_addref(SEGPTR lockbytes) {
+ DWORD args[1];
+ HRESULT hres;
+
+ args[0] = (DWORD)lockbytes; /* iface */
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const ILockBytes16Vtbl*)MapSL(
+ (SEGPTR)((LPLOCKBYTES16)MapSL(lockbytes))->lpVtbl)
+ )->AddRef,
+ WCB16_PASCAL,
+ 1*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ ))
+ ERR("CallTo16 ILockBytes16::AddRef() failed, hres %lx\n",hres);
+}
+
+static void
+_ilockbytes16_release(SEGPTR lockbytes) {
+ DWORD args[1];
+ HRESULT hres;
+
+ args[0] = (DWORD)lockbytes; /* iface */
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const ILockBytes16Vtbl*)MapSL(
+ (SEGPTR)((LPLOCKBYTES16)MapSL(lockbytes))->lpVtbl)
+ )->Release,
+ WCB16_PASCAL,
+ 1*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ ))
+ ERR("CallTo16 ILockBytes16::Release() failed, hres %lx\n",hres);
+}
+
+static void
+_ilockbytes16_flush(SEGPTR lockbytes) {
+ DWORD args[1];
+ HRESULT hres;
+
+ args[0] = (DWORD)lockbytes; /* iface */
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const ILockBytes16Vtbl*)MapSL(
+ (SEGPTR)((LPLOCKBYTES16)MapSL(lockbytes))->lpVtbl)
+ )->Flush,
+ WCB16_PASCAL,
+ 1*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ ))
+ ERR("CallTo16 ILockBytes16::Flush() failed, hres %lx\n",hres);
+}
+
/******************************************************************************
* IStream16_Release [STORAGE.520]
*/
ULONG IStream16_fnRelease(IStream16* iface) {
IStream16Impl *This = (IStream16Impl *)iface;
ULONG ref;
- FlushFileBuffers(This->hf);
+
+ if (This->str.hf)
+ FlushFileBuffers(This->str.hf);
+ else
+ _ilockbytes16_flush(This->str.lockbytes);
ref = InterlockedDecrement(&This->ref);
- if (!ref) {
- CloseHandle(This->hf);
- UnMapLS( This->thisptr );
- HeapFree( GetProcessHeap(), 0, This );
- }
- return ref;
+ if (ref)
+ return ref;
+
+ if (This->str.hf)
+ CloseHandle(This->str.hf);
+ else
+ _ilockbytes16_release(This->str.lockbytes);
+ UnMapLS( This->thisptr );
+ HeapFree( GetProcessHeap(), 0, This );
+ return 0;
}
/******************************************************************************
@@ -1072,11 +1237,11 @@
cb=This->stde.pps_size-This->offset.u.LowPart;
if (This->stde.pps_size < 0x1000) {
/* use small block reader */
- blocknr = STORAGE_get_nth_next_small_blocknr(This->hf,This->stde.pps_sb,This->offset.u.LowPart/SMALLSIZE);
+ blocknr = STORAGE_get_nth_next_small_blocknr(&This->str,This->stde.pps_sb,This->offset.u.LowPart/SMALLSIZE);
while (cb) {
unsigned int cc;
- if (!STORAGE_get_small_block(This->hf,blocknr,block)) {
+ if (!STORAGE_get_small_block(&This->str,blocknr,block)) {
WARN("small block read failed!!!\n");
return E_FAIL;
}
@@ -1088,15 +1253,15 @@
pbv+=cc;
*bytesread+=cc;
cb-=cc;
- blocknr = STORAGE_get_next_small_blocknr(This->hf,blocknr);
+ blocknr = STORAGE_get_next_small_blocknr(&This->str,blocknr);
}
} else {
/* use big block reader */
- blocknr = STORAGE_get_nth_next_big_blocknr(This->hf,This->stde.pps_sb,This->offset.u.LowPart/BIGSIZE);
+ blocknr = STORAGE_get_nth_next_big_blocknr(&This->str,This->stde.pps_sb,This->offset.u.LowPart/BIGSIZE);
while (cb) {
unsigned int cc;
- if (!STORAGE_get_big_block(This->hf,blocknr,block)) {
+ if (!STORAGE_get_big_block(&This->str,blocknr,block)) {
WARN("big block read failed!!!\n");
return E_FAIL;
}
@@ -1108,7 +1273,7 @@
pbv+=cc;
*bytesread+=cc;
cb-=cc;
- blocknr=STORAGE_get_next_big_blocknr(This->hf,blocknr);
+ blocknr=STORAGE_get_next_big_blocknr(&This->str,blocknr);
}
}
return S_OK;
@@ -1124,7 +1289,6 @@
BYTE block[BIGSIZE];
ULONG *byteswritten=pcbWrite,xxwritten;
int oldsize,newsize,i,curoffset=0,lastblocknr,blocknr,cc;
- HANDLE hf = This->hf;
const BYTE* pbv = (const BYTE*)pv;
if (!pcbWrite) byteswritten=&xxwritten;
@@ -1137,20 +1301,20 @@
if (newsize < oldsize) {
if (oldsize < 0x1000) {
/* only small blocks */
- blocknr=STORAGE_get_nth_next_small_blocknr(hf,This->stde.pps_sb,newsize/SMALLSIZE);
+ blocknr=STORAGE_get_nth_next_small_blocknr(&This->str,This->stde.pps_sb,newsize/SMALLSIZE);
assert(blocknr>=0);
/* will set the rest of the chain to 'free' */
- if (!STORAGE_set_small_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_small_chain(&This->str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return E_FAIL;
} else {
if (newsize >= 0x1000) {
- blocknr=STORAGE_get_nth_next_big_blocknr(hf,This->stde.pps_sb,newsize/BIGSIZE);
+ blocknr=STORAGE_get_nth_next_big_blocknr(&This->str,This->stde.pps_sb,newsize/BIGSIZE);
assert(blocknr>=0);
/* will set the rest of the chain to 'free' */
- if (!STORAGE_set_big_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(&This->str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return E_FAIL;
} else {
/* Migrate large blocks to small blocks
@@ -1163,35 +1327,35 @@
blocknr = This->stde.pps_sb;
curdata = data;
while (cc>0) {
- if (!STORAGE_get_big_block(hf,blocknr,curdata)) {
+ if (!STORAGE_get_big_block(&This->str,blocknr,curdata)) {
HeapFree(GetProcessHeap(),0,data);
return E_FAIL;
}
curdata += BIGSIZE;
cc -= BIGSIZE;
- blocknr = STORAGE_get_next_big_blocknr(hf,blocknr);
+ blocknr = STORAGE_get_next_big_blocknr(&This->str,blocknr);
}
/* frees complete chain for this stream */
- if (!STORAGE_set_big_chain(hf,This->stde.pps_sb,STORAGE_CHAINENTRY_FREE))
+ if (!STORAGE_set_big_chain(&This->str,This->stde.pps_sb,STORAGE_CHAINENTRY_FREE))
goto err;
curdata = data;
- blocknr = This->stde.pps_sb = STORAGE_get_free_small_blocknr(hf);
+ blocknr = This->stde.pps_sb = STORAGE_get_free_small_blocknr(&This->str);
if (blocknr<0)
goto err;
cc = newsize;
while (cc>0) {
- if (!STORAGE_put_small_block(hf,blocknr,curdata))
+ if (!STORAGE_put_small_block(&This->str,blocknr,curdata))
goto err;
cc -= SMALLSIZE;
if (cc<=0) {
- if (!STORAGE_set_small_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_small_chain(&This->str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
goto err;
break;
} else {
- int newblocknr = STORAGE_get_free_small_blocknr(hf);
+ int newblocknr = STORAGE_get_free_small_blocknr(&This->str);
if (newblocknr<0)
goto err;
- if (!STORAGE_set_small_chain(hf,blocknr,newblocknr))
+ if (!STORAGE_set_small_chain(&This->str,blocknr,newblocknr))
goto err;
blocknr = newblocknr;
}
@@ -1210,46 +1374,46 @@
if (newsize > oldsize) {
if (oldsize >= 0x1000) {
/* should return the block right before the 'endofchain' */
- blocknr = STORAGE_get_nth_next_big_blocknr(hf,This->stde.pps_sb,This->stde.pps_size/BIGSIZE);
+ blocknr = STORAGE_get_nth_next_big_blocknr(&This->str,This->stde.pps_sb,This->stde.pps_size/BIGSIZE);
assert(blocknr>=0);
lastblocknr = blocknr;
for (i=oldsize/BIGSIZE;i<newsize/BIGSIZE;i++) {
- blocknr = STORAGE_get_free_big_blocknr(hf);
+ blocknr = STORAGE_get_free_big_blocknr(&This->str);
if (blocknr<0)
return E_FAIL;
- if (!STORAGE_set_big_chain(hf,lastblocknr,blocknr))
+ if (!STORAGE_set_big_chain(&This->str,lastblocknr,blocknr))
return E_FAIL;
lastblocknr = blocknr;
}
- if (!STORAGE_set_big_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(&This->str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return E_FAIL;
} else {
if (newsize < 0x1000) {
/* find startblock */
if (!oldsize)
- This->stde.pps_sb = blocknr = STORAGE_get_free_small_blocknr(hf);
+ This->stde.pps_sb = blocknr = STORAGE_get_free_small_blocknr(&This->str);
else
- blocknr = STORAGE_get_nth_next_small_blocknr(hf,This->stde.pps_sb,This->stde.pps_size/SMALLSIZE);
+ blocknr = STORAGE_get_nth_next_small_blocknr(&This->str,This->stde.pps_sb,This->stde.pps_size/SMALLSIZE);
if (blocknr<0)
return E_FAIL;
/* allocate required new small blocks */
lastblocknr = blocknr;
for (i=oldsize/SMALLSIZE;i<newsize/SMALLSIZE;i++) {
- blocknr = STORAGE_get_free_small_blocknr(hf);
+ blocknr = STORAGE_get_free_small_blocknr(&This->str);
if (blocknr<0)
return E_FAIL;
- if (!STORAGE_set_small_chain(hf,lastblocknr,blocknr))
+ if (!STORAGE_set_small_chain(&This->str,lastblocknr,blocknr))
return E_FAIL;
lastblocknr = blocknr;
}
/* and terminate the chain */
- if (!STORAGE_set_small_chain(hf,lastblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_small_chain(&This->str,lastblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return E_FAIL;
} else {
if (!oldsize) {
/* no single block allocated yet */
- blocknr=STORAGE_get_free_big_blocknr(hf);
+ blocknr=STORAGE_get_free_big_blocknr(&This->str);
if (blocknr<0)
return E_FAIL;
This->stde.pps_sb = blocknr;
@@ -1263,34 +1427,34 @@
curdata = data;
/* slurp in */
while (cc>0) {
- if (!STORAGE_get_small_block(hf,blocknr,curdata))
+ if (!STORAGE_get_small_block(&This->str,blocknr,curdata))
goto err2;
curdata += SMALLSIZE;
cc -= SMALLSIZE;
- blocknr = STORAGE_get_next_small_blocknr(hf,blocknr);
+ blocknr = STORAGE_get_next_small_blocknr(&This->str,blocknr);
}
/* free small block chain */
- if (!STORAGE_set_small_chain(hf,This->stde.pps_sb,STORAGE_CHAINENTRY_FREE))
+ if (!STORAGE_set_small_chain(&This->str,This->stde.pps_sb,STORAGE_CHAINENTRY_FREE))
goto err2;
curdata = data;
- blocknr = This->stde.pps_sb = STORAGE_get_free_big_blocknr(hf);
+ blocknr = This->stde.pps_sb = STORAGE_get_free_big_blocknr(&This->str);
if (blocknr<0)
goto err2;
/* put the data into the big blocks */
cc = This->stde.pps_size;
while (cc>0) {
- if (!STORAGE_put_big_block(hf,blocknr,curdata))
+ if (!STORAGE_put_big_block(&This->str,blocknr,curdata))
goto err2;
cc -= BIGSIZE;
if (cc<=0) {
- if (!STORAGE_set_big_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(&This->str,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
goto err2;
break;
} else {
- int newblocknr = STORAGE_get_free_big_blocknr(hf);
+ int newblocknr = STORAGE_get_free_big_blocknr(&This->str);
if (newblocknr<0)
goto err2;
- if (!STORAGE_set_big_chain(hf,blocknr,newblocknr))
+ if (!STORAGE_set_big_chain(&This->str,blocknr,newblocknr))
goto err2;
blocknr = newblocknr;
}
@@ -1305,15 +1469,15 @@
/* generate big blocks to fit the new data */
lastblocknr = blocknr;
for (i=oldsize/BIGSIZE;i<newsize/BIGSIZE;i++) {
- blocknr = STORAGE_get_free_big_blocknr(hf);
+ blocknr = STORAGE_get_free_big_blocknr(&This->str);
if (blocknr<0)
return E_FAIL;
- if (!STORAGE_set_big_chain(hf,lastblocknr,blocknr))
+ if (!STORAGE_set_big_chain(&This->str,lastblocknr,blocknr))
return E_FAIL;
lastblocknr = blocknr;
}
/* terminate chain */
- if (!STORAGE_set_big_chain(hf,lastblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
+ if (!STORAGE_set_big_chain(&This->str,lastblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN))
return E_FAIL;
}
}
@@ -1323,12 +1487,12 @@
/* There are just some cases where we didn't modify it, we write it out
* everytime
*/
- if (!STORAGE_put_pps_entry(hf,This->ppsent,&(This->stde)))
+ if (!STORAGE_put_pps_entry(&This->str,This->ppsent,&(This->stde)))
return E_FAIL;
/* finally the write pass */
if (This->stde.pps_size < 0x1000) {
- blocknr = STORAGE_get_nth_next_small_blocknr(hf,This->stde.pps_sb,This->offset.u.LowPart/SMALLSIZE);
+ blocknr = STORAGE_get_nth_next_small_blocknr(&This->str,This->stde.pps_sb,This->offset.u.LowPart/SMALLSIZE);
assert(blocknr>=0);
while (cb>0) {
/* we ensured that it is allocated above */
@@ -1336,7 +1500,7 @@
/* Read old block everytime, since we can have
* overlapping data at START and END of the write
*/
- if (!STORAGE_get_small_block(hf,blocknr,block))
+ if (!STORAGE_get_small_block(&This->str,blocknr,block))
return E_FAIL;
cc = SMALLSIZE-(This->offset.u.LowPart&(SMALLSIZE-1));
@@ -1346,17 +1510,17 @@
pbv+curoffset,
cc
);
- if (!STORAGE_put_small_block(hf,blocknr,block))
+ if (!STORAGE_put_small_block(&This->str,blocknr,block))
return E_FAIL;
cb -= cc;
curoffset += cc;
pbv += cc;
This->offset.u.LowPart += cc;
*byteswritten += cc;
- blocknr = STORAGE_get_next_small_blocknr(hf,blocknr);
+ blocknr = STORAGE_get_next_small_blocknr(&This->str,blocknr);
}
} else {
- blocknr = STORAGE_get_nth_next_big_blocknr(hf,This->stde.pps_sb,This->offset.u.LowPart/BIGSIZE);
+ blocknr = STORAGE_get_nth_next_big_blocknr(&This->str,This->stde.pps_sb,This->offset.u.LowPart/BIGSIZE);
assert(blocknr>=0);
while (cb>0) {
/* we ensured that it is allocated above, so it better is */
@@ -1364,7 +1528,7 @@
/* read old block everytime, since we can have
* overlapping data at START and END of the write
*/
- if (!STORAGE_get_big_block(hf,blocknr,block))
+ if (!STORAGE_get_big_block(&This->str,blocknr,block))
return E_FAIL;
cc = BIGSIZE-(This->offset.u.LowPart&(BIGSIZE-1));
@@ -1374,14 +1538,14 @@
pbv+curoffset,
cc
);
- if (!STORAGE_put_big_block(hf,blocknr,block))
+ if (!STORAGE_put_big_block(&This->str,blocknr,block))
return E_FAIL;
cb -= cc;
curoffset += cc;
pbv += cc;
This->offset.u.LowPart += cc;
*byteswritten += cc;
- blocknr = STORAGE_get_next_big_blocknr(hf,blocknr);
+ blocknr = STORAGE_get_next_big_blocknr(&This->str,blocknr);
}
}
return S_OK;
@@ -1440,6 +1604,8 @@
lpst->lpVtbl = segstrvt16;
lpst->ref = 1;
lpst->thisptr = MapLS( lpst );
+ lpst->str.hf = NULL;
+ lpst->str.lockbytes = 0;
*str = (void*)lpst->thisptr;
}
@@ -1454,7 +1620,7 @@
/* IStream32 fields */
struct storage_pps_entry stde;
int ppsent;
- HANDLE hf;
+ HANDLE hf;
ULARGE_INTEGER offset;
} IStream32Impl;
@@ -1498,20 +1664,6 @@
return ref;
}
-/* --- IStorage16 implementation */
-
-typedef struct
-{
- /* IUnknown fields */
- const IStorage16Vtbl *lpVtbl;
- LONG ref;
- /* IStorage16 fields */
- SEGPTR thisptr; /* pointer to this struct as segmented */
- struct storage_pps_entry stde;
- int ppsent;
- HANDLE hf;
-} IStorage16Impl;
-
/******************************************************************************
* IStorage16_QueryInterface [STORAGE.500]
*/
@@ -1616,12 +1768,10 @@
int ppsent,x;
struct storage_pps_entry stde;
struct storage_header sth;
- HANDLE hf=This->hf;
BOOL ret;
int nPPSEntries;
- READ_HEADER;
-
+ READ_HEADER(&This->str);
TRACE("(%p)->(%s,0x%08lx,0x%08lx,0x%08lx,%p)\n",
This,pwcsName,grfMode,dwStgFormat,reserved2,ppstg
);
@@ -1629,9 +1779,15 @@
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istorage16(ppstg);
lpstg = MapSL((SEGPTR)*ppstg);
- lpstg->hf = This->hf;
+ if (This->str.hf) {
+ DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
+ &lpstg->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ } else {
+ lpstg->str.lockbytes = This->str.lockbytes;
+ _ilockbytes16_addref(This->str.lockbytes);
+ }
- ppsent=STORAGE_get_free_pps_entry(lpstg->hf);
+ ppsent=STORAGE_get_free_pps_entry(&lpstg->str);
if (ppsent<0)
return E_FAIL;
stde=This->stde;
@@ -1641,18 +1797,18 @@
} else {
FIXME(" use prev chain too ?\n");
x=stde.pps_dir;
- if (1!=STORAGE_get_pps_entry(lpstg->hf,x,&stde))
+ if (1!=STORAGE_get_pps_entry(&lpstg->str,x,&stde))
return E_FAIL;
while (stde.pps_next!=-1) {
x=stde.pps_next;
- if (1!=STORAGE_get_pps_entry(lpstg->hf,x,&stde))
+ if (1!=STORAGE_get_pps_entry(&lpstg->str,x,&stde))
return E_FAIL;
}
stde.pps_next = ppsent;
}
- ret = STORAGE_put_pps_entry(lpstg->hf,x,&stde);
+ ret = STORAGE_put_pps_entry(&lpstg->str,x,&stde);
assert(ret);
- nPPSEntries = STORAGE_get_pps_entry(lpstg->hf,ppsent,&(lpstg->stde));
+ nPPSEntries = STORAGE_get_pps_entry(&lpstg->str,ppsent,&(lpstg->stde));
assert(nPPSEntries == 1);
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, lpstg->stde.pps_rawname,
sizeof(lpstg->stde.pps_rawname)/sizeof(WCHAR));
@@ -1665,7 +1821,7 @@
lpstg->stde.pps_type = 1;
lpstg->ppsent = ppsent;
/* FIXME: timestamps? */
- if (!STORAGE_put_pps_entry(lpstg->hf,ppsent,&(lpstg->stde)))
+ if (!STORAGE_put_pps_entry(&lpstg->str,ppsent,&(lpstg->stde)))
return E_FAIL;
return S_OK;
}
@@ -1690,12 +1846,17 @@
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm);
lpstr = MapSL((SEGPTR)*ppstm);
- DuplicateHandle( GetCurrentProcess(), This->hf, GetCurrentProcess(),
- &lpstr->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ if (This->str.hf) {
+ DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
+ &lpstr->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ } else {
+ lpstr->str.lockbytes = This->str.lockbytes;
+ _ilockbytes16_addref(This->str.lockbytes);
+ }
lpstr->offset.u.LowPart = 0;
- lpstr->offset.u.HighPart = 0;
+ lpstr->offset.u.HighPart= 0;
- ppsent=STORAGE_get_free_pps_entry(lpstr->hf);
+ ppsent=STORAGE_get_free_pps_entry(&lpstr->str);
if (ppsent<0)
return E_FAIL;
stde=This->stde;
@@ -1704,13 +1865,13 @@
else
while (stde.pps_next!=-1) {
x=stde.pps_next;
- if (1!=STORAGE_get_pps_entry(lpstr->hf,x,&stde))
+ if (1!=STORAGE_get_pps_entry(&lpstr->str,x,&stde))
return E_FAIL;
}
stde.pps_next = ppsent;
- ret = STORAGE_put_pps_entry(lpstr->hf,x,&stde);
+ ret = STORAGE_put_pps_entry(&lpstr->str,x,&stde);
assert(ret);
- nPPSEntries = STORAGE_get_pps_entry(lpstr->hf,ppsent,&(lpstr->stde));
+ nPPSEntries = STORAGE_get_pps_entry(&lpstr->str,ppsent,&(lpstr->stde));
assert(nPPSEntries == 1);
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, lpstr->stde.pps_rawname,
sizeof(lpstr->stde.pps_rawname)/sizeof(WCHAR));
@@ -1722,8 +1883,9 @@
lpstr->stde.pps_size = 0;
lpstr->stde.pps_type = 2;
lpstr->ppsent = ppsent;
+
/* FIXME: timestamps? */
- if (!STORAGE_put_pps_entry(lpstr->hf,ppsent,&(lpstr->stde)))
+ if (!STORAGE_put_pps_entry(&lpstr->str,ppsent,&(lpstr->stde)))
return E_FAIL;
return S_OK;
}
@@ -1739,23 +1901,28 @@
WCHAR name[33];
int newpps;
- TRACE_(relay)("(%p)->(%s,%p,0x%08lx,%p,0x%08lx,%p)\n",
+ TRACE("(%p)->(%s,%p,0x%08lx,%p,0x%08lx,%p)\n",
This,pwcsName,pstgPrio,grfMode,snbExclude,reserved,ppstg
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istorage16(ppstg);
lpstg = MapSL((SEGPTR)*ppstg);
- DuplicateHandle( GetCurrentProcess(), This->hf, GetCurrentProcess(),
- &lpstg->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ if (This->str.hf) {
+ DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
+ &lpstg->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ } else {
+ lpstg->str.lockbytes = This->str.lockbytes;
+ _ilockbytes16_addref(This->str.lockbytes);
+ }
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, name, sizeof(name)/sizeof(WCHAR));
- newpps = STORAGE_look_for_named_pps(lpstg->hf,This->stde.pps_dir,name);
+ newpps = STORAGE_look_for_named_pps(&lpstg->str,This->stde.pps_dir,name);
if (newpps==-1) {
IStream16_fnRelease((IStream16*)lpstg);
return E_FAIL;
}
- if (1!=STORAGE_get_pps_entry(lpstg->hf,newpps,&(lpstg->stde))) {
+ if (1!=STORAGE_get_pps_entry(&lpstg->str,newpps,&(lpstg->stde))) {
IStream16_fnRelease((IStream16*)lpstg);
return E_FAIL;
}
@@ -1774,29 +1941,34 @@
WCHAR name[33];
int newpps;
- TRACE_(relay)("(%p)->(%s,%p,0x%08lx,0x%08lx,%p)\n",
+ TRACE("(%p)->(%s,%p,0x%08lx,0x%08lx,%p)\n",
This,pwcsName,reserved1,grfMode,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm);
lpstr = MapSL((SEGPTR)*ppstm);
- DuplicateHandle( GetCurrentProcess(), This->hf, GetCurrentProcess(),
- &lpstr->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ if (This->str.hf) {
+ DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
+ &lpstr->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ } else {
+ lpstr->str.lockbytes = This->str.lockbytes;
+ _ilockbytes16_addref(This->str.lockbytes);
+ }
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, name, sizeof(name)/sizeof(WCHAR));
- newpps = STORAGE_look_for_named_pps(lpstr->hf,This->stde.pps_dir,name);
+ newpps = STORAGE_look_for_named_pps(&lpstr->str,This->stde.pps_dir,name);
if (newpps==-1) {
IStream16_fnRelease((IStream16*)lpstr);
return E_FAIL;
}
- if (1!=STORAGE_get_pps_entry(lpstr->hf,newpps,&(lpstr->stde))) {
+ if (1!=STORAGE_get_pps_entry(&lpstr->str,newpps,&(lpstr->stde))) {
IStream16_fnRelease((IStream16*)lpstr);
return E_FAIL;
}
- lpstr->offset.u.LowPart = 0;
+ lpstr->offset.u.LowPart = 0;
lpstr->offset.u.HighPart = 0;
- lpstr->ppsent = newpps;
+ lpstr->ppsent = newpps;
return S_OK;
}
@@ -1858,6 +2030,8 @@
}
lpst = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpst) );
lpst->lpVtbl = segstvt16;
+ lpst->str.hf = NULL;
+ lpst->str.lockbytes = 0;
lpst->ref = 1;
lpst->thisptr = MapLS(lpst);
*stg = (void*)lpst->thisptr;
@@ -1888,15 +2062,16 @@
return E_FAIL;
}
lpstg = MapSL((SEGPTR)*ppstgOpen);
- lpstg->hf = hf;
+ lpstg->str.hf = hf;
+ lpstg->str.lockbytes = 0;
/* FIXME: check for existence before overwriting? */
- if (!STORAGE_init_storage(hf)) {
+ if (!STORAGE_init_storage(&lpstg->str)) {
CloseHandle(hf);
return E_FAIL;
}
i=0;ret=0;
while (!ret) { /* neither 1 nor <0 */
- ret=STORAGE_get_pps_entry(hf,i,&stde);
+ ret=STORAGE_get_pps_entry(&lpstg->str,i,&stde);
if ((ret==1) && (stde.pps_type==5)) {
lpstg->stde = stde;
lpstg->ppsent = i;
@@ -1948,11 +2123,11 @@
return E_FAIL;
}
lpstg = MapSL((SEGPTR)*ppstgOpen);
- lpstg->hf = hf;
+ lpstg->str.hf = hf;
i=0;ret=0;
while (!ret) { /* neither 1 nor <0 */
- ret=STORAGE_get_pps_entry(hf,i,&stde);
+ ret=STORAGE_get_pps_entry(&lpstg->str,i,&stde);
if ((ret==1) && (stde.pps_type==5)) {
lpstg->stde=stde;
break;
@@ -2008,24 +2183,92 @@
* StgOpenStorageOnILockBytes [STORAGE.4]
*/
HRESULT WINAPI StgOpenStorageOnILockBytes16(
- ILockBytes16 *plkbyt,
- IStorage16 *pstgPriority,
- DWORD grfMode,
- SNB16 snbExclude,
- DWORD reserved,
- IStorage16 **ppstgOpen)
+ SEGPTR /*ILockBytes16 **/plkbyt,
+ IStorage16 *pstgPriority,
+ DWORD grfMode,
+ SNB16 snbExclude,
+ DWORD reserved,
+ IStorage16 **ppstgOpen)
{
- IStorage16Impl* lpstg;
+ IStorage16Impl* lpstg;
+ int i,ret;
+ struct storage_pps_entry stde;
+
+ FIXME("(%lx, %p, 0x%08lx, %d, %lx, %p)\n", plkbyt, pstgPriority, grfMode, (int)snbExclude, reserved, ppstgOpen);
+ if ((plkbyt == 0) || (ppstgOpen == 0))
+ return STG_E_INVALIDPOINTER;
- if ((plkbyt == 0) || (ppstgOpen == 0))
- return STG_E_INVALIDPOINTER;
+ *ppstgOpen = 0;
- *ppstgOpen = 0;
+ _create_istorage16(ppstgOpen);
+ lpstg = MapSL((SEGPTR)*ppstgOpen);
+ lpstg->str.hf = NULL;
+ lpstg->str.lockbytes = plkbyt;
+ i=0;ret=0;
+ while (!ret) { /* neither 1 nor <0 */
+ ret=STORAGE_get_pps_entry(&lpstg->str,i,&stde);
+ if ((ret==1) && (stde.pps_type==5)) {
+ lpstg->stde=stde;
+ break;
+ }
+ i++;
+ }
+ if (ret!=1) {
+ IStorage16_fnRelease((IStorage16*)lpstg); /* will remove it */
+ return E_FAIL;
+ }
+ return S_OK;
+}
- _create_istorage16(ppstgOpen);
- lpstg = MapSL((SEGPTR)*ppstgOpen);
+/***********************************************************************
+ * ReadClassStg (OLE2.@)
+ *
+ * This method reads the CLSID previously written to a storage object with the WriteClassStg.
+ */
+HRESULT WINAPI ReadClassStg16(SEGPTR /*IStorage **/pstg,CLSID *pclsid){
+ STATSTG16 statstg;
+ HANDLE16 hstatstg;
+ HRESULT hres;
+ DWORD args[3];
- /* just teach it to use HANDLE instead of ilockbytes :/ */
+ TRACE("(%lx, %p)\n", pstg, pclsid);
- return S_OK;
+ if(pclsid==NULL)
+ return E_POINTER;
+ /*
+ * read a STATSTG structure (contains the clsid) from the storage
+ */
+ args[0] = (DWORD)pstg; /* iface */
+ args[1] = (DWORD)K32WOWGlobalAllocLock16( 0, sizeof(STATSTG16), &hstatstg );
+ args[2] = STATFLAG_DEFAULT;
+
+ if (!K32WOWCallback16Ex(
+ (DWORD)((const IStorage16Vtbl*)MapSL(
+ (SEGPTR)((LPSTORAGE16)MapSL(pstg))->lpVtbl)
+ )->Stat,
+ WCB16_PASCAL,
+ 3*sizeof(DWORD),
+ (LPVOID)args,
+ (LPDWORD)&hres
+ )) {
+ K32WOWGlobalUnlockFree16(args[1]);
+ ERR("CallTo16 IStorage16::Stat() failed, hres %lx\n",hres);
+ return hres;
+ }
+ memcpy(&statstg, MapSL(args[1]), sizeof(STATSTG16));
+ K32WOWGlobalUnlockFree16(args[1]);
+
+ if(SUCCEEDED(hres)) {
+ *pclsid=statstg.clsid;
+ TRACE("clsid is %s\n", debugstr_guid(&statstg.clsid));
+ }
+ return hres;
+}
+
+/***********************************************************************
+ * GetConvertStg (OLE2.@)
+ */
+HRESULT WINAPI GetConvertStg16(IStorage *stg) {
+ FIXME("unimplemented stub!\n");
+ return E_FAIL;
}
Index: dlls/ole32/storage.spec
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage.spec,v
retrieving revision 1.5
diff -u -r1.5 storage.spec
--- dlls/ole32/storage.spec 5 Jan 2003 01:04:34 -0000 1.5
+++ dlls/ole32/storage.spec 5 Aug 2005 20:38:20 -0000
@@ -6,7 +6,7 @@
2 stub StgCreateDocFileOnILockBytes
# 2 pascal StgCreateDocFileOnILockBytes(ptr long long ptr) StgCreateDocFileOnILockBytes16
3 pascal StgOpenStorage(str ptr long ptr long ptr) StgOpenStorage16
-4 pascal StgOpenStorageOnILockBytes(ptr ptr long long long ptr) StgOpenStorageOnILockBytes16
+4 pascal StgOpenStorageOnILockBytes(segptr ptr long long long ptr) StgOpenStorageOnILockBytes16
5 pascal StgIsStorageFile(str) StgIsStorageFile16
6 pascal StgIsStorageILockBytes(segptr) StgIsStorageILockBytes16
7 stub StgSetTimes
More information about the wine-patches
mailing list