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
ec1ea1ea
Commit
ec1ea1ea
authored
Oct 09, 2020
by
Paul Gofman
Committed by
Alexandre Julliard
Oct 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Call FLS callbacks.
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7341f4ad
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
119 additions
and
32 deletions
+119
-32
fiber.c
dlls/kernel32/tests/fiber.c
+20
-4
loader.c
dlls/kernel32/tests/loader.c
+57
-22
loader.c
dlls/ntdll/loader.c
+7
-1
thread.c
dlls/ntdll/thread.c
+35
-5
No files found.
dlls/kernel32/tests/fiber.c
View file @
ec1ea1ea
...
...
@@ -223,8 +223,11 @@ static unsigned int check_linked_list(const LIST_ENTRY *le, const LIST_ENTRY *se
return
count
;
}
static
unsigned
int
test_fls_callback_call_count
;
static
void
WINAPI
test_fls_callback
(
void
*
data
)
{
++
test_fls_callback_call_count
;
}
static
unsigned
int
test_fls_chunk_size
(
unsigned
int
chunk_index
)
...
...
@@ -377,8 +380,11 @@ static void test_FiberLocalStorage(void)
ok
(
status
==
STATUS_INVALID_PARAMETER
,
"Got unexpected status %#x.
\n
"
,
status
);
g_fls_data
->
fls_callback_chunks
[
j
]
->
callbacks
[
index
].
callback
=
test_fls_callback
;
test_fls_callback_call_count
=
0
;
status
=
pRtlFlsFree
(
fls_indices
[
0x10
]);
ok
(
!
status
,
"Got unexpected status %#x.
\n
"
,
status
);
ok
(
test_fls_callback_call_count
==
1
,
"Got unexpected callback call count %u.
\n
"
,
test_fls_callback_call_count
);
ok
(
!
fls_data
->
fls_data_chunks
[
j
][
0
],
"Got unexpected fls_data->fls_data_chunks[%u][0] %p.
\n
"
,
j
,
fls_data
->
fls_data_chunks
[
j
][
0
]);
...
...
@@ -405,7 +411,7 @@ static void test_FiberLocalStorage(void)
ok
(
val
==
(
void
*
)
0xdeadbeef
,
"Got unexpected val %p.
\n
"
,
val
);
ok
(
!
new_fls_data
,
"Got unexpected teb->FlsSlots %p.
\n
"
,
new_fls_data
);
status
=
pRtlFlsSetValue
(
fls_indices
[
1
],
NULL
);
status
=
pRtlFlsSetValue
(
fls_indices
[
1
],
(
void
*
)(
ULONG_PTR
)
0x28
);
new_fls_data
=
teb
->
FlsSlots
;
ok
(
!
status
,
"Got unexpected status %#x.
\n
"
,
status
);
ok
(
!!
new_fls_data
,
"Got unexpected teb->FlsSlots %p.
\n
"
,
new_fls_data
);
...
...
@@ -450,11 +456,15 @@ static void test_FiberLocalStorage(void)
ok
(
result
==
WAIT_OBJECT_0
,
"Got unexpected result %u.
\n
"
,
result
);
teb
->
FlsSlots
=
NULL
;
test_fls_callback_call_count
=
0
;
saved_entry
=
new_fls_data
->
fls_list_entry
;
pRtlProcessFlsData
(
new_fls_data
,
1
);
ok
(
!
teb
->
FlsSlots
,
"Got unexpected teb->FlsSlots %p.
\n
"
,
teb
->
FlsSlots
);
teb
->
FlsSlots
=
fls_data
;
ok
(
test_fls_callback_call_count
==
1
,
"Got unexpected callback call count %u.
\n
"
,
test_fls_callback_call_count
);
SetEvent
(
test_fiberlocalstorage_done_event
);
WaitForSingleObject
(
hthread
,
INFINITE
);
CloseHandle
(
hthread
);
...
...
@@ -467,7 +477,13 @@ static void test_FiberLocalStorage(void)
saved_entry
.
Blink
);
size
=
HeapSize
(
GetProcessHeap
(),
0
,
new_fls_data
);
ok
(
size
==
sizeof
(
*
new_fls_data
),
"Got unexpected size %p.
\n
"
,
(
void
*
)
size
);
test_fls_callback_call_count
=
0
;
i
=
test_fls_chunk_index_from_index
(
fls_indices
[
1
],
&
index
);
new_fls_data
->
fls_data_chunks
[
i
][
index
+
1
]
=
(
void
*
)(
ULONG_PTR
)
0x28
;
pRtlProcessFlsData
(
new_fls_data
,
2
);
ok
(
!
test_fls_callback_call_count
,
"Got unexpected callback call count %u.
\n
"
,
test_fls_callback_call_count
);
if
(
0
)
{
/* crashes on Windows. */
...
...
@@ -676,7 +692,7 @@ static void test_FiberLocalStorageCallback(PFLS_CALLBACK_FUNCTION cbfunc)
ret
=
pFlsFree
(
fls
);
ok
(
ret
,
"FlsFree failed with error %u
\n
"
,
GetLastError
()
);
todo_wine
ok
(
cbCount
==
1
,
"Wrong callback count: %d
\n
"
,
cbCount
);
ok
(
cbCount
==
1
,
"Wrong callback count: %d
\n
"
,
cbCount
);
/* Test that callback is not executed if value is NULL */
cbCount
=
0
;
...
...
@@ -741,14 +757,14 @@ static void test_FiberLocalStorageWithFibers(PFLS_CALLBACK_FUNCTION cbfunc)
fls_value_to_set
=
val1
;
pDeleteFiber
(
fibers
[
1
]);
ok
(
fiberCount
==
0
,
"Wrong fiber count: %d
\n
"
,
fiberCount
);
todo_wine
ok
(
cbCount
==
1
,
"Wrong callback count: %d
\n
"
,
cbCount
);
ok
(
cbCount
==
1
,
"Wrong callback count: %d
\n
"
,
cbCount
);
fiberCount
=
0
;
cbCount
=
0
;
fls_value_to_set
=
val2
;
pFlsFree
(
fls_index_to_set
);
ok
(
fiberCount
==
0
,
"Wrong fiber count: %d
\n
"
,
fiberCount
);
todo_wine
ok
(
cbCount
==
2
,
"Wrong callback count: %d
\n
"
,
cbCount
);
ok
(
cbCount
==
2
,
"Wrong callback count: %d
\n
"
,
cbCount
);
fiberCount
=
0
;
cbCount
=
0
;
...
...
dlls/kernel32/tests/loader.c
View file @
ec1ea1ea
...
...
@@ -2318,12 +2318,34 @@ static VOID WINAPI fls_callback(PVOID lpFlsData)
InterlockedIncrement
(
&
fls_callback_count
);
}
static
LIST_ENTRY
*
fls_list_head
;
static
unsigned
int
check_linked_list
(
const
LIST_ENTRY
*
le
,
const
LIST_ENTRY
*
search_entry
,
unsigned
int
*
index_found
)
{
unsigned
int
count
=
0
;
LIST_ENTRY
*
entry
;
*
index_found
=
~
0
;
for
(
entry
=
le
->
Flink
;
entry
!=
le
;
entry
=
entry
->
Flink
)
{
if
(
entry
==
search_entry
)
{
ok
(
*
index_found
==
~
0
,
"Duplicate list entry.
\n
"
);
*
index_found
=
count
;
}
++
count
;
}
return
count
;
}
static
BOOL
WINAPI
dll_entry_point
(
HINSTANCE
hinst
,
DWORD
reason
,
LPVOID
param
)
{
static
LONG
noop_thread_started
;
static
DWORD
fls_index
=
FLS_OUT_OF_INDEXES
;
static
DWORD
fls_index
=
FLS_OUT_OF_INDEXES
,
fls_index2
=
FLS_OUT_OF_INDEXES
;
static
int
fls_count
=
0
;
static
int
thread_detach_count
=
0
;
static
int
thread_count
;
DWORD
ret
;
ok
(
!
inside_loader_lock
,
"inside_loader_lock should not be set
\n
"
);
...
...
@@ -2352,8 +2374,11 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
bret
=
pFlsSetValue
(
fls_index
,
(
void
*
)
0x31415
);
ok
(
bret
,
"FlsSetValue failed
\n
"
);
fls_count
++
;
}
fls_index2
=
pFlsAlloc
(
&
fls_callback
);
ok
(
fls_index2
!=
FLS_OUT_OF_INDEXES
,
"FlsAlloc returned %d
\n
"
,
ret
);
}
++
thread_count
;
break
;
case
DLL_PROCESS_DETACH
:
{
...
...
@@ -2423,18 +2448,12 @@ todo_wine
void
*
value
;
SetLastError
(
0xdeadbeef
);
value
=
pFlsGetValue
(
fls_index
);
todo_wine
{
ok
(
broken
(
value
==
(
void
*
)
0x31415
)
||
/* Win2k3 */
value
==
NULL
,
"FlsGetValue returned %p, expected NULL
\n
"
,
value
);
}
ok
(
broken
(
value
==
(
void
*
)
0x31415
)
||
/* Win2k3 */
value
==
NULL
,
"FlsGetValue returned %p, expected NULL
\n
"
,
value
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"FlsGetValue failed with error %u
\n
"
,
GetLastError
());
todo_wine
{
ok
(
broken
(
fls_callback_count
==
thread_detach_count
)
||
/* Win2k3 */
fls_callback_count
==
thread_detach_count
+
1
,
"wrong FLS callback count %d, expected %d
\n
"
,
fls_callback_count
,
thread_detach_count
+
1
);
}
ok
(
broken
(
fls_callback_count
==
thread_detach_count
)
||
/* Win2k3 */
fls_callback_count
==
thread_detach_count
+
1
,
"wrong FLS callback count %d, expected %d
\n
"
,
fls_callback_count
,
thread_detach_count
+
1
);
}
if
(
pFlsFree
)
{
...
...
@@ -2443,11 +2462,8 @@ todo_wine
ret
=
pFlsFree
(
fls_index
);
ok
(
ret
,
"FlsFree failed with error %u
\n
"
,
GetLastError
());
fls_index
=
FLS_OUT_OF_INDEXES
;
todo_wine
{
ok
(
fls_callback_count
==
fls_count
,
"wrong FLS callback count %d, expected %d
\n
"
,
fls_callback_count
,
fls_count
);
}
ok
(
fls_callback_count
==
fls_count
,
"wrong FLS callback count %d, expected %d
\n
"
,
fls_callback_count
,
fls_count
);
}
ok
(
attached_thread_count
>=
2
,
"attached thread count should be >= 2
\n
"
);
...
...
@@ -2611,6 +2627,8 @@ todo_wine
case
DLL_THREAD_ATTACH
:
trace
(
"dll: %p, DLL_THREAD_ATTACH, %p
\n
"
,
hinst
,
param
);
++
thread_count
;
ret
=
pRtlDllShutdownInProgress
();
ok
(
!
ret
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
...
...
@@ -2638,6 +2656,7 @@ todo_wine
break
;
case
DLL_THREAD_DETACH
:
trace
(
"dll: %p, DLL_THREAD_DETACH, %p
\n
"
,
hinst
,
param
);
--
thread_count
;
thread_detach_count
++
;
ret
=
pRtlDllShutdownInProgress
();
...
...
@@ -2656,15 +2675,25 @@ todo_wine
*/
if
(
pFlsGetValue
&&
fls_index
!=
FLS_OUT_OF_INDEXES
)
{
unsigned
int
index
,
count
;
void
*
value
;
BOOL
bret
;
SetLastError
(
0xdeadbeef
);
value
=
pFlsGetValue
(
fls_index
);
todo_wine
ok
(
broken
(
value
==
(
void
*
)
0x31415
)
||
/* Win2k3 */
!
value
,
"FlsGetValue returned %p, expected NULL
\n
"
,
value
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"FlsGetValue failed with error %u
\n
"
,
GetLastError
());
bret
=
pFlsSetValue
(
fls_index2
,
(
void
*
)
0x31415
);
ok
(
bret
,
"FlsSetValue failed
\n
"
);
if
(
fls_list_head
)
{
ok
(
broken
(
value
==
(
void
*
)
0x31415
)
||
/* Win2k3 */
!
value
,
"FlsGetValue returned %p, expected NULL
\n
"
,
value
);
count
=
check_linked_list
(
fls_list_head
,
&
NtCurrentTeb
()
->
FlsSlots
->
fls_list_entry
,
&
index
);
ok
(
count
<=
thread_count
,
"Got unexpected count %u, thread_count %u.
\n
"
,
count
,
thread_count
);
ok
(
index
==
~
0
,
"Got unexpected index %u.
\n
"
,
index
);
}
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"FlsGetValue failed with error %u
\n
"
,
GetLastError
());
}
break
;
...
...
@@ -2689,6 +2718,12 @@ static void child_process(const char *dll_name, DWORD target_offset)
trace
(
"phase %d: writing %p at %#x
\n
"
,
test_dll_phase
,
dll_entry_point
,
target_offset
);
if
(
pFlsAlloc
)
{
fls_list_head
=
NtCurrentTeb
()
->
Peb
->
FlsListHead
.
Flink
?
&
NtCurrentTeb
()
->
Peb
->
FlsListHead
:
NtCurrentTeb
()
->
FlsSlots
->
fls_list_entry
.
Flink
;
}
SetLastError
(
0xdeadbeef
);
mutex
=
CreateMutexW
(
NULL
,
FALSE
,
NULL
);
ok
(
mutex
!=
0
,
"CreateMutex error %d
\n
"
,
GetLastError
());
...
...
dlls/ntdll/loader.c
View file @
ec1ea1ea
...
...
@@ -3194,6 +3194,10 @@ fail:
void
WINAPI
LdrShutdownProcess
(
void
)
{
TRACE
(
"()
\n
"
);
if
(
!
process_detaching
)
RtlProcessFlsData
(
NtCurrentTeb
()
->
FlsSlots
,
1
);
process_detaching
=
TRUE
;
process_detach
();
}
...
...
@@ -3228,6 +3232,8 @@ void WINAPI LdrShutdownThread(void)
/* don't do any detach calls if process is exiting */
if
(
process_detaching
)
return
;
RtlProcessFlsData
(
NtCurrentTeb
()
->
FlsSlots
,
1
);
RtlEnterCriticalSection
(
&
loader_section
);
wm
=
get_modref
(
NtCurrentTeb
()
->
Peb
->
ImageBaseAddress
);
...
...
@@ -3254,7 +3260,7 @@ void WINAPI LdrShutdownThread(void)
for
(
i
=
0
;
i
<
tls_module_count
;
i
++
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
pointers
[
i
]
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
pointers
);
}
RtlProcessFlsData
(
NtCurrentTeb
()
->
FlsSlots
,
3
);
RtlProcessFlsData
(
NtCurrentTeb
()
->
FlsSlots
,
2
);
NtCurrentTeb
()
->
FlsSlots
=
NULL
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
NtCurrentTeb
()
->
TlsExpansionSlots
);
NtCurrentTeb
()
->
TlsExpansionSlots
=
NULL
;
...
...
dlls/ntdll/thread.c
View file @
ec1ea1ea
...
...
@@ -374,7 +374,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsAlloc( PFLS_CALLBACK_FUNCTION callback,
}
++
chunk
->
count
;
chunk
->
callbacks
[
index
].
callback
=
callback
?
callback
:
(
void
*
)
~
(
ULONG_PTR
)
0
;
chunk
->
callbacks
[
index
].
callback
=
callback
?
callback
:
(
PFLS_CALLBACK_FUNCTION
)
~
(
ULONG_PTR
)
0
;
if
((
*
ret_index
=
fls_index_from_chunk_index
(
chunk_index
,
index
))
>
fls_data
.
fls_high_index
)
fls_data
.
fls_high_index
=
*
ret_index
;
...
...
@@ -390,6 +390,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsAlloc( PFLS_CALLBACK_FUNCTION callback,
*/
NTSTATUS
WINAPI
DECLSPEC_HOTPATCH
RtlFlsFree
(
ULONG
index
)
{
PFLS_CALLBACK_FUNCTION
callback
;
unsigned
int
chunk_index
,
idx
;
FLS_INFO_CHUNK
*
chunk
;
LIST_ENTRY
*
entry
;
...
...
@@ -404,7 +405,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsFree( ULONG index )
chunk_index
=
fls_chunk_index_from_index
(
index
,
&
idx
);
if
(
!
(
chunk
=
fls_data
.
fls_callback_chunks
[
chunk_index
])
||
!
chunk
->
callbacks
[
idx
].
callback
)
||
!
(
callback
=
chunk
->
callbacks
[
idx
].
callback
)
)
{
unlock_fls_data
();
return
STATUS_INVALID_PARAMETER
;
...
...
@@ -414,9 +415,15 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsFree( ULONG index )
{
TEB_FLS_DATA
*
fls
=
CONTAINING_RECORD
(
entry
,
TEB_FLS_DATA
,
fls_list_entry
);
if
(
fls
->
fls_data_chunks
[
chunk_index
])
if
(
fls
->
fls_data_chunks
[
chunk_index
]
&&
fls
->
fls_data_chunks
[
chunk_index
][
idx
+
1
]
)
{
/* FIXME: call Fls callback */
if
(
callback
!=
(
void
*
)
~
(
ULONG_PTR
)
0
)
{
TRACE_
(
relay
)(
"Calling FLS callback %p, arg %p.
\n
"
,
callback
,
fls
->
fls_data_chunks
[
chunk_index
][
idx
+
1
]);
callback
(
fls
->
fls_data_chunks
[
chunk_index
][
idx
+
1
]
);
}
fls
->
fls_data_chunks
[
chunk_index
][
idx
+
1
]
=
NULL
;
}
}
...
...
@@ -481,7 +488,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsGetValue( ULONG index, void **data )
void
WINAPI
DECLSPEC_HOTPATCH
RtlProcessFlsData
(
void
*
teb_fls_data
,
ULONG
flags
)
{
TEB_FLS_DATA
*
fls
=
teb_fls_data
;
unsigned
int
i
;
unsigned
int
i
,
index
;
TRACE_
(
thread
)(
"teb_fls_data %p, flags %#x.
\n
"
,
teb_fls_data
,
flags
);
...
...
@@ -494,6 +501,29 @@ void WINAPI DECLSPEC_HOTPATCH RtlProcessFlsData( void *teb_fls_data, ULONG flags
if
(
flags
&
1
)
{
lock_fls_data
();
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fls
->
fls_data_chunks
);
++
i
)
{
if
(
!
fls
->
fls_data_chunks
[
i
]
||
!
fls_data
.
fls_callback_chunks
[
i
]
||
!
fls_data
.
fls_callback_chunks
[
i
]
->
count
)
continue
;
for
(
index
=
0
;
index
<
fls_chunk_size
(
i
);
++
index
)
{
PFLS_CALLBACK_FUNCTION
callback
=
fls_data
.
fls_callback_chunks
[
i
]
->
callbacks
[
index
].
callback
;
if
(
!
fls
->
fls_data_chunks
[
i
][
index
+
1
])
continue
;
if
(
callback
&&
callback
!=
(
void
*
)
~
(
ULONG_PTR
)
0
)
{
TRACE_
(
relay
)(
"Calling FLS callback %p, arg %p.
\n
"
,
callback
,
fls
->
fls_data_chunks
[
i
][
index
+
1
]);
callback
(
fls
->
fls_data_chunks
[
i
][
index
+
1
]
);
}
fls
->
fls_data_chunks
[
i
][
index
+
1
]
=
NULL
;
}
}
/* Not using RemoveEntryList() as Windows does not zero list entry here. */
fls
->
fls_list_entry
.
Flink
->
Blink
=
fls
->
fls_list_entry
.
Blink
;
fls
->
fls_list_entry
.
Blink
->
Flink
=
fls
->
fls_list_entry
.
Flink
;
...
...
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