4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/debug.h"
30 #include "stackframe.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
38 static RTL_CRITICAL_SECTION peb_lock
= CRITICAL_SECTION_INIT("peb_lock");
44 /***********************************************************************
45 * RtlInitializeResource (NTDLL.@)
47 * xxxResource() functions implement multiple-reader-single-writer lock.
48 * The code is based on information published in WDJ January 1999 issue.
50 void WINAPI
RtlInitializeResource(LPRTL_RWLOCK rwl
)
54 rwl
->iNumberActive
= 0;
55 rwl
->uExclusiveWaiters
= 0;
56 rwl
->uSharedWaiters
= 0;
57 rwl
->hOwningThreadId
= 0;
58 rwl
->dwTimeoutBoost
= 0; /* no info on this one, default value is 0 */
59 RtlInitializeCriticalSection( &rwl
->rtlCS
);
60 NtCreateSemaphore( &rwl
->hExclusiveReleaseSemaphore
, 0, NULL
, 0, 65535 );
61 NtCreateSemaphore( &rwl
->hSharedReleaseSemaphore
, 0, NULL
, 0, 65535 );
66 /***********************************************************************
67 * RtlDeleteResource (NTDLL.@)
69 void WINAPI
RtlDeleteResource(LPRTL_RWLOCK rwl
)
73 RtlEnterCriticalSection( &rwl
->rtlCS
);
74 if( rwl
->iNumberActive
|| rwl
->uExclusiveWaiters
|| rwl
->uSharedWaiters
)
75 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl
);
76 rwl
->hOwningThreadId
= 0;
77 rwl
->uExclusiveWaiters
= rwl
->uSharedWaiters
= 0;
78 rwl
->iNumberActive
= 0;
79 NtClose( rwl
->hExclusiveReleaseSemaphore
);
80 NtClose( rwl
->hSharedReleaseSemaphore
);
81 RtlLeaveCriticalSection( &rwl
->rtlCS
);
82 RtlDeleteCriticalSection( &rwl
->rtlCS
);
87 /***********************************************************************
88 * RtlAcquireResourceExclusive (NTDLL.@)
90 BYTE WINAPI
RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl
, BYTE fWait
)
96 RtlEnterCriticalSection( &rwl
->rtlCS
);
97 if( rwl
->iNumberActive
== 0 ) /* lock is free */
99 rwl
->iNumberActive
= -1;
102 else if( rwl
->iNumberActive
< 0 ) /* exclusive lock in progress */
104 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
107 rwl
->iNumberActive
--;
113 rwl
->uExclusiveWaiters
++;
115 RtlLeaveCriticalSection( &rwl
->rtlCS
);
116 if( WaitForSingleObject( rwl
->hExclusiveReleaseSemaphore
, INFINITE
) == WAIT_FAILED
)
118 goto start
; /* restart the acquisition to avoid deadlocks */
121 else /* one or more shared locks are in progress */
126 rwl
->hOwningThreadId
= GetCurrentThreadId();
128 RtlLeaveCriticalSection( &rwl
->rtlCS
);
132 /***********************************************************************
133 * RtlAcquireResourceShared (NTDLL.@)
135 BYTE WINAPI
RtlAcquireResourceShared(LPRTL_RWLOCK rwl
, BYTE fWait
)
137 DWORD dwWait
= WAIT_FAILED
;
142 RtlEnterCriticalSection( &rwl
->rtlCS
);
143 if( rwl
->iNumberActive
< 0 )
145 if( rwl
->hOwningThreadId
== GetCurrentThreadId() )
147 rwl
->iNumberActive
--;
154 rwl
->uSharedWaiters
++;
155 RtlLeaveCriticalSection( &rwl
->rtlCS
);
156 if( (dwWait
= WaitForSingleObject( rwl
->hSharedReleaseSemaphore
, INFINITE
)) == WAIT_FAILED
)
163 if( dwWait
!= WAIT_OBJECT_0
) /* otherwise RtlReleaseResource() has already done it */
164 rwl
->iNumberActive
++;
168 RtlLeaveCriticalSection( &rwl
->rtlCS
);
173 /***********************************************************************
174 * RtlReleaseResource (NTDLL.@)
176 void WINAPI
RtlReleaseResource(LPRTL_RWLOCK rwl
)
178 RtlEnterCriticalSection( &rwl
->rtlCS
);
180 if( rwl
->iNumberActive
> 0 ) /* have one or more readers */
182 if( --rwl
->iNumberActive
== 0 )
184 if( rwl
->uExclusiveWaiters
)
187 rwl
->uExclusiveWaiters
--;
188 NtReleaseSemaphore( rwl
->hExclusiveReleaseSemaphore
, 1, NULL
);
193 if( rwl
->iNumberActive
< 0 ) /* have a writer, possibly recursive */
195 if( ++rwl
->iNumberActive
== 0 )
197 rwl
->hOwningThreadId
= 0;
198 if( rwl
->uExclusiveWaiters
)
201 if( rwl
->uSharedWaiters
)
203 UINT n
= rwl
->uSharedWaiters
;
204 rwl
->iNumberActive
= rwl
->uSharedWaiters
; /* prevent new writers from joining until
205 * all queued readers have done their thing */
206 rwl
->uSharedWaiters
= 0;
207 NtReleaseSemaphore( rwl
->hSharedReleaseSemaphore
, n
, NULL
);
211 RtlLeaveCriticalSection( &rwl
->rtlCS
);
215 /***********************************************************************
216 * RtlDumpResource (NTDLL.@)
218 void WINAPI
RtlDumpResource(LPRTL_RWLOCK rwl
)
222 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
223 rwl
, rwl
->iNumberActive
, rwl
->uSharedWaiters
, rwl
->uExclusiveWaiters
);
224 if( rwl
->iNumberActive
)
225 MESSAGE("\towner thread = %08x\n", rwl
->hOwningThreadId
);
233 /******************************************************************************
236 void WINAPIV
DbgPrint(LPCSTR fmt
, ...)
242 vsprintf(buf
,fmt
, args
);
245 MESSAGE("DbgPrint says: %s",buf
);
246 /* hmm, raise exception? */
249 /******************************************************************************
250 * RtlAcquirePebLock [NTDLL.@]
252 VOID WINAPI
RtlAcquirePebLock(void)
254 RtlEnterCriticalSection( &peb_lock
);
257 /******************************************************************************
258 * RtlReleasePebLock [NTDLL.@]
260 VOID WINAPI
RtlReleasePebLock(void)
262 RtlLeaveCriticalSection( &peb_lock
);
265 /******************************************************************************
266 * RtlIntegerToChar [NTDLL.@]
268 DWORD WINAPI
RtlIntegerToChar(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
) {
269 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
272 /******************************************************************************
273 * RtlSetEnvironmentVariable [NTDLL.@]
275 DWORD WINAPI
RtlSetEnvironmentVariable(DWORD x1
,PUNICODE_STRING key
,PUNICODE_STRING val
) {
276 FIXME("(0x%08lx,%s,%s),stub!\n",x1
,debugstr_w(key
->Buffer
),debugstr_w(val
->Buffer
));
280 /******************************************************************************
281 * RtlNewSecurityObject [NTDLL.@]
283 DWORD WINAPI
RtlNewSecurityObject(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
,DWORD x5
,DWORD x6
) {
284 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
,x5
,x6
);
288 /******************************************************************************
289 * RtlDeleteSecurityObject [NTDLL.@]
291 DWORD WINAPI
RtlDeleteSecurityObject(DWORD x1
) {
292 FIXME("(0x%08lx),stub!\n",x1
);
296 /**************************************************************************
297 * RtlNormalizeProcessParams [NTDLL.@]
299 LPVOID WINAPI
RtlNormalizeProcessParams(LPVOID x
)
301 FIXME("(%p), stub\n",x
);
305 /**************************************************************************
306 * RtlGetNtProductType [NTDLL.@]
308 BOOLEAN WINAPI
RtlGetNtProductType(LPDWORD type
)
310 FIXME("(%p): stub\n", type
);
311 *type
=3; /* dunno. 1 for client, 3 for server? */
315 /**************************************************************************
318 * Glorified "enter xxxx".
320 void WINAPI
NTDLL_chkstk( CONTEXT86
*context
)
322 context
->Esp
-= context
->Eax
;
325 /**************************************************************************
326 * _alloca_probe [NTDLL.@]
328 * Glorified "enter xxxx".
330 void WINAPI
NTDLL_alloca_probe( CONTEXT86
*context
)
332 context
->Esp
-= context
->Eax
;
335 /**************************************************************************
336 * RtlDosPathNameToNtPathName_U [NTDLL.@]
338 * FIXME: convert to UNC or whatever is expected here
340 BOOLEAN WINAPI
RtlDosPathNameToNtPathName_U(
341 LPWSTR from
,PUNICODE_STRING us
,DWORD x2
,DWORD x3
)
343 FIXME("(%s,%p,%08lx,%08lx)\n",debugstr_w(from
),us
,x2
,x3
);
344 if (us
) RtlCreateUnicodeString( us
, from
);
349 /***********************************************************************
350 * RtlImageNtHeader (NTDLL.@)
352 PIMAGE_NT_HEADERS WINAPI
RtlImageNtHeader(HMODULE hModule
)
354 IMAGE_NT_HEADERS
*ret
= NULL
;
355 IMAGE_DOS_HEADER
*dos
= (IMAGE_DOS_HEADER
*)hModule
;
357 if (dos
->e_magic
== IMAGE_DOS_SIGNATURE
)
359 ret
= (IMAGE_NT_HEADERS
*)((char *)dos
+ dos
->e_lfanew
);
360 if (ret
->Signature
!= IMAGE_NT_SIGNATURE
) ret
= NULL
;
366 /******************************************************************************
367 * RtlCreateEnvironment [NTDLL.@]
369 DWORD WINAPI
RtlCreateEnvironment(DWORD x1
,DWORD x2
) {
370 FIXME("(0x%08lx,0x%08lx),stub!\n",x1
,x2
);
375 /******************************************************************************
376 * RtlDestroyEnvironment [NTDLL.@]
378 DWORD WINAPI
RtlDestroyEnvironment(DWORD x
) {
379 FIXME("(0x%08lx),stub!\n",x
);
383 /******************************************************************************
384 * RtlQueryEnvironmentVariable_U [NTDLL.@]
386 DWORD WINAPI
RtlQueryEnvironmentVariable_U(DWORD x1
,PUNICODE_STRING key
,PUNICODE_STRING val
) {
387 FIXME("(0x%08lx,%s,%p),stub!\n",x1
,debugstr_w(key
->Buffer
),val
);
390 /******************************************************************************
391 * RtlInitializeGenericTable [NTDLL.@]
393 DWORD WINAPI
RtlInitializeGenericTable(void)
399 /******************************************************************************
400 * RtlInitializeBitMap [NTDLL.@]
403 NTSTATUS WINAPI
RtlInitializeBitMap(DWORD x1
,DWORD x2
,DWORD x3
)
405 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
409 /******************************************************************************
410 * RtlSetBits [NTDLL.@]
413 NTSTATUS WINAPI
RtlSetBits(DWORD x1
,DWORD x2
,DWORD x3
)
415 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
419 /******************************************************************************
420 * RtlFindClearBits [NTDLL.@]
423 NTSTATUS WINAPI
RtlFindClearBits(DWORD x1
,DWORD x2
,DWORD x3
)
425 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
429 /******************************************************************************
430 * RtlClearBits [NTDLL.@]
433 NTSTATUS WINAPI
RtlClearBits(DWORD x1
,DWORD x2
,DWORD x3
)
435 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
);
439 /******************************************************************************
440 * RtlCopyMemory [NTDLL]
444 VOID WINAPI
RtlCopyMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
446 memcpy(Destination
, Source
, Length
);
449 /******************************************************************************
450 * RtlMoveMemory [NTDLL.@]
453 VOID WINAPI
RtlMoveMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
455 memmove(Destination
, Source
, Length
);
458 /******************************************************************************
459 * RtlFillMemory [NTDLL.@]
462 VOID WINAPI
RtlFillMemory( VOID
*Destination
, SIZE_T Length
, BYTE Fill
)
464 memset(Destination
, Fill
, Length
);
467 /******************************************************************************
468 * RtlZeroMemory [NTDLL.@]
471 VOID WINAPI
RtlZeroMemory( VOID
*Destination
, SIZE_T Length
)
473 memset(Destination
, 0, Length
);
476 /******************************************************************************
477 * RtlCompareMemory [NTDLL.@]
479 SIZE_T WINAPI
RtlCompareMemory( const VOID
*Source1
, const VOID
*Source2
, SIZE_T Length
)
482 for(i
=0; (i
<Length
) && (((LPBYTE
)Source1
)[i
]==((LPBYTE
)Source2
)[i
]); i
++);
486 /******************************************************************************
487 * RtlAssert [NTDLL.@]
489 * Not implemented in non-debug versions.
491 void WINAPI
RtlAssert(LPVOID x1
,LPVOID x2
,DWORD x3
, DWORD x4
)
493 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1
,x2
,x3
,x4
);