Moved heap functions to ntdll.
[wine/wine-kai.git] / dlls / ntdll / rtl.c
bloba6cf39da67f2aa59a6b6d7de43636fe3d9667b16
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 "debugtools.h"
14 #include "windef.h"
15 #include "winerror.h"
16 #include "stackframe.h"
18 #include "ntddk.h"
19 #include "winreg.h"
21 DEFAULT_DEBUG_CHANNEL(ntdll);
24 static RTL_CRITICAL_SECTION peb_lock = CRITICAL_SECTION_INIT("peb_lock");
27 * resource functions
30 /***********************************************************************
31 * RtlInitializeResource (NTDLL.@)
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 RtlInitializeCriticalSection( &rwl->rtlCS );
46 NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, 0, NULL, 0, 65535 );
47 NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, 0, NULL, 0, 65535 );
52 /***********************************************************************
53 * RtlDeleteResource (NTDLL.@)
55 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
57 if( rwl )
59 RtlEnterCriticalSection( &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 NtClose( rwl->hExclusiveReleaseSemaphore );
66 NtClose( rwl->hSharedReleaseSemaphore );
67 RtlLeaveCriticalSection( &rwl->rtlCS );
68 RtlDeleteCriticalSection( &rwl->rtlCS );
73 /***********************************************************************
74 * RtlAcquireResourceExclusive (NTDLL.@)
76 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
78 BYTE retVal = 0;
79 if( !rwl ) return 0;
81 start:
82 RtlEnterCriticalSection( &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 RtlLeaveCriticalSection( &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 RtlLeaveCriticalSection( &rwl->rtlCS );
115 return retVal;
118 /***********************************************************************
119 * RtlAcquireResourceShared (NTDLL.@)
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 RtlEnterCriticalSection( &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 RtlLeaveCriticalSection( &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 RtlLeaveCriticalSection( &rwl->rtlCS );
155 return retVal;
159 /***********************************************************************
160 * RtlReleaseResource (NTDLL.@)
162 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
164 RtlEnterCriticalSection( &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 NtReleaseSemaphore( 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 NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
197 RtlLeaveCriticalSection( &rwl->rtlCS );
201 /***********************************************************************
202 * RtlDumpResource (NTDLL.@)
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 * misc functions
219 /******************************************************************************
220 * DbgPrint [NTDLL.@]
222 void WINAPIV DbgPrint(LPCSTR fmt, ...)
224 char buf[512];
225 va_list args;
227 va_start(args, fmt);
228 vsprintf(buf,fmt, args);
229 va_end(args);
231 MESSAGE("DbgPrint says: %s",buf);
232 /* hmm, raise exception? */
235 /******************************************************************************
236 * RtlAcquirePebLock [NTDLL.@]
238 VOID WINAPI RtlAcquirePebLock(void)
240 RtlEnterCriticalSection( &peb_lock );
243 /******************************************************************************
244 * RtlReleasePebLock [NTDLL.@]
246 VOID WINAPI RtlReleasePebLock(void)
248 RtlLeaveCriticalSection( &peb_lock );
251 /******************************************************************************
252 * RtlIntegerToChar [NTDLL.@]
254 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
255 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
256 return 0;
258 /******************************************************************************
259 * RtlSetEnvironmentVariable [NTDLL.@]
261 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
262 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
263 return 0;
266 /******************************************************************************
267 * RtlNewSecurityObject [NTDLL.@]
269 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
270 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
271 return 0;
274 /******************************************************************************
275 * RtlDeleteSecurityObject [NTDLL.@]
277 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
278 FIXME("(0x%08lx),stub!\n",x1);
279 return 0;
282 /**************************************************************************
283 * RtlNormalizeProcessParams [NTDLL.@]
285 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
287 FIXME("(%p), stub\n",x);
288 return x;
291 /**************************************************************************
292 * RtlGetNtProductType [NTDLL.@]
294 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
296 FIXME("(%p): stub\n", type);
297 *type=3; /* dunno. 1 for client, 3 for server? */
298 return 1;
301 /**************************************************************************
302 * _chkstk [NTDLL.@]
304 * Glorified "enter xxxx".
306 void WINAPI NTDLL_chkstk( CONTEXT86 *context )
308 context->Esp -= context->Eax;
311 /**************************************************************************
312 * _alloca_probe [NTDLL.@]
314 * Glorified "enter xxxx".
316 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
318 context->Esp -= context->Eax;
321 /**************************************************************************
322 * RtlDosPathNameToNtPathName_U [NTDLL.@]
324 * FIXME: convert to UNC or whatever is expected here
326 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
327 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
329 FIXME("(%s,%p,%08lx,%08lx)\n",debugstr_w(from),us,x2,x3);
330 if (us) RtlCreateUnicodeString( us, from );
331 return TRUE;
335 /***********************************************************************
336 * RtlImageNtHeader (NTDLL.@)
338 PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
340 IMAGE_NT_HEADERS *ret = NULL;
341 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
343 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
345 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
346 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
348 return ret;
352 /******************************************************************************
353 * RtlCreateEnvironment [NTDLL.@]
355 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
356 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
357 return 0;
361 /******************************************************************************
362 * RtlDestroyEnvironment [NTDLL.@]
364 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
365 FIXME("(0x%08lx),stub!\n",x);
366 return 0;
369 /******************************************************************************
370 * RtlQueryEnvironmentVariable_U [NTDLL.@]
372 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
373 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
374 return 0;
376 /******************************************************************************
377 * RtlInitializeGenericTable [NTDLL.@]
379 DWORD WINAPI RtlInitializeGenericTable(void)
381 FIXME("\n");
382 return 0;
385 /******************************************************************************
386 * RtlInitializeBitMap [NTDLL.@]
389 NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
391 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
392 return 0;
395 /******************************************************************************
396 * RtlSetBits [NTDLL.@]
399 NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
401 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
402 return 0;
405 /******************************************************************************
406 * RtlFindClearBits [NTDLL.@]
409 NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
411 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
412 return 0;
415 /******************************************************************************
416 * RtlClearBits [NTDLL.@]
419 NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
421 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
422 return 0;
425 /******************************************************************************
426 * RtlCopyMemory [NTDLL]
429 #undef RtlCopyMemory
430 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
432 memcpy(Destination, Source, Length);
435 /******************************************************************************
436 * RtlMoveMemory [NTDLL.@]
438 #undef RtlMoveMemory
439 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
441 memmove(Destination, Source, Length);
444 /******************************************************************************
445 * RtlFillMemory [NTDLL.@]
447 #undef RtlFillMemory
448 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
450 memset(Destination, Fill, Length);
453 /******************************************************************************
454 * RtlZeroMemory [NTDLL.@]
456 #undef RtlZeroMemory
457 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
459 memset(Destination, 0, Length);
462 /******************************************************************************
463 * RtlCompareMemory [NTDLL.@]
465 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
467 int i;
468 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
469 return i;
472 /******************************************************************************
473 * RtlAssert [NTDLL.@]
475 * Not implemented in non-debug versions.
477 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
479 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);