windows.applicationmodel/tests: Use PathRemoveFileSpecW() instead of PathCchRemoveFil...
[wine.git] / dlls / ntdll / misc.c
bloba658d94a7e850a21b3b9d1a05e3cf33bef4bf974
1 /*
2 * Helper functions for ntdll
4 * Copyright 2000 Juergen Schmied
5 * Copyright 2010 Marcus Meissner
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <time.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "wine/debug.h"
27 #include "ntdll_misc.h"
28 #include "wmistr.h"
29 #include "evntrace.h"
30 #include "evntprov.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
34 LPCSTR debugstr_us( const UNICODE_STRING *us )
36 if (!us) return "<null>";
37 return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
40 static int __cdecl compare_wrapper(void *ctx, const void *e1, const void *e2)
42 int (__cdecl *compare)( const void *, const void * ) = ctx;
43 return compare( e1, e2 );
46 static inline void swap(char *l, char *r, size_t size)
48 char tmp;
50 while(size--) {
51 tmp = *l;
52 *l++ = *r;
53 *r++ = tmp;
57 static void small_sort(void *base, size_t nmemb, size_t size,
58 int (CDECL *compar)(void *, const void *, const void *), void *context)
60 size_t e, i;
61 char *max, *p;
63 for(e=nmemb; e>1; e--) {
64 max = base;
65 for(i=1; i<e; i++) {
66 p = (char*)base + i*size;
67 if(compar(context, p, max) > 0)
68 max = p;
71 if(p != max)
72 swap(p, max, size);
76 static void quick_sort(void *base, size_t nmemb, size_t size,
77 int (CDECL *compar)(void *, const void *, const void *), void *context)
79 size_t stack_lo[8*sizeof(size_t)], stack_hi[8*sizeof(size_t)];
80 size_t beg, end, lo, hi, med;
81 int stack_pos;
83 stack_pos = 0;
84 stack_lo[stack_pos] = 0;
85 stack_hi[stack_pos] = nmemb-1;
87 #define X(i) ((char*)base+size*(i))
88 while(stack_pos >= 0) {
89 beg = stack_lo[stack_pos];
90 end = stack_hi[stack_pos--];
92 if(end-beg < 8) {
93 small_sort(X(beg), end-beg+1, size, compar, context);
94 continue;
97 lo = beg;
98 hi = end;
99 med = lo + (hi-lo+1)/2;
100 if(compar(context, X(lo), X(med)) > 0)
101 swap(X(lo), X(med), size);
102 if(compar(context, X(lo), X(hi)) > 0)
103 swap(X(lo), X(hi), size);
104 if(compar(context, X(med), X(hi)) > 0)
105 swap(X(med), X(hi), size);
107 lo++;
108 hi--;
109 while(1) {
110 while(lo <= hi) {
111 if(lo!=med && compar(context, X(lo), X(med))>0)
112 break;
113 lo++;
116 while(med != hi) {
117 if(compar(context, X(hi), X(med)) <= 0)
118 break;
119 hi--;
122 if(hi < lo)
123 break;
125 swap(X(lo), X(hi), size);
126 if(hi == med)
127 med = lo;
128 lo++;
129 hi--;
132 while(hi > beg) {
133 if(hi!=med && compar(context, X(hi), X(med))!=0)
134 break;
135 hi--;
138 if(hi-beg >= end-lo) {
139 stack_lo[++stack_pos] = beg;
140 stack_hi[stack_pos] = hi;
141 stack_lo[++stack_pos] = lo;
142 stack_hi[stack_pos] = end;
143 }else {
144 stack_lo[++stack_pos] = lo;
145 stack_hi[stack_pos] = end;
146 stack_lo[++stack_pos] = beg;
147 stack_hi[stack_pos] = hi;
150 #undef X
154 /*********************************************************************
155 * qsort_s (NTDLL.@)
157 void __cdecl qsort_s( void *base, size_t nmemb, size_t size,
158 int (__cdecl *compar)(void *, const void *, const void *), void *context )
160 const size_t total_size = nmemb * size;
162 if (!base && nmemb) return;
163 if (!size) return;
164 if (!compar) return;
165 if (total_size / size != nmemb) return;
166 if (nmemb < 2) return;
167 quick_sort( base, nmemb, size, compar, context );
171 /*********************************************************************
172 * qsort (NTDLL.@)
174 void __cdecl qsort( void *base, size_t nmemb, size_t size,
175 int (__cdecl *compar)(const void *, const void *) )
177 qsort_s( base, nmemb, size, compare_wrapper, compar );
181 /*********************************************************************
182 * bsearch_s (NTDLL.@)
184 void * __cdecl bsearch_s( const void *key, const void *base, size_t nmemb, size_t size,
185 int (__cdecl *compare)(void *, const void *, const void *), void *ctx )
187 ssize_t min = 0;
188 ssize_t max = nmemb - 1;
190 if (!size) return NULL;
191 if (!compare) return NULL;
193 while (min <= max)
195 ssize_t cursor = min + (max - min) / 2;
196 int ret = compare(ctx, key,(const char *)base+(cursor*size));
197 if (!ret)
198 return (char*)base+(cursor*size);
199 if (ret < 0)
200 max = cursor - 1;
201 else
202 min = cursor + 1;
204 return NULL;
208 /*********************************************************************
209 * bsearch (NTDLL.@)
211 void * __cdecl bsearch( const void *key, const void *base, size_t nmemb,
212 size_t size, int (__cdecl *compar)(const void *, const void *) )
214 return bsearch_s( key, base, nmemb, size, compare_wrapper, compar );
219 /*********************************************************************
220 * _lfind (NTDLL.@)
222 void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb,
223 size_t size, int(__cdecl *compar)(const void *, const void *) )
225 size_t i, n = *nmemb;
227 for (i=0;i<n;i++)
228 if (!compar(key,(char*)base+(size*i)))
229 return (char*)base+(size*i);
230 return NULL;
233 /******************************************************************************
234 * WinSqmEndSession (NTDLL.@)
236 NTSTATUS WINAPI WinSqmEndSession(HANDLE session)
238 FIXME("(%p): stub\n", session);
239 return STATUS_NOT_IMPLEMENTED;
242 /*********************************************************************
243 * WinSqmIncrementDWORD (NTDLL.@)
245 void WINAPI WinSqmIncrementDWORD(DWORD unk1, DWORD unk2, DWORD unk3)
247 FIXME("(%ld, %ld, %ld): stub\n", unk1, unk2, unk3);
250 /*********************************************************************
251 * WinSqmIsOptedIn (NTDLL.@)
253 BOOL WINAPI WinSqmIsOptedIn(void)
255 FIXME("(): stub\n");
256 return FALSE;
259 /******************************************************************************
260 * WinSqmStartSession (NTDLL.@)
262 HANDLE WINAPI WinSqmStartSession(GUID *sessionguid, DWORD sessionid, DWORD unknown1)
264 FIXME("(%p, 0x%lx, 0x%lx): stub\n", sessionguid, sessionid, unknown1);
265 return INVALID_HANDLE_VALUE;
268 /***********************************************************************
269 * WinSqmSetDWORD (NTDLL.@)
271 void WINAPI WinSqmSetDWORD(HANDLE session, DWORD datapoint_id, DWORD datapoint_value)
273 FIXME("(%p, %ld, %ld): stub\n", session, datapoint_id, datapoint_value);
276 /******************************************************************************
277 * EtwEventActivityIdControl (NTDLL.@)
279 ULONG WINAPI EtwEventActivityIdControl(ULONG code, GUID *guid)
281 static int once;
283 if (!once++) FIXME("0x%lx, %p: stub\n", code, guid);
284 return ERROR_SUCCESS;
287 /******************************************************************************
288 * EtwEventProviderEnabled (NTDLL.@)
290 BOOLEAN WINAPI EtwEventProviderEnabled( REGHANDLE handle, UCHAR level, ULONGLONG keyword )
292 WARN("%s, %u, %s: stub\n", wine_dbgstr_longlong(handle), level, wine_dbgstr_longlong(keyword));
293 return FALSE;
296 /******************************************************************************
297 * EtwEventRegister (NTDLL.@)
299 ULONG WINAPI EtwEventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID context,
300 PREGHANDLE handle )
302 WARN("(%s, %p, %p, %p) stub.\n", debugstr_guid(provider), callback, context, handle);
304 if (!handle) return ERROR_INVALID_PARAMETER;
306 *handle = 0xdeadbeef;
307 return ERROR_SUCCESS;
310 /******************************************************************************
311 * EtwEventUnregister (NTDLL.@)
313 ULONG WINAPI EtwEventUnregister( REGHANDLE handle )
315 WARN("(%s) stub.\n", wine_dbgstr_longlong(handle));
316 return ERROR_SUCCESS;
319 /*********************************************************************
320 * EtwEventSetInformation (NTDLL.@)
322 ULONG WINAPI EtwEventSetInformation( REGHANDLE handle, EVENT_INFO_CLASS class, void *info,
323 ULONG length )
325 FIXME("(%s, %u, %p, %lu) stub\n", wine_dbgstr_longlong(handle), class, info, length);
326 return ERROR_SUCCESS;
329 /******************************************************************************
330 * EtwEventWriteString (NTDLL.@)
332 ULONG WINAPI EtwEventWriteString( REGHANDLE handle, UCHAR level, ULONGLONG keyword, PCWSTR string )
334 FIXME("%s, %u, %s, %s: stub\n", wine_dbgstr_longlong(handle), level,
335 wine_dbgstr_longlong(keyword), debugstr_w(string));
336 return ERROR_SUCCESS;
339 /******************************************************************************
340 * EtwEventWriteTransfer (NTDLL.@)
342 ULONG WINAPI EtwEventWriteTransfer( REGHANDLE handle, PCEVENT_DESCRIPTOR descriptor, LPCGUID activity,
343 LPCGUID related, ULONG count, PEVENT_DATA_DESCRIPTOR data )
345 FIXME("%s, %p, %s, %s, %lu, %p: stub\n", wine_dbgstr_longlong(handle), descriptor,
346 debugstr_guid(activity), debugstr_guid(related), count, data);
347 return ERROR_SUCCESS;
350 /******************************************************************************
351 * EtwRegisterTraceGuidsW (NTDLL.@)
353 * Register an event trace provider and the event trace classes that it uses
354 * to generate events.
356 * PARAMS
357 * RequestAddress [I] ControlCallback function
358 * RequestContext [I] Optional provider-defined context
359 * ControlGuid [I] GUID of the registering provider
360 * GuidCount [I] Number of elements in the TraceGuidReg array
361 * TraceGuidReg [I/O] Array of TRACE_GUID_REGISTRATION structures
362 * MofImagePath [I] not supported, set to NULL
363 * MofResourceName [I] not supported, set to NULL
364 * RegistrationHandle [O] Provider's registration handle
366 * RETURNS
367 * Success: ERROR_SUCCESS
368 * Failure: System error code
370 ULONG WINAPI EtwRegisterTraceGuidsW( WMIDPREQUEST RequestAddress,
371 void *RequestContext, const GUID *ControlGuid, ULONG GuidCount,
372 TRACE_GUID_REGISTRATION *TraceGuidReg, const WCHAR *MofImagePath,
373 const WCHAR *MofResourceName, TRACEHANDLE *RegistrationHandle )
375 WARN("(%p, %p, %s, %lu, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext,
376 debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_w(MofImagePath),
377 debugstr_w(MofResourceName), RegistrationHandle);
379 if (TraceGuidReg)
381 ULONG i;
382 for (i = 0; i < GuidCount; i++)
384 FIXME(" register trace class %s\n", debugstr_guid(TraceGuidReg[i].Guid));
385 TraceGuidReg[i].RegHandle = (HANDLE)0xdeadbeef;
388 *RegistrationHandle = (TRACEHANDLE)0xdeadbeef;
389 return ERROR_SUCCESS;
392 /******************************************************************************
393 * EtwRegisterTraceGuidsA (NTDLL.@)
395 ULONG WINAPI EtwRegisterTraceGuidsA( WMIDPREQUEST RequestAddress,
396 void *RequestContext, const GUID *ControlGuid, ULONG GuidCount,
397 TRACE_GUID_REGISTRATION *TraceGuidReg, const char *MofImagePath,
398 const char *MofResourceName, TRACEHANDLE *RegistrationHandle )
400 WARN("(%p, %p, %s, %lu, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext,
401 debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_a(MofImagePath),
402 debugstr_a(MofResourceName), RegistrationHandle);
403 return ERROR_SUCCESS;
406 /******************************************************************************
407 * EtwUnregisterTraceGuids (NTDLL.@)
409 ULONG WINAPI EtwUnregisterTraceGuids( TRACEHANDLE RegistrationHandle )
411 if (!RegistrationHandle)
412 return ERROR_INVALID_PARAMETER;
414 WARN("%s: stub\n", wine_dbgstr_longlong(RegistrationHandle));
415 return ERROR_SUCCESS;
418 /******************************************************************************
419 * EtwEventEnabled (NTDLL.@)
421 BOOLEAN WINAPI EtwEventEnabled( REGHANDLE handle, const EVENT_DESCRIPTOR *descriptor )
423 WARN("(%s, %p): stub\n", wine_dbgstr_longlong(handle), descriptor);
424 return FALSE;
427 /******************************************************************************
428 * EtwEventWrite (NTDLL.@)
430 ULONG WINAPI EtwEventWrite( REGHANDLE handle, const EVENT_DESCRIPTOR *descriptor, ULONG count,
431 EVENT_DATA_DESCRIPTOR *data )
433 FIXME("(%s, %p, %lu, %p): stub\n", wine_dbgstr_longlong(handle), descriptor, count, data);
434 return ERROR_SUCCESS;
437 /******************************************************************************
438 * EtwGetTraceEnableFlags (NTDLL.@)
440 ULONG WINAPI EtwGetTraceEnableFlags( TRACEHANDLE handle )
442 FIXME("(%s) stub\n", wine_dbgstr_longlong(handle));
443 return 0;
446 /******************************************************************************
447 * EtwGetTraceEnableLevel (NTDLL.@)
449 UCHAR WINAPI EtwGetTraceEnableLevel( TRACEHANDLE handle )
451 FIXME("(%s) stub\n", wine_dbgstr_longlong(handle));
452 return TRACE_LEVEL_VERBOSE;
455 /******************************************************************************
456 * EtwGetTraceLoggerHandle (NTDLL.@)
458 TRACEHANDLE WINAPI EtwGetTraceLoggerHandle( PVOID buf )
460 FIXME("(%p) stub\n", buf);
461 return INVALID_PROCESSTRACE_HANDLE;
464 /******************************************************************************
465 * EtwLogTraceEvent (NTDLL.@)
467 ULONG WINAPI EtwLogTraceEvent( TRACEHANDLE SessionHandle, PEVENT_TRACE_HEADER EventTrace )
469 FIXME("%s %p\n", wine_dbgstr_longlong(SessionHandle), EventTrace);
470 return ERROR_CALL_NOT_IMPLEMENTED;
473 /******************************************************************************
474 * EtwTraceMessageVa (NTDLL.@)
476 ULONG WINAPI EtwTraceMessageVa( TRACEHANDLE handle, ULONG flags, LPGUID guid, USHORT number,
477 va_list args )
479 FIXME("(%s %lx %s %d) : stub\n", wine_dbgstr_longlong(handle), flags, debugstr_guid(guid), number);
480 return ERROR_SUCCESS;
483 /******************************************************************************
484 * EtwTraceMessage (NTDLL.@)
486 ULONG WINAPIV EtwTraceMessage( TRACEHANDLE handle, ULONG flags, LPGUID guid, /*USHORT*/ ULONG number, ... )
488 va_list valist;
489 ULONG ret;
491 va_start( valist, number );
492 ret = EtwTraceMessageVa( handle, flags, guid, number, valist );
493 va_end( valist );
494 return ret;