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
f50198f6
Commit
f50198f6
authored
Apr 28, 2010
by
Andrew Nguyen
Committed by
Alexandre Julliard
Apr 28, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Improve flag error handling in FormatMessageA/W.
parent
9df55f06
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
204 additions
and
9 deletions
+204
-9
format_msg.c
dlls/kernel32/format_msg.c
+23
-9
format_msg.c
dlls/kernel32/tests/format_msg.c
+181
-0
No files found.
dlls/kernel32/format_msg.c
View file @
f50198f6
...
...
@@ -393,15 +393,17 @@ DWORD WINAPI FormatMessageA(
TRACE
(
"(0x%x,%p,%d,0x%x,%p,%d,%p)
\n
"
,
dwFlags
,
lpSource
,
dwMessageId
,
dwLanguageId
,
lpBuffer
,
nSize
,
args
);
if
((
dwFlags
&
FORMAT_MESSAGE_FROM_STRING
)
&&
((
dwFlags
&
FORMAT_MESSAGE_FROM_SYSTEM
)
||
(
dwFlags
&
FORMAT_MESSAGE_FROM_HMODULE
)))
return
0
;
if
((
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
&&
!
lpBuffer
)
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
{
if
(
!
lpBuffer
)
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
else
*
(
LPSTR
*
)
lpBuffer
=
NULL
;
}
if
(
dwFlags
&
FORMAT_MESSAGE_ARGUMENT_ARRAY
)
{
...
...
@@ -425,13 +427,19 @@ DWORD WINAPI FormatMessageA(
from
=
HeapAlloc
(
GetProcessHeap
(),
0
,
length
*
sizeof
(
WCHAR
)
);
MultiByteToWideChar
(
CP_ACP
,
0
,
lpSource
,
-
1
,
from
,
length
);
}
else
{
else
if
(
dwFlags
&
(
FORMAT_MESSAGE_FROM_HMODULE
|
FORMAT_MESSAGE_FROM_SYSTEM
))
{
if
(
dwFlags
&
FORMAT_MESSAGE_FROM_HMODULE
)
from
=
load_message
(
(
HMODULE
)
lpSource
,
dwMessageId
,
dwLanguageId
);
if
(
!
from
&&
(
dwFlags
&
FORMAT_MESSAGE_FROM_SYSTEM
))
from
=
load_message
(
kernel32_handle
,
dwMessageId
,
dwLanguageId
);
if
(
!
from
)
return
0
;
}
else
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
target
=
format_message
(
FALSE
,
dwFlags
,
from
,
&
format_args
);
if
(
!
target
)
...
...
@@ -483,9 +491,6 @@ DWORD WINAPI FormatMessageW(
TRACE
(
"(0x%x,%p,%d,0x%x,%p,%d,%p)
\n
"
,
dwFlags
,
lpSource
,
dwMessageId
,
dwLanguageId
,
lpBuffer
,
nSize
,
args
);
if
((
dwFlags
&
FORMAT_MESSAGE_FROM_STRING
)
&&
((
dwFlags
&
FORMAT_MESSAGE_FROM_SYSTEM
)
||
(
dwFlags
&
FORMAT_MESSAGE_FROM_HMODULE
)))
return
0
;
if
(
!
lpBuffer
)
{
...
...
@@ -493,6 +498,9 @@ DWORD WINAPI FormatMessageW(
return
0
;
}
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
*
(
LPWSTR
*
)
lpBuffer
=
NULL
;
if
(
dwFlags
&
FORMAT_MESSAGE_ARGUMENT_ARRAY
)
{
format_args
.
args
=
(
ULONG_PTR
*
)
args
;
...
...
@@ -514,13 +522,19 @@ DWORD WINAPI FormatMessageW(
sizeof
(
WCHAR
)
);
strcpyW
(
from
,
lpSource
);
}
else
{
else
if
(
dwFlags
&
(
FORMAT_MESSAGE_FROM_HMODULE
|
FORMAT_MESSAGE_FROM_SYSTEM
))
{
if
(
dwFlags
&
FORMAT_MESSAGE_FROM_HMODULE
)
from
=
load_message
(
(
HMODULE
)
lpSource
,
dwMessageId
,
dwLanguageId
);
if
(
!
from
&&
(
dwFlags
&
FORMAT_MESSAGE_FROM_SYSTEM
))
from
=
load_message
(
kernel32_handle
,
dwMessageId
,
dwLanguageId
);
if
(
!
from
)
return
0
;
}
else
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
target
=
format_message
(
TRUE
,
dwFlags
,
from
,
&
format_args
);
if
(
!
target
)
...
...
dlls/kernel32/tests/format_msg.c
View file @
f50198f6
...
...
@@ -1112,6 +1112,185 @@ static void test_message_from_hmodule(void)
"last error %u
\n
"
,
error
);
}
static
void
test_message_invalid_flags
(
void
)
{
static
const
char
init_buf
[]
=
{
'x'
,
'x'
,
'x'
,
'x'
,
'x'
};
DWORD
ret
;
CHAR
out
[
5
];
char
*
ptr
;
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
0
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ptr
=
(
char
*
)
0xdeadbeef
;
ret
=
FormatMessageA
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
"test"
,
0
,
0
,
(
char
*
)
&
ptr
,
0
,
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
ptr
==
NULL
||
broken
(
ptr
==
(
char
*
)
0xdeadbeef
),
/* Win9x */
"Expected output pointer to be initialized to NULL, got %p
\n
"
,
ptr
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_IGNORE_INSERTS
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_ARGUMENT_ARRAY
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_MAX_WIDTH_MASK
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
/* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
* flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
* precedence in this case. */
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_SYSTEM
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageA to return 4, got %u
\n
"
,
ret
);
ok
(
!
strcmp
(
"test"
,
out
),
"Expected the output buffer to be untouched
\n
"
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_HMODULE
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageA to return 4, got %u
\n
"
,
ret
);
ok
(
!
strcmp
(
"test"
,
out
),
"Expected the output buffer to be untouched
\n
"
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_HMODULE
|
FORMAT_MESSAGE_FROM_SYSTEM
,
"test"
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageA to return 4, got %u
\n
"
,
ret
);
ok
(
!
strcmp
(
"test"
,
out
),
"Expected the output buffer to be untouched
\n
"
);
}
static
void
test_message_invalid_flags_wide
(
void
)
{
static
const
WCHAR
init_buf
[]
=
{
'x'
,
'x'
,
'x'
,
'x'
,
'x'
};
static
const
WCHAR
test
[]
=
{
't'
,
'e'
,
's'
,
't'
,
0
};
DWORD
ret
;
WCHAR
out
[
5
];
WCHAR
*
ptr
;
SetLastError
(
0xdeadbeef
);
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
,
NULL
,
0
,
0
,
NULL
,
0
,
NULL
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_CALL_NOT_IMPLEMENTED
)
{
win_skip
(
"FormatMessageW is not implemented
\n
"
);
return
;
}
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
0
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ptr
=
(
WCHAR
*
)
0xdeadbeef
;
ret
=
FormatMessageW
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
test
,
0
,
0
,
(
WCHAR
*
)
&
ptr
,
0
,
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
ptr
==
NULL
,
"Expected output pointer to be initialized to NULL, got %p
\n
"
,
ptr
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_IGNORE_INSERTS
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_ARGUMENT_ARRAY
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_MAX_WIDTH_MASK
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
)),
"Expected the output buffer to be untouched
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u
\n
"
,
GetLastError
());
/* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
* flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
* precedence in this case. */
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_SYSTEM
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageW to return 4, got %u
\n
"
,
ret
);
ok
(
!
lstrcmpW
(
test
,
out
),
"Expected the output buffer to be untouched
\n
"
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_HMODULE
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageW to return 4, got %u
\n
"
,
ret
);
ok
(
!
lstrcmpW
(
test
,
out
),
"Expected the output buffer to be untouched
\n
"
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_FROM_HMODULE
|
FORMAT_MESSAGE_FROM_SYSTEM
,
test
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
ok
(
ret
==
4
,
"Expected FormatMessageW to return 4, got %u
\n
"
,
ret
);
ok
(
!
lstrcmpW
(
test
,
out
),
"Expected the output buffer to be untouched
\n
"
);
}
START_TEST
(
format_msg
)
{
test_message_from_string
();
...
...
@@ -1123,4 +1302,6 @@ START_TEST(format_msg)
test_message_allocate_buffer
();
test_message_allocate_buffer_wide
();
test_message_from_hmodule
();
test_message_invalid_flags
();
test_message_invalid_flags_wide
();
}
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