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
== (HANDLE
)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
= (HANDLE
)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
== (HANDLE
)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 * RtlCreateEnvironment [NTDLL.@]
352 DWORD WINAPI
RtlCreateEnvironment(DWORD x1
,DWORD x2
) {
353 FIXME("(0x%08lx,0x%08lx),stub!\n",x1
,x2
);
358 /******************************************************************************
359 * RtlDestroyEnvironment [NTDLL.@]
361 DWORD WINAPI
RtlDestroyEnvironment(DWORD x
) {
362 FIXME("(0x%08lx),stub!\n",x
);
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
);
373 /******************************************************************************
374 * RtlInitializeGenericTable [NTDLL.@]
376 DWORD WINAPI
RtlInitializeGenericTable(void)
382 /******************************************************************************
383 * RtlCopyMemory [NTDLL]
387 VOID WINAPI
RtlCopyMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
389 memcpy(Destination
, Source
, Length
);
392 /******************************************************************************
393 * RtlMoveMemory [NTDLL.@]
396 VOID WINAPI
RtlMoveMemory( VOID
*Destination
, CONST VOID
*Source
, SIZE_T Length
)
398 memmove(Destination
, Source
, Length
);
401 /******************************************************************************
402 * RtlFillMemory [NTDLL.@]
405 VOID WINAPI
RtlFillMemory( VOID
*Destination
, SIZE_T Length
, BYTE Fill
)
407 memset(Destination
, Fill
, Length
);
410 /******************************************************************************
411 * RtlZeroMemory [NTDLL.@]
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
)
425 for(i
=0; (i
<Length
) && (((LPBYTE
)Source1
)[i
]==((LPBYTE
)Source2
)[i
]); 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
);
452 *major
= versionInfo
.dwMajorVersion
;
457 *minor
= versionInfo
.dwMinorVersion
;
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.
473 * lpDest [I] Bitmap pointer
474 * ulCount [I] Number of dwords to write
475 * ulValue [I] Value to fill with
480 VOID WINAPI
RtlFillMemoryUlong(ULONG
* lpDest
, ULONG ulCount
, ULONG ulValue
)
482 TRACE("(%p,%ld,%ld)\n", lpDest
, ulCount
, ulValue
);
488 /*************************************************************************
489 * RtlGetLongestNtPathLength [NTDLL.@]
491 * Get the longest allowed path length
497 * The longest allowed path length (277 characters under Win2k).
499 DWORD WINAPI
RtlGetLongestNtPathLength(void)