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
);
24 static RTL_CRITICAL_SECTION peb_lock
= CRITICAL_SECTION_INIT("peb_lock");
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
)
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
)
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
)
82 RtlEnterCriticalSection( &rwl
->rtlCS
);
83 if( rwl
->iNumberActive
== 0 ) /* lock is free */
85 rwl
->iNumberActive
= -1;
88 else if( rwl
->iNumberActive
< 0 ) /* exclusive lock in progress */
90 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
99 rwl
->uExclusiveWaiters
++;
101 RtlLeaveCriticalSection( &rwl
->rtlCS
);
102 if( WaitForSingleObject( rwl
->hExclusiveReleaseSemaphore
, INFINITE
) == WAIT_FAILED
)
104 goto start
; /* restart the acquisition to avoid deadlocks */
107 else /* one or more shared locks are in progress */
112 rwl
->hOwningThreadId
= GetCurrentThreadId();
114 RtlLeaveCriticalSection( &rwl
->rtlCS
);
118 /***********************************************************************
119 * RtlAcquireResourceShared (NTDLL.@)
121 BYTE WINAPI
RtlAcquireResourceShared(LPRTL_RWLOCK rwl
, BYTE fWait
)
123 DWORD dwWait
= WAIT_FAILED
;
128 RtlEnterCriticalSection( &rwl
->rtlCS
);
129 if( rwl
->iNumberActive
< 0 )
131 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
133 rwl
->iNumberActive
--;
140 rwl
->uSharedWaiters
++;
141 RtlLeaveCriticalSection( &rwl
->rtlCS
);
142 if( (dwWait
= WaitForSingleObject( rwl
->hSharedReleaseSemaphore
, INFINITE
)) == WAIT_FAILED
)
149 if( dwWait
!= WAIT_OBJECT_0
) /* otherwise RtlReleaseResource() has already done it */
150 rwl
->iNumberActive
++;
154 RtlLeaveCriticalSection( &rwl
->rtlCS
);
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
)
173 rwl
->uExclusiveWaiters
--;
174 NtReleaseSemaphore( rwl
->hExclusiveReleaseSemaphore
, 1, NULL
);
179 if( rwl
->iNumberActive
< 0 ) /* have a writer, possibly recursive */
181 if( ++rwl
->iNumberActive
== 0 )
183 rwl
->hOwningThreadId
= 0;
184 if( rwl
->uExclusiveWaiters
)
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
)
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
);
219 /******************************************************************************
222 void WINAPIV
DbgPrint(LPCSTR fmt
, ...)
228 vsprintf(buf
,fmt
, 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
);
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
));
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
);
274 /******************************************************************************
275 * RtlDeleteSecurityObject [NTDLL.@]
277 DWORD WINAPI
RtlDeleteSecurityObject(DWORD x1
) {
278 FIXME("(0x%08lx),stub!\n",x1
);
282 /**************************************************************************
283 * RtlNormalizeProcessParams [NTDLL.@]
285 LPVOID WINAPI
RtlNormalizeProcessParams(LPVOID x
)
287 FIXME("(%p), stub\n",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? */
301 /**************************************************************************
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
);
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
;
352 /******************************************************************************
353 * RtlCreateEnvironment [NTDLL.@]
355 DWORD WINAPI
RtlCreateEnvironment(DWORD x1
,DWORD x2
) {
356 FIXME("(0x%08lx,0x%08lx),stub!\n",x1
,x2
);
361 /******************************************************************************
362 * RtlDestroyEnvironment [NTDLL.@]
364 DWORD WINAPI
RtlDestroyEnvironment(DWORD x
) {
365 FIXME("(0x%08lx),stub!\n",x
);
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
);
376 /******************************************************************************
377 * RtlInitializeGenericTable [NTDLL.@]
379 DWORD WINAPI
RtlInitializeGenericTable(void)
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
);
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
);
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
);
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
);
425 /******************************************************************************
426 * RtlCopyMemory [NTDLL]
430 VOID WINAPI
RtlCopyMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
432 memcpy(Destination
, Source
, Length
);
435 /******************************************************************************
436 * RtlMoveMemory [NTDLL.@]
439 VOID WINAPI
RtlMoveMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
441 memmove(Destination
, Source
, Length
);
444 /******************************************************************************
445 * RtlFillMemory [NTDLL.@]
448 VOID WINAPI
RtlFillMemory( VOID
*Destination
, SIZE_T Length
, BYTE Fill
)
450 memset(Destination
, Fill
, Length
);
453 /******************************************************************************
454 * RtlZeroMemory [NTDLL.@]
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
)
468 for(i
=0; (i
<Length
) && (((LPBYTE
)Source1
)[i
]==((LPBYTE
)Source2
)[i
]); 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
);