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
b6766167
Commit
b6766167
authored
Dec 13, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 13, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Handle optional WCHAR data when loading item moniker.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7a98b052
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
151 additions
and
52 deletions
+151
-52
itemmoniker.c
dlls/ole32/itemmoniker.c
+81
-47
moniker.c
dlls/ole32/tests/moniker.c
+70
-5
No files found.
dlls/ole32/itemmoniker.c
View file @
b6766167
...
@@ -157,72 +157,106 @@ static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
...
@@ -157,72 +157,106 @@ static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
return
S_FALSE
;
return
S_FALSE
;
}
}
/******************************************************************************
static
HRESULT
item_moniker_load_string_record
(
IStream
*
stream
,
WCHAR
**
ret
)
* ItemMoniker_Load
******************************************************************************/
static
HRESULT
WINAPI
ItemMonikerImpl_Load
(
IMoniker
*
iface
,
IStream
*
pStm
)
{
{
ItemMonikerImpl
*
This
=
impl_from_IMoniker
(
iface
);
DWORD
str_len
,
read_len
,
lenW
,
i
;
HRESULT
res
;
HRESULT
hr
=
S_OK
;
DWORD
delimiterLength
,
nameLength
,
lenW
;
char
*
buffer
;
CHAR
*
itemNameA
,
*
itemDelimiterA
;
WCHAR
*
str
;
ULONG
bread
;
TRACE
(
"
\n
"
);
/* for more details about data read by this function see comments of ItemMonikerImpl_Save function */
IStream_Read
(
stream
,
&
str_len
,
sizeof
(
str_len
),
&
read_len
);
if
(
read_len
!=
sizeof
(
str_len
))
/* read item delimiter string length + 1 */
res
=
IStream_Read
(
pStm
,
&
delimiterLength
,
sizeof
(
DWORD
),
&
bread
);
if
(
bread
!=
sizeof
(
DWORD
))
return
E_FAIL
;
return
E_FAIL
;
/* read item delimiter string */
if
(
!
str_len
)
if
(
!
(
itemDelimiterA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
delimiterLength
)))
{
heap_free
(
*
ret
);
*
ret
=
NULL
;
return
S_OK
;
}
if
(
!
(
buffer
=
heap_alloc
(
str_len
)))
return
E_OUTOFMEMORY
;
return
E_OUTOFMEMORY
;
res
=
IStream_Read
(
pStm
,
itemDelimiterA
,
delimiterLength
,
&
bread
);
if
(
bread
!=
delimiterLength
)
IStream_Read
(
stream
,
buffer
,
str_len
,
&
read_len
);
if
(
read_len
!=
str_len
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
itemDelimiterA
);
heap_free
(
buffer
);
return
E_FAIL
;
return
E_FAIL
;
}
}
lenW
=
MultiByteToWideChar
(
CP_ACP
,
0
,
itemDelimiterA
,
-
1
,
NULL
,
0
);
/* Skip ansi buffer, it must be null terminated. */
This
->
itemDelimiter
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
This
->
itemDelimiter
,
lenW
*
sizeof
(
WCHAR
));
i
=
0
;
if
(
!
This
->
itemDelimiter
)
while
(
i
<
str_len
&&
buffer
[
i
])
i
++
;
if
(
buffer
[
i
])
{
{
HeapFree
(
GetProcessHeap
(),
0
,
itemDelimiterA
);
WARN
(
"Expected null terminated ansi name.
\n
"
);
return
E_OUTOFMEMORY
;
hr
=
E_FAIL
;
goto
end
;
}
}
MultiByteToWideChar
(
CP_ACP
,
0
,
itemDelimiterA
,
-
1
,
This
->
itemDelimiter
,
lenW
);
HeapFree
(
GetProcessHeap
(),
0
,
itemDelimiterA
);
/* read item name string length + 1*/
if
(
i
<
str_len
-
1
)
res
=
IStream_Read
(
pStm
,
&
nameLength
,
sizeof
(
DWORD
),
&
bread
);
{
if
(
bread
!=
sizeof
(
DWORD
))
str_len
-=
i
+
1
;
return
E_FAIL
;
/* read item name string */
if
(
str_len
%
sizeof
(
WCHAR
))
if
(
!
(
itemNameA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
nameLength
)))
{
return
E_OUTOFMEMORY
;
WARN
(
"Unexpected Unicode name length %d.
\n
"
,
str_len
);
res
=
IStream_Read
(
pStm
,
itemNameA
,
nameLength
,
&
bread
);
hr
=
E_FAIL
;
if
(
bread
!=
nameLength
)
goto
end
;
}
str
=
heap_alloc
(
str_len
+
sizeof
(
WCHAR
));
if
(
str
)
{
memcpy
(
str
,
&
buffer
[
i
+
1
],
str_len
);
str
[
str_len
/
sizeof
(
WCHAR
)]
=
0
;
}
}
else
{
{
HeapFree
(
GetProcessHeap
(),
0
,
itemNameA
);
lenW
=
MultiByteToWideChar
(
CP_ACP
,
0
,
buffer
,
-
1
,
NULL
,
0
);
return
E_FAIL
;
str
=
heap_alloc
(
lenW
*
sizeof
(
WCHAR
));
if
(
str
)
MultiByteToWideChar
(
CP_ACP
,
0
,
buffer
,
-
1
,
str
,
lenW
);
}
}
lenW
=
MultiByteToWideChar
(
CP_ACP
,
0
,
itemNameA
,
-
1
,
NULL
,
0
);
if
(
str
)
This
->
itemName
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
This
->
itemName
,
lenW
*
sizeof
(
WCHAR
));
if
(
!
This
->
itemName
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
itemNameA
);
heap_free
(
*
ret
);
return
E_OUTOFMEMORY
;
*
ret
=
str
;
}
}
MultiByteToWideChar
(
CP_ACP
,
0
,
itemNameA
,
-
1
,
This
->
itemName
,
lenW
);
else
HeapFree
(
GetProcessHeap
(),
0
,
itemNameA
)
;
hr
=
E_OUTOFMEMORY
;
return
res
;
end:
heap_free
(
buffer
);
return
hr
;
}
/******************************************************************************
* ItemMoniker_Load
******************************************************************************/
static
HRESULT
WINAPI
ItemMonikerImpl_Load
(
IMoniker
*
iface
,
IStream
*
stream
)
{
ItemMonikerImpl
*
This
=
impl_from_IMoniker
(
iface
);
HRESULT
hr
;
TRACE
(
"(%p, %p)
\n
"
,
iface
,
stream
);
/* Delimiter and name use the same record structure: 4 bytes byte-length field, followed by
string data. Data starts with single byte null-terminated string, WCHAR non-terminated
string optionally follows. Length of WCHAR string is determined as a difference between total
byte-length and single byte string length. */
hr
=
item_moniker_load_string_record
(
stream
,
&
This
->
itemDelimiter
);
if
(
SUCCEEDED
(
hr
))
hr
=
item_moniker_load_string_record
(
stream
,
&
This
->
itemName
);
return
hr
;
}
}
/******************************************************************************
/******************************************************************************
...
...
dlls/ole32/tests/moniker.c
View file @
b6766167
...
@@ -1674,9 +1674,37 @@ static void test_file_monikers(void)
...
@@ -1674,9 +1674,37 @@ static void test_file_monikers(void)
static
void
test_item_moniker
(
void
)
static
void
test_item_moniker
(
void
)
{
{
static
const
char
item_moniker_unicode_delim_stream
[]
=
{
0x05
,
0x00
,
0x00
,
0x00
,
0xff
,
0xff
,
0x00
,
'!'
,
0x00
,
0x02
,
0x00
,
0x00
,
0x00
,
'A'
,
0x00
,
};
static
const
char
item_moniker_unicode_item_stream
[]
=
{
0x02
,
0x00
,
0x00
,
0x00
,
'!'
,
0x00
,
0x05
,
0x00
,
0x00
,
0x00
,
0xff
,
0xff
,
0x00
,
'B'
,
0x00
,
};
static
const
char
item_moniker_unicode_delim_item_stream
[]
=
{
0x05
,
0x00
,
0x00
,
0x00
,
0xff
,
0xff
,
0x00
,
'!'
,
0x00
,
0x06
,
0x00
,
0x00
,
0x00
,
0xff
,
0xff
,
0xff
,
0x00
,
'C'
,
0x00
,
};
static
struct
{
const
char
*
data
;
int
data_len
;
const
WCHAR
*
display_name
;
}
item_moniker_data
[]
=
{
{
item_moniker_unicode_delim_stream
,
sizeof
(
item_moniker_unicode_delim_stream
),
L"!A"
},
{
item_moniker_unicode_item_stream
,
sizeof
(
item_moniker_unicode_item_stream
),
L"!B"
},
{
item_moniker_unicode_delim_item_stream
,
sizeof
(
item_moniker_unicode_delim_item_stream
),
L"!C"
},
};
IMoniker
*
moniker
,
*
moniker2
;
HRESULT
hr
;
HRESULT
hr
;
IMoniker
*
moniker
;
DWORD
moniker_type
,
i
;
DWORD
moniker_type
;
DWORD
hash
;
DWORD
hash
;
IBindCtx
*
bindctx
;
IBindCtx
*
bindctx
;
IMoniker
*
inverse
;
IMoniker
*
inverse
;
...
@@ -1684,6 +1712,9 @@ static void test_item_moniker(void)
...
@@ -1684,6 +1712,9 @@ static void test_item_moniker(void)
static
const
WCHAR
wszDelimiter
[]
=
{
'!'
,
0
};
static
const
WCHAR
wszDelimiter
[]
=
{
'!'
,
0
};
static
const
WCHAR
wszObjectName
[]
=
{
'T'
,
'e'
,
's'
,
't'
,
0
};
static
const
WCHAR
wszObjectName
[]
=
{
'T'
,
'e'
,
's'
,
't'
,
0
};
static
const
WCHAR
expected_display_name
[]
=
{
'!'
,
'T'
,
'e'
,
's'
,
't'
,
0
};
static
const
WCHAR
expected_display_name
[]
=
{
'!'
,
'T'
,
'e'
,
's'
,
't'
,
0
};
WCHAR
*
display_name
;
LARGE_INTEGER
pos
;
IStream
*
stream
;
hr
=
CreateItemMoniker
(
NULL
,
wszObjectName
,
&
moniker
);
hr
=
CreateItemMoniker
(
NULL
,
wszObjectName
,
&
moniker
);
ok
(
hr
==
S_OK
,
"Failed to create item moniker, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to create item moniker, hr %#x.
\n
"
,
hr
);
...
@@ -1727,6 +1758,43 @@ static void test_item_moniker(void)
...
@@ -1727,6 +1758,43 @@ static void test_item_moniker(void)
expected_item_moniker_comparison_data5
,
sizeof
(
expected_item_moniker_comparison_data5
),
expected_item_moniker_comparison_data5
,
sizeof
(
expected_item_moniker_comparison_data5
),
58
,
L"abTest"
);
58
,
L"abTest"
);
/* Serialize and load back. */
hr
=
CreateItemMoniker
(
NULL
,
L"object"
,
&
moniker2
);
ok
(
hr
==
S_OK
,
"Failed to create item moniker, hr %#x.
\n
"
,
hr
);
hr
=
CreateStreamOnHGlobal
(
NULL
,
TRUE
,
&
stream
);
ok
(
hr
==
S_OK
,
"Failed to create a stream, hr %#x.
\n
"
,
hr
);
hr
=
CreateBindCtx
(
0
,
&
bindctx
);
ok
(
hr
==
S_OK
,
"Failed to create bind context, hr %#x.
\n
"
,
hr
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
item_moniker_data
);
++
i
)
{
pos
.
QuadPart
=
0
;
hr
=
IStream_Seek
(
stream
,
pos
,
STREAM_SEEK_SET
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to seek stream, hr %#x.
\n
"
,
hr
);
hr
=
IStream_Write
(
stream
,
item_moniker_data
[
i
].
data
,
item_moniker_data
[
i
].
data_len
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to write stream contents, hr %#x.
\n
"
,
hr
);
pos
.
QuadPart
=
0
;
hr
=
IStream_Seek
(
stream
,
pos
,
STREAM_SEEK_SET
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to seek stream, hr %#x.
\n
"
,
hr
);
hr
=
IMoniker_Load
(
moniker2
,
stream
);
ok
(
hr
==
S_OK
,
"Failed to load moniker, hr %#x.
\n
"
,
hr
);
hr
=
IMoniker_GetDisplayName
(
moniker2
,
bindctx
,
NULL
,
&
display_name
);
ok
(
hr
==
S_OK
,
"Failed to get display name, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
display_name
,
item_moniker_data
[
i
].
display_name
),
"%d: unexpected display name %s.
\n
"
,
i
,
wine_dbgstr_w
(
display_name
));
CoTaskMemFree
(
display_name
);
}
IStream_Release
(
stream
);
IMoniker_Release
(
moniker2
);
IMoniker_Release
(
moniker
);
IMoniker_Release
(
moniker
);
hr
=
CreateItemMoniker
(
wszDelimiter
,
wszObjectName
,
&
moniker
);
hr
=
CreateItemMoniker
(
wszDelimiter
,
wszObjectName
,
&
moniker
);
...
@@ -1756,9 +1824,6 @@ static void test_item_moniker(void)
...
@@ -1756,9 +1824,6 @@ static void test_item_moniker(void)
"dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x
\n
"
,
"dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x
\n
"
,
moniker_type
);
moniker_type
);
hr
=
CreateBindCtx
(
0
,
&
bindctx
);
ok_ole_success
(
hr
,
CreateBindCtx
);
/* IsRunning test */
/* IsRunning test */
hr
=
IMoniker_IsRunning
(
moniker
,
NULL
,
NULL
,
NULL
);
hr
=
IMoniker_IsRunning
(
moniker
,
NULL
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x
\n
"
,
hr
);
ok
(
hr
==
E_INVALIDARG
,
"IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x
\n
"
,
hr
);
...
...
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