/* * Helper functions for ntdll * * Copyright 2000 Juergen Schmied * Copyright 2010 Marcus Meissner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" #include <time.h> #include <math.h> #ifdef HAVE_SYS_UTSNAME_H #include <sys/utsname.h> #endif #include "ntstatus.h" #define WIN32_NO_STATUS #include "wine/library.h" #include "wine/debug.h" #include "ntdll_misc.h" #include "wmistr.h" #include "evntrace.h" #include "evntprov.h" WINE_DEFAULT_DEBUG_CHANNEL(ntdll); LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) { if (!oa) return "<null>"; return wine_dbg_sprintf( "{name=%s, attr=0x%08x, hRoot=%p, sd=%p}\n", debugstr_us(oa->ObjectName), oa->Attributes, oa->RootDirectory, oa->SecurityDescriptor ); } LPCSTR debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR)); } /********************************************************************* * wine_get_version (NTDLL.@) */ const char * CDECL NTDLL_wine_get_version(void) { return wine_get_version(); } /********************************************************************* * wine_get_build_id (NTDLL.@) */ const char * CDECL NTDLL_wine_get_build_id(void) { return wine_get_build_id(); } /********************************************************************* * wine_get_host_version (NTDLL.@) */ void CDECL NTDLL_wine_get_host_version( const char **sysname, const char **release ) { #ifdef HAVE_SYS_UTSNAME_H static struct utsname buf; static BOOL init_done; if (!init_done) { uname( &buf ); init_done = TRUE; } if (sysname) *sysname = buf.sysname; if (release) *release = buf.release; #else if (sysname) *sysname = ""; if (release) *release = ""; #endif } /********************************************************************* * abs (NTDLL.@) */ int CDECL NTDLL_abs( int i ) { return abs( i ); } /********************************************************************* * labs (NTDLL.@) */ LONG CDECL NTDLL_labs( LONG i ) { return labs( i ); } /********************************************************************* * atan (NTDLL.@) */ double CDECL NTDLL_atan( double d ) { return atan( d ); } /********************************************************************* * ceil (NTDLL.@) */ double CDECL NTDLL_ceil( double d ) { return ceil( d ); } /********************************************************************* * cos (NTDLL.@) */ double CDECL NTDLL_cos( double d ) { return cos( d ); } /********************************************************************* * fabs (NTDLL.@) */ double CDECL NTDLL_fabs( double d ) { return fabs( d ); } /********************************************************************* * floor (NTDLL.@) */ double CDECL NTDLL_floor( double d ) { return floor( d ); } /********************************************************************* * log (NTDLL.@) */ double CDECL NTDLL_log( double d ) { return log( d ); } /********************************************************************* * pow (NTDLL.@) */ double CDECL NTDLL_pow( double x, double y ) { return pow( x, y ); } /********************************************************************* * sin (NTDLL.@) */ double CDECL NTDLL_sin( double d ) { return sin( d ); } /********************************************************************* * sqrt (NTDLL.@) */ double CDECL NTDLL_sqrt( double d ) { return sqrt( d ); } /********************************************************************* * tan (NTDLL.@) */ double CDECL NTDLL_tan( double d ) { return tan( d ); } #if defined(__GNUC__) && defined(__i386__) #define FPU_DOUBLE(var) double var; \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : ) #define FPU_DOUBLES(var1,var2) double var1,var2; \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : ) /********************************************************************* * _CIcos (NTDLL.@) */ double CDECL NTDLL__CIcos(void) { FPU_DOUBLE(x); return NTDLL_cos(x); } /********************************************************************* * _CIlog (NTDLL.@) */ double CDECL NTDLL__CIlog(void) { FPU_DOUBLE(x); return NTDLL_log(x); } /********************************************************************* * _CIpow (NTDLL.@) */ double CDECL NTDLL__CIpow(void) { FPU_DOUBLES(x,y); return NTDLL_pow(x,y); } /********************************************************************* * _CIsin (NTDLL.@) */ double CDECL NTDLL__CIsin(void) { FPU_DOUBLE(x); return NTDLL_sin(x); } /********************************************************************* * _CIsqrt (NTDLL.@) */ double CDECL NTDLL__CIsqrt(void) { FPU_DOUBLE(x); return NTDLL_sqrt(x); } /********************************************************************* * _ftol (NTDLL.@) */ LONGLONG CDECL NTDLL__ftol(void) { FPU_DOUBLE(x); return (LONGLONG)x; } #endif /* defined(__GNUC__) && defined(__i386__) */ static void NTDLL_mergesort( void *arr, void *barr, size_t elemsize, int(__cdecl *compar)(const void *, const void *), size_t left, size_t right ) { if(right>left) { size_t i, j, k, m; m=left+(right-left)/2; NTDLL_mergesort( arr, barr, elemsize, compar, left, m); NTDLL_mergesort( arr, barr, elemsize, compar, m+1, right); #define X(a,i) ((char*)a+elemsize*(i)) for (k=left, i=left, j=m+1; i<=m && j<=right; k++) { if (compar(X(arr, i), X(arr,j)) <= 0) { memcpy(X(barr,k), X(arr, i), elemsize); i++; } else { memcpy(X(barr,k), X(arr, j), elemsize); j++; } } if (i<=m) memcpy(X(barr,k), X(arr,i), (m-i+1)*elemsize); else memcpy(X(barr,k), X(arr,j), (right-j+1)*elemsize); memcpy(X(arr, left), X(barr, left), (right-left+1)*elemsize); } #undef X } /********************************************************************* * qsort (NTDLL.@) */ void __cdecl NTDLL_qsort( void *base, size_t nmemb, size_t size, int(__cdecl *compar)(const void *, const void *) ) { void *secondarr; if (nmemb < 2 || size == 0) return; secondarr = RtlAllocateHeap (GetProcessHeap(), 0, nmemb*size); NTDLL_mergesort( base, secondarr, size, compar, 0, nmemb-1 ); RtlFreeHeap (GetProcessHeap(),0, secondarr); } /********************************************************************* * bsearch (NTDLL.@) */ void * __cdecl NTDLL_bsearch( const void *key, const void *base, size_t nmemb, size_t size, int (__cdecl *compar)(const void *, const void *) ) { ssize_t min = 0; ssize_t max = nmemb - 1; while (min <= max) { ssize_t cursor = min + (max - min) / 2; int ret = compar(key,(const char *)base+(cursor*size)); if (!ret) return (char*)base+(cursor*size); if (ret < 0) max = cursor - 1; else min = cursor + 1; } return NULL; } /********************************************************************* * _lfind (NTDLL.@) */ void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb, size_t size, int(__cdecl *compar)(const void *, const void *) ) { size_t i, n = *nmemb; for (i=0;i<n;i++) if (!compar(key,(char*)base+(size*i))) return (char*)base+(size*i); return NULL; } /****************************************************************************** * WinSqmEndSession (NTDLL.@) */ NTSTATUS WINAPI WinSqmEndSession(HANDLE session) { FIXME("(%p): stub\n", session); return STATUS_NOT_IMPLEMENTED; } /********************************************************************* * WinSqmIsOptedIn (NTDLL.@) */ BOOL WINAPI WinSqmIsOptedIn(void) { FIXME("(): stub\n"); return FALSE; } /****************************************************************************** * WinSqmStartSession (NTDLL.@) */ HANDLE WINAPI WinSqmStartSession(GUID *sessionguid, DWORD sessionid, DWORD unknown1) { FIXME("(%p, 0x%x, 0x%x): stub\n", sessionguid, sessionid, unknown1); return INVALID_HANDLE_VALUE; } /****************************************************************************** * EtwEventRegister (NTDLL.@) */ ULONG WINAPI EtwEventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID context, PREGHANDLE handle ) { FIXME("(%s, %p, %p, %p) stub.\n", debugstr_guid(provider), callback, context, handle); *handle = 0xdeadbeef; return ERROR_SUCCESS; } /****************************************************************************** * EtwEventUnregister (NTDLL.@) */ ULONG WINAPI EtwEventUnregister( REGHANDLE handle ) { FIXME("(%s) stub.\n", wine_dbgstr_longlong(handle)); return ERROR_SUCCESS; } /********************************************************************* * EtwEventSetInformation (NTDLL.@) */ ULONG WINAPI EtwEventSetInformation( REGHANDLE handle, EVENT_INFO_CLASS class, void *info, ULONG length ) { FIXME("(%s, %u, %p, %u) stub\n", wine_dbgstr_longlong(handle), class, info, length); return ERROR_SUCCESS; } /****************************************************************************** * EtwRegisterTraceGuidsW (NTDLL.@) * * Register an event trace provider and the event trace classes that it uses * to generate events. * * PARAMS * RequestAddress [I] ControlCallback function * RequestContext [I] Optional provider-defined context * ControlGuid [I] GUID of the registering provider * GuidCount [I] Number of elements in the TraceGuidReg array * TraceGuidReg [I/O] Array of TRACE_GUID_REGISTRATION structures * MofImagePath [I] not supported, set to NULL * MofResourceName [I] not supported, set to NULL * RegistrationHandle [O] Provider's registration handle * * RETURNS * Success: ERROR_SUCCESS * Failure: System error code */ ULONG WINAPI EtwRegisterTraceGuidsW( WMIDPREQUEST RequestAddress, void *RequestContext, const GUID *ControlGuid, ULONG GuidCount, TRACE_GUID_REGISTRATION *TraceGuidReg, const WCHAR *MofImagePath, const WCHAR *MofResourceName, TRACEHANDLE *RegistrationHandle ) { FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_w(MofImagePath), debugstr_w(MofResourceName), RegistrationHandle); if (TraceGuidReg) { ULONG i; for (i = 0; i < GuidCount; i++) { FIXME(" register trace class %s\n", debugstr_guid(TraceGuidReg[i].Guid)); TraceGuidReg[i].RegHandle = (HANDLE)0xdeadbeef; } } *RegistrationHandle = (TRACEHANDLE)0xdeadbeef; return ERROR_SUCCESS; } /****************************************************************************** * EtwRegisterTraceGuidsA (NTDLL.@) */ ULONG WINAPI EtwRegisterTraceGuidsA( WMIDPREQUEST RequestAddress, void *RequestContext, const GUID *ControlGuid, ULONG GuidCount, TRACE_GUID_REGISTRATION *TraceGuidReg, const char *MofImagePath, const char *MofResourceName, TRACEHANDLE *RegistrationHandle ) { FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_a(MofImagePath), debugstr_a(MofResourceName), RegistrationHandle); return ERROR_SUCCESS; } /****************************************************************************** * EtwUnregisterTraceGuids (NTDLL.@) */ ULONG WINAPI EtwUnregisterTraceGuids( TRACEHANDLE RegistrationHandle ) { if (!RegistrationHandle) return ERROR_INVALID_PARAMETER; FIXME("%s: stub\n", wine_dbgstr_longlong(RegistrationHandle)); return ERROR_SUCCESS; } /****************************************************************************** * EtwEventEnabled (NTDLL.@) */ BOOLEAN WINAPI EtwEventEnabled( REGHANDLE handle, const EVENT_DESCRIPTOR *descriptor ) { FIXME("(%s, %p): stub\n", wine_dbgstr_longlong(handle), descriptor); return FALSE; } /****************************************************************************** * EtwEventWrite (NTDLL.@) */ ULONG WINAPI EtwEventWrite( REGHANDLE handle, const EVENT_DESCRIPTOR *descriptor, ULONG count, EVENT_DATA_DESCRIPTOR *data ) { FIXME("(%s, %p, %u, %p): stub\n", wine_dbgstr_longlong(handle), descriptor, count, data); return ERROR_SUCCESS; }