Add check for <sys/ioctl.h>.
[wine/multimedia.git] / dlls / ntdll / rtl.c
blob23431cbab0d410e973ac07284c61a40ed3b6346c
1 /*
2 * NT basis DLL
3 *
4 * This file contains the Rtl* API functions. These should be implementable.
5 *
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 == 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 = 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 == 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 * 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;
362 return ret;
366 /******************************************************************************
367 * RtlCreateEnvironment [NTDLL.@]
369 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
370 FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
371 return 0;
375 /******************************************************************************
376 * RtlDestroyEnvironment [NTDLL.@]
378 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
379 FIXME("(0x%08lx),stub!\n",x);
380 return 0;
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);
388 return 0;
390 /******************************************************************************
391 * RtlInitializeGenericTable [NTDLL.@]
393 DWORD WINAPI RtlInitializeGenericTable(void)
395 FIXME("\n");
396 return 0;
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);
406 return 0;
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);
416 return 0;
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);
426 return 0;
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);
436 return 0;
439 /******************************************************************************
440 * RtlCopyMemory [NTDLL]
443 #undef RtlCopyMemory
444 VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
446 memcpy(Destination, Source, Length);
449 /******************************************************************************
450 * RtlMoveMemory [NTDLL.@]
452 #undef RtlMoveMemory
453 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
455 memmove(Destination, Source, Length);
458 /******************************************************************************
459 * RtlFillMemory [NTDLL.@]
461 #undef RtlFillMemory
462 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
464 memset(Destination, Fill, Length);
467 /******************************************************************************
468 * RtlZeroMemory [NTDLL.@]
470 #undef RtlZeroMemory
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)
481 int i;
482 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
483 return 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);