4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
13 #include "debugtools.h"
16 #include "stackframe.h"
21 DEFAULT_DEBUG_CHANNEL(ntdll)
28 /***********************************************************************
29 * RtlInitializeResource (NTDLL.409)
31 * xxxResource() functions implement multiple-reader-single-writer lock.
32 * The code is based on information published in WDJ January 1999 issue.
34 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
38 rwl->iNumberActive = 0;
39 rwl->uExclusiveWaiters = 0;
40 rwl->uSharedWaiters = 0;
41 rwl->hOwningThreadId = 0;
42 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
43 InitializeCriticalSection( &rwl->rtlCS );
44 rwl->hExclusiveReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
45 rwl->hSharedReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
50 /***********************************************************************
51 * RtlDeleteResource (NTDLL.330)
53 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
57 EnterCriticalSection( &rwl->rtlCS );
58 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
59 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl );
60 rwl->hOwningThreadId = 0;
61 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
62 rwl->iNumberActive = 0;
63 CloseHandle( rwl->hExclusiveReleaseSemaphore );
64 CloseHandle( rwl->hSharedReleaseSemaphore );
65 LeaveCriticalSection( &rwl->rtlCS );
66 DeleteCriticalSection( &rwl->rtlCS );
71 /***********************************************************************
72 * RtlAcquireResourceExclusive (NTDLL.256)
74 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
80 EnterCriticalSection( &rwl->rtlCS );
81 if( rwl->iNumberActive == 0 ) /* lock is free */
83 rwl->iNumberActive = -1;
86 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
88 if( rwl->hOwningThreadId == GetCurrentThreadId() )
97 rwl->uExclusiveWaiters++;
99 LeaveCriticalSection( &rwl->rtlCS );
100 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
102 goto start; /* restart the acquisition to avoid deadlocks */
105 else /* one or more shared locks are in progress */
110 rwl->hOwningThreadId = GetCurrentThreadId();
112 LeaveCriticalSection( &rwl->rtlCS );
116 /***********************************************************************
117 * RtlAcquireResourceShared (NTDLL.257)
119 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
121 DWORD dwWait = WAIT_FAILED;
126 EnterCriticalSection( &rwl->rtlCS );
127 if( rwl->iNumberActive < 0 )
129 if( rwl->hOwningThreadId == GetCurrentThreadId() )
131 rwl->iNumberActive--;
138 rwl->uSharedWaiters++;
139 LeaveCriticalSection( &rwl->rtlCS );
140 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
147 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
148 rwl->iNumberActive++;
152 LeaveCriticalSection( &rwl->rtlCS );
157 /***********************************************************************
158 * RtlReleaseResource (NTDLL.471)
160 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
162 EnterCriticalSection( &rwl->rtlCS );
164 if( rwl->iNumberActive > 0 ) /* have one or more readers */
166 if( --rwl->iNumberActive == 0 )
168 if( rwl->uExclusiveWaiters )
171 rwl->uExclusiveWaiters--;
172 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
177 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
179 if( ++rwl->iNumberActive == 0 )
181 rwl->hOwningThreadId = 0;
182 if( rwl->uExclusiveWaiters )
185 if( rwl->uSharedWaiters )
187 UINT n = rwl->uSharedWaiters;
188 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
189 * all queued readers have done their thing */
190 rwl->uSharedWaiters = 0;
191 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
195 LeaveCriticalSection( &rwl->rtlCS );
199 /***********************************************************************
200 * RtlDumpResource (NTDLL.340)
202 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
206 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
207 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
208 if( rwl->iNumberActive )
209 MESSAGE("\towner thread = %08x\n", rwl->hOwningThreadId );
217 /******************************************************************************
218 * RtlCreateHeap [NTDLL]
220 HANDLE WINAPI RtlCreateHeap(
226 PRTL_HEAP_DEFINITION Definition)
228 FIXME("(0x%08lx, %p, 0x%08lx, 0x%08lx, %p, %p) semi-stub\n",
229 Flags, BaseAddress, SizeToReserve, SizeToCommit, Unknown, Definition);
231 return HeapCreate ( Flags, SizeToCommit, SizeToReserve);
234 /******************************************************************************
235 * RtlAllocateHeap [NTDLL]
237 PVOID WINAPI RtlAllocateHeap(
242 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
244 return HeapAlloc(Heap, Flags, Size);
247 /******************************************************************************
248 * RtlFreeHeap [NTDLL]
250 BOOLEAN WINAPI RtlFreeHeap(
255 TRACE("(0x%08x, 0x%08lx, %p) semi stub\n",
256 Heap, Flags, Address);
257 return HeapFree(Heap, Flags, Address);
260 /******************************************************************************
261 * RtlDestroyHeap [NTDLL]
263 * FIXME: prototype guessed
265 BOOLEAN WINAPI RtlDestroyHeap(
268 TRACE("(0x%08x) semi stub\n", Heap);
269 return HeapDestroy(Heap);
276 /******************************************************************************
279 void WINAPIV DbgPrint(LPCSTR fmt, ...) {
284 wvsprintfA(buf,fmt, args);
287 MESSAGE("DbgPrint says: %s",buf);
288 /* hmm, raise exception? */
291 /******************************************************************************
292 * RtlAcquirePebLock [NTDLL]
294 VOID WINAPI RtlAcquirePebLock(void) {
296 /* enter critical section ? */
299 /******************************************************************************
300 * RtlReleasePebLock [NTDLL]
302 VOID WINAPI RtlReleasePebLock(void) {
304 /* leave critical section ? */
307 /******************************************************************************
308 * RtlIntegerToChar [NTDLL]
310 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
311 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
314 /******************************************************************************
315 * RtlSetEnvironmentVariable [NTDLL]
317 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
318 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
322 /******************************************************************************
323 * RtlNewSecurityObject [NTDLL]
325 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
326 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
330 /******************************************************************************
331 * RtlDeleteSecurityObject [NTDLL]
333 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
334 FIXME("(0x%08lx),stub!\n",x1);
338 /**************************************************************************
339 * RtlNormalizeProcessParams [NTDLL.441]
341 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
343 FIXME("(%p), stub\n",x);
347 /**************************************************************************
348 * RtlGetNtProductType [NTDLL.390]
350 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
352 FIXME("(%p): stub\n", type);
353 *type=3; /* dunno. 1 for client, 3 for server? */
357 /**************************************************************************
358 * NTDLL_chkstk [NTDLL.862]
359 * NTDLL_alloca_probe [NTDLL.861]
360 * Glorified "enter xxxx".
362 void WINAPI NTDLL_chkstk( CONTEXT86 *context )
364 ESP_reg(context) -= EAX_reg(context);
366 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
368 ESP_reg(context) -= EAX_reg(context);
371 /******************************************************************************
372 * RtlExtendedLargeIntegerDivide [NTDLL.359]
374 INT WINAPI RtlExtendedLargeIntegerDivide(
375 LARGE_INTEGER dividend,
379 #if SIZEOF_LONG_LONG==8
380 long long x1 = *(long long*)÷nd;
383 *rest = x1 % divisor;
386 FIXME("((%ld<<32)+%ld,%ld,%p), implement this using normal integer arithmetic!\n",
387 dividend.s.HighPart,dividend.s.LowPart,divisor,rest);
392 /******************************************************************************
393 * RtlExtendedLargeIntegerMultiply [NTDLL.359]
394 * Note: This even works, since gcc returns 64bit values in eax/edx just like
395 * the caller expects. However... The relay code won't grok this I think.
397 LARGE_INTEGER WINAPI RtlExtendedIntegerMultiply(
398 LARGE_INTEGER factor1,
401 #if SIZEOF_LONG_LONG==8
402 long long result = (*(long long*)&factor1) * factor2;
403 return (*(LARGE_INTEGER*)&result);
405 LARGE_INTEGER result;
406 result.s.HighPart = 0;
407 result.s.LowPart = 0;
408 FIXME("((%ld<<32)+%ld,%d), implement this using normal integer arithmetic!\n",
409 factor1.s.HighPart,factor1.s.LowPart,factor2);
414 /**************************************************************************
415 * RtlDosPathNameToNtPathName_U [NTDLL.338]
417 * FIXME: convert to UNC or whatever is expected here
419 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
420 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
422 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
424 FIXME("(%s,%p,%08lx,%08lx)\n",fromA,us,x2,x3);
426 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
430 /******************************************************************************
431 * RtlCreateEnvironment [NTDLL]
433 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
434 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
439 /******************************************************************************
440 * RtlDestroyEnvironment [NTDLL]
442 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
443 FIXME("(0x%08lx),stub!\n",x);
447 /******************************************************************************
448 * RtlQueryEnvironmentVariable_U [NTDLL]
450 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
451 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
454 /******************************************************************************
455 * RtlInitializeGenericTable [NTDLL]
457 DWORD WINAPI RtlInitializeGenericTable(void)
463 /******************************************************************************
464 * RtlInitializeBitMap [NTDLL]
467 NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
469 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
473 /******************************************************************************
477 NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
479 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
483 /******************************************************************************
484 * RtlFindClearBits [NTDLL]
487 NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
489 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
493 /******************************************************************************
494 * RtlClearBits [NTDLL]
497 NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
499 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);