Why are we adding Wineisms to core binaries like kernel32? These functions
should be in NTDLL and not in kernel32, and they are badly written anyway.
Best regards,
Alex Ionescu
On Sat, Feb 28, 2015 at 10:46 AM, <akhaldi(a)svn.reactos.org> wrote:
  Author: akhaldi
 Date: Sat Feb 28 15:46:43 2015
 New Revision: 66500
 URL: 
http://svn.reactos.org/svn/reactos?rev=66500&view=rev
 Log:
 [KERNEL32_VISTA] Add and export InitOnceExecuteOnce(). CORE-9246
 Added:
     trunk/reactos/dll/win32/kernel32_vista/InitOnceExecuteOnce.c   (with
 props)
 Modified:
     trunk/reactos/dll/win32/kernel32_vista/CMakeLists.txt
     trunk/reactos/dll/win32/kernel32_vista/kernel32_vista.spec
 Modified: trunk/reactos/dll/win32/kernel32_vista/CMakeLists.txt
 URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32_vista/C…
 ==============================================================================
 --- trunk/reactos/dll/win32/kernel32_vista/CMakeLists.txt
  [iso-8859-1] (original)
 +++ trunk/reactos/dll/win32/kernel32_vista/CMakeLists.txt
  [iso-8859-1] Sat Feb 28 15:46:43 2015
 @@ -8,15 +8,11 @@
  list(APPEND SOURCE
      DllMain.c
      GetTickCount64.c
 +    InitOnceExecuteOnce.c
      ${CMAKE_CURRENT_BINARY_DIR}/kernel32_vista.def)
  add_library(kernel32_vista SHARED ${SOURCE})
  set_module_type(kernel32_vista win32dll HOTPATCHABLE ENTRYPOINT DllMain
 12)
 -add_importlibs(kernel32_vista kernel32)
 -
 -if(MSVC)
 -    add_importlibs(kernel32_vista ntdll)
 -endif()
 -
 +add_importlibs(kernel32_vista kernel32 ntdll)
  add_dependencies(kernel32_vista psdk)
  add_cd_file(TARGET kernel32_vista DESTINATION reactos/system32 FOR all)
 Added: trunk/reactos/dll/win32/kernel32_vista/InitOnceExecuteOnce.c
 URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32_vista/I…
 ==============================================================================
 --- trunk/reactos/dll/win32/kernel32_vista/InitOnceExecuteOnce.c
 (added)
 +++ trunk/reactos/dll/win32/kernel32_vista/InitOnceExecuteOnce.c
 [iso-8859-1] Sat Feb 28 15:46:43 2015
 @@ -0,0 +1,118 @@
 +
 +#include "k32_vista.h"
 +
 +#include <ndk/exfuncs.h>
 +#include <wine/config.h>
 +#include <wine/port.h>
 +
 +/* Taken from Wine ntdll/sync.c */
 +
 +HANDLE keyed_event = NULL;
 +
 +static DWORD WINAPI RtlRunOnceBeginInitialize( RTL_RUN_ONCE *once, ULONG
 flags, void **context )
 +{
 +    if (flags & RTL_RUN_ONCE_CHECK_ONLY)
 +    {
 +        ULONG_PTR val = (ULONG_PTR)once->Ptr;
 +
 +        if (flags & RTL_RUN_ONCE_ASYNC) return STATUS_INVALID_PARAMETER;
 +        if ((val & 3) != 2) return STATUS_UNSUCCESSFUL;
 +        if (context) *context = (void *)(val & ~3);
 +        return STATUS_SUCCESS;
 +    }
 +
 +    for (;;)
 +    {
 +        ULONG_PTR next, val = (ULONG_PTR)once->Ptr;
 +
 +        switch (val & 3)
 +        {
 +        case 0:  /* first time */
 +            if (!interlocked_cmpxchg_ptr( &once->Ptr,
 +                                          (flags & RTL_RUN_ONCE_ASYNC) ?
 (void *)3 : (void *)1, 0 ))
 +                return STATUS_PENDING;
 +            break;
 +
 +        case 1:  /* in progress, wait */
 +            if (flags & RTL_RUN_ONCE_ASYNC) return
 STATUS_INVALID_PARAMETER;
 +            next = val & ~3;
 +            if (interlocked_cmpxchg_ptr( &once->Ptr, (void
 *)((ULONG_PTR)&next | 1),
 +                                         (void *)val ) == (void *)val)
 +                NtWaitForKeyedEvent( keyed_event, &next, FALSE, NULL );
 +            break;
 +
 +        case 2:  /* done */
 +            if (context) *context = (void *)(val & ~3);
 +            return STATUS_SUCCESS;
 +
 +        case 3:  /* in progress, async */
 +            if (!(flags & RTL_RUN_ONCE_ASYNC)) return
 STATUS_INVALID_PARAMETER;
 +            return STATUS_PENDING;
 +        }
 +    }
 +}
 +
 +static DWORD WINAPI RtlpRunOnceComplete( RTL_RUN_ONCE *once, ULONG flags,
 void *context )
 +{
 +    if ((ULONG_PTR)context & 3) return STATUS_INVALID_PARAMETER;
 +
 +    if (flags & RTL_RUN_ONCE_INIT_FAILED)
 +    {
 +        if (context) return STATUS_INVALID_PARAMETER;
 +        if (flags & RTL_RUN_ONCE_ASYNC) return STATUS_INVALID_PARAMETER;
 +    }
 +    else context = (void *)((ULONG_PTR)context | 2);
 +
 +    for (;;)
 +    {
 +        ULONG_PTR val = (ULONG_PTR)once->Ptr;
 +
 +        switch (val & 3)
 +        {
 +        case 1:  /* in progress */
 +            if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val
 ) != (void *)val) break;
 +            val &= ~3;
 +            while (val)
 +            {
 +                ULONG_PTR next = *(ULONG_PTR *)val;
 +                NtReleaseKeyedEvent( keyed_event, (void *)val, FALSE,
 NULL );
 +                val = next;
 +            }
 +            return STATUS_SUCCESS;
 +
 +        case 3:  /* in progress, async */
 +            if (!(flags & RTL_RUN_ONCE_ASYNC)) return
 STATUS_INVALID_PARAMETER;
 +            if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val
 ) != (void *)val) break;
 +            return STATUS_SUCCESS;
 +
 +        default:
 +            return STATUS_UNSUCCESSFUL;
 +        }
 +    }
 +}
 +
 +static DWORD WINAPI RtlpRunOnceExecuteOnce( RTL_RUN_ONCE *once,
 PRTL_RUN_ONCE_INIT_FN func,
 +                                           void *param, void **context )
 +{
 +    DWORD ret = RtlRunOnceBeginInitialize( once, 0, context );
 +
 +    if (ret != STATUS_PENDING) return ret;
 +
 +    if (!func( once, param, context ))
 +    {
 +        RtlpRunOnceComplete( once, RTL_RUN_ONCE_INIT_FAILED, NULL );
 +        return STATUS_UNSUCCESSFUL;
 +    }
 +
 +    return RtlpRunOnceComplete( once, 0, context ? *context : NULL );
 +}
 +
 +/* Taken from Wine kernel32/sync.c */
 +
 +/*
 + * @implemented
 + */
 +BOOL NTAPI InitOnceExecuteOnce( INIT_ONCE *once, PINIT_ONCE_FN func, void
 *param, void **context )
 +{
 +    return !RtlpRunOnceExecuteOnce( once, (PRTL_RUN_ONCE_INIT_FN)func,
 param, context );
 +}
 Propchange: trunk/reactos/dll/win32/kernel32_vista/InitOnceExecuteOnce.c
 ------------------------------------------------------------------------------
     svn:eol-style = native
 Modified: trunk/reactos/dll/win32/kernel32_vista/kernel32_vista.spec
 URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32_vista/k…
 ==============================================================================
 --- trunk/reactos/dll/win32/kernel32_vista/kernel32_vista.spec
 [iso-8859-1] (original)
 +++ trunk/reactos/dll/win32/kernel32_vista/kernel32_vista.spec
 [iso-8859-1] Sat Feb 28 15:46:43 2015
 @@ -1,2 +1,3 @@
  @ stdcall -ret64 GetTickCount64()
 +@ stdcall InitOnceExecuteOnce(ptr ptr ptr ptr)