Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
170470ee
Commit
170470ee
authored
Aug 08, 2005
by
Marcus Meissner
Committed by
Alexandre Julliard
Aug 08, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented ILockBytes16 (memorystream) support for the 16bit compound
storage implementation. Added ReadClassStg, OleDoAutoConvert, GetConvertStg implementations/stubs.
parent
843314ed
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
490 additions
and
238 deletions
+490
-238
ole2.c
dlls/ole32/ole2.c
+9
-0
ole2.spec
dlls/ole32/ole2.spec
+3
-3
storage.c
dlls/ole32/storage.c
+477
-234
storage.spec
dlls/ole32/storage.spec
+1
-1
No files found.
dlls/ole32/ole2.c
View file @
170470ee
...
...
@@ -2328,6 +2328,15 @@ HRESULT WINAPI OleDoAutoConvert(IStorage *pStg, LPCLSID pClsidNew)
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]
*
...
...
dlls/ole32/ole2.spec
View file @
170470ee
...
...
@@ -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
...
...
dlls/ole32/storage.c
View file @
170470ee
...
...
@@ -89,7 +89,7 @@ static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
#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 @@ static void _create_istream16(LPSTREAM16 *str);
* 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 @@ static void _create_istream16(LPSTREAM16 *str);
* 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_get_big_block(HANDLE hf,int n,BYTE *block)
* 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_next_big_blocknr(HANDLE hf,int blocknr) {
* 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 @@ STORAGE_get_nth_next_big_blocknr(HANDLE hf,int blocknr,int nr) {
/* 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_nth_next_big_blocknr(HANDLE hf,int blocknr,int nr) {
* 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 @@ STORAGE_get_root_pps_entry(HANDLE hf,struct storage_pps_entry *pstde) {
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_root_pps_entry(HANDLE hf,struct storage_pps_entry *pstde) {
* 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_get_small_block(HANDLE hf,int blocknr,BYTE *sblock) {
* 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_put_small_block(HANDLE hf,int blocknr,BYTE *sblock) {
* 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_next_small_blocknr(HANDLE hf,int blocknr) {
* 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_nth_next_small_blocknr(HANDLE hf,int blocknr,int nr) {
* 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_get_pps_entry(HANDLE hf,int n,struct storage_pps_entry *pstde) {
* 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_put_pps_entry(HANDLE hf,int n,struct storage_pps_entry *pstde) {
* 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_dump_pps_entry(struct storage_pps_entry *stde) {
* 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 @@ STORAGE_init_storage(HANDLE hf) {
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 @@ STORAGE_init_storage(HANDLE hf) {
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_big_chain(HANDLE hf,int blocknr,INT type) {
* 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_set_small_chain(HANDLE hf,int blocknr,INT type) {
* 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 @@ STORAGE_get_free_big_blocknr(HANDLE hf) {
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 @@ STORAGE_get_free_big_blocknr(HANDLE hf) {
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_big_blocknr(HANDLE hf) {
* 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 @@ STORAGE_get_free_small_blocknr(HANDLE hf) {
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_small_blocknr(HANDLE hf) {
* 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 @@ typedef struct
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 @@ ULONG IStream16_fnAddRef(IStream16* iface) {
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 @@ HRESULT IStream16_fnRead(
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 @@ HRESULT IStream16_fnRead(
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 @@ HRESULT IStream16_fnRead(
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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
/* 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 @@ HRESULT IStream16_fnWrite(
/* 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 @@ HRESULT IStream16_fnWrite(
/* 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 @@ HRESULT IStream16_fnWrite(
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 @@ HRESULT IStream16_fnWrite(
/* 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 @@ HRESULT IStream16_fnWrite(
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 @@ static void _create_istream16(LPSTREAM16 *str) {
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 @@ typedef struct
/* IStream32 fields */
struct
storage_pps_entry
stde
;
int
ppsent
;
HANDLE
hf
;
HANDLE
hf
;
ULARGE_INTEGER
offset
;
}
IStream32Impl
;
...
...
@@ -1498,20 +1664,6 @@ ULONG WINAPI IStream_fnRelease(IStream* iface) {
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 @@ HRESULT IStorage16_fnCreateStorage(
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 @@ HRESULT IStorage16_fnCreateStorage(
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 @@ HRESULT IStorage16_fnCreateStorage(
}
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 @@ HRESULT IStorage16_fnCreateStorage(
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 @@ HRESULT IStorage16_fnCreateStream(
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 @@ HRESULT IStorage16_fnCreateStream(
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 @@ HRESULT IStorage16_fnCreateStream(
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 @@ HRESULT IStorage16_fnOpenStorage(
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 @@ HRESULT IStorage16_fnOpenStream(
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 @@ static void _create_istorage16(LPSTORAGE16 *stg) {
}
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 @@ HRESULT WINAPI StgCreateDocFile16(
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 @@ HRESULT WINAPI StgOpenStorage16(
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 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
* 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
;
if
((
plkbyt
==
0
)
||
(
ppstgOpen
==
0
))
return
STG_E_INVALIDPOINTER
;
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
;
*
ppstgOpen
=
0
;
*
ppstgOpen
=
0
;
_create_istorage16
(
ppstgOpen
);
lpstg
=
MapSL
((
SEGPTR
)
*
ppstgOpen
);
_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
;
}
/***********************************************************************
* 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
];
TRACE
(
"(%lx, %p)
\n
"
,
pstg
,
pclsid
);
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
]);
/* just teach it to use HANDLE instead of ilockbytes :/ */
if
(
SUCCEEDED
(
hres
))
{
*
pclsid
=
statstg
.
clsid
;
TRACE
(
"clsid is %s
\n
"
,
debugstr_guid
(
&
statstg
.
clsid
));
}
return
hres
;
}
return
S_OK
;
/***********************************************************************
* GetConvertStg (OLE2.@)
*/
HRESULT
WINAPI
GetConvertStg16
(
IStorage
*
stg
)
{
FIXME
(
"unimplemented stub!
\n
"
);
return
E_FAIL
;
}
dlls/ole32/storage.spec
View file @
170470ee
...
...
@@ -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(
seg
ptr ptr long long long ptr) StgOpenStorageOnILockBytes16
5 pascal StgIsStorageFile(str) StgIsStorageFile16
6 pascal StgIsStorageILockBytes(segptr) StgIsStorageILockBytes16
7 stub StgSetTimes
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment