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
);
25 static RTL_CRITICAL_SECTION peb_lock
= CRITICAL_SECTION_INIT
;
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
)
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
)
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
)
83 RtlEnterCriticalSection( &rwl
->rtlCS
);
84 if( rwl
->iNumberActive
== 0 ) /* lock is free */
86 rwl
->iNumberActive
= -1;
89 else if( rwl
->iNumberActive
< 0 ) /* exclusive lock in progress */
91 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
100 rwl
->uExclusiveWaiters
++;
102 RtlLeaveCriticalSection( &rwl
->rtlCS
);
103 if( WaitForSingleObject( rwl
->hExclusiveReleaseSemaphore
, INFINITE
) == WAIT_FAILED
)
105 goto start
; /* restart the acquisition to avoid deadlocks */
108 else /* one or more shared locks are in progress */
113 rwl
->hOwningThreadId
= GetCurrentThreadId();
115 RtlLeaveCriticalSection( &rwl
->rtlCS
);
119 /***********************************************************************
120 * RtlAcquireResourceShared (NTDLL.257)
122 BYTE WINAPI
RtlAcquireResourceShared(LPRTL_RWLOCK rwl
, BYTE fWait
)
124 DWORD dwWait
= WAIT_FAILED
;
129 RtlEnterCriticalSection( &rwl
->rtlCS
);
130 if( rwl
->iNumberActive
< 0 )
132 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
134 rwl
->iNumberActive
--;
141 rwl
->uSharedWaiters
++;
142 RtlLeaveCriticalSection( &rwl
->rtlCS
);
143 if( (dwWait
= WaitForSingleObject( rwl
->hSharedReleaseSemaphore
, INFINITE
)) == WAIT_FAILED
)
150 if( dwWait
!= WAIT_OBJECT_0
) /* otherwise RtlReleaseResource() has already done it */
151 rwl
->iNumberActive
++;
155 RtlLeaveCriticalSection( &rwl
->rtlCS
);
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
)
174 rwl
->uExclusiveWaiters
--;
175 NtReleaseSemaphore( rwl
->hExclusiveReleaseSemaphore
, 1, NULL
);
180 if( rwl
->iNumberActive
< 0 ) /* have a writer, possibly recursive */
182 if( ++rwl
->iNumberActive
== 0 )
184 rwl
->hOwningThreadId
= 0;
185 if( rwl
->uExclusiveWaiters
)
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
)
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
);
220 /******************************************************************************
221 * RtlCreateHeap [NTDLL]
223 HANDLE WINAPI
RtlCreateHeap(
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(
245 TRACE("(0x%08x, 0x%08lx, 0x%08lx) semi stub\n",
247 return HeapAlloc(Heap
, Flags
, Size
);
250 /******************************************************************************
251 * RtlFreeHeap [NTDLL]
253 BOOLEAN WINAPI
RtlFreeHeap(
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(
271 TRACE("(0x%08x) semi stub\n", Heap
);
272 return HeapDestroy(Heap
);
279 /******************************************************************************
282 void WINAPIV
DbgPrint(LPCSTR fmt
, ...)
288 vsprintf(buf
,fmt
, 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
);
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
));
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
);
334 /******************************************************************************
335 * RtlDeleteSecurityObject [NTDLL]
337 DWORD WINAPI
RtlDeleteSecurityObject(DWORD x1
) {
338 FIXME("(0x%08lx),stub!\n",x1
);
342 /**************************************************************************
343 * RtlNormalizeProcessParams [NTDLL.441]
345 LPVOID WINAPI
RtlNormalizeProcessParams(LPVOID x
)
347 FIXME("(%p), stub\n",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? */
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
);
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
;
406 /******************************************************************************
407 * RtlCreateEnvironment [NTDLL]
409 DWORD WINAPI
RtlCreateEnvironment(DWORD x1
,DWORD x2
) {
410 FIXME("(0x%08lx,0x%08lx),stub!\n",x1
,x2
);
415 /******************************************************************************
416 * RtlDestroyEnvironment [NTDLL]
418 DWORD WINAPI
RtlDestroyEnvironment(DWORD x
) {
419 FIXME("(0x%08lx),stub!\n",x
);
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
);
430 /******************************************************************************
431 * RtlInitializeGenericTable [NTDLL]
433 DWORD WINAPI
RtlInitializeGenericTable(void)
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
);
449 /******************************************************************************
453 NTSTATUS WINAPI
RtlSetBits(DWORD x1
,DWORD x2
,DWORD x3
)
455 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
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
);
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
);
479 /******************************************************************************
480 * RtlCopyMemory [NTDLL]
484 VOID WINAPI
RtlCopyMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
486 memcpy(Destination
, Source
, Length
);
489 /******************************************************************************
490 * RtlMoveMemory [NTDLL]
493 VOID WINAPI
RtlMoveMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
495 memmove(Destination
, Source
, Length
);
498 /******************************************************************************
499 * RtlFillMemory [NTDLL]
502 VOID WINAPI
RtlFillMemory( VOID
*Destination
, SIZE_T Length
, BYTE Fill
)
504 memset(Destination
, Fill
, Length
);
507 /******************************************************************************
508 * RtlZeroMemory [NTDLL]
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
)
522 for(i
=0; (i
<Length
) && (((LPBYTE
)Source1
)[i
]==((LPBYTE
)Source2
)[i
]); i
++);
526 /******************************************************************************
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
);