Repaired shared PE data sections.
[wine/multimedia.git] / dlls / ntdll / rtl.c
blobfbf1c896c39f112dcfcea1f5cf41c5d04c4d99b2
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);
25 static RTL_CRITICAL_SECTION peb_lock = CRITICAL_SECTION_INIT;
28 * resource functions
31 /***********************************************************************
32 * RtlInitializeResource (NTDLL.409)
34 * xxxResource() functions implement multiple-reader-single-writer lock.
35 * The code is based on information published in WDJ January 1999 issue.
37 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
39 if( rwl )
41 rwl->iNumberActive = 0;
42 rwl->uExclusiveWaiters = 0;
43 rwl->uSharedWaiters = 0;
44 rwl->hOwningThreadId = 0;
45 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
46 RtlInitializeCriticalSection( &rwl->rtlCS );
47 NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, 0, NULL, 0, 65535 );
48 NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, 0, NULL, 0, 65535 );
53 /***********************************************************************
54 * RtlDeleteResource (NTDLL.330)
56 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
58 if( rwl )
60 RtlEnterCriticalSection( &rwl->rtlCS );
61 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
62 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl );
63 rwl->hOwningThreadId = 0;
64 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
65 rwl->iNumberActive = 0;
66 NtClose( rwl->hExclusiveReleaseSemaphore );
67 NtClose( rwl->hSharedReleaseSemaphore );
68 RtlLeaveCriticalSection( &rwl->rtlCS );
69 RtlDeleteCriticalSection( &rwl->rtlCS );
74 /***********************************************************************
75 * RtlAcquireResourceExclusive (NTDLL.256)
77 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
79 BYTE retVal = 0;
80 if( !rwl ) return 0;
82 start:
83 RtlEnterCriticalSection( &rwl->rtlCS );
84 if( rwl->iNumberActive == 0 ) /* lock is free */
86 rwl->iNumberActive = -1;
87 retVal = 1;
89 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
91 if( rwl->hOwningThreadId == GetCurrentThreadId() )
93 retVal = 1;
94 rwl->iNumberActive--;
95 goto done;
97 wait:
98 if( fWait )
100 rwl->uExclusiveWaiters++;
102 RtlLeaveCriticalSection( &rwl->rtlCS );
103 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
104 goto done;
105 goto start; /* restart the acquisition to avoid deadlocks */
108 else /* one or more shared locks are in progress */
109 if( fWait )
110 goto wait;
112 if( retVal == 1 )
113 rwl->hOwningThreadId = GetCurrentThreadId();
114 done:
115 RtlLeaveCriticalSection( &rwl->rtlCS );
116 return retVal;
119 /***********************************************************************
120 * RtlAcquireResourceShared (NTDLL.257)
122 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
124 DWORD dwWait = WAIT_FAILED;
125 BYTE retVal = 0;
126 if( !rwl ) return 0;
128 start:
129 RtlEnterCriticalSection( &rwl->rtlCS );
130 if( rwl->iNumberActive < 0 )
132 if( rwl->hOwningThreadId == GetCurrentThreadId() )
134 rwl->iNumberActive--;
135 retVal = 1;
136 goto done;
139 if( fWait )
141 rwl->uSharedWaiters++;
142 RtlLeaveCriticalSection( &rwl->rtlCS );
143 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
144 goto done;
145 goto start;
148 else
150 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
151 rwl->iNumberActive++;
152 retVal = 1;
154 done:
155 RtlLeaveCriticalSection( &rwl->rtlCS );
156 return retVal;
160 /***********************************************************************
161 * RtlReleaseResource (NTDLL.471)
163 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
165 RtlEnterCriticalSection( &rwl->rtlCS );
167 if( rwl->iNumberActive > 0 ) /* have one or more readers */
169 if( --rwl->iNumberActive == 0 )
171 if( rwl->uExclusiveWaiters )
173 wake_exclusive:
174 rwl->uExclusiveWaiters--;
175 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
179 else
180 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
182 if( ++rwl->iNumberActive == 0 )
184 rwl->hOwningThreadId = 0;
185 if( rwl->uExclusiveWaiters )
186 goto wake_exclusive;
187 else
188 if( rwl->uSharedWaiters )
190 UINT n = rwl->uSharedWaiters;
191 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
192 * all queued readers have done their thing */
193 rwl->uSharedWaiters = 0;
194 NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
198 RtlLeaveCriticalSection( &rwl->rtlCS );
202 /***********************************************************************
203 * RtlDumpResource (NTDLL.340)
205 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
207 if( rwl )
209 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
210 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
211 if( rwl->iNumberActive )
212 MESSAGE("\towner thread = %08x\n", rwl->hOwningThreadId );
217 * heap functions
220 /******************************************************************************
221 * RtlCreateHeap [NTDLL]
223 HANDLE WINAPI RtlCreateHeap(
224 ULONG Flags,
225 PVOID BaseAddress,
226 ULONG SizeToReserve,
227 ULONG SizeToCommit,
228 PVOID Unknown,
229 PRTL_HEAP_DEFINITION Definition)
231 FIXME("(0x%08lx, %p, 0x%08lx, 0x%08lx, %p, %p) semi-stub\n",
232 Flags, BaseAddress, SizeToReserve, SizeToCommit, Unknown, Definition);
234 return HeapCreate ( Flags, SizeToCommit, SizeToReserve);
237 /******************************************************************************
238 * RtlAllocateHeap [NTDLL]
240 PVOID WINAPI RtlAllocateHeap(
241 HANDLE Heap,
242 ULONG Flags,
243 ULONG Size)
245 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
246 Heap, Flags, Size);
247 return HeapAlloc(Heap, Flags, Size);
250 /******************************************************************************
251 * RtlFreeHeap [NTDLL]
253 BOOLEAN WINAPI RtlFreeHeap(
254 HANDLE Heap,
255 ULONG Flags,
256 PVOID Address)
258 TRACE("(0x%08x, 0x%08lx, %p) semi stub\n",
259 Heap, Flags, Address);
260 return HeapFree(Heap, Flags, Address);
263 /******************************************************************************
264 * RtlDestroyHeap [NTDLL]
266 * FIXME: prototype guessed
268 BOOLEAN WINAPI RtlDestroyHeap(
269 HANDLE Heap)
271 TRACE("(0x%08x) semi stub\n", Heap);
272 return HeapDestroy(Heap);
276 * misc functions
279 /******************************************************************************
280 * DbgPrint [NTDLL]
282 void WINAPIV DbgPrint(LPCSTR fmt, ...)
284 char buf[512];
285 va_list args;
287 va_start(args, fmt);
288 vsprintf(buf,fmt, args);
289 va_end(args);
291 MESSAGE("DbgPrint says: %s",buf);
292 /* hmm, raise exception? */
295 /******************************************************************************
296 * RtlAcquirePebLock [NTDLL]
298 VOID WINAPI RtlAcquirePebLock(void)
300 RtlEnterCriticalSection( &peb_lock );
303 /******************************************************************************
304 * RtlReleasePebLock [NTDLL]
306 VOID WINAPI RtlReleasePebLock(void)
308 RtlLeaveCriticalSection( &peb_lock );
311 /******************************************************************************
312 * RtlIntegerToChar [NTDLL]
314 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
315 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
316 return 0;
318 /******************************************************************************
319 * RtlSetEnvironmentVariable [NTDLL]
321 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
322 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
323 return 0;
326 /******************************************************************************
327 * RtlNewSecurityObject [NTDLL]
329 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
330 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
331 return 0;
334 /******************************************************************************
335 * RtlDeleteSecurityObject [NTDLL]
337 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
338 FIXME("(0x%08lx),stub!\n",x1);
339 return 0;
342 /**************************************************************************
343 * RtlNormalizeProcessParams [NTDLL.441]
345 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
347 FIXME("(%p), stub\n",x);
348 return x;
351 /**************************************************************************
352 * RtlGetNtProductType [NTDLL.390]
354 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
356 FIXME("(%p): stub\n", type);
357 *type=3; /* dunno. 1 for client, 3 for server? */
358 return 1;
361 /**************************************************************************
362 * NTDLL_chkstk [NTDLL.862]
363 * NTDLL_alloca_probe [NTDLL.861]
364 * Glorified "enter xxxx".
366 void WINAPI NTDLL_chkstk( CONTEXT86 *context )
368 context->Esp -= context->Eax;
370 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
372 context->Esp -= context->Eax;
375 /**************************************************************************
376 * RtlDosPathNameToNtPathName_U [NTDLL.338]
378 * FIXME: convert to UNC or whatever is expected here
380 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
381 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
383 FIXME("(%s,%p,%08lx,%08lx)\n",debugstr_w(from),us,x2,x3);
384 if (us) RtlCreateUnicodeString( us, from );
385 return TRUE;
389 /***********************************************************************
390 * RtlImageNtHeader (NTDLL)
392 PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
394 IMAGE_NT_HEADERS *ret = NULL;
395 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
397 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
399 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
400 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
402 return ret;
406 /******************************************************************************
407 * RtlCreateEnvironment [NTDLL]
409 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
410 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
411 return 0;
415 /******************************************************************************
416 * RtlDestroyEnvironment [NTDLL]
418 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
419 FIXME("(0x%08lx),stub!\n",x);
420 return 0;
423 /******************************************************************************
424 * RtlQueryEnvironmentVariable_U [NTDLL]
426 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
427 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
428 return 0;
430 /******************************************************************************
431 * RtlInitializeGenericTable [NTDLL]
433 DWORD WINAPI RtlInitializeGenericTable(void)
435 FIXME("\n");
436 return 0;
439 /******************************************************************************
440 * RtlInitializeBitMap [NTDLL]
443 NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
445 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
446 return 0;
449 /******************************************************************************
450 * RtlSetBits [NTDLL]
453 NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
455 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
456 return 0;
459 /******************************************************************************
460 * RtlFindClearBits [NTDLL]
463 NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
465 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
466 return 0;
469 /******************************************************************************
470 * RtlClearBits [NTDLL]
473 NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
475 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
476 return 0;
479 /******************************************************************************
480 * RtlCopyMemory [NTDLL]
483 #undef RtlCopyMemory
484 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
486 memcpy(Destination, Source, Length);
489 /******************************************************************************
490 * RtlMoveMemory [NTDLL]
492 #undef RtlMoveMemory
493 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
495 memmove(Destination, Source, Length);
498 /******************************************************************************
499 * RtlFillMemory [NTDLL]
501 #undef RtlFillMemory
502 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
504 memset(Destination, Fill, Length);
507 /******************************************************************************
508 * RtlZeroMemory [NTDLL]
510 #undef RtlZeroMemory
511 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
513 memset(Destination, 0, Length);
516 /******************************************************************************
517 * RtlCompareMemory [NTDLL]
519 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
521 int i;
522 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
523 return i;
526 /******************************************************************************
527 * RtlAssert [NTDLL]
529 * Not implemented in non-debug versions.
531 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
533 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);