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
dd4bb947
Commit
dd4bb947
authored
Nov 27, 2018
by
Nikolay Sivov
Committed by
Alexandre Julliard
Nov 27, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shcore: Add file-based stream.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b54d72ef
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
329 additions
and
6 deletions
+329
-6
Makefile.in
dlls/shcore/Makefile.in
+1
-1
main.c
dlls/shcore/main.c
+325
-2
shcore.spec
dlls/shcore/shcore.spec
+3
-3
No files found.
dlls/shcore/Makefile.in
View file @
dd4bb947
MODULE
=
shcore.dll
IMPORTS
=
user32 gdi32
IMPORTS
=
user32 gdi32
ole32
C_SRCS
=
\
main.c
dlls/shcore/main.c
View file @
dd4bb947
...
...
@@ -508,6 +508,12 @@ struct shstream
DWORD
length
;
DWORD
position
;
}
mem
;
struct
{
HANDLE
handle
;
DWORD
mode
;
WCHAR
*
path
;
}
file
;
}
u
;
};
...
...
@@ -742,7 +748,7 @@ static HRESULT WINAPI shstream_Clone(IStream *iface, IStream **dest)
return
E_NOTIMPL
;
}
static
const
IStreamVtbl
sh
streamvtbl
=
static
const
IStreamVtbl
mem
streamvtbl
=
{
shstream_QueryInterface
,
shstream_AddRef
,
...
...
@@ -786,7 +792,7 @@ IStream * WINAPI SHCreateMemStream(const BYTE *data, UINT data_len)
data_len
=
0
;
stream
=
heap_alloc
(
sizeof
(
*
stream
));
stream
->
IStream_iface
.
lpVtbl
=
&
sh
streamvtbl
;
stream
->
IStream_iface
.
lpVtbl
=
&
mem
streamvtbl
;
stream
->
refcount
=
1
;
stream
->
u
.
mem
.
buffer
=
heap_alloc
(
data_len
);
if
(
!
stream
->
u
.
mem
.
buffer
)
...
...
@@ -800,3 +806,320 @@ IStream * WINAPI SHCreateMemStream(const BYTE *data, UINT data_len)
return
&
stream
->
IStream_iface
;
}
static
ULONG
WINAPI
filestream_Release
(
IStream
*
iface
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
ULONG
refcount
=
InterlockedDecrement
(
&
stream
->
refcount
);
TRACE
(
"(%p)->(%u)
\n
"
,
stream
,
refcount
);
if
(
!
refcount
)
{
CloseHandle
(
stream
->
u
.
file
.
handle
);
heap_free
(
stream
);
}
return
refcount
;
}
static
HRESULT
WINAPI
filestream_Read
(
IStream
*
iface
,
void
*
buff
,
ULONG
size
,
ULONG
*
read_len
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
DWORD
read
=
0
;
TRACE
(
"(%p, %p, %u, %p)
\n
"
,
stream
,
buff
,
size
,
read_len
);
if
(
!
ReadFile
(
stream
->
u
.
file
.
handle
,
buff
,
size
,
&
read
,
NULL
))
{
WARN
(
"error %d reading file
\n
"
,
GetLastError
());
return
S_FALSE
;
}
if
(
read_len
)
*
read_len
=
read
;
return
read
==
size
?
S_OK
:
S_FALSE
;
}
static
HRESULT
WINAPI
filestream_Write
(
IStream
*
iface
,
const
void
*
buff
,
ULONG
size
,
ULONG
*
written
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
DWORD
written_len
=
0
;
TRACE
(
"(%p, %p, %u, %p)
\n
"
,
stream
,
buff
,
size
,
written
);
switch
(
stream
->
u
.
file
.
mode
&
0xf
)
{
case
STGM_WRITE
:
case
STGM_READWRITE
:
break
;
default:
return
STG_E_ACCESSDENIED
;
}
if
(
!
WriteFile
(
stream
->
u
.
file
.
handle
,
buff
,
size
,
&
written_len
,
NULL
))
return
HRESULT_FROM_WIN32
(
GetLastError
());
if
(
written
)
*
written
=
written_len
;
return
S_OK
;
}
static
HRESULT
WINAPI
filestream_Seek
(
IStream
*
iface
,
LARGE_INTEGER
move
,
DWORD
origin
,
ULARGE_INTEGER
*
new_pos
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
DWORD
position
;
TRACE
(
"(%p, %s, %d, %p)
\n
"
,
stream
,
wine_dbgstr_longlong
(
move
.
QuadPart
),
origin
,
new_pos
);
position
=
SetFilePointer
(
stream
->
u
.
file
.
handle
,
move
.
u
.
LowPart
,
NULL
,
origin
);
if
(
position
==
INVALID_SET_FILE_POINTER
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
if
(
new_pos
)
{
new_pos
->
u
.
HighPart
=
0
;
new_pos
->
u
.
LowPart
=
position
;
}
return
S_OK
;
}
static
HRESULT
WINAPI
filestream_SetSize
(
IStream
*
iface
,
ULARGE_INTEGER
size
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
TRACE
(
"(%p, %s)
\n
"
,
stream
,
wine_dbgstr_longlong
(
size
.
QuadPart
));
if
(
!
SetFilePointer
(
stream
->
u
.
file
.
handle
,
size
.
QuadPart
,
NULL
,
FILE_BEGIN
))
return
E_FAIL
;
if
(
!
SetEndOfFile
(
stream
->
u
.
file
.
handle
))
return
E_FAIL
;
return
S_OK
;
}
static
HRESULT
WINAPI
filestream_CopyTo
(
IStream
*
iface
,
IStream
*
dest
,
ULARGE_INTEGER
size
,
ULARGE_INTEGER
*
read_len
,
ULARGE_INTEGER
*
written
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
HRESULT
hr
=
S_OK
;
char
buff
[
1024
];
TRACE
(
"(%p, %p, %s, %p, %p)
\n
"
,
stream
,
dest
,
wine_dbgstr_longlong
(
size
.
QuadPart
),
read_len
,
written
);
if
(
read_len
)
read_len
->
QuadPart
=
0
;
if
(
written
)
written
->
QuadPart
=
0
;
if
(
!
dest
)
return
S_OK
;
while
(
size
.
QuadPart
)
{
ULONG
left
,
read_chunk
,
written_chunk
;
left
=
size
.
QuadPart
>
sizeof
(
buff
)
?
sizeof
(
buff
)
:
size
.
QuadPart
;
/* Read */
hr
=
IStream_Read
(
iface
,
buff
,
left
,
&
read_chunk
);
if
(
FAILED
(
hr
)
||
read_chunk
==
0
)
break
;
if
(
read_len
)
read_len
->
QuadPart
+=
read_chunk
;
/* Write */
hr
=
IStream_Write
(
dest
,
buff
,
read_chunk
,
&
written_chunk
);
if
(
written_chunk
)
written
->
QuadPart
+=
written_chunk
;
if
(
FAILED
(
hr
)
||
written_chunk
!=
left
)
break
;
size
.
QuadPart
-=
left
;
}
return
hr
;
}
static
HRESULT
WINAPI
filestream_Stat
(
IStream
*
iface
,
STATSTG
*
statstg
,
DWORD
flags
)
{
struct
shstream
*
stream
=
impl_from_IStream
(
iface
);
BY_HANDLE_FILE_INFORMATION
fi
;
TRACE
(
"(%p, %p, %#x)
\n
"
,
stream
,
statstg
,
flags
);
if
(
!
statstg
)
return
STG_E_INVALIDPOINTER
;
memset
(
&
fi
,
0
,
sizeof
(
fi
));
GetFileInformationByHandle
(
stream
->
u
.
file
.
handle
,
&
fi
);
if
(
flags
&
STATFLAG_NONAME
)
statstg
->
pwcsName
=
NULL
;
else
{
int
len
=
strlenW
(
stream
->
u
.
file
.
path
);
if
((
statstg
->
pwcsName
=
CoTaskMemAlloc
((
len
+
1
)
*
sizeof
(
WCHAR
))))
memcpy
(
statstg
->
pwcsName
,
stream
->
u
.
file
.
path
,
(
len
+
1
)
*
sizeof
(
WCHAR
));
}
statstg
->
type
=
0
;
statstg
->
cbSize
.
u
.
LowPart
=
fi
.
nFileSizeLow
;
statstg
->
cbSize
.
u
.
HighPart
=
fi
.
nFileSizeHigh
;
statstg
->
mtime
=
fi
.
ftLastWriteTime
;
statstg
->
ctime
=
fi
.
ftCreationTime
;
statstg
->
atime
=
fi
.
ftLastAccessTime
;
statstg
->
grfMode
=
stream
->
u
.
file
.
mode
;
statstg
->
grfLocksSupported
=
0
;
memcpy
(
&
statstg
->
clsid
,
&
IID_IStream
,
sizeof
(
CLSID
));
statstg
->
grfStateBits
=
0
;
statstg
->
reserved
=
0
;
return
S_OK
;
}
static
const
IStreamVtbl
filestreamvtbl
=
{
shstream_QueryInterface
,
shstream_AddRef
,
filestream_Release
,
filestream_Read
,
filestream_Write
,
filestream_Seek
,
filestream_SetSize
,
filestream_CopyTo
,
shstream_Commit
,
shstream_Revert
,
shstream_LockRegion
,
shstream_UnlockRegion
,
filestream_Stat
,
shstream_Clone
,
};
/*************************************************************************
* SHCreateStreamOnFileEx [SHCORE.@]
*/
HRESULT
WINAPI
SHCreateStreamOnFileEx
(
const
WCHAR
*
path
,
DWORD
mode
,
DWORD
attributes
,
BOOL
create
,
IStream
*
template
,
IStream
**
ret
)
{
DWORD
access
,
share
,
creation_disposition
,
len
;
struct
shstream
*
stream
;
HANDLE
hFile
;
TRACE
(
"(%s, %d, 0x%08X, %d, %p, %p)
\n
"
,
debugstr_w
(
path
),
mode
,
attributes
,
create
,
template
,
ret
);
if
(
!
path
||
!
ret
||
template
)
return
E_INVALIDARG
;
*
ret
=
NULL
;
/* Access */
switch
(
mode
&
0xf
)
{
case
STGM_WRITE
:
case
STGM_READWRITE
:
access
=
GENERIC_READ
|
GENERIC_WRITE
;
break
;
case
STGM_READ
:
access
=
GENERIC_READ
;
break
;
default:
return
E_INVALIDARG
;
}
/* Sharing */
switch
(
mode
&
0xf0
)
{
case
0
:
case
STGM_SHARE_DENY_NONE
:
share
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
;
break
;
case
STGM_SHARE_DENY_READ
:
share
=
FILE_SHARE_WRITE
;
break
;
case
STGM_SHARE_DENY_WRITE
:
share
=
FILE_SHARE_READ
;
break
;
case
STGM_SHARE_EXCLUSIVE
:
share
=
0
;
break
;
default:
return
E_INVALIDARG
;
}
switch
(
mode
&
0xf000
)
{
case
STGM_FAILIFTHERE
:
creation_disposition
=
create
?
CREATE_NEW
:
OPEN_EXISTING
;
break
;
case
STGM_CREATE
:
creation_disposition
=
CREATE_ALWAYS
;
break
;
default:
return
E_INVALIDARG
;
}
hFile
=
CreateFileW
(
path
,
access
,
share
,
NULL
,
creation_disposition
,
attributes
,
0
);
if
(
hFile
==
INVALID_HANDLE_VALUE
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
stream
=
heap_alloc
(
sizeof
(
*
stream
));
stream
->
IStream_iface
.
lpVtbl
=
&
filestreamvtbl
;
stream
->
refcount
=
1
;
stream
->
u
.
file
.
handle
=
hFile
;
stream
->
u
.
file
.
mode
=
mode
;
len
=
strlenW
(
path
);
stream
->
u
.
file
.
path
=
heap_alloc
((
len
+
1
)
*
sizeof
(
WCHAR
));
memcpy
(
stream
->
u
.
file
.
path
,
path
,
(
len
+
1
)
*
sizeof
(
WCHAR
));
*
ret
=
&
stream
->
IStream_iface
;
return
S_OK
;
}
/*************************************************************************
* SHCreateStreamOnFileW [SHCORE.@]
*/
HRESULT
WINAPI
SHCreateStreamOnFileW
(
const
WCHAR
*
path
,
DWORD
mode
,
IStream
**
stream
)
{
TRACE
(
"(%s, %#x, %p)
\n
"
,
debugstr_w
(
path
),
mode
,
stream
);
if
(
!
path
||
!
stream
)
return
E_INVALIDARG
;
if
((
mode
&
(
STGM_CONVERT
|
STGM_DELETEONRELEASE
|
STGM_TRANSACTED
))
!=
0
)
return
E_INVALIDARG
;
return
SHCreateStreamOnFileEx
(
path
,
mode
,
0
,
FALSE
,
NULL
,
stream
);
}
/*************************************************************************
* SHCreateStreamOnFileA [SHCORE.@]
*/
HRESULT
WINAPI
SHCreateStreamOnFileA
(
const
char
*
path
,
DWORD
mode
,
IStream
**
stream
)
{
WCHAR
*
pathW
;
HRESULT
hr
;
DWORD
len
;
TRACE
(
"(%s, %#x, %p)
\n
"
,
debugstr_a
(
path
),
mode
,
stream
);
if
(
!
path
)
return
HRESULT_FROM_WIN32
(
ERROR_PATH_NOT_FOUND
);
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
path
,
-
1
,
NULL
,
0
);
pathW
=
heap_alloc
(
len
*
sizeof
(
WCHAR
));
if
(
!
pathW
)
return
E_OUTOFMEMORY
;
MultiByteToWideChar
(
CP_ACP
,
0
,
path
,
-
1
,
pathW
,
len
);
hr
=
SHCreateStreamOnFileW
(
pathW
,
mode
,
stream
);
heap_free
(
pathW
);
return
hr
;
}
dlls/shcore/shcore.spec
View file @
dd4bb947
...
...
@@ -34,9 +34,9 @@
@ stdcall SHCopyKeyA(long str long long) shlwapi.SHCopyKeyA
@ stdcall SHCopyKeyW(long wstr long long) shlwapi.SHCopyKeyW
@ stdcall SHCreateMemStream(ptr long)
@ stdcall SHCreateStreamOnFileA(str long ptr)
shlwapi.SHCreateStreamOnFileA
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr)
shlwapi.SHCreateStreamOnFileEx
@ stdcall SHCreateStreamOnFileW(wstr long ptr)
shlwapi.SHCreateStreamOnFileW
@ stdcall SHCreateStreamOnFileA(str long ptr)
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr)
@ stdcall SHCreateStreamOnFileW(wstr long ptr)
@ stdcall SHCreateThread(ptr ptr long ptr) shlwapi.SHCreateThread
@ stdcall SHCreateThreadRef(ptr ptr) shlwapi.SHCreateThreadRef
@ stub SHCreateThreadWithHandle
...
...
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