Removed winmm from import list.
[wine/multimedia.git] / dlls / ntdll / rtl.c
blob5a0e46f28e2101e9d962c02d0aec8c88a12c1f4d
1 /*
2 * NT basis DLL
3 *
4 * This file contains the Rtl* API functions. These should be implementable.
5 *
6 * Copyright 1996-1998 Marcus Meissner
7 * 1999 Alex Korobka
8 */
10 #include <stdlib.h>
11 #include <string.h>
12 #include "heap.h"
13 #include "debugtools.h"
14 #include "windef.h"
15 #include "wingdi.h"
16 #include "winuser.h"
17 #include "winerror.h"
18 #include "stackframe.h"
20 #include "ntddk.h"
21 #include "winreg.h"
23 DEFAULT_DEBUG_CHANNEL(ntdll)
27 * resource functions
30 /***********************************************************************
31 * RtlInitializeResource (NTDLL.409)
33 * xxxResource() functions implement multiple-reader-single-writer lock.
34 * The code is based on information published in WDJ January 1999 issue.
36 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
38 if( rwl )
40 rwl->iNumberActive = 0;
41 rwl->uExclusiveWaiters = 0;
42 rwl->uSharedWaiters = 0;
43 rwl->hOwningThreadId = 0;
44 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
45 InitializeCriticalSection( &rwl->rtlCS );
46 rwl->hExclusiveReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
47 rwl->hSharedReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
52 /***********************************************************************
53 * RtlDeleteResource (NTDLL.330)
55 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
57 if( rwl )
59 EnterCriticalSection( &rwl->rtlCS );
60 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
61 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl );
62 rwl->hOwningThreadId = 0;
63 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
64 rwl->iNumberActive = 0;
65 CloseHandle( rwl->hExclusiveReleaseSemaphore );
66 CloseHandle( rwl->hSharedReleaseSemaphore );
67 LeaveCriticalSection( &rwl->rtlCS );
68 DeleteCriticalSection( &rwl->rtlCS );
73 /***********************************************************************
74 * RtlAcquireResourceExclusive (NTDLL.256)
76 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
78 BYTE retVal = 0;
79 if( !rwl ) return 0;
81 start:
82 EnterCriticalSection( &rwl->rtlCS );
83 if( rwl->iNumberActive == 0 ) /* lock is free */
85 rwl->iNumberActive = -1;
86 retVal = 1;
88 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
90 if( rwl->hOwningThreadId == GetCurrentThreadId() )
92 retVal = 1;
93 rwl->iNumberActive--;
94 goto done;
96 wait:
97 if( fWait )
99 rwl->uExclusiveWaiters++;
101 LeaveCriticalSection( &rwl->rtlCS );
102 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
103 goto done;
104 goto start; /* restart the acquisition to avoid deadlocks */
107 else /* one or more shared locks are in progress */
108 if( fWait )
109 goto wait;
111 if( retVal == 1 )
112 rwl->hOwningThreadId = GetCurrentThreadId();
113 done:
114 LeaveCriticalSection( &rwl->rtlCS );
115 return retVal;
118 /***********************************************************************
119 * RtlAcquireResourceShared (NTDLL.257)
121 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
123 DWORD dwWait = WAIT_FAILED;
124 BYTE retVal = 0;
125 if( !rwl ) return 0;
127 start:
128 EnterCriticalSection( &rwl->rtlCS );
129 if( rwl->iNumberActive < 0 )
131 if( rwl->hOwningThreadId == GetCurrentThreadId() )
133 rwl->iNumberActive--;
134 retVal = 1;
135 goto done;
138 if( fWait )
140 rwl->uSharedWaiters++;
141 LeaveCriticalSection( &rwl->rtlCS );
142 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
143 goto done;
144 goto start;
147 else
149 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
150 rwl->iNumberActive++;
151 retVal = 1;
153 done:
154 LeaveCriticalSection( &rwl->rtlCS );
155 return retVal;
159 /***********************************************************************
160 * RtlReleaseResource (NTDLL.471)
162 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
164 EnterCriticalSection( &rwl->rtlCS );
166 if( rwl->iNumberActive > 0 ) /* have one or more readers */
168 if( --rwl->iNumberActive == 0 )
170 if( rwl->uExclusiveWaiters )
172 wake_exclusive:
173 rwl->uExclusiveWaiters--;
174 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
178 else
179 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
181 if( ++rwl->iNumberActive == 0 )
183 rwl->hOwningThreadId = 0;
184 if( rwl->uExclusiveWaiters )
185 goto wake_exclusive;
186 else
187 if( rwl->uSharedWaiters )
189 UINT n = rwl->uSharedWaiters;
190 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
191 * all queued readers have done their thing */
192 rwl->uSharedWaiters = 0;
193 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
197 LeaveCriticalSection( &rwl->rtlCS );
201 /***********************************************************************
202 * RtlDumpResource (NTDLL.340)
204 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
206 if( rwl )
208 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
209 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
210 if( rwl->iNumberActive )
211 MESSAGE("\towner thread = %08x\n", rwl->hOwningThreadId );
216 * heap functions
219 /******************************************************************************
220 * RtlCreateHeap [NTDLL]
222 HANDLE WINAPI RtlCreateHeap(
223 ULONG Flags,
224 PVOID BaseAddress,
225 ULONG SizeToReserve,
226 ULONG SizeToCommit,
227 PVOID Unknown,
228 PRTL_HEAP_DEFINITION Definition)
230 FIXME("(0x%08lx, %p, 0x%08lx, 0x%08lx, %p, %p) semi-stub\n",
231 Flags, BaseAddress, SizeToReserve, SizeToCommit, Unknown, Definition);
233 return HeapCreate ( Flags, SizeToCommit, SizeToReserve);
236 /******************************************************************************
237 * RtlAllocateHeap [NTDLL]
239 PVOID WINAPI RtlAllocateHeap(
240 HANDLE Heap,
241 ULONG Flags,
242 ULONG Size)
244 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
245 Heap, Flags, Size);
246 return HeapAlloc(Heap, Flags, Size);
249 /******************************************************************************
250 * RtlFreeHeap [NTDLL]
252 BOOLEAN WINAPI RtlFreeHeap(
253 HANDLE Heap,
254 ULONG Flags,
255 PVOID Address)
257 TRACE("(0x%08x, 0x%08lx, %p) semi stub\n",
258 Heap, Flags, Address);
259 return HeapFree(Heap, Flags, Address);
262 /******************************************************************************
263 * RtlDestroyHeap [NTDLL]
265 * FIXME: prototype guessed
267 BOOLEAN WINAPI RtlDestroyHeap(
268 HANDLE Heap)
270 TRACE("(0x%08x) semi stub\n", Heap);
271 return HeapDestroy(Heap);
275 * misc functions
278 /******************************************************************************
279 * DbgPrint [NTDLL]
281 void WINAPIV DbgPrint(LPCSTR fmt, ...) {
282 char buf[512];
283 va_list args;
285 va_start(args, fmt);
286 wvsprintfA(buf,fmt, args);
287 va_end(args);
289 MESSAGE("DbgPrint says: %s",buf);
290 /* hmm, raise exception? */
293 /******************************************************************************
294 * RtlAcquirePebLock [NTDLL]
296 VOID WINAPI RtlAcquirePebLock(void) {
297 FIXME("()\n");
298 /* enter critical section ? */
301 /******************************************************************************
302 * RtlReleasePebLock [NTDLL]
304 VOID WINAPI RtlReleasePebLock(void) {
305 FIXME("()\n");
306 /* leave critical section ? */
309 /******************************************************************************
310 * RtlIntegerToChar [NTDLL]
312 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
313 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
314 return 0;
316 /******************************************************************************
317 * RtlSetEnvironmentVariable [NTDLL]
319 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
320 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
321 return 0;
324 /******************************************************************************
325 * RtlNewSecurityObject [NTDLL]
327 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
328 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
329 return 0;
332 /******************************************************************************
333 * RtlDeleteSecurityObject [NTDLL]
335 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
336 FIXME("(0x%08lx),stub!\n",x1);
337 return 0;
340 /**************************************************************************
341 * RtlNormalizeProcessParams [NTDLL.441]
343 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
345 FIXME("(%p), stub\n",x);
346 return x;
349 /**************************************************************************
350 * RtlGetNtProductType [NTDLL.390]
352 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
354 FIXME("(%p): stub\n", type);
355 *type=3; /* dunno. 1 for client, 3 for server? */
356 return 1;
359 /**************************************************************************
360 * NTDLL_chkstk [NTDLL.862]
361 * NTDLL_alloca_probe [NTDLL.861]
362 * Glorified "enter xxxx".
364 void WINAPI NTDLL_chkstk( CONTEXT86 *context )
366 ESP_reg(context) -= EAX_reg(context);
368 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
370 ESP_reg(context) -= EAX_reg(context);
373 /******************************************************************************
374 * RtlExtendedLargeIntegerDivide [NTDLL.359]
376 INT WINAPI RtlExtendedLargeIntegerDivide(
377 LARGE_INTEGER dividend,
378 DWORD divisor,
379 LPDWORD rest
381 #if SIZEOF_LONG_LONG==8
382 long long x1 = *(long long*)&dividend;
384 if (*rest)
385 *rest = x1 % divisor;
386 return x1/divisor;
387 #else
388 FIXME("((%ld<<32)+%ld,%ld,%p), implement this using normal integer arithmetic!\n",
389 dividend.s.HighPart,dividend.s.LowPart,divisor,rest);
390 return 0;
391 #endif
394 /******************************************************************************
395 * RtlExtendedIntegerMultiply [NTDLL.359]
396 * Note: This even works, since gcc returns 64bit values in eax/edx just like
397 * the caller expects. However... The relay code won't grok this I think.
399 LARGE_INTEGER WINAPI RtlExtendedIntegerMultiply(
400 LARGE_INTEGER factor1,
401 INT factor2)
403 #if SIZEOF_LONG_LONG==8
404 long long result = (*(long long*)&factor1) * factor2;
405 return (*(LARGE_INTEGER*)&result);
406 #else
407 LARGE_INTEGER result;
408 result.s.HighPart = 0;
409 result.s.LowPart = 0;
410 FIXME("((%ld<<32)+%ld,%d), implement this using normal integer arithmetic!\n",
411 factor1.s.HighPart,factor1.s.LowPart,factor2);
412 return result;
413 #endif
416 /**************************************************************************
417 * RtlDosPathNameToNtPathName_U [NTDLL.338]
419 * FIXME: convert to UNC or whatever is expected here
421 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
422 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
424 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
426 FIXME("(%s,%p,%08lx,%08lx)\n",fromA,us,x2,x3);
427 if (us)
428 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
429 return TRUE;
432 /******************************************************************************
433 * RtlCreateEnvironment [NTDLL]
435 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
436 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
437 return 0;
441 /******************************************************************************
442 * RtlDestroyEnvironment [NTDLL]
444 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
445 FIXME("(0x%08lx),stub!\n",x);
446 return 0;
449 /******************************************************************************
450 * RtlQueryEnvironmentVariable_U [NTDLL]
452 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
453 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
454 return 0;
456 /******************************************************************************
457 * RtlInitializeGenericTable [NTDLL]
459 DWORD WINAPI RtlInitializeGenericTable(void)
461 FIXME("\n");
462 return 0;
465 /******************************************************************************
466 * RtlInitializeBitMap [NTDLL]
469 NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
471 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
472 return 0;
475 /******************************************************************************
476 * RtlSetBits [NTDLL]
479 NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
481 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
482 return 0;
485 /******************************************************************************
486 * RtlFindClearBits [NTDLL]
489 NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
491 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
492 return 0;
495 /******************************************************************************
496 * RtlClearBits [NTDLL]
499 NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
501 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
502 return 0;
505 /******************************************************************************
506 * RtlCopyMemory [NTDLL]
509 #undef RtlCopyMemory
510 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
512 memcpy(Destination, Source, Length);
515 /******************************************************************************
516 * RtlMoveMemory [NTDLL]
518 #undef RtlMoveMemory
519 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
521 memmove(Destination, Source, Length);
524 /******************************************************************************
525 * RtlFillMemory [NTDLL]
527 #undef RtlFillMemory
528 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
530 memset(Destination, Fill, Length);
533 /******************************************************************************
534 * RtlZeroMemory [NTDLL]
536 #undef RtlZeroMemory
537 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
539 memset(Destination, 0, Length);
542 /******************************************************************************
543 * RtlCompareMemory [NTDLL]
545 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
547 int i;
548 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
549 return i;
552 /******************************************************************************
553 * RtlAssert [NTDLL]
555 * Not implemented in non-debug versions.
557 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
559 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);