Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
9797a38b
Commit
9797a38b
authored
Jul 16, 2002
by
Jon Griffiths
Committed by
Alexandre Julliard
Jul 16, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement SHCreateStreamOnFileA/W/Ex, ordinals @166,184,212-214.
parent
1e54c1f0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
848 additions
and
10 deletions
+848
-10
Makefile.in
dlls/shlwapi/Makefile.in
+1
-0
istream.c
dlls/shlwapi/istream.c
+666
-0
shlwapi.spec
dlls/shlwapi/shlwapi.spec
+8
-7
clist.c
dlls/shlwapi/tests/clist.c
+173
-3
No files found.
dlls/shlwapi/Makefile.in
View file @
9797a38b
...
...
@@ -13,6 +13,7 @@ SYMBOLFILE = $(MODULE).tmp.o
C_SRCS
=
\
clist.c
\
istream.c
\
ordinal.c
\
path.c
\
reg.c
\
...
...
dlls/shlwapi/istream.c
0 → 100644
View file @
9797a38b
/*
* SHLWAPI IStream functions
*
* Copyright 2002 Jon Griffiths
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "wine/obj_base.h"
#include "wine/obj_storage.h"
#define NO_SHLWAPI_REG
#define NO_SHLWAPI_PATH
#include "shlwapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
shell
);
/* Layout of ISHFileStream object */
typedef
struct
{
ICOM_VFIELD
(
IStream
);
ULONG
ref
;
HANDLE
hFile
;
DWORD
dwMode
;
LPOLESTR
lpszPath
;
DWORD
type
;
DWORD
grfStateBits
;
}
ISHFileStream
;
static
HRESULT
WINAPI
IStream_fnCommit
(
IStream
*
,
DWORD
);
/**************************************************************************
* IStream_fnQueryInterface
*/
static
HRESULT
WINAPI
IStream_fnQueryInterface
(
IStream
*
iface
,
REFIID
riid
,
LPVOID
*
ppvObj
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p,%s,%p)
\n
"
,
This
,
debugstr_guid
(
riid
),
ppvObj
);
*
ppvObj
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IStream
))
{
*
ppvObj
=
This
;
IStream_AddRef
((
IStream
*
)
*
ppvObj
);
return
S_OK
;
}
return
E_NOINTERFACE
;
}
/**************************************************************************
* IStream_fnAddRef
*/
static
ULONG
WINAPI
IStream_fnAddRef
(
IStream
*
iface
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
return
InterlockedIncrement
(
&
This
->
ref
);
}
/**************************************************************************
* IStream_fnRelease
*/
static
ULONG
WINAPI
IStream_fnRelease
(
IStream
*
iface
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
ULONG
ulRet
;
TRACE
(
"(%p)
\n
"
,
This
);
if
(
!
(
ulRet
=
InterlockedDecrement
(
&
This
->
ref
)))
{
IStream_fnCommit
(
iface
,
0
);
/* If ever buffered, this will be needed */
LocalFree
((
HLOCAL
)
This
->
lpszPath
);
CloseHandle
(
This
->
hFile
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
return
ulRet
;
}
/**************************************************************************
* IStream_fnRead
*/
static
HRESULT
WINAPI
IStream_fnRead
(
IStream
*
iface
,
void
*
pv
,
ULONG
cb
,
ULONG
*
pcbRead
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
HRESULT
hRet
=
S_OK
;
DWORD
dwRead
=
0
;
TRACE
(
"(%p,%p,0x%08lx,%p)
\n
"
,
This
,
pv
,
cb
,
pcbRead
);
if
(
!
pv
)
hRet
=
STG_E_INVALIDPOINTER
;
else
if
(
!
ReadFile
(
This
->
hFile
,
pv
,
cb
,
&
dwRead
,
NULL
))
{
hRet
=
(
HRESULT
)
GetLastError
();
if
(
hRet
>
0
)
hRet
=
HRESULT_FROM_WIN32
(
hRet
);
}
if
(
pcbRead
)
*
pcbRead
=
dwRead
;
return
hRet
;
}
/**************************************************************************
* IStream_fnWrite
*/
static
HRESULT
WINAPI
IStream_fnWrite
(
IStream
*
iface
,
const
void
*
pv
,
ULONG
cb
,
ULONG
*
pcbWritten
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
HRESULT
hRet
=
S_OK
;
DWORD
dwWritten
=
0
;
TRACE
(
"(%p,%p,0x%08lx,%p)
\n
"
,
This
,
pv
,
cb
,
pcbWritten
);
if
(
!
pv
)
hRet
=
STG_E_INVALIDPOINTER
;
else
if
(
!
(
This
->
dwMode
&
STGM_WRITE
))
hRet
=
E_FAIL
;
else
if
(
!
WriteFile
(
This
->
hFile
,
pv
,
cb
,
&
dwWritten
,
NULL
))
{
hRet
=
(
HRESULT
)
GetLastError
();
if
(
hRet
>
0
)
hRet
=
HRESULT_FROM_WIN32
(
hRet
);
}
if
(
pcbWritten
)
*
pcbWritten
=
dwWritten
;
return
hRet
;
}
/**************************************************************************
* IStream_fnSeek
*/
static
HRESULT
WINAPI
IStream_fnSeek
(
IStream
*
iface
,
LARGE_INTEGER
dlibMove
,
DWORD
dwOrigin
,
ULARGE_INTEGER
*
pNewPos
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
DWORD
dwPos
;
TRACE
(
"(%p,%ld,%ld,%p)
\n
"
,
This
,
dlibMove
.
s
.
LowPart
,
dwOrigin
,
pNewPos
);
IStream_fnCommit
(
iface
,
0
);
/* If ever buffered, this will be needed */
dwPos
=
SetFilePointer
(
This
->
hFile
,
dlibMove
.
s
.
LowPart
,
NULL
,
dwOrigin
);
if
(
pNewPos
)
{
pNewPos
->
s
.
HighPart
=
0
;
pNewPos
->
s
.
LowPart
=
dwPos
;
}
return
S_OK
;
}
/**************************************************************************
* IStream_fnSetSize
*/
static
HRESULT
WINAPI
IStream_fnSetSize
(
IStream
*
iface
,
ULARGE_INTEGER
libNewSize
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p,%ld)
\n
"
,
This
,
libNewSize
.
s
.
LowPart
);
IStream_fnCommit
(
iface
,
0
);
/* If ever buffered, this will be needed */
return
E_NOTIMPL
;
}
/**************************************************************************
* IStream_fnCopyTo
*/
static
HRESULT
WINAPI
IStream_fnCopyTo
(
IStream
*
iface
,
IStream
*
pstm
,
ULARGE_INTEGER
cb
,
ULARGE_INTEGER
*
pcbRead
,
ULARGE_INTEGER
*
pcbWritten
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
char
copyBuff
[
1024
];
ULONGLONG
ulSize
;
HRESULT
hRet
=
S_OK
;
TRACE
(
"(%p,%p,%ld,%p,%p)
\n
"
,
This
,
pstm
,
cb
.
s
.
LowPart
,
pcbRead
,
pcbWritten
);
if
(
pcbRead
)
pcbRead
->
QuadPart
=
0
;
if
(
pcbWritten
)
pcbWritten
->
QuadPart
=
0
;
if
(
!
pstm
)
return
STG_E_INVALIDPOINTER
;
IStream_fnCommit
(
iface
,
0
);
/* If ever buffered, this will be needed */
/* Copy data */
ulSize
=
cb
.
QuadPart
;
while
(
ulSize
)
{
ULONG
ulLeft
,
ulAmt
;
ulLeft
=
ulSize
>
sizeof
(
copyBuff
)
?
sizeof
(
copyBuff
)
:
ulSize
;
/* Read */
hRet
=
IStream_fnRead
(
iface
,
copyBuff
,
ulLeft
,
&
ulAmt
);
if
(
pcbRead
)
pcbRead
->
QuadPart
+=
ulAmt
;
if
(
FAILED
(
hRet
)
||
ulAmt
!=
ulLeft
)
break
;
/* Write */
hRet
=
IStream_fnWrite
(
pstm
,
copyBuff
,
ulLeft
,
&
ulAmt
);
if
(
pcbWritten
)
pcbWritten
->
QuadPart
+=
ulAmt
;
if
(
FAILED
(
hRet
)
||
ulAmt
!=
ulLeft
)
break
;
ulSize
-=
ulLeft
;
}
return
hRet
;
}
/**************************************************************************
* IStream_fnCommit
*/
static
HRESULT
WINAPI
IStream_fnCommit
(
IStream
*
iface
,
DWORD
grfCommitFlags
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p,%ld)
\n
"
,
This
,
grfCommitFlags
);
/* Currently unbuffered: This function is not needed */
return
S_OK
;
}
/**************************************************************************
* IStream_fnRevert
*/
static
HRESULT
WINAPI
IStream_fnRevert
(
IStream
*
iface
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
return
E_NOTIMPL
;
}
/**************************************************************************
* IStream_fnLockUnlockRegion
*/
static
HRESULT
WINAPI
IStream_fnLockUnlockRegion
(
IStream
*
iface
,
ULARGE_INTEGER
libOffset
,
ULARGE_INTEGER
cb
,
DWORD
dwLockType
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p,%ld,%ld,%ld)
\n
"
,
This
,
libOffset
.
s
.
LowPart
,
cb
.
s
.
LowPart
,
dwLockType
);
return
E_NOTIMPL
;
}
/*************************************************************************
* IStream_fnStat
*/
static
HRESULT
WINAPI
IStream_fnStat
(
IStream
*
iface
,
STATSTG
*
lpStat
,
DWORD
grfStatFlag
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
BY_HANDLE_FILE_INFORMATION
fi
;
HRESULT
hRet
=
S_OK
;
TRACE
(
"(%p,%p,%ld)
\n
"
,
This
,
lpStat
,
grfStatFlag
);
if
(
!
grfStatFlag
)
hRet
=
STG_E_INVALIDPOINTER
;
else
{
memset
(
&
fi
,
0
,
sizeof
(
fi
));
GetFileInformationByHandle
(
This
->
hFile
,
&
fi
);
if
(
grfStatFlag
&
STATFLAG_NONAME
)
lpStat
->
pwcsName
=
NULL
;
else
lpStat
->
pwcsName
=
StrDupW
(
This
->
lpszPath
);
lpStat
->
type
=
This
->
type
;
lpStat
->
cbSize
.
s
.
LowPart
=
fi
.
nFileSizeLow
;
lpStat
->
cbSize
.
s
.
HighPart
=
fi
.
nFileSizeHigh
;
lpStat
->
mtime
=
fi
.
ftLastWriteTime
;
lpStat
->
ctime
=
fi
.
ftCreationTime
;
lpStat
->
atime
=
fi
.
ftLastAccessTime
;
lpStat
->
grfMode
=
This
->
dwMode
;
lpStat
->
grfLocksSupported
=
0
;
memcpy
(
&
lpStat
->
clsid
,
&
IID_IStream
,
sizeof
(
CLSID
));
lpStat
->
grfStateBits
=
This
->
grfStateBits
;
lpStat
->
reserved
=
0
;
}
return
hRet
;
}
/*************************************************************************
* IStream_fnClone
*/
static
HRESULT
WINAPI
IStream_fnClone
(
IStream
*
iface
,
IStream
**
ppstm
)
{
ICOM_THIS
(
ISHFileStream
,
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
if
(
ppstm
)
*
ppstm
=
NULL
;
return
E_NOTIMPL
;
}
static
struct
ICOM_VTABLE
(
IStream
)
SHLWAPI_fsVTable
=
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IStream_fnQueryInterface
,
IStream_fnAddRef
,
IStream_fnRelease
,
IStream_fnRead
,
IStream_fnWrite
,
IStream_fnSeek
,
IStream_fnSetSize
,
IStream_fnCopyTo
,
IStream_fnCommit
,
IStream_fnRevert
,
IStream_fnLockUnlockRegion
,
IStream_fnLockUnlockRegion
,
IStream_fnStat
,
IStream_fnClone
};
/**************************************************************************
* IStream_Create
*
* Internal helper: Create and initialise a new file stream object.
*/
static
IStream
*
IStream_Create
(
LPCWSTR
lpszPath
,
HANDLE
hFile
,
DWORD
dwMode
)
{
ISHFileStream
*
fileStream
;
fileStream
=
(
ISHFileStream
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
ISHFileStream
));
if
(
fileStream
)
{
ICOM_VTBL
(
fileStream
)
=
&
SHLWAPI_fsVTable
;
fileStream
->
ref
=
1
;
fileStream
->
hFile
=
hFile
;
fileStream
->
dwMode
=
dwMode
;
fileStream
->
lpszPath
=
StrDupW
(
lpszPath
);
fileStream
->
type
=
0
;
/* FIXME */
fileStream
->
grfStateBits
=
0
;
/* FIXME */
}
TRACE
(
"Returning %p
\n
"
,
fileStream
);
return
(
IStream
*
)
fileStream
;
}
/*************************************************************************
* SHCreateStreamOnFileEx [SHLWAPI.@]
*
* Create a stream on a file.
*
* PARAMS
* lpszPath [I] Path of file to create stream on
* dwMode [I] Mode to create stream in
* dwAttributes [I] Attributes of the file
* bCreate [I] Whether to create the file if it doesn't exist
* lpTemplate [I] Reserved, must be NULL
* lppStream [O] Destination for created stream
*
* RETURNS
* Success: S_OK. lppStream contains the new stream object
* Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
*
* NOTES
* This function is available in Unicode only.
*/
HRESULT
WINAPI
SHCreateStreamOnFileEx
(
LPCWSTR
lpszPath
,
DWORD
dwMode
,
DWORD
dwAttributes
,
BOOL
bCreate
,
IStream
*
lpTemplate
,
IStream
**
lppStream
)
{
DWORD
dwAccess
,
dwShare
,
dwCreate
;
HANDLE
hFile
;
TRACE
(
"(%s,%ld,0x%08lX,%d,%p,%p)
\n
"
,
debugstr_w
(
lpszPath
),
dwMode
,
dwAttributes
,
bCreate
,
lpTemplate
,
lppStream
);
if
(
!
lpszPath
||
!
lppStream
||
lpTemplate
)
return
E_INVALIDARG
;
*
lppStream
=
NULL
;
if
(
dwMode
&
~
(
STGM_WRITE
|
STGM_READWRITE
|
STGM_SHARE_DENY_NONE
|
STGM_SHARE_DENY_READ
|
STGM_CREATE
))
{
WARN
(
"Invalid mode 0x%08lX
\n
"
,
dwMode
);
return
E_INVALIDARG
;
}
/* Access */
switch
(
dwMode
&
(
STGM_WRITE
|
STGM_READWRITE
))
{
case
STGM_READWRITE
|
STGM_WRITE
:
case
STGM_READWRITE
:
dwAccess
=
GENERIC_READ
|
GENERIC_WRITE
;
break
;
case
STGM_WRITE
:
dwAccess
=
GENERIC_WRITE
;
break
;
default:
dwAccess
=
GENERIC_READ
;
break
;
}
/* Sharing */
switch
(
dwMode
&
STGM_SHARE_DENY_READ
)
{
case
STGM_SHARE_DENY_READ
:
dwShare
=
FILE_SHARE_WRITE
;
break
;
case
STGM_SHARE_DENY_WRITE
:
dwShare
=
FILE_SHARE_READ
;
break
;
case
STGM_SHARE_EXCLUSIVE
:
dwShare
=
0
;
break
;
default:
dwShare
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
;
}
/* FIXME: Creation Flags, MSDN is fuzzy on the mapping... */
if
(
dwMode
==
STGM_FAILIFTHERE
)
dwCreate
=
bCreate
?
CREATE_NEW
:
OPEN_EXISTING
;
else
if
(
dwMode
&
STGM_CREATE
)
dwCreate
=
CREATE_ALWAYS
;
else
dwCreate
=
OPEN_ALWAYS
;
/* Open HANDLE to file */
hFile
=
CreateFileW
(
lpszPath
,
dwAccess
,
dwShare
,
NULL
,
dwCreate
,
dwAttributes
,
(
HANDLE
)
0
);
if
(
hFile
==
INVALID_HANDLE_VALUE
)
{
HRESULT
hRet
=
(
HRESULT
)
GetLastError
();
if
(
hRet
>
0
)
hRet
=
HRESULT_FROM_WIN32
(
hRet
);
return
hRet
;
}
*
lppStream
=
IStream_Create
(
lpszPath
,
hFile
,
dwMode
);
if
(
!*
lppStream
)
{
CloseHandle
(
hFile
);
return
E_OUTOFMEMORY
;
}
return
S_OK
;
}
/*************************************************************************
* SHCreateStreamOnFileW [SHLWAPI.@]
*
* See SHCreateStreamOnFileA.
*/
HRESULT
WINAPI
SHCreateStreamOnFileW
(
LPCWSTR
lpszPath
,
DWORD
dwMode
,
IStream
**
lppStream
)
{
DWORD
dwAttr
;
TRACE
(
"(%s,%ld,%p)
\n
"
,
debugstr_w
(
lpszPath
),
dwMode
,
lppStream
);
if
(
!
lpszPath
||
!
lppStream
)
return
E_INVALIDARG
;
dwAttr
=
GetFileAttributesW
(
lpszPath
);
if
(
dwAttr
==
-
1u
)
dwAttr
=
0
;
return
SHCreateStreamOnFileEx
(
lpszPath
,
dwMode
|
STGM_WRITE
,
dwAttr
,
TRUE
,
NULL
,
lppStream
);
}
/*************************************************************************
* SHCreateStreamOnFileA [SHLWAPI.@]
*
* Create a stream on a file.
*
* PARAMS
* lpszPath [I] Path of file to create stream on
* dwMode [I] Mode to create stream in
* lppStream [O] Destination for created stream
*
* RETURNS
* Success: S_OK. lppStream contains the new stream object
* Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
*/
HRESULT
WINAPI
SHCreateStreamOnFileA
(
LPCSTR
lpszPath
,
DWORD
dwMode
,
IStream
**
lppStream
)
{
WCHAR
szPath
[
MAX_PATH
];
TRACE
(
"(%s,%ld,%p)
\n
"
,
debugstr_a
(
lpszPath
),
dwMode
,
lppStream
);
if
(
!
lpszPath
)
return
E_INVALIDARG
;
MultiByteToWideChar
(
0
,
0
,
lpszPath
,
-
1
,
szPath
,
MAX_PATH
);
return
SHCreateStreamOnFileW
(
szPath
,
dwMode
,
lppStream
);
}
/*************************************************************************
* @ [SHLWAPI.184]
*
* Call IStream::Read on a Stream.
*
* PARAMS
* lpStream [I] IStream object
* lpvDest [O] Destination for data read
* ulSize [I] Size of data to read
*
* RETURNS
* Success: S_OK. ulSize bytes have been read from the stream into lpvDest.
* Failure: An HRESULT error code, or E_FAIL if the read succeeded but the
* number of bytes read does not match.
*/
HRESULT
WINAPI
SHLWAPI_184
(
IStream
*
lpStream
,
LPVOID
lpvDest
,
ULONG
ulSize
)
{
ULONG
ulRead
;
HRESULT
hRet
;
TRACE
(
"(%p,%p,%ld)
\n
"
,
lpStream
,
lpvDest
,
ulSize
);
hRet
=
IStream_Read
(
lpStream
,
lpvDest
,
ulSize
,
&
ulRead
);
if
(
SUCCEEDED
(
hRet
)
&&
ulRead
!=
ulSize
)
hRet
=
E_FAIL
;
return
hRet
;
}
/*************************************************************************
* @ [SHLWAPI.166]
*
* Determine if a stream has 0 length.
*
* PARAMS
* lpStream [I] IStream object
*
* RETURNS
* TRUE: If the stream has 0 length
* FALSE: Otherwise.
*/
BOOL
WINAPI
SHLWAPI_166
(
IStream
*
lpStream
)
{
STATSTG
statstg
;
BOOL
bRet
=
TRUE
;
TRACE
(
"(%p)
\n
"
,
lpStream
);
memset
(
&
statstg
,
0
,
sizeof
(
statstg
));
if
(
SUCCEEDED
(
IStream_Stat
(
lpStream
,
&
statstg
,
1
)))
{
if
(
statstg
.
cbSize
.
QuadPart
)
bRet
=
FALSE
;
/* Non-Zero */
}
else
{
DWORD
dwDummy
;
/* Try to read from the stream */
if
(
SUCCEEDED
(
SHLWAPI_184
(
lpStream
,
&
dwDummy
,
sizeof
(
dwDummy
))))
{
LARGE_INTEGER
zero
;
zero
.
QuadPart
=
0
;
IStream_Seek
(
lpStream
,
zero
,
0
,
NULL
);
bRet
=
FALSE
;
/* Non-Zero */
}
}
return
bRet
;
}
/*************************************************************************
* @ [SHLWAPI.212]
*
* Call IStream::Write on a Stream.
*
* PARAMS
* lpStream [I] IStream object
* lpvSrc [I] Source for data to write
* ulSize [I] Size of data
*
* RETURNS
* Success: S_OK. ulSize bytes have been written to the stream from lpvSrc.
* Failure: An HRESULT error code, or E_FAIL if the write succeeded but the
* number of bytes written does not match.
*/
HRESULT
WINAPI
SHLWAPI_212
(
IStream
*
lpStream
,
LPCVOID
lpvSrc
,
ULONG
ulSize
)
{
ULONG
ulWritten
;
HRESULT
hRet
;
TRACE
(
"(%p,%p,%ld)
\n
"
,
lpStream
,
lpvSrc
,
ulSize
);
hRet
=
IStream_Write
(
lpStream
,
lpvSrc
,
ulSize
,
&
ulWritten
);
if
(
SUCCEEDED
(
hRet
)
&&
ulWritten
!=
ulSize
)
hRet
=
E_FAIL
;
return
hRet
;
}
/*************************************************************************
* @ [SHLWAPI.213]
*
* Seek to the start of a stream.
*
* PARAMS
* lpStream [I] IStream object
*
* RETURNS
* Success: S_OK. The current position within the stream is updated
* Failure: An HRESULT error code.
*/
HRESULT
WINAPI
SHLWAPI_213
(
IStream
*
lpStream
)
{
LARGE_INTEGER
zero
;
TRACE
(
"(%p)
\n
"
,
lpStream
);
zero
.
QuadPart
=
0
;
return
IStream_Seek
(
lpStream
,
zero
,
0
,
NULL
);
}
/*************************************************************************
* @ [SHLWAPI.214]
*
* Get the size of a Stream.
*
* PARAMS
* lpStream [I] IStream object
* lpulSize [O] Destination for size
*
* RETURNS
* Success: S_OK. lpulSize contains the size of the stream.
* Failure: An HRESULT error code.
*/
HRESULT
WINAPI
SHLWAPI_214
(
IStream
*
lpStream
,
ULARGE_INTEGER
*
lpulSize
)
{
STATSTG
statstg
;
HRESULT
hRet
;
TRACE
(
"(%p,%p)
\n
"
,
lpStream
,
lpulSize
);
memset
(
&
statstg
,
0
,
sizeof
(
statstg
));
hRet
=
IStream_Stat
(
lpStream
,
&
statstg
,
1
);
if
(
SUCCEEDED
(
hRet
)
&&
lpulSize
)
*
lpulSize
=
statstg
.
cbSize
;
return
hRet
;
}
dlls/shlwapi/shlwapi.spec
View file @
9797a38b
...
...
@@ -165,7 +165,7 @@ init SHLWAPI_LibMain
163 stub @
164 stdcall @(ptr ptr ptr ptr ptr ptr) SHLWAPI_164
165 stdcall @(long long long long) SHLWAPI_165
166 st
ub @
166 st
dcall @(ptr) SHLWAPI_166
167 stub @
168 stub @
169 stdcall @(long) SHLWAPI_169
...
...
@@ -183,7 +183,7 @@ init SHLWAPI_LibMain
181 stdcall @(long long long) SHLWAPI_181
182 stub @
183 stdcall @(ptr) SHLWAPI_183
184 st
ub @
184 st
dcall @(ptr ptr long) SHLWAPI_184
185 stub @
186 stub @
187 stub @
...
...
@@ -211,9 +211,9 @@ init SHLWAPI_LibMain
209 stdcall @(ptr) SHLWAPI_209
210 stdcall @(ptr long ptr) SHLWAPI_210
211 stdcall @(ptr long) SHLWAPI_211
212 st
ub @
213 st
ub @
214 st
ub @
212 st
dcall @(ptr ptr long) SHLWAPI_212
213 st
dcall @(ptr) SHLWAPI_213
214 st
dcall @(ptr ptr) SHLWAPI_214
215 stdcall @(long long long) SHLWAPI_215
216 stub @
217 stdcall @(wstr ptr ptr) SHLWAPI_217
...
...
@@ -708,8 +708,9 @@ init SHLWAPI_LibMain
@ stub SHCopyKeyA
@ stub SHCopyKeyW
@ stub SHAutoComplete
@ stub SHCreateStreamOnFileA
@ stub SHCreateStreamOnFileW
@ stdcall SHCreateStreamOnFileA(str long ptr) SHCreateStreamOnFileA
@ stdcall SHCreateStreamOnFileW(wstr long ptr) SHCreateStreamOnFileW
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) SHCreateStreamOnFileEx
@ stub SHCreateStreamWrapper
@ stub SHCreateThread
@ stdcall SHGetThreadRef (ptr) SHGetThreadRef
...
...
dlls/shlwapi/tests/clist.c
View file @
9797a38b
/* Unit test suite for SHLWAPI Compact List functions
/* Unit test suite for SHLWAPI Compact List
and IStream ordinal
functions
*
* Copyright 2002 Jon Griffiths
*
...
...
@@ -61,7 +61,9 @@ typedef struct
BOOL
failwritesize
;
int
seekcalls
;
int
statcalls
;
BOOL
failstatcall
;
LPCSHLWAPI_CLIST
item
;
ULARGE_INTEGER
pos
;
}
_IDummyStream
;
static
...
...
@@ -154,8 +156,9 @@ static HRESULT WINAPI Seek(_IDummyStream* This, LARGE_INTEGER dlibMove,
DWORD
dwOrigin
,
ULARGE_INTEGER
*
plibNewPosition
)
{
++
This
->
seekcalls
;
This
->
pos
.
QuadPart
=
dlibMove
.
QuadPart
;
if
(
plibNewPosition
)
plibNewPosition
->
QuadPart
=
sizeof
(
ULONG
)
;
plibNewPosition
->
QuadPart
=
dlibMove
.
QuadPart
;
return
S_OK
;
}
...
...
@@ -163,8 +166,10 @@ static HRESULT WINAPI Stat(_IDummyStream* This, STATSTG* pstatstg,
DWORD
grfStatFlag
)
{
++
This
->
statcalls
;
if
(
This
->
failstatcall
)
return
E_FAIL
;
if
(
pstatstg
)
pstatstg
->
cbSize
.
QuadPart
=
5000l
;
pstatstg
->
cbSize
.
QuadPart
=
This
->
pos
.
QuadPart
;
return
S_OK
;
}
...
...
@@ -197,6 +202,13 @@ static LPSHLWAPI_CLIST (WINAPI *pSHLWAPI_22)(LPSHLWAPI_CLIST,ULONG);
static
HRESULT
(
WINAPI
*
pSHLWAPI_17
)(
_IDummyStream
*
,
LPSHLWAPI_CLIST
);
static
HRESULT
(
WINAPI
*
pSHLWAPI_18
)(
_IDummyStream
*
,
LPSHLWAPI_CLIST
*
);
static
BOOL
(
WINAPI
*
pSHLWAPI_166
)(
_IDummyStream
*
);
static
HRESULT
(
WINAPI
*
pSHLWAPI_184
)(
_IDummyStream
*
,
LPVOID
,
ULONG
);
static
HRESULT
(
WINAPI
*
pSHLWAPI_212
)(
_IDummyStream
*
,
LPCVOID
,
ULONG
);
static
HRESULT
(
WINAPI
*
pSHLWAPI_213
)(
_IDummyStream
*
);
static
HRESULT
(
WINAPI
*
pSHLWAPI_214
)(
_IDummyStream
*
,
ULARGE_INTEGER
*
);
static
void
InitFunctionPtrs
()
{
SHLWAPI_hshlwapi
=
LoadLibraryA
(
"shlwapi.dll"
);
...
...
@@ -215,6 +227,16 @@ static void InitFunctionPtrs()
ok
(
pSHLWAPI_21
!=
0
,
"No Ordinal 21"
);
pSHLWAPI_22
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
22
);
ok
(
pSHLWAPI_22
!=
0
,
"No Ordinal 22"
);
pSHLWAPI_166
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
166
);
ok
(
pSHLWAPI_166
!=
0
,
"No Ordinal 166"
);
pSHLWAPI_184
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
184
);
ok
(
pSHLWAPI_184
!=
0
,
"No Ordinal 184"
);
pSHLWAPI_212
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
212
);
ok
(
pSHLWAPI_212
!=
0
,
"No Ordinal 212"
);
pSHLWAPI_213
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
213
);
ok
(
pSHLWAPI_213
!=
0
,
"No Ordinal 213"
);
pSHLWAPI_214
=
(
void
*
)
GetProcAddress
(
SHLWAPI_hshlwapi
,
(
LPSTR
)
214
);
ok
(
pSHLWAPI_214
!=
0
,
"No Ordinal 214"
);
}
}
...
...
@@ -232,7 +254,9 @@ static void InitDummyStream(_IDummyStream* iface)
iface
->
failwritesize
=
FALSE
;
iface
->
seekcalls
=
0
;
iface
->
statcalls
=
0
;
iface
->
failstatcall
=
FALSE
;
iface
->
item
=
SHLWAPI_CLIST_items
;
iface
->
pos
.
QuadPart
=
0
;
}
...
...
@@ -442,6 +466,146 @@ static void test_CList(void)
pSHLWAPI_19
(
list
);
}
static
void
test_SHLWAPI_166
(
void
)
{
_IDummyStream
streamobj
;
BOOL
bRet
;
if
(
!
pSHLWAPI_166
)
return
;
InitDummyStream
(
&
streamobj
);
bRet
=
pSHLWAPI_166
(
&
streamobj
);
ok
(
bRet
==
TRUE
,
"failed before seek adjusted"
);
ok
(
streamobj
.
readcalls
==
0
,
"called Read()"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
0
,
"called Seek()"
);
ok
(
streamobj
.
statcalls
==
1
,
"wrong call count"
);
streamobj
.
statcalls
=
0
;
streamobj
.
pos
.
QuadPart
=
50001
;
bRet
=
pSHLWAPI_166
(
&
streamobj
);
ok
(
bRet
==
FALSE
,
"failed after seek adjusted"
);
ok
(
streamobj
.
readcalls
==
0
,
"called Read()"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
0
,
"called Seek()"
);
ok
(
streamobj
.
statcalls
==
1
,
"wrong call count"
);
/* Failure cases */
InitDummyStream
(
&
streamobj
);
streamobj
.
pos
.
QuadPart
=
50001
;
streamobj
.
failstatcall
=
TRUE
;
/* 1: Stat() Bad, Read() OK */
bRet
=
pSHLWAPI_166
(
&
streamobj
);
ok
(
bRet
==
FALSE
,
"should be FALSE after read is OK"
);
ok
(
streamobj
.
readcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
statcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
pos
.
QuadPart
==
0
,
"Didn't seek to start"
);
InitDummyStream
(
&
streamobj
);
streamobj
.
pos
.
QuadPart
=
50001
;
streamobj
.
failstatcall
=
TRUE
;
streamobj
.
failreadcall
=
TRUE
;
/* 2: Stat() Bad, Read() Bad Also */
bRet
=
pSHLWAPI_166
(
&
streamobj
);
ok
(
bRet
==
TRUE
,
"Should be true after read fails"
);
ok
(
streamobj
.
readcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
0
,
"Called Seek()"
);
ok
(
streamobj
.
statcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
pos
.
QuadPart
==
50001
,
"called Seek() after read failed"
);
}
static
void
test_SHLWAPI_184
(
void
)
{
_IDummyStream
streamobj
;
char
buff
[
256
];
HRESULT
hRet
;
if
(
!
pSHLWAPI_184
)
return
;
InitDummyStream
(
&
streamobj
);
hRet
=
pSHLWAPI_184
(
&
streamobj
,
buff
,
sizeof
(
buff
));
ok
(
hRet
==
S_OK
,
"failed Read()"
);
ok
(
streamobj
.
readcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
0
,
"called Seek()"
);
}
static
void
test_SHLWAPI_212
(
void
)
{
_IDummyStream
streamobj
;
char
buff
[
256
];
HRESULT
hRet
;
if
(
!
pSHLWAPI_212
)
return
;
InitDummyStream
(
&
streamobj
);
hRet
=
pSHLWAPI_212
(
&
streamobj
,
buff
,
sizeof
(
buff
));
ok
(
hRet
==
S_OK
,
"failed Write()"
);
ok
(
streamobj
.
readcalls
==
0
,
"called Read()"
);
ok
(
streamobj
.
writecalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
seekcalls
==
0
,
"called Seek()"
);
}
static
void
test_SHLWAPI_213
(
void
)
{
_IDummyStream
streamobj
;
ULARGE_INTEGER
ul
;
LARGE_INTEGER
ll
;
HRESULT
hRet
;
if
(
!
pSHLWAPI_213
||
!
pSHLWAPI_214
)
return
;
InitDummyStream
(
&
streamobj
);
ll
.
QuadPart
=
5000l
;
Seek
(
&
streamobj
,
ll
,
0
,
NULL
);
/* Seek to 5000l */
streamobj
.
seekcalls
=
0
;
pSHLWAPI_213
(
&
streamobj
);
/* Should rewind */
ok
(
streamobj
.
statcalls
==
0
,
"called Stat()"
);
ok
(
streamobj
.
readcalls
==
0
,
"called Read()"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
1
,
"wrong call count"
);
ul
.
QuadPart
=
50001
;
hRet
=
pSHLWAPI_214
(
&
streamobj
,
&
ul
);
ok
(
hRet
==
S_OK
,
"failed Stat()"
);
ok
(
ul
.
QuadPart
==
0
,
"213 didn't rewind stream"
);
}
static
void
test_SHLWAPI_214
(
void
)
{
_IDummyStream
streamobj
;
ULARGE_INTEGER
ul
;
LARGE_INTEGER
ll
;
HRESULT
hRet
;
if
(
!
pSHLWAPI_214
)
return
;
InitDummyStream
(
&
streamobj
);
ll
.
QuadPart
=
5000l
;
Seek
(
&
streamobj
,
ll
,
0
,
NULL
);
ul
.
QuadPart
=
0
;
streamobj
.
seekcalls
=
0
;
hRet
=
pSHLWAPI_214
(
&
streamobj
,
&
ul
);
ok
(
hRet
==
S_OK
,
"failed Stat()"
);
ok
(
streamobj
.
statcalls
==
1
,
"wrong call count"
);
ok
(
streamobj
.
readcalls
==
0
,
"called Read()"
);
ok
(
streamobj
.
writecalls
==
0
,
"called Write()"
);
ok
(
streamobj
.
seekcalls
==
0
,
"called Seek()"
);
ok
(
ul
.
QuadPart
==
5000l
,
"Stat gave wrong size"
);
}
START_TEST
(
clist
)
{
...
...
@@ -449,6 +613,12 @@ START_TEST(clist)
test_CList
();
test_SHLWAPI_166
();
test_SHLWAPI_184
();
test_SHLWAPI_212
();
test_SHLWAPI_213
();
test_SHLWAPI_214
();
if
(
SHLWAPI_hshlwapi
)
FreeLibrary
(
SHLWAPI_hshlwapi
);
}
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