Implementing Fiber-Local Storage Callbacks: sharing data between DLLs

André Hentschel nerv at dawncrow.de
Fri Sep 2 07:27:04 CDT 2016


Am 02.09.2016 um 14:01 schrieb John Sheu:
> On Thu, Sep 1, 2016 at 8:08 PM, Alexandre Julliard <julliard at winehq.org> wrote:
>> John Sheu <sheu at google.com> writes:
>>
>>> The question is how we manage this.  One option is to introduce
>>> additional function call entry points to either ntdll or kernel32,
>>> called by the other, to manages FLS lifetime.  I see though that the
>>> list of entry points is pretty tightly defined in the .spec files for
>>> each DLL, and the convention may be (correct me if I'm wrong) not to
>>> introduce "weird" private Wine-only APIs to the list.  The other
>>> option is to use some internal structs, pointed to by the PEB and TEB
>>> structures.  That's the approach I'd like to go with.
>>>
>>> My proposal would be:
>>>
>>> 1.  Define a common struct to hold the FLS data array, that would be:
>>>       struct FlsSlots {
>>>         LIST_ENTRY fls_link;
>>>         void fls_slots[SLOT_COUNT];
>>>       };
>>> 2.  TEB.FlsSlots right now is a void** member; make this a struct
>>> FlsSlots* member instead.
>>> 3.  Link the FlsSlots struct into PEB.FlsListHead.
>>>
>>> This would require that struct FlsSlots be defined somewhere -- either
>>> in wine/include, as mentioned, or in <include/winternl.h>.  Since it
>>> isn't declared publicly in the win32 API, even as an opaque pointer --
>>> I'm leaning toward the former.  Maybe in "wine/include/fls.h" ?
>>
>> In general adding private headers is reserved for things that are used
>> across a wide range of modules, and cannot possibly be done through the
>> Windows API.
>>
>> If you really have to share a private structure like this, you can
>> duplicate the definition, but that should only be a last resort. In
>> general if there's no equivalent structure on Windows, it means that
>> it's supposed to work in a different way.
>>
>> I'll note that recent Windows versions export functions like RtlFlsAlloc
>> and RtlFlsFree, which probably means it should all be handled inside
>> ntdll.  Of course it would first need some tests to find out what these
>> functions do.
> 
> I'm enthusiastic about putting it in <include/winternl.h>, since it
> isn't a known Windows structure -- I don't doubt though that there's
> an equivalent structure in Windows; we just don't know about it.  But
> duplicating the definition is just.. ick.  So I'd just like to put it
> in a private header, or perhaps in the Wine-private section of
> winternl.h (and that is seeming like the better solution at the
> moment).
> 
> Of course the optimal solution is to implement the Windows APIs.  In
> ntdll I'm aware of three FLS-related functions: RtlFlsAlloc,
> RtlFlsFree, and RtlProcessFlsData.  Unfortunately they are all three
> undocumented, even without information on their function signatures.
> So writing conformance tests for these is outside the scope my
> experience (fuzz testing maybe?).  If you have some advice on how such
> testing is usually done for Wine, I'd be glad to hear it.  Otherwise I
> think I'll just go with sticking it in the #ifdef __WINESRC__ section
> of winternl.h
> 
> -John Sheu

The RtlFls* way seems the way to go...
I found some hints on the signature and more in this file (from Google? from VMWare?):
https://github.com/DynamoRIO/dynamorio/blob/master/core/win32/drwinapi/ntdll_redir.c




More information about the wine-devel mailing list