Removed dependencies on the internals of the CLASS structure.
[wine/multimedia.git] / dlls / ntdll / rtl.c
blobbd8e45db53786ef1ca0ad8530783e1d1e10666db
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 <stdio.h>
12 #include <string.h>
13 #include "heap.h"
14 #include "debugtools.h"
15 #include "windef.h"
16 #include "winerror.h"
17 #include "stackframe.h"
19 #include "ntddk.h"
20 #include "winreg.h"
22 DEFAULT_DEBUG_CHANNEL(ntdll);
26 * resource functions
29 /***********************************************************************
30 * RtlInitializeResource (NTDLL.409)
32 * xxxResource() functions implement multiple-reader-single-writer lock.
33 * The code is based on information published in WDJ January 1999 issue.
35 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
37 if( rwl )
39 rwl->iNumberActive = 0;
40 rwl->uExclusiveWaiters = 0;
41 rwl->uSharedWaiters = 0;
42 rwl->hOwningThreadId = 0;
43 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
44 RtlInitializeCriticalSection( &rwl->rtlCS );
45 NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, 0, NULL, 0, 65535 );
46 NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, 0, NULL, 0, 65535 );
51 /***********************************************************************
52 * RtlDeleteResource (NTDLL.330)
54 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
56 if( rwl )
58 RtlEnterCriticalSection( &rwl->rtlCS );
59 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
60 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl );
61 rwl->hOwningThreadId = 0;
62 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
63 rwl->iNumberActive = 0;
64 NtClose( rwl->hExclusiveReleaseSemaphore );
65 NtClose( rwl->hSharedReleaseSemaphore );
66 RtlLeaveCriticalSection( &rwl->rtlCS );
67 RtlDeleteCriticalSection( &rwl->rtlCS );
72 /***********************************************************************
73 * RtlAcquireResourceExclusive (NTDLL.256)
75 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
77 BYTE retVal = 0;
78 if( !rwl ) return 0;
80 start:
81 RtlEnterCriticalSection( &rwl->rtlCS );
82 if( rwl->iNumberActive == 0 ) /* lock is free */
84 rwl->iNumberActive = -1;
85 retVal = 1;
87 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
89 if( rwl->hOwningThreadId == GetCurrentThreadId() )
91 retVal = 1;
92 rwl->iNumberActive--;
93 goto done;
95 wait:
96 if( fWait )
98 rwl->uExclusiveWaiters++;
100 RtlLeaveCriticalSection( &rwl->rtlCS );
101 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
102 goto done;
103 goto start; /* restart the acquisition to avoid deadlocks */
106 else /* one or more shared locks are in progress */
107 if( fWait )
108 goto wait;
110 if( retVal == 1 )
111 rwl->hOwningThreadId = GetCurrentThreadId();
112 done:
113 RtlLeaveCriticalSection( &rwl->rtlCS );
114 return retVal;
117 /***********************************************************************
118 * RtlAcquireResourceShared (NTDLL.257)
120 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
122 DWORD dwWait = WAIT_FAILED;
123 BYTE retVal = 0;
124 if( !rwl ) return 0;
126 start:
127 RtlEnterCriticalSection( &rwl->rtlCS );
128 if( rwl->iNumberActive < 0 )
130 if( rwl->hOwningThreadId == GetCurrentThreadId() )
132 rwl->iNumberActive--;
133 retVal = 1;
134 goto done;
137 if( fWait )
139 rwl->uSharedWaiters++;
140 RtlLeaveCriticalSection( &rwl->rtlCS );
141 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
142 goto done;
143 goto start;
146 else
148 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
149 rwl->iNumberActive++;
150 retVal = 1;
152 done:
153 RtlLeaveCriticalSection( &rwl->rtlCS );
154 return retVal;
158 /***********************************************************************
159 * RtlReleaseResource (NTDLL.471)
161 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
163 RtlEnterCriticalSection( &rwl->rtlCS );
165 if( rwl->iNumberActive > 0 ) /* have one or more readers */
167 if( --rwl->iNumberActive == 0 )
169 if( rwl->uExclusiveWaiters )
171 wake_exclusive:
172 rwl->uExclusiveWaiters--;
173 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
177 else
178 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
180 if( ++rwl->iNumberActive == 0 )
182 rwl->hOwningThreadId = 0;
183 if( rwl->uExclusiveWaiters )
184 goto wake_exclusive;
185 else
186 if( rwl->uSharedWaiters )
188 UINT n = rwl->uSharedWaiters;
189 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
190 * all queued readers have done their thing */
191 rwl->uSharedWaiters = 0;
192 NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
196 RtlLeaveCriticalSection( &rwl->rtlCS );
200 /***********************************************************************
201 * RtlDumpResource (NTDLL.340)
203 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
205 if( rwl )
207 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
208 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
209 if( rwl->iNumberActive )
210 MESSAGE("\towner thread = %08x\n", rwl->hOwningThreadId );
215 * heap functions
218 /******************************************************************************
219 * RtlCreateHeap [NTDLL]
221 HANDLE WINAPI RtlCreateHeap(
222 ULONG Flags,
223 PVOID BaseAddress,
224 ULONG SizeToReserve,
225 ULONG SizeToCommit,
226 PVOID Unknown,
227 PRTL_HEAP_DEFINITION Definition)
229 FIXME("(0x%08lx, %p, 0x%08lx, 0x%08lx, %p, %p) semi-stub\n",
230 Flags, BaseAddress, SizeToReserve, SizeToCommit, Unknown, Definition);
232 return HeapCreate ( Flags, SizeToCommit, SizeToReserve);
235 /******************************************************************************
236 * RtlAllocateHeap [NTDLL]
238 PVOID WINAPI RtlAllocateHeap(
239 HANDLE Heap,
240 ULONG Flags,
241 ULONG Size)
243 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
244 Heap, Flags, Size);
245 return HeapAlloc(Heap, Flags, Size);
248 /******************************************************************************
249 * RtlFreeHeap [NTDLL]
251 BOOLEAN WINAPI RtlFreeHeap(
252 HANDLE Heap,
253 ULONG Flags,
254 PVOID Address)
256 TRACE("(0x%08x, 0x%08lx, %p) semi stub\n",
257 Heap, Flags, Address);
258 return HeapFree(Heap, Flags, Address);
261 /******************************************************************************
262 * RtlDestroyHeap [NTDLL]
264 * FIXME: prototype guessed
266 BOOLEAN WINAPI RtlDestroyHeap(
267 HANDLE Heap)
269 TRACE("(0x%08x) semi stub\n", Heap);
270 return HeapDestroy(Heap);
274 * misc functions
277 /******************************************************************************
278 * DbgPrint [NTDLL]
280 void WINAPIV DbgPrint(LPCSTR fmt, ...)
282 char buf[512];
283 va_list args;
285 va_start(args, fmt);
286 vsprintf(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 context->Esp -= context->Eax;
368 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
370 context->Esp -= context->Eax;
373 /**************************************************************************
374 * RtlDosPathNameToNtPathName_U [NTDLL.338]
376 * FIXME: convert to UNC or whatever is expected here
378 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
379 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
381 FIXME("(%s,%p,%08lx,%08lx)\n",debugstr_w(from),us,x2,x3);
382 if (us) RtlCreateUnicodeString( us, from );
383 return TRUE;
387 /***********************************************************************
388 * RtlImageNtHeader (NTDLL)
390 PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
392 IMAGE_NT_HEADERS *ret = NULL;
393 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
395 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
397 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
398 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
400 return ret;
404 /******************************************************************************
405 * RtlCreateEnvironment [NTDLL]
407 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
408 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
409 return 0;
413 /******************************************************************************
414 * RtlDestroyEnvironment [NTDLL]
416 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
417 FIXME("(0x%08lx),stub!\n",x);
418 return 0;
421 /******************************************************************************
422 * RtlQueryEnvironmentVariable_U [NTDLL]
424 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
425 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
426 return 0;
428 /******************************************************************************
429 * RtlInitializeGenericTable [NTDLL]
431 DWORD WINAPI RtlInitializeGenericTable(void)
433 FIXME("\n");
434 return 0;
437 /******************************************************************************
438 * RtlInitializeBitMap [NTDLL]
441 NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
443 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
444 return 0;
447 /******************************************************************************
448 * RtlSetBits [NTDLL]
451 NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
453 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
454 return 0;
457 /******************************************************************************
458 * RtlFindClearBits [NTDLL]
461 NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
463 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
464 return 0;
467 /******************************************************************************
468 * RtlClearBits [NTDLL]
471 NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
473 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
474 return 0;
477 /******************************************************************************
478 * RtlCopyMemory [NTDLL]
481 #undef RtlCopyMemory
482 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
484 memcpy(Destination, Source, Length);
487 /******************************************************************************
488 * RtlMoveMemory [NTDLL]
490 #undef RtlMoveMemory
491 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
493 memmove(Destination, Source, Length);
496 /******************************************************************************
497 * RtlFillMemory [NTDLL]
499 #undef RtlFillMemory
500 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
502 memset(Destination, Fill, Length);
505 /******************************************************************************
506 * RtlZeroMemory [NTDLL]
508 #undef RtlZeroMemory
509 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
511 memset(Destination, 0, Length);
514 /******************************************************************************
515 * RtlCompareMemory [NTDLL]
517 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
519 int i;
520 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
521 return i;
524 /******************************************************************************
525 * RtlAssert [NTDLL]
527 * Not implemented in non-debug versions.
529 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
531 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);