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
31 #include "wine/unicode.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
37 static RTL_CRITICAL_SECTION peb_lock = CRITICAL_SECTION_INIT("peb_lock");
43 /***********************************************************************
44 * RtlInitializeResource (NTDLL.@)
46 * xxxResource() functions implement multiple-reader-single-writer lock.
47 * The code is based on information published in WDJ January 1999 issue.
49 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
53 rwl->iNumberActive = 0;
54 rwl->uExclusiveWaiters = 0;
55 rwl->uSharedWaiters = 0;
56 rwl->hOwningThreadId = 0;
57 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
58 RtlInitializeCriticalSection( &rwl->rtlCS );
59 NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, 0, NULL, 0, 65535 );
60 NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, 0, NULL, 0, 65535 );
65 /***********************************************************************
66 * RtlDeleteResource (NTDLL.@)
68 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
72 RtlEnterCriticalSection( &rwl->rtlCS );
73 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
74 MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl );
75 rwl->hOwningThreadId = 0;
76 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
77 rwl->iNumberActive = 0;
78 NtClose( rwl->hExclusiveReleaseSemaphore );
79 NtClose( rwl->hSharedReleaseSemaphore );
80 RtlLeaveCriticalSection( &rwl->rtlCS );
81 RtlDeleteCriticalSection( &rwl->rtlCS );
86 /***********************************************************************
87 * RtlAcquireResourceExclusive (NTDLL.@)
89 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
95 RtlEnterCriticalSection( &rwl->rtlCS );
96 if( rwl->iNumberActive == 0 ) /* lock is free */
98 rwl->iNumberActive = -1;
101 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
103 if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() )
106 rwl->iNumberActive--;
112 rwl->uExclusiveWaiters++;
114 RtlLeaveCriticalSection( &rwl->rtlCS );
115 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
117 goto start; /* restart the acquisition to avoid deadlocks */
120 else /* one or more shared locks are in progress */
125 rwl->hOwningThreadId = (HANDLE)GetCurrentThreadId();
127 RtlLeaveCriticalSection( &rwl->rtlCS );
131 /***********************************************************************
132 * RtlAcquireResourceShared (NTDLL.@)
134 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
136 DWORD dwWait = WAIT_FAILED;
141 RtlEnterCriticalSection( &rwl->rtlCS );
142 if( rwl->iNumberActive < 0 )
144 if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() )
146 rwl->iNumberActive--;
153 rwl->uSharedWaiters++;
154 RtlLeaveCriticalSection( &rwl->rtlCS );
155 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
162 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
163 rwl->iNumberActive++;
167 RtlLeaveCriticalSection( &rwl->rtlCS );
172 /***********************************************************************
173 * RtlReleaseResource (NTDLL.@)
175 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
177 RtlEnterCriticalSection( &rwl->rtlCS );
179 if( rwl->iNumberActive > 0 ) /* have one or more readers */
181 if( --rwl->iNumberActive == 0 )
183 if( rwl->uExclusiveWaiters )
186 rwl->uExclusiveWaiters--;
187 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
192 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
194 if( ++rwl->iNumberActive == 0 )
196 rwl->hOwningThreadId = 0;
197 if( rwl->uExclusiveWaiters )
200 if( rwl->uSharedWaiters )
202 UINT n = rwl->uSharedWaiters;
203 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
204 * all queued readers have done their thing */
205 rwl->uSharedWaiters = 0;
206 NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
210 RtlLeaveCriticalSection( &rwl->rtlCS );
214 /***********************************************************************
215 * RtlDumpResource (NTDLL.@)
217 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
221 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
222 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
223 if( rwl->iNumberActive )
224 MESSAGE("\towner thread = %p\n", rwl->hOwningThreadId );
232 /******************************************************************************
235 void WINAPIV DbgPrint(LPCSTR fmt, ...)
241 vsprintf(buf,fmt, args);
244 MESSAGE("DbgPrint says: %s",buf);
245 /* hmm, raise exception? */
248 /******************************************************************************
249 * RtlAcquirePebLock [NTDLL.@]
251 VOID WINAPI RtlAcquirePebLock(void)
253 RtlEnterCriticalSection( &peb_lock );
256 /******************************************************************************
257 * RtlReleasePebLock [NTDLL.@]
259 VOID WINAPI RtlReleasePebLock(void)
261 RtlLeaveCriticalSection( &peb_lock );
264 /******************************************************************************
265 * RtlIntegerToChar [NTDLL.@]
267 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
268 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
271 /******************************************************************************
272 * RtlSetEnvironmentVariable [NTDLL.@]
274 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
275 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
279 /******************************************************************************
280 * RtlNewSecurityObject [NTDLL.@]
282 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
283 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
287 /******************************************************************************
288 * RtlDeleteSecurityObject [NTDLL.@]
290 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
291 FIXME("(0x%08lx),stub!\n",x1);
295 /**************************************************************************
296 * RtlNormalizeProcessParams [NTDLL.@]
298 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
300 FIXME("(%p), stub\n",x);
304 /**************************************************************************
305 * RtlGetNtProductType [NTDLL.@]
307 BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
309 FIXME("(%p): stub\n", type);
310 *type=3; /* dunno. 1 for client, 3 for server? */
314 /**************************************************************************
317 * Glorified "enter xxxx".
319 void WINAPI NTDLL_chkstk( CONTEXT86 *context )
321 context->Esp -= context->Eax;
324 /**************************************************************************
325 * _alloca_probe [NTDLL.@]
327 * Glorified "enter xxxx".
329 void WINAPI NTDLL_alloca_probe( CONTEXT86 *context )
331 context->Esp -= context->Eax;
334 /**************************************************************************
335 * RtlDosPathNameToNtPathName_U [NTDLL.@]
337 * szwDosPath: a fully qualified DOS path name
338 * ntpath: pointer to a UNICODE_STRING to hold the converted
341 * FIXME: Should we not allocate the ntpath buffer under some
343 * Are the conversions static? (always prepend '\??\' ?)
344 * Not really sure about the last two arguments.
346 BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
347 LPWSTR szwDosPath,PUNICODE_STRING ntpath,
351 UNICODE_STRING pathprefix;
352 WCHAR szPrefix[] = { '\\', '?', '?', '\\', 0 };
354 FIXME("(%s,%p,%08lx,%08lx) partial stub\n",
355 debugstr_w(szwDosPath),ntpath,x2,x3);
360 if ( !szwDosPath[0] )
363 if ( szwDosPath[1]!= ':' )
366 length = strlenW(szwDosPath) * sizeof (WCHAR) + sizeof szPrefix;
368 ntpath->Buffer = RtlAllocateHeap(GetProcessHeap(), 0, length);
370 ntpath->MaximumLength = length;
372 if ( !ntpath->Buffer )
375 RtlInitUnicodeString( &pathprefix, szPrefix );
376 RtlCopyUnicodeString( ntpath, &pathprefix );
377 RtlAppendUnicodeToString( ntpath, szwDosPath );
383 /******************************************************************************
384 * RtlCreateEnvironment [NTDLL.@]
386 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
387 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
392 /******************************************************************************
393 * RtlDestroyEnvironment [NTDLL.@]
395 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
396 FIXME("(0x%08lx),stub!\n",x);
400 /******************************************************************************
401 * RtlQueryEnvironmentVariable_U [NTDLL.@]
403 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
404 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
407 /******************************************************************************
408 * RtlInitializeGenericTable [NTDLL.@]
410 DWORD WINAPI RtlInitializeGenericTable(void)
416 /******************************************************************************
417 * RtlCopyMemory [NTDLL]
421 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
423 memcpy(Destination, Source, Length);
426 /******************************************************************************
427 * RtlMoveMemory [NTDLL.@]
430 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
432 memmove(Destination, Source, Length);
435 /******************************************************************************
436 * RtlFillMemory [NTDLL.@]
439 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
441 memset(Destination, Fill, Length);
444 /******************************************************************************
445 * RtlZeroMemory [NTDLL.@]
448 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
450 memset(Destination, 0, Length);
453 /******************************************************************************
454 * RtlCompareMemory [NTDLL.@]
456 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
459 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
463 /******************************************************************************
464 * RtlAssert [NTDLL.@]
466 * Not implemented in non-debug versions.
468 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
470 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
473 /******************************************************************************
474 * RtlGetNtVersionNumbers [NTDLL.@]
476 * Introduced in Windows XP (NT5.1)
478 void WINAPI RtlGetNtVersionNumbers(LPDWORD major, LPDWORD minor, LPDWORD build)
480 OSVERSIONINFOEXW versionInfo;
481 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
482 GetVersionExW((OSVERSIONINFOW*)&versionInfo);
486 *major = versionInfo.dwMajorVersion;
491 *minor = versionInfo.dwMinorVersion;
496 /* FIXME: Does anybody know the real formula? */
497 *build = (0xF0000000 | versionInfo.dwBuildNumber);
501 /*************************************************************************
502 * RtlFillMemoryUlong [NTDLL.@]
504 * Fill memory with a 32 bit (dword) value.
507 * lpDest [I] Bitmap pointer
508 * ulCount [I] Number of dwords to write
509 * ulValue [I] Value to fill with
514 VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
516 TRACE("(%p,%ld,%ld)\n", lpDest, ulCount, ulValue);
522 /*************************************************************************
523 * RtlGetLongestNtPathLength [NTDLL.@]
525 * Get the longest allowed path length
531 * The longest allowed path length (277 characters under Win2k).
533 DWORD WINAPI RtlGetLongestNtPathLength(void)