vbscript: Implemented Tan.
[wine.git] / dlls / ntdll / rtl.c
blob8f6f386e45f1ee9f8398def0873eaca1f3282e5f
1 /*
2 * NT basis DLL
4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
7 * Copyright 1999 Alex Korobka
8 * Copyright 2003 Thomas Mertes
9 * Crc32 code Copyright 1986 Gary S. Brown (Public domain)
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "config.h"
27 #include "wine/port.h"
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36 #include "ntstatus.h"
37 #define NONAMELESSUNION
38 #define NONAMELESSSTRUCT
39 #define WIN32_NO_STATUS
40 #define USE_WS_PREFIX
41 #include "windef.h"
42 #include "winternl.h"
43 #include "wine/debug.h"
44 #include "wine/exception.h"
45 #include "wine/unicode.h"
46 #include "ntdll_misc.h"
47 #include "inaddr.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
51 static RTL_CRITICAL_SECTION peb_lock;
52 static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
54 0, 0, &peb_lock,
55 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
56 0, 0, { (DWORD_PTR)(__FILE__ ": peb_lock") }
58 static RTL_CRITICAL_SECTION peb_lock = { &critsect_debug, -1, 0, 0, 0, 0 };
60 /* CRC polynomial 0xedb88320 */
61 static const DWORD CRC_table[256] =
63 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
64 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
65 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
66 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
67 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
68 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
69 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
70 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
71 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
72 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
73 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
74 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
75 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
76 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
77 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
78 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
79 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
80 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
81 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
82 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
83 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
84 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
85 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
86 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
87 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
88 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
89 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
90 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
91 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
92 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
93 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
94 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
95 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
96 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
97 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
98 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
99 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
100 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
101 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
102 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
103 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
104 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
105 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
109 * resource functions
112 /***********************************************************************
113 * RtlInitializeResource (NTDLL.@)
115 * xxxResource() functions implement multiple-reader-single-writer lock.
116 * The code is based on information published in WDJ January 1999 issue.
118 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
120 if( rwl )
122 rwl->iNumberActive = 0;
123 rwl->uExclusiveWaiters = 0;
124 rwl->uSharedWaiters = 0;
125 rwl->hOwningThreadId = 0;
126 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
127 RtlInitializeCriticalSection( &rwl->rtlCS );
128 rwl->rtlCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": RTL_RWLOCK.rtlCS");
129 NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 );
130 NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 );
135 /***********************************************************************
136 * RtlDeleteResource (NTDLL.@)
138 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
140 if( rwl )
142 RtlEnterCriticalSection( &rwl->rtlCS );
143 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
144 ERR("Deleting active MRSW lock (%p), expect failure\n", rwl );
145 rwl->hOwningThreadId = 0;
146 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
147 rwl->iNumberActive = 0;
148 NtClose( rwl->hExclusiveReleaseSemaphore );
149 NtClose( rwl->hSharedReleaseSemaphore );
150 RtlLeaveCriticalSection( &rwl->rtlCS );
151 rwl->rtlCS.DebugInfo->Spare[0] = 0;
152 RtlDeleteCriticalSection( &rwl->rtlCS );
157 /***********************************************************************
158 * RtlAcquireResourceExclusive (NTDLL.@)
160 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
162 BYTE retVal = 0;
163 if( !rwl ) return 0;
165 start:
166 RtlEnterCriticalSection( &rwl->rtlCS );
167 if( rwl->iNumberActive == 0 ) /* lock is free */
169 rwl->iNumberActive = -1;
170 retVal = 1;
172 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
174 if( rwl->hOwningThreadId == ULongToHandle(GetCurrentThreadId()) )
176 retVal = 1;
177 rwl->iNumberActive--;
178 goto done;
180 wait:
181 if( fWait )
183 NTSTATUS status;
185 rwl->uExclusiveWaiters++;
187 RtlLeaveCriticalSection( &rwl->rtlCS );
188 status = NtWaitForSingleObject( rwl->hExclusiveReleaseSemaphore, FALSE, NULL );
189 if( HIWORD(status) )
190 goto done;
191 goto start; /* restart the acquisition to avoid deadlocks */
194 else /* one or more shared locks are in progress */
195 if( fWait )
196 goto wait;
198 if( retVal == 1 )
199 rwl->hOwningThreadId = ULongToHandle(GetCurrentThreadId());
200 done:
201 RtlLeaveCriticalSection( &rwl->rtlCS );
202 return retVal;
205 /***********************************************************************
206 * RtlAcquireResourceShared (NTDLL.@)
208 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
210 NTSTATUS status = STATUS_UNSUCCESSFUL;
211 BYTE retVal = 0;
212 if( !rwl ) return 0;
214 start:
215 RtlEnterCriticalSection( &rwl->rtlCS );
216 if( rwl->iNumberActive < 0 )
218 if( rwl->hOwningThreadId == ULongToHandle(GetCurrentThreadId()) )
220 rwl->iNumberActive--;
221 retVal = 1;
222 goto done;
225 if( fWait )
227 rwl->uSharedWaiters++;
228 RtlLeaveCriticalSection( &rwl->rtlCS );
229 status = NtWaitForSingleObject( rwl->hSharedReleaseSemaphore, FALSE, NULL );
230 if( HIWORD(status) )
231 goto done;
232 goto start;
235 else
237 if( status != STATUS_WAIT_0 ) /* otherwise RtlReleaseResource() has already done it */
238 rwl->iNumberActive++;
239 retVal = 1;
241 done:
242 RtlLeaveCriticalSection( &rwl->rtlCS );
243 return retVal;
247 /***********************************************************************
248 * RtlReleaseResource (NTDLL.@)
250 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
252 RtlEnterCriticalSection( &rwl->rtlCS );
254 if( rwl->iNumberActive > 0 ) /* have one or more readers */
256 if( --rwl->iNumberActive == 0 )
258 if( rwl->uExclusiveWaiters )
260 wake_exclusive:
261 rwl->uExclusiveWaiters--;
262 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
266 else
267 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
269 if( ++rwl->iNumberActive == 0 )
271 rwl->hOwningThreadId = 0;
272 if( rwl->uExclusiveWaiters )
273 goto wake_exclusive;
274 else
275 if( rwl->uSharedWaiters )
277 UINT n = rwl->uSharedWaiters;
278 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
279 * all queued readers have done their thing */
280 rwl->uSharedWaiters = 0;
281 NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
285 RtlLeaveCriticalSection( &rwl->rtlCS );
289 /***********************************************************************
290 * RtlDumpResource (NTDLL.@)
292 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
294 if( rwl )
296 MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
297 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
298 if( rwl->iNumberActive )
299 MESSAGE("\towner thread = %p\n", rwl->hOwningThreadId );
304 * misc functions
307 /******************************************************************************
308 * DbgPrint [NTDLL.@]
310 NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...)
312 char buf[512];
313 __ms_va_list args;
315 __ms_va_start(args, fmt);
316 NTDLL__vsnprintf(buf, sizeof(buf), fmt, args);
317 __ms_va_end(args);
319 MESSAGE("DbgPrint says: %s",buf);
320 /* hmm, raise exception? */
321 return STATUS_SUCCESS;
325 /******************************************************************************
326 * DbgPrintEx [NTDLL.@]
328 NTSTATUS WINAPIV DbgPrintEx(ULONG iComponentId, ULONG Level, LPCSTR fmt, ...)
330 NTSTATUS ret;
331 __ms_va_list args;
333 __ms_va_start(args, fmt);
334 ret = vDbgPrintEx(iComponentId, Level, fmt, args);
335 __ms_va_end(args);
336 return ret;
339 /******************************************************************************
340 * vDbgPrintEx [NTDLL.@]
342 NTSTATUS WINAPI vDbgPrintEx( ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args )
344 return vDbgPrintExWithPrefix( "", id, level, fmt, args );
347 /******************************************************************************
348 * vDbgPrintExWithPrefix [NTDLL.@]
350 NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args )
352 char buf[1024];
354 NTDLL__vsnprintf(buf, sizeof(buf), fmt, args);
356 switch (level & DPFLTR_MASK)
358 case DPFLTR_ERROR_LEVEL: ERR("%s%x: %s", prefix, id, buf); break;
359 case DPFLTR_WARNING_LEVEL: WARN("%s%x: %s", prefix, id, buf); break;
360 case DPFLTR_TRACE_LEVEL:
361 case DPFLTR_INFO_LEVEL:
362 default: TRACE("%s%x: %s", prefix, id, buf); break;
364 return STATUS_SUCCESS;
367 /******************************************************************************
368 * RtlAcquirePebLock [NTDLL.@]
370 VOID WINAPI RtlAcquirePebLock(void)
372 RtlEnterCriticalSection( &peb_lock );
375 /******************************************************************************
376 * RtlReleasePebLock [NTDLL.@]
378 VOID WINAPI RtlReleasePebLock(void)
380 RtlLeaveCriticalSection( &peb_lock );
383 /******************************************************************************
384 * RtlNewSecurityObject [NTDLL.@]
386 NTSTATUS WINAPI
387 RtlNewSecurityObject( PSECURITY_DESCRIPTOR ParentDescriptor,
388 PSECURITY_DESCRIPTOR CreatorDescriptor,
389 PSECURITY_DESCRIPTOR *NewDescriptor,
390 BOOLEAN IsDirectoryObject,
391 HANDLE Token,
392 PGENERIC_MAPPING GenericMapping )
394 FIXME("(%p %p %p %d %p %p) stub!\n", ParentDescriptor, CreatorDescriptor,
395 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
396 return STATUS_NOT_IMPLEMENTED;
399 /******************************************************************************
400 * RtlDeleteSecurityObject [NTDLL.@]
402 NTSTATUS WINAPI
403 RtlDeleteSecurityObject( PSECURITY_DESCRIPTOR *ObjectDescriptor )
405 FIXME("(%p) stub!\n", ObjectDescriptor);
406 return STATUS_NOT_IMPLEMENTED;
409 /******************************************************************************
410 * RtlInitializeGenericTable [NTDLL.@]
412 PVOID WINAPI RtlInitializeGenericTable(PVOID pTable, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
414 FIXME("(%p,%p,%p,%p,%p) stub!\n", pTable, arg2, arg3, arg4, arg5);
415 return NULL;
418 /******************************************************************************
419 * RtlEnumerateGenericTableWithoutSplaying [NTDLL.@]
421 PVOID RtlEnumerateGenericTableWithoutSplaying(PVOID pTable, PVOID *RestartKey)
423 static int warn_once;
425 if (!warn_once++)
426 FIXME("(%p,%p) stub!\n", pTable, RestartKey);
427 return NULL;
430 /******************************************************************************
431 * RtlNumberGenericTableElements [NTDLL.@]
433 ULONG RtlNumberGenericTableElements(PVOID pTable)
435 FIXME("(%p) stub!\n", pTable);
436 return 0;
439 /******************************************************************************
440 * RtlMoveMemory [NTDLL.@]
442 * Move a block of memory that may overlap.
444 * PARAMS
445 * Destination [O] End destination for block
446 * Source [O] Where to start copying from
447 * Length [I] Number of bytes to copy
449 * RETURNS
450 * Nothing.
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 * Set a block of memory with a value.
463 * PARAMS
464 * Destination [O] Block to fill
465 * Length [I] Number of bytes to fill
466 * Fill [I] Value to set
468 * RETURNS
469 * Nothing.
471 #undef RtlFillMemory
472 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
474 memset(Destination, Fill, Length);
477 /******************************************************************************
478 * RtlZeroMemory [NTDLL.@]
480 * Set a block of memory with 0's.
482 * PARAMS
483 * Destination [O] Block to fill
484 * Length [I] Number of bytes to fill
486 * RETURNS
487 * Nothing.
489 #undef RtlZeroMemory
490 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
492 memset(Destination, 0, Length);
495 /******************************************************************************
496 * RtlCompareMemory [NTDLL.@]
498 * Compare one block of memory with another
500 * PARAMS
501 * Source1 [I] Source block
502 * Source2 [I] Block to compare to Source1
503 * Length [I] Number of bytes to compare
505 * RETURNS
506 * The length of the first byte at which Source1 and Source2 differ, or Length
507 * if they are the same.
509 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
511 SIZE_T i;
512 for(i=0; (i<Length) && (((const BYTE*)Source1)[i]==((const BYTE*)Source2)[i]); i++);
513 return i;
516 /******************************************************************************
517 * RtlCompareMemoryUlong [NTDLL.@]
519 * Compare a block of memory with a value, a ULONG at a time
521 * PARAMS
522 * Source1 [I] Source block. This must be ULONG aligned
523 * Length [I] Number of bytes to compare. This should be a multiple of 4
524 * dwVal [I] Value to compare to
526 * RETURNS
527 * The byte position of the first byte at which Source1 is not dwVal.
529 SIZE_T WINAPI RtlCompareMemoryUlong(const ULONG *Source1, SIZE_T Length, ULONG dwVal)
531 SIZE_T i;
532 for(i = 0; i < Length/sizeof(ULONG) && Source1[i] == dwVal; i++);
533 return i * sizeof(ULONG);
536 /******************************************************************************
537 * RtlAssert [NTDLL.@]
539 * Fail a debug assertion.
541 * RETURNS
542 * Nothing. This call does not return control to its caller.
544 * NOTES
545 * Not implemented in non-debug versions.
547 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
549 FIXME("(%p,%p,0x%08x,0x%08x),stub\n",x1,x2,x3,x4);
552 /*************************************************************************
553 * RtlFillMemoryUlong [NTDLL.@]
555 * Fill memory with a 32 bit (dword) value.
557 * PARAMS
558 * lpDest [I] Bitmap pointer
559 * ulCount [I] Number of dwords to write
560 * ulValue [I] Value to fill with
562 * RETURNS
563 * Nothing.
565 VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
567 TRACE("(%p,%d,%d)\n", lpDest, ulCount, ulValue);
569 ulCount /= sizeof(ULONG);
570 while(ulCount--)
571 *lpDest++ = ulValue;
574 /*********************************************************************
575 * RtlComputeCrc32 [NTDLL.@]
577 * Calculate the CRC32 checksum of a block of bytes
579 * PARAMS
580 * dwInitial [I] Initial CRC value
581 * pData [I] Data block
582 * iLen [I] Length of the byte block
584 * RETURNS
585 * The cumulative CRC32 of dwInitial and iLen bytes of the pData block.
587 DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, const BYTE *pData, INT iLen)
589 DWORD crc = ~dwInitial;
591 TRACE("(%d,%p,%d)\n", dwInitial, pData, iLen);
593 while (iLen > 0)
595 crc = CRC_table[(crc ^ *pData) & 0xff] ^ (crc >> 8);
596 pData++;
597 iLen--;
599 return ~crc;
603 /*************************************************************************
604 * RtlUlonglongByteSwap [NTDLL.@]
606 * Swap the bytes of an unsigned long long value.
608 * PARAMS
609 * i [I] Value to swap bytes of
611 * RETURNS
612 * The value with its bytes swapped.
614 ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG i)
616 return ((ULONGLONG)RtlUlongByteSwap(i) << 32) | RtlUlongByteSwap(i>>32);
619 /*************************************************************************
620 * RtlUlongByteSwap [NTDLL.@]
622 * Swap the bytes of an unsigned int value.
624 * NOTES
625 * ix86 version takes argument in %ecx. Other systems use the inline version.
627 #ifdef __i386__
628 __ASM_GLOBAL_FUNC(NTDLL_RtlUlongByteSwap,
629 "movl %ecx,%eax\n\t"
630 "bswap %eax\n\t"
631 "ret")
632 #endif
634 /*************************************************************************
635 * RtlUshortByteSwap [NTDLL.@]
637 * Swap the bytes of an unsigned short value.
639 * NOTES
640 * i386 version takes argument in %cx. Other systems use the inline version.
642 #ifdef __i386__
643 __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap,
644 "movb %ch,%al\n\t"
645 "movb %cl,%ah\n\t"
646 "ret")
647 #endif
650 /*************************************************************************
651 * RtlUniform [NTDLL.@]
653 * Generates an uniform random number
655 * PARAMS
656 * seed [O] The seed of the Random function
658 * RETURNS
659 * It returns a random number uniformly distributed over [0..MAXLONG-1].
661 * NOTES
662 * Generates an uniform random number using D.H. Lehmer's 1948 algorithm.
663 * In our case the algorithm is:
665 *| result = (*seed * 0x7fffffed + 0x7fffffc3) % MAXLONG;
667 *| *seed = result;
669 * DIFFERENCES
670 * The native documentation states that the random number is
671 * uniformly distributed over [0..MAXLONG]. In reality the native
672 * function and our function return a random number uniformly
673 * distributed over [0..MAXLONG-1].
675 ULONG WINAPI RtlUniform (PULONG seed)
677 ULONG result;
680 * Instead of the algorithm stated above, we use the algorithm
681 * below, which is totally equivalent (see the tests), but does
682 * not use a division and therefore is faster.
684 result = *seed * 0xffffffed + 0x7fffffc3;
685 if (result == 0xffffffff || result == 0x7ffffffe) {
686 result = (result + 2) & MAXLONG;
687 } else if (result == 0x7fffffff) {
688 result = 0;
689 } else if ((result & 0x80000000) == 0) {
690 result = result + (~result & 1);
691 } else {
692 result = (result + (result & 1)) & MAXLONG;
693 } /* if */
694 *seed = result;
695 return result;
699 /*************************************************************************
700 * RtlRandom [NTDLL.@]
702 * Generates a random number
704 * PARAMS
705 * seed [O] The seed of the Random function
707 * RETURNS
708 * It returns a random number distributed over [0..MAXLONG-1].
710 ULONG WINAPI RtlRandom (PULONG seed)
712 static ULONG saved_value[128] =
713 { /* 0 */ 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626, 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa,
714 /* 8 */ 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8, 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09,
715 /* 16 */ 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5, 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311,
716 /* 24 */ 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be, 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82,
717 /* 32 */ 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4, 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd,
718 /* 40 */ 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016, 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52,
719 /* 48 */ 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c, 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb,
720 /* 56 */ 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8, 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e,
721 /* 64 */ 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb, 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0,
722 /* 72 */ 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743, 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd,
723 /* 80 */ 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78, 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35,
724 /* 88 */ 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a, 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379,
725 /* 96 */ 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d, 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd,
726 /* 104 */ 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515, 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b,
727 /* 112 */ 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975, 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b,
728 /* 120 */ 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb, 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d };
729 ULONG rand;
730 int pos;
731 ULONG result;
733 rand = (*seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
734 *seed = (rand * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
735 pos = *seed & 0x7f;
736 result = saved_value[pos];
737 saved_value[pos] = rand;
738 return(result);
742 /*************************************************************************
743 * RtlAreAllAccessesGranted [NTDLL.@]
745 * Check if all desired accesses are granted
747 * RETURNS
748 * TRUE: All desired accesses are granted
749 * FALSE: Otherwise
751 BOOLEAN WINAPI RtlAreAllAccessesGranted(
752 ACCESS_MASK GrantedAccess,
753 ACCESS_MASK DesiredAccess)
755 return (GrantedAccess & DesiredAccess) == DesiredAccess;
759 /*************************************************************************
760 * RtlAreAnyAccessesGranted [NTDLL.@]
762 * Check if at least one of the desired accesses is granted
764 * PARAMS
765 * GrantedAccess [I] Access mask of granted accesses
766 * DesiredAccess [I] Access mask of desired accesses
768 * RETURNS
769 * TRUE: At least one of the desired accesses is granted
770 * FALSE: Otherwise
772 BOOLEAN WINAPI RtlAreAnyAccessesGranted(
773 ACCESS_MASK GrantedAccess,
774 ACCESS_MASK DesiredAccess)
776 return (GrantedAccess & DesiredAccess) != 0;
780 /*************************************************************************
781 * RtlMapGenericMask [NTDLL.@]
783 * Determine the nongeneric access rights specified by an access mask
785 * RETURNS
786 * Nothing.
788 void WINAPI RtlMapGenericMask(
789 PACCESS_MASK AccessMask,
790 const GENERIC_MAPPING *GenericMapping)
792 if (*AccessMask & GENERIC_READ) {
793 *AccessMask |= GenericMapping->GenericRead;
794 } /* if */
796 if (*AccessMask & GENERIC_WRITE) {
797 *AccessMask |= GenericMapping->GenericWrite;
798 } /* if */
800 if (*AccessMask & GENERIC_EXECUTE) {
801 *AccessMask |= GenericMapping->GenericExecute;
802 } /* if */
804 if (*AccessMask & GENERIC_ALL) {
805 *AccessMask |= GenericMapping->GenericAll;
806 } /* if */
808 *AccessMask &= 0x0FFFFFFF;
812 /*************************************************************************
813 * RtlCopyLuid [NTDLL.@]
815 * Copy a local unique ID.
817 * PARAMS
818 * LuidDest [O] Destination for the copied Luid
819 * LuidSrc [I] Source Luid to copy to LuidDest
821 * RETURNS
822 * Nothing.
824 void WINAPI RtlCopyLuid (PLUID LuidDest, const LUID *LuidSrc)
826 *LuidDest = *LuidSrc;
830 /*************************************************************************
831 * RtlEqualLuid [NTDLL.@]
833 * Compare two local unique IDs.
835 * PARAMS
836 * Luid1 [I] First Luid to compare to Luid2
837 * Luid2 [I] Second Luid to compare to Luid1
839 * RETURNS
840 * TRUE: The two LUIDs are equal.
841 * FALSE: Otherwise
843 BOOLEAN WINAPI RtlEqualLuid (const LUID *Luid1, const LUID *Luid2)
845 return (Luid1->LowPart == Luid2->LowPart && Luid1->HighPart == Luid2->HighPart);
849 /*************************************************************************
850 * RtlCopyLuidAndAttributesArray [NTDLL.@]
852 * Copy an array of local unique IDs and attributes.
854 * PARAMS
855 * Count [I] Number of Luid/attributes in Src
856 * Src [I] Source Luid/attributes to copy
857 * Dest [O] Destination for copied Luid/attributes
859 * RETURNS
860 * Nothing.
862 * NOTES
863 * Dest must be large enough to hold Src.
865 void WINAPI RtlCopyLuidAndAttributesArray(
866 ULONG Count,
867 const LUID_AND_ATTRIBUTES *Src,
868 PLUID_AND_ATTRIBUTES Dest)
870 ULONG i;
872 for (i = 0; i < Count; i++) Dest[i] = Src[i];
875 NTSTATUS WINAPI RtlIpv4StringToAddressExW(PULONG IP, PULONG Port,
876 LPCWSTR Buffer, PULONG MaxSize)
878 FIXME("(%p,%p,%p,%p): stub\n", IP, Port, Buffer, MaxSize);
880 return STATUS_SUCCESS;
883 /***********************************************************************
884 * RtlIpv4AddressToStringExW [NTDLL.@]
886 * Convert the given ipv4 address and optional the port to a string
888 * PARAMS
889 * pin [I] PTR to the ip address to convert (network byte order)
890 * port [I] optional port to convert (network byte order)
891 * buffer [O] destination buffer for the result
892 * psize [IO] PTR to available/used size of the destination buffer
894 * RETURNS
895 * Success: STATUS_SUCCESS
896 * Failure: STATUS_INVALID_PARAMETER
899 NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWSTR buffer, PULONG psize)
901 WCHAR tmp_ip[32];
902 static const WCHAR fmt_ip[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
903 static const WCHAR fmt_port[] = {':','%','u',0};
904 ULONG needed;
906 if (!pin || !buffer || !psize)
907 return STATUS_INVALID_PARAMETER;
909 TRACE("(%p:0x%x, %d, %p, %p:%d)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
911 needed = sprintfW(tmp_ip, fmt_ip,
912 pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
913 pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
915 if (port) needed += sprintfW(tmp_ip + needed, fmt_port, ntohs(port));
917 if (*psize > needed) {
918 *psize = needed + 1;
919 strcpyW(buffer, tmp_ip);
920 return STATUS_SUCCESS;
923 *psize = needed + 1;
924 return STATUS_INVALID_PARAMETER;
927 /***********************************************************************
928 * RtlIpv4AddressToStringExA [NTDLL.@]
930 * Convert the given ipv4 address and optional the port to a string
932 * See RtlIpv4AddressToStringExW
934 NTSTATUS WINAPI RtlIpv4AddressToStringExA(const IN_ADDR *pin, USHORT port, LPSTR buffer, PULONG psize)
936 CHAR tmp_ip[32];
937 ULONG needed;
939 if (!pin || !buffer || !psize)
940 return STATUS_INVALID_PARAMETER;
942 TRACE("(%p:0x%x, %d, %p, %p:%d)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
944 needed = sprintf(tmp_ip, "%u.%u.%u.%u",
945 pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
946 pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
948 if (port) needed += sprintf(tmp_ip + needed, ":%u", ntohs(port));
950 if (*psize > needed) {
951 *psize = needed + 1;
952 strcpy(buffer, tmp_ip);
953 return STATUS_SUCCESS;
956 *psize = needed + 1;
957 return STATUS_INVALID_PARAMETER;
960 /***********************************************************************
961 * RtlIpv4AddressToStringW [NTDLL.@]
963 * Convert the given ipv4 address to a string
965 * PARAMS
966 * pin [I] PTR to the ip address to convert (network byte order)
967 * buffer [O] destination buffer for the result (at least 16 character)
969 * RETURNS
970 * PTR to the 0 character at the end of the converted string
973 WCHAR * WINAPI RtlIpv4AddressToStringW(const IN_ADDR *pin, LPWSTR buffer)
975 ULONG size = 16;
977 if (RtlIpv4AddressToStringExW(pin, 0, buffer, &size)) size = 0;
978 return buffer + size - 1;
981 /***********************************************************************
982 * RtlIpv4AddressToStringA [NTDLL.@]
984 * Convert the given ipv4 address to a string
986 * See RtlIpv4AddressToStringW
988 CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer)
990 ULONG size = 16;
992 if (RtlIpv4AddressToStringExA(pin, 0, buffer, &size)) size = 0;
993 return buffer + size - 1;
996 /***********************************************************************
997 * get_pointer_obfuscator (internal)
999 static DWORD_PTR get_pointer_obfuscator( void )
1001 static DWORD_PTR pointer_obfuscator;
1003 if (!pointer_obfuscator)
1005 ULONG seed = NtGetTickCount();
1006 ULONG_PTR rand;
1008 /* generate a random value for the obfuscator */
1009 rand = RtlUniform( &seed );
1011 /* handle 64bit pointers */
1012 rand ^= (ULONG_PTR)RtlUniform( &seed ) << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
1014 /* set the high bits so dereferencing obfuscated pointers will (usually) crash */
1015 rand |= (ULONG_PTR)0xc0000000 << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
1017 interlocked_cmpxchg_ptr( (void**) &pointer_obfuscator, (void*) rand, NULL );
1020 return pointer_obfuscator;
1023 /*************************************************************************
1024 * RtlEncodePointer [NTDLL.@]
1026 PVOID WINAPI RtlEncodePointer( PVOID ptr )
1028 DWORD_PTR ptrval = (DWORD_PTR) ptr;
1029 return (PVOID)(ptrval ^ get_pointer_obfuscator());
1032 PVOID WINAPI RtlDecodePointer( PVOID ptr )
1034 DWORD_PTR ptrval = (DWORD_PTR) ptr;
1035 return (PVOID)(ptrval ^ get_pointer_obfuscator());
1038 /*************************************************************************
1039 * RtlInitializeSListHead [NTDLL.@]
1041 VOID WINAPI RtlInitializeSListHead(PSLIST_HEADER list)
1043 #ifdef _WIN64
1044 list->s.Alignment = list->s.Region = 0;
1045 list->Header16.HeaderType = 1; /* we use the 16-byte header */
1046 #else
1047 list->Alignment = 0;
1048 #endif
1051 /*************************************************************************
1052 * RtlQueryDepthSList [NTDLL.@]
1054 WORD WINAPI RtlQueryDepthSList(PSLIST_HEADER list)
1056 #ifdef _WIN64
1057 return list->Header16.Depth;
1058 #else
1059 return list->s.Depth;
1060 #endif
1063 /*************************************************************************
1064 * RtlFirstEntrySList [NTDLL.@]
1066 PSLIST_ENTRY WINAPI RtlFirstEntrySList(const SLIST_HEADER* list)
1068 #ifdef _WIN64
1069 return (SLIST_ENTRY *)((ULONG_PTR)list->Header16.NextEntry << 4);
1070 #else
1071 return list->s.Next.Next;
1072 #endif
1075 /*************************************************************************
1076 * RtlInterlockedFlushSList [NTDLL.@]
1078 PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list)
1080 SLIST_HEADER old, new;
1082 #ifdef _WIN64
1083 if (!list->Header16.NextEntry) return NULL;
1084 new.s.Alignment = new.s.Region = 0;
1085 new.Header16.HeaderType = 1; /* we use the 16-byte header */
1088 old = *list;
1089 new.Header16.Sequence = old.Header16.Sequence + 1;
1090 } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1091 return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1092 #else
1093 if (!list->s.Next.Next) return NULL;
1094 new.Alignment = 0;
1097 old = *list;
1098 new.s.Sequence = old.s.Sequence + 1;
1099 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1100 old.Alignment) != old.Alignment);
1101 return old.s.Next.Next;
1102 #endif
1105 /*************************************************************************
1106 * RtlInterlockedPushEntrySList [NTDLL.@]
1108 PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTRY entry)
1110 SLIST_HEADER old, new;
1112 #ifdef _WIN64
1113 new.Header16.NextEntry = (ULONG_PTR)entry >> 4;
1116 old = *list;
1117 entry->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1118 new.Header16.Depth = old.Header16.Depth + 1;
1119 new.Header16.Sequence = old.Header16.Sequence + 1;
1120 } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1121 return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1122 #else
1123 new.s.Next.Next = entry;
1126 old = *list;
1127 entry->Next = old.s.Next.Next;
1128 new.s.Depth = old.s.Depth + 1;
1129 new.s.Sequence = old.s.Sequence + 1;
1130 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1131 old.Alignment) != old.Alignment);
1132 return old.s.Next.Next;
1133 #endif
1136 /*************************************************************************
1137 * RtlInterlockedPopEntrySList [NTDLL.@]
1139 PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list)
1141 SLIST_HEADER old, new;
1142 PSLIST_ENTRY entry;
1144 #ifdef _WIN64
1147 old = *list;
1148 if (!(entry = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4))) return NULL;
1149 /* entry could be deleted by another thread */
1150 __TRY
1152 new.Header16.NextEntry = (ULONG_PTR)entry->Next >> 4;
1153 new.Header16.Depth = old.Header16.Depth - 1;
1154 new.Header16.Sequence = old.Header16.Sequence + 1;
1156 __EXCEPT_PAGE_FAULT
1159 __ENDTRY
1160 } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1161 #else
1164 old = *list;
1165 if (!(entry = old.s.Next.Next)) return NULL;
1166 /* entry could be deleted by another thread */
1167 __TRY
1169 new.s.Next.Next = entry->Next;
1170 new.s.Depth = old.s.Depth - 1;
1171 new.s.Sequence = old.s.Sequence + 1;
1173 __EXCEPT_PAGE_FAULT
1176 __ENDTRY
1177 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1178 old.Alignment) != old.Alignment);
1179 #endif
1180 return entry;
1183 /*************************************************************************
1184 * RtlInterlockedPushListSList [NTDLL.@]
1186 PSLIST_ENTRY WINAPI RtlInterlockedPushListSList(PSLIST_HEADER list, PSLIST_ENTRY first,
1187 PSLIST_ENTRY last, ULONG count)
1189 SLIST_HEADER old, new;
1191 #ifdef _WIN64
1192 new.Header16.NextEntry = (ULONG_PTR)first >> 4;
1195 old = *list;
1196 new.Header16.Depth = old.Header16.Depth + count;
1197 new.Header16.Sequence = old.Header16.Sequence + 1;
1198 last->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1199 } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1200 return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1201 #else
1202 new.s.Next.Next = first;
1205 old = *list;
1206 new.s.Depth = old.s.Depth + count;
1207 new.s.Sequence = old.s.Sequence + 1;
1208 last->Next = old.s.Next.Next;
1209 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1210 old.Alignment) != old.Alignment);
1211 return old.s.Next.Next;
1212 #endif
1215 /******************************************************************************
1216 * RtlGetCompressionWorkSpaceSize [NTDLL.@]
1218 NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT CompressionFormatAndEngine,
1219 PULONG CompressBufferWorkSpaceSize,
1220 PULONG CompressFragmentWorkSpaceSize)
1222 FIXME("0x%04x, %p, %p: stub!\n", CompressionFormatAndEngine, CompressBufferWorkSpaceSize,
1223 CompressFragmentWorkSpaceSize);
1225 return STATUS_NOT_IMPLEMENTED;
1228 /******************************************************************************
1229 * RtlCompressBuffer [NTDLL.@]
1231 NTSTATUS WINAPI RtlCompressBuffer(USHORT CompressionFormatAndEngine, PUCHAR UncompressedBuffer,
1232 ULONG UncompressedBufferSize, PUCHAR CompressedBuffer,
1233 ULONG CompressedBufferSize, ULONG UncompressedChunkSize,
1234 PULONG FinalCompressedSize, PVOID WorkSpace)
1236 FIXME("0x%04x, %p, %u, %p, %u, %u, %p, %p :stub\n", CompressionFormatAndEngine, UncompressedBuffer,
1237 UncompressedBufferSize, CompressedBuffer, CompressedBufferSize, UncompressedChunkSize,
1238 FinalCompressedSize, WorkSpace);
1240 return STATUS_NOT_IMPLEMENTED;
1243 /******************************************************************************
1244 * RtlDecompressBuffer [NTDLL.@]
1246 NTSTATUS WINAPI RtlDecompressBuffer(USHORT CompressionFormat, PUCHAR UncompressedBuffer,
1247 ULONG UncompressedBufferSize, PUCHAR CompressedBuffer,
1248 ULONG CompressedBufferSize, PULONG FinalUncompressedSize)
1250 FIXME("0x%04x, %p, %u, %p, %u, %p :stub\n", CompressionFormat, UncompressedBuffer, UncompressedBufferSize,
1251 CompressedBuffer, CompressedBufferSize, FinalUncompressedSize);
1253 return STATUS_NOT_IMPLEMENTED;
1256 /***********************************************************************
1257 * RtlSetThreadErrorMode [NTDLL.@]
1259 * Set the thread local error mode.
1261 * PARAMS
1262 * mode [I] The new error mode
1263 * oldmode [O] Destination of the old error mode (may be NULL)
1265 * RETURNS
1266 * Success: STATUS_SUCCESS
1267 * Failure: STATUS_INVALID_PARAMETER_1
1269 NTSTATUS WINAPI RtlSetThreadErrorMode( DWORD mode, LPDWORD oldmode )
1271 if (mode & ~0x70)
1272 return STATUS_INVALID_PARAMETER_1;
1274 if (oldmode)
1275 *oldmode = NtCurrentTeb()->HardErrorDisabled;
1277 NtCurrentTeb()->HardErrorDisabled = mode;
1278 return STATUS_SUCCESS;
1281 /***********************************************************************
1282 * RtlGetThreadErrorMode [NTDLL.@]
1284 * Get the thread local error mode.
1286 * PARAMS
1287 * None.
1289 * RETURNS
1290 * The current thread local error mode.
1292 DWORD WINAPI RtlGetThreadErrorMode( void )
1294 return NtCurrentTeb()->HardErrorDisabled;
1297 /******************************************************************************
1298 * RtlGetCurrentTransaction [NTDLL.@]
1300 HANDLE WINAPI RtlGetCurrentTransaction(void)
1302 FIXME("() :stub\n");
1303 return NULL;
1306 /******************************************************************************
1307 * RtlSetCurrentTransaction [NTDLL.@]
1309 BOOL WINAPI RtlSetCurrentTransaction(HANDLE new_transaction)
1311 FIXME("(%p) :stub\n", new_transaction);
1312 return FALSE;