4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
14 #include "debugtools.h"
17 #include "stackframe.h"
22 DEFAULT_DEBUG_CHANNEL(ntdll
);
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
)
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 InitializeCriticalSection( &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
)
58 EnterCriticalSection( &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 LeaveCriticalSection( &rwl
->rtlCS
);
67 DeleteCriticalSection( &rwl
->rtlCS
);
72 /***********************************************************************
73 * RtlAcquireResourceExclusive (NTDLL.256)
75 BYTE WINAPI
RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl
, BYTE fWait
)
81 EnterCriticalSection( &rwl
->rtlCS
);
82 if( rwl
->iNumberActive
== 0 ) /* lock is free */
84 rwl
->iNumberActive
= -1;
87 else if( rwl
->iNumberActive
< 0 ) /* exclusive lock in progress */
89 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
98 rwl
->uExclusiveWaiters
++;
100 LeaveCriticalSection( &rwl
->rtlCS
);
101 if( WaitForSingleObject( rwl
->hExclusiveReleaseSemaphore
, INFINITE
) == WAIT_FAILED
)
103 goto start
; /* restart the acquisition to avoid deadlocks */
106 else /* one or more shared locks are in progress */
111 rwl
->hOwningThreadId
= GetCurrentThreadId();
113 LeaveCriticalSection( &rwl
->rtlCS
);
117 /***********************************************************************
118 * RtlAcquireResourceShared (NTDLL.257)
120 BYTE WINAPI
RtlAcquireResourceShared(LPRTL_RWLOCK rwl
, BYTE fWait
)
122 DWORD dwWait
= WAIT_FAILED
;
127 EnterCriticalSection( &rwl
->rtlCS
);
128 if( rwl
->iNumberActive
< 0 )
130 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
132 rwl
->iNumberActive
--;
139 rwl
->uSharedWaiters
++;
140 LeaveCriticalSection( &rwl
->rtlCS
);
141 if( (dwWait
= WaitForSingleObject( rwl
->hSharedReleaseSemaphore
, INFINITE
)) == WAIT_FAILED
)
148 if( dwWait
!= WAIT_OBJECT_0
) /* otherwise RtlReleaseResource() has already done it */
149 rwl
->iNumberActive
++;
153 LeaveCriticalSection( &rwl
->rtlCS
);
158 /***********************************************************************
159 * RtlReleaseResource (NTDLL.471)
161 void WINAPI
RtlReleaseResource(LPRTL_RWLOCK rwl
)
163 EnterCriticalSection( &rwl
->rtlCS
);
165 if( rwl
->iNumberActive
> 0 ) /* have one or more readers */
167 if( --rwl
->iNumberActive
== 0 )
169 if( rwl
->uExclusiveWaiters
)
172 rwl
->uExclusiveWaiters
--;
173 NtReleaseSemaphore( rwl
->hExclusiveReleaseSemaphore
, 1, NULL
);
178 if( rwl
->iNumberActive
< 0 ) /* have a writer, possibly recursive */
180 if( ++rwl
->iNumberActive
== 0 )
182 rwl
->hOwningThreadId
= 0;
183 if( rwl
->uExclusiveWaiters
)
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 LeaveCriticalSection( &rwl
->rtlCS
);
200 /***********************************************************************
201 * RtlDumpResource (NTDLL.340)
203 void WINAPI
RtlDumpResource(LPRTL_RWLOCK 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
);
218 /******************************************************************************
219 * RtlCreateHeap [NTDLL]
221 HANDLE WINAPI
RtlCreateHeap(
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(
243 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
245 return HeapAlloc(Heap
, Flags
, Size
);
248 /******************************************************************************
249 * RtlFreeHeap [NTDLL]
251 BOOLEAN WINAPI
RtlFreeHeap(
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(
269 TRACE("(0x%08x) semi stub\n", Heap
);
270 return HeapDestroy(Heap
);
277 /******************************************************************************
280 void WINAPIV
DbgPrint(LPCSTR fmt
, ...)
286 vsprintf(buf
,fmt
, args
);
289 MESSAGE("DbgPrint says: %s",buf
);
290 /* hmm, raise exception? */
293 /******************************************************************************
294 * RtlAcquirePebLock [NTDLL]
296 VOID WINAPI
RtlAcquirePebLock(void) {
298 /* enter critical section ? */
301 /******************************************************************************
302 * RtlReleasePebLock [NTDLL]
304 VOID WINAPI
RtlReleasePebLock(void) {
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
);
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
));
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
);
332 /******************************************************************************
333 * RtlDeleteSecurityObject [NTDLL]
335 DWORD WINAPI
RtlDeleteSecurityObject(DWORD x1
) {
336 FIXME("(0x%08lx),stub!\n",x1
);
340 /**************************************************************************
341 * RtlNormalizeProcessParams [NTDLL.441]
343 LPVOID WINAPI
RtlNormalizeProcessParams(LPVOID x
)
345 FIXME("(%p), stub\n",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? */
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
,
381 #if SIZEOF_LONG_LONG==8
382 long long x1
= *(long long*)÷nd
;
385 *rest
= x1
% divisor
;
388 FIXME("((%ld<<32)+%ld,%ld,%p), implement this using normal integer arithmetic!\n",
389 dividend
.s
.HighPart
,dividend
.s
.LowPart
,divisor
,rest
);
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
,
403 #if SIZEOF_LONG_LONG==8
404 long long result
= (*(long long*)&factor1
) * factor2
;
405 return (*(LARGE_INTEGER
*)&result
);
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
);
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
);
428 RtlInitUnicodeString(us
,HEAP_strdupW(GetProcessHeap(),0,from
));
433 /***********************************************************************
434 * RtlImageNtHeader (NTDLL)
436 PIMAGE_NT_HEADERS WINAPI
RtlImageNtHeader(HMODULE hModule
)
438 IMAGE_NT_HEADERS
*ret
= NULL
;
439 IMAGE_DOS_HEADER
*dos
= (IMAGE_DOS_HEADER
*)hModule
;
441 if (dos
->e_magic
== IMAGE_DOS_SIGNATURE
)
443 ret
= (IMAGE_NT_HEADERS
*)((char *)dos
+ dos
->e_lfanew
);
444 if (ret
->Signature
!= IMAGE_NT_SIGNATURE
) ret
= NULL
;
450 /******************************************************************************
451 * RtlCreateEnvironment [NTDLL]
453 DWORD WINAPI
RtlCreateEnvironment(DWORD x1
,DWORD x2
) {
454 FIXME("(0x%08lx,0x%08lx),stub!\n",x1
,x2
);
459 /******************************************************************************
460 * RtlDestroyEnvironment [NTDLL]
462 DWORD WINAPI
RtlDestroyEnvironment(DWORD x
) {
463 FIXME("(0x%08lx),stub!\n",x
);
467 /******************************************************************************
468 * RtlQueryEnvironmentVariable_U [NTDLL]
470 DWORD WINAPI
RtlQueryEnvironmentVariable_U(DWORD x1
,PUNICODE_STRING key
,PUNICODE_STRING val
) {
471 FIXME("(0x%08lx,%s,%p),stub!\n",x1
,debugstr_w(key
->Buffer
),val
);
474 /******************************************************************************
475 * RtlInitializeGenericTable [NTDLL]
477 DWORD WINAPI
RtlInitializeGenericTable(void)
483 /******************************************************************************
484 * RtlInitializeBitMap [NTDLL]
487 NTSTATUS WINAPI
RtlInitializeBitMap(DWORD x1
,DWORD x2
,DWORD x3
)
489 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
493 /******************************************************************************
497 NTSTATUS WINAPI
RtlSetBits(DWORD x1
,DWORD x2
,DWORD x3
)
499 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
503 /******************************************************************************
504 * RtlFindClearBits [NTDLL]
507 NTSTATUS WINAPI
RtlFindClearBits(DWORD x1
,DWORD x2
,DWORD x3
)
509 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
513 /******************************************************************************
514 * RtlClearBits [NTDLL]
517 NTSTATUS WINAPI
RtlClearBits(DWORD x1
,DWORD x2
,DWORD x3
)
519 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
523 /******************************************************************************
524 * RtlCopyMemory [NTDLL]
528 VOID WINAPI
RtlCopyMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
530 memcpy(Destination
, Source
, Length
);
533 /******************************************************************************
534 * RtlMoveMemory [NTDLL]
537 VOID WINAPI
RtlMoveMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
539 memmove(Destination
, Source
, Length
);
542 /******************************************************************************
543 * RtlFillMemory [NTDLL]
546 VOID WINAPI
RtlFillMemory( VOID
*Destination
, SIZE_T Length
, BYTE Fill
)
548 memset(Destination
, Fill
, Length
);
551 /******************************************************************************
552 * RtlZeroMemory [NTDLL]
555 VOID WINAPI
RtlZeroMemory( VOID
*Destination
, SIZE_T Length
)
557 memset(Destination
, 0, Length
);
560 /******************************************************************************
561 * RtlCompareMemory [NTDLL]
563 SIZE_T WINAPI
RtlCompareMemory( const VOID
*Source1
, const VOID
*Source2
, SIZE_T Length
)
566 for(i
=0; (i
<Length
) && (((LPBYTE
)Source1
)[i
]==((LPBYTE
)Source2
)[i
]); i
++);
570 /******************************************************************************
573 * Not implemented in non-debug versions.
575 void WINAPI
RtlAssert(LPVOID x1
,LPVOID x2
,DWORD x3
, DWORD x4
)
577 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
,x4
);