Fixed some issues found by winapi_check.
[wine/dcerpc.git] / dlls / ntdll / rtl.c
blob4b3ac8102c4e40231fea756eb3b64e9bf058243d
1 /*
2 * NT basis DLL
4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
7 * 1999 Alex Korobka
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
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include "wine/debug.h"
28 #include "windef.h"
29 #include "winerror.h"
30 #include "stackframe.h"
32 #include "ntddk.h"
33 #include "winreg.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
38 static RTL_CRITICAL_SECTION peb_lock = CRITICAL_SECTION_INIT("peb_lock");
41 * resource functions
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)
52 if( 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)
71 if( 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)
92 BYTE retVal = 0;
93 if( !rwl ) return 0;
95 start:
96 RtlEnterCriticalSection( &rwl->rtlCS );
97 if( rwl->iNumberActive == 0 ) /* lock is free */
99 rwl->iNumberActive = -1;
100 retVal = 1;
102 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
104 if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() )
106 retVal = 1;
107 rwl->iNumberActive--;
108 goto done;
110 wait:
111 if( fWait )
113 rwl->uExclusiveWaiters++;
115 RtlLeaveCriticalSection( &rwl->rtlCS );
116 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
117 goto done;
118 goto start; /* restart the acquisition to avoid deadlocks */
121 else /* one or more shared locks are in progress */
122 if( fWait )
123 goto wait;
125 if( retVal == 1 )
126 rwl->hOwningThreadId = (HANDLE)GetCurrentThreadId();
127 done:
128 RtlLeaveCriticalSection( &rwl->rtlCS );
129 return retVal;
132 /***********************************************************************
133 * RtlAcquireResourceShared (NTDLL.@)
135 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
137 DWORD dwWait = WAIT_FAILED;
138 BYTE retVal = 0;
139 if( !rwl ) return 0;
141 start:
142 RtlEnterCriticalSection( &rwl->rtlCS );
143 if( rwl->iNumberActive < 0 )
145 if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() )
147 rwl->iNumberActive--;
148 retVal = 1;
149 goto done;
152 if( fWait )
154 rwl->uSharedWaiters++;
155 RtlLeaveCriticalSection( &rwl->rtlCS );
156 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
157 goto done;
158 goto start;
161 else
163 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
164 rwl->iNumberActive++;
165 retVal = 1;
167 done:
168 RtlLeaveCriticalSection( &rwl->rtlCS );
169 return retVal;
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 )
186 wake_exclusive:
187 rwl->uExclusiveWaiters--;
188 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
192 else
193 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
195 if( ++rwl->iNumberActive == 0 )
197 rwl->hOwningThreadId = 0;
198 if( rwl->uExclusiveWaiters )
199 goto wake_exclusive;
200 else
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)
220 if( 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 );
230 * misc functions
233 /******************************************************************************
234 * DbgPrint [NTDLL.@]
236 void WINAPIV DbgPrint(LPCSTR fmt, ...)
238 char buf[512];
239 va_list args;
241 va_start(args, fmt);
242 vsprintf(buf,fmt, args);
243 va_end(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);
270 return 0;
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));
277 return 0;
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);
285 return 0;
288 /******************************************************************************
289 * RtlDeleteSecurityObject [NTDLL.@]
291 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
292 FIXME("(0x%08lx),stub!\n",x1);
293 return 0;
296 /**************************************************************************
297 * RtlNormalizeProcessParams [NTDLL.@]
299 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
301 FIXME("(%p), stub\n",x);
302 return 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? */
312 return 1;
315 /**************************************************************************
316 * _chkstk [NTDLL.@]
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 );
345 return TRUE;
349 /******************************************************************************
350 * RtlCreateEnvironment [NTDLL.@]
352 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
353 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
354 return 0;
358 /******************************************************************************
359 * RtlDestroyEnvironment [NTDLL.@]
361 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
362 FIXME("(0x%08lx),stub!\n",x);
363 return 0;
366 /******************************************************************************
367 * RtlQueryEnvironmentVariable_U [NTDLL.@]
369 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
370 FIXME("(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
371 return 0;
373 /******************************************************************************
374 * RtlInitializeGenericTable [NTDLL.@]
376 DWORD WINAPI RtlInitializeGenericTable(void)
378 FIXME("\n");
379 return 0;
382 /******************************************************************************
383 * RtlCopyMemory [NTDLL]
386 #undef RtlCopyMemory
387 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
389 memcpy(Destination, Source, Length);
392 /******************************************************************************
393 * RtlMoveMemory [NTDLL.@]
395 #undef RtlMoveMemory
396 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
398 memmove(Destination, Source, Length);
401 /******************************************************************************
402 * RtlFillMemory [NTDLL.@]
404 #undef RtlFillMemory
405 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
407 memset(Destination, Fill, Length);
410 /******************************************************************************
411 * RtlZeroMemory [NTDLL.@]
413 #undef RtlZeroMemory
414 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
416 memset(Destination, 0, Length);
419 /******************************************************************************
420 * RtlCompareMemory [NTDLL.@]
422 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
424 int i;
425 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
426 return i;
429 /******************************************************************************
430 * RtlAssert [NTDLL.@]
432 * Not implemented in non-debug versions.
434 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
436 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
439 /******************************************************************************
440 * RtlGetNtVersionNumbers [NTDLL.@]
442 * Introduced in Windows XP (NT5.1)
444 void WINAPI RtlGetNtVersionNumbers(LPDWORD major, LPDWORD minor, LPDWORD build)
446 OSVERSIONINFOEXW versionInfo;
447 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
448 GetVersionExW((OSVERSIONINFOW*)&versionInfo);
450 if (major)
452 *major = versionInfo.dwMajorVersion;
455 if (minor)
457 *minor = versionInfo.dwMinorVersion;
460 if (build)
462 /* FIXME: Does anybody know the real formula? */
463 *build = (0xF0000000 | versionInfo.dwBuildNumber);
467 /*************************************************************************
468 * RtlFillMemoryUlong [NTDLL.@]
470 * Fill memory with a 32 bit (dword) value.
472 * PARAMS
473 * lpDest [I] Bitmap pointer
474 * ulCount [I] Number of dwords to write
475 * ulValue [I] Value to fill with
477 * RETURNS
478 * Nothing.
480 VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
482 TRACE("(%p,%ld,%ld)\n", lpDest, ulCount, ulValue);
484 while(ulCount--)
485 *lpDest++ = ulValue;
488 /*************************************************************************
489 * RtlGetLongestNtPathLength [NTDLL.@]
491 * Get the longest allowed path length
493 * PARAMS
494 * None.
496 * RETURNS
497 * The longest allowed path length (277 characters under Win2k).
499 DWORD WINAPI RtlGetLongestNtPathLength(void)
501 TRACE("()\n");
502 return 277;