~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ntdll/rtl.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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  * Copyright 1999      Alex Korobka
  8  * Copyright 2003      Thomas Mertes
  9  * Crc32 code Copyright 1986 Gary S. Brown (Public domain)
 10  *
 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.
 15  *
 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.
 20  *
 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
 24  */
 25 
 26 #include "config.h"
 27 #include "wine/port.h"
 28 
 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 NONAMELESSSTRUCT
 38 #define WIN32_NO_STATUS
 39 #define USE_WS_PREFIX
 40 #include "windef.h"
 41 #include "winternl.h"
 42 #include "wine/debug.h"
 43 #include "wine/exception.h"
 44 #include "wine/unicode.h"
 45 #include "ntdll_misc.h"
 46 #include "inaddr.h"
 47 
 48 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
 49 
 50 static RTL_CRITICAL_SECTION peb_lock;
 51 static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
 52 {
 53     0, 0, &peb_lock,
 54     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
 55       0, 0, { (DWORD_PTR)(__FILE__ ": peb_lock") }
 56 };
 57 static RTL_CRITICAL_SECTION peb_lock = { &critsect_debug, -1, 0, 0, 0, 0 };
 58 
 59 /* CRC polynomial 0xedb88320 */
 60 static const DWORD CRC_table[256] =
 61 {
 62     0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
 63     0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
 64     0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
 65     0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
 66     0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
 67     0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
 68     0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
 69     0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
 70     0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
 71     0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
 72     0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
 73     0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
 74     0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
 75     0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
 76     0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
 77     0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
 78     0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
 79     0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
 80     0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
 81     0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 82     0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
 83     0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
 84     0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
 85     0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
 86     0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
 87     0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
 88     0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
 89     0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
 90     0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
 91     0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 92     0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
 93     0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
 94     0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
 95     0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
 96     0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
 97     0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
 98     0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
 99     0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
100     0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
101     0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
102     0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
103     0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
104     0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
105 };
106 
107 /*
108  *      resource functions
109  */
110 
111 /***********************************************************************
112  *           RtlInitializeResource      (NTDLL.@)
113  *
114  * xxxResource() functions implement multiple-reader-single-writer lock.
115  * The code is based on information published in WDJ January 1999 issue.
116  */
117 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
118 {
119     if( rwl )
120     {
121         rwl->iNumberActive = 0;
122         rwl->uExclusiveWaiters = 0;
123         rwl->uSharedWaiters = 0;
124         rwl->hOwningThreadId = 0;
125         rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
126         RtlInitializeCriticalSection( &rwl->rtlCS );
127         rwl->rtlCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": RTL_RWLOCK.rtlCS");
128         NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 );
129         NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 );
130     }
131 }
132 
133 
134 /***********************************************************************
135  *           RtlDeleteResource          (NTDLL.@)
136  */
137 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
138 {
139     if( rwl )
140     {
141         RtlEnterCriticalSection( &rwl->rtlCS );
142         if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
143             ERR("Deleting active MRSW lock (%p), expect failure\n", rwl );
144         rwl->hOwningThreadId = 0;
145         rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
146         rwl->iNumberActive = 0;
147         NtClose( rwl->hExclusiveReleaseSemaphore );
148         NtClose( rwl->hSharedReleaseSemaphore );
149         RtlLeaveCriticalSection( &rwl->rtlCS );
150         rwl->rtlCS.DebugInfo->Spare[0] = 0;
151         RtlDeleteCriticalSection( &rwl->rtlCS );
152     }
153 }
154 
155 
156 /***********************************************************************
157  *          RtlAcquireResourceExclusive (NTDLL.@)
158  */
159 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
160 {
161     BYTE retVal = 0;
162     if( !rwl ) return 0;
163 
164 start:
165     RtlEnterCriticalSection( &rwl->rtlCS );
166     if( rwl->iNumberActive == 0 ) /* lock is free */
167     {
168         rwl->iNumberActive = -1;
169         retVal = 1;
170     }
171     else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
172     {
173          if( rwl->hOwningThreadId == ULongToHandle(GetCurrentThreadId()) )
174          {
175              retVal = 1;
176              rwl->iNumberActive--;
177              goto done;
178          }
179 wait:
180          if( fWait )
181          {
182              NTSTATUS status;
183 
184              rwl->uExclusiveWaiters++;
185 
186              RtlLeaveCriticalSection( &rwl->rtlCS );
187              status = NtWaitForSingleObject( rwl->hExclusiveReleaseSemaphore, FALSE, NULL );
188              if( HIWORD(status) )
189                  goto done;
190              goto start; /* restart the acquisition to avoid deadlocks */
191          }
192     }
193     else  /* one or more shared locks are in progress */
194          if( fWait )
195              goto wait;
196 
197     if( retVal == 1 )
198         rwl->hOwningThreadId = ULongToHandle(GetCurrentThreadId());
199 done:
200     RtlLeaveCriticalSection( &rwl->rtlCS );
201     return retVal;
202 }
203 
204 /***********************************************************************
205  *          RtlAcquireResourceShared    (NTDLL.@)
206  */
207 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
208 {
209     NTSTATUS status = STATUS_UNSUCCESSFUL;
210     BYTE retVal = 0;
211     if( !rwl ) return 0;
212 
213 start:
214     RtlEnterCriticalSection( &rwl->rtlCS );
215     if( rwl->iNumberActive < 0 )
216     {
217         if( rwl->hOwningThreadId == ULongToHandle(GetCurrentThreadId()) )
218         {
219             rwl->iNumberActive--;
220             retVal = 1;
221             goto done;
222         }
223 
224         if( fWait )
225         {
226             rwl->uSharedWaiters++;
227             RtlLeaveCriticalSection( &rwl->rtlCS );
228             status = NtWaitForSingleObject( rwl->hSharedReleaseSemaphore, FALSE, NULL );
229             if( HIWORD(status) )
230                 goto done;
231             goto start;
232         }
233     }
234     else
235     {
236         if( status != STATUS_WAIT_0 ) /* otherwise RtlReleaseResource() has already done it */
237             rwl->iNumberActive++;
238         retVal = 1;
239     }
240 done:
241     RtlLeaveCriticalSection( &rwl->rtlCS );
242     return retVal;
243 }
244 
245 
246 /***********************************************************************
247  *           RtlReleaseResource         (NTDLL.@)
248  */
249 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
250 {
251     RtlEnterCriticalSection( &rwl->rtlCS );
252 
253     if( rwl->iNumberActive > 0 ) /* have one or more readers */
254     {
255         if( --rwl->iNumberActive == 0 )
256         {
257             if( rwl->uExclusiveWaiters )
258             {
259 wake_exclusive:
260                 rwl->uExclusiveWaiters--;
261                 NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
262             }
263         }
264     }
265     else
266     if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
267     {
268         if( ++rwl->iNumberActive == 0 )
269         {
270             rwl->hOwningThreadId = 0;
271             if( rwl->uExclusiveWaiters )
272                 goto wake_exclusive;
273             else
274                 if( rwl->uSharedWaiters )
275                 {
276                     UINT n = rwl->uSharedWaiters;
277                     rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
278                                                                * all queued readers have done their thing */
279                     rwl->uSharedWaiters = 0;
280                     NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
281                 }
282         }
283     }
284     RtlLeaveCriticalSection( &rwl->rtlCS );
285 }
286 
287 
288 /***********************************************************************
289  *           RtlDumpResource            (NTDLL.@)
290  */
291 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
292 {
293     if( rwl )
294     {
295         MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
296                 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
297         if( rwl->iNumberActive )
298             MESSAGE("\towner thread = %p\n", rwl->hOwningThreadId );
299     }
300 }
301 
302 /*
303  *      misc functions
304  */
305 
306 /******************************************************************************
307  *      DbgPrint        [NTDLL.@]
308  */
309 NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...)
310 {
311   char buf[512];
312   __ms_va_list args;
313 
314   __ms_va_start(args, fmt);
315   NTDLL__vsnprintf(buf, sizeof(buf), fmt, args);
316   __ms_va_end(args);
317 
318   MESSAGE("DbgPrint says: %s",buf);
319   /* hmm, raise exception? */
320   return STATUS_SUCCESS;
321 }
322 
323 
324 /******************************************************************************
325  *      DbgPrintEx      [NTDLL.@]
326  */
327 NTSTATUS WINAPIV DbgPrintEx(ULONG iComponentId, ULONG Level, LPCSTR fmt, ...)
328 {
329     NTSTATUS ret;
330     __ms_va_list args;
331 
332     __ms_va_start(args, fmt);
333     ret = vDbgPrintEx(iComponentId, Level, fmt, args);
334     __ms_va_end(args);
335     return ret;
336 }
337 
338 /******************************************************************************
339  *      vDbgPrintEx     [NTDLL.@]
340  */
341 NTSTATUS WINAPI vDbgPrintEx( ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args )
342 {
343     return vDbgPrintExWithPrefix( "", id, level, fmt, args );
344 }
345 
346 /******************************************************************************
347  *      vDbgPrintExWithPrefix  [NTDLL.@]
348  */
349 NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args )
350 {
351     char buf[1024];
352 
353     NTDLL__vsnprintf(buf, sizeof(buf), fmt, args);
354 
355     switch (level & DPFLTR_MASK)
356     {
357     case DPFLTR_ERROR_LEVEL:   ERR("%s%x: %s", prefix, id, buf); break;
358     case DPFLTR_WARNING_LEVEL: WARN("%s%x: %s", prefix, id, buf); break;
359     case DPFLTR_TRACE_LEVEL:
360     case DPFLTR_INFO_LEVEL:
361     default:                   TRACE("%s%x: %s", prefix, id, buf); break;
362     }
363     return STATUS_SUCCESS;
364 }
365 
366 /******************************************************************************
367  *  RtlAcquirePebLock           [NTDLL.@]
368  */
369 VOID WINAPI RtlAcquirePebLock(void)
370 {
371     RtlEnterCriticalSection( &peb_lock );
372 }
373 
374 /******************************************************************************
375  *  RtlReleasePebLock           [NTDLL.@]
376  */
377 VOID WINAPI RtlReleasePebLock(void)
378 {
379     RtlLeaveCriticalSection( &peb_lock );
380 }
381 
382 /******************************************************************************
383  *  RtlNewSecurityObject                [NTDLL.@]
384  */
385 NTSTATUS WINAPI
386 RtlNewSecurityObject( PSECURITY_DESCRIPTOR ParentDescriptor,
387                       PSECURITY_DESCRIPTOR CreatorDescriptor,
388                       PSECURITY_DESCRIPTOR *NewDescriptor,
389                       BOOLEAN IsDirectoryObject,
390                       HANDLE Token,
391                       PGENERIC_MAPPING GenericMapping )
392 {
393     FIXME("(%p %p %p %d %p %p) stub!\n", ParentDescriptor, CreatorDescriptor,
394           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
395     return STATUS_NOT_IMPLEMENTED;
396 }
397 
398 /******************************************************************************
399  *  RtlDeleteSecurityObject             [NTDLL.@]
400  */
401 NTSTATUS WINAPI
402 RtlDeleteSecurityObject( PSECURITY_DESCRIPTOR *ObjectDescriptor )
403 {
404     FIXME("(%p) stub!\n", ObjectDescriptor);
405     return STATUS_NOT_IMPLEMENTED;
406 }
407 
408 /******************************************************************************
409  *  RtlInitializeGenericTable           [NTDLL.@]
410  */
411 PVOID WINAPI RtlInitializeGenericTable(PVOID pTable, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
412 {
413   FIXME("(%p,%p,%p,%p,%p) stub!\n", pTable, arg2, arg3, arg4, arg5);
414   return NULL;
415 }
416 
417 /******************************************************************************
418  *  RtlEnumerateGenericTableWithoutSplaying           [NTDLL.@]
419  */
420 PVOID RtlEnumerateGenericTableWithoutSplaying(PVOID pTable, PVOID *RestartKey)
421 {
422     static int warn_once;
423 
424     if (!warn_once++)
425         FIXME("(%p,%p) stub!\n", pTable, RestartKey);
426     return NULL;
427 }
428 
429 /******************************************************************************
430  *  RtlNumberGenericTableElements           [NTDLL.@]
431  */
432 ULONG RtlNumberGenericTableElements(PVOID pTable)
433 {
434     FIXME("(%p) stub!\n", pTable);
435     return 0;
436 }
437 
438 /******************************************************************************
439  *  RtlMoveMemory   [NTDLL.@]
440  *
441  * Move a block of memory that may overlap.
442  *
443  * PARAMS
444  *  Destination [O] End destination for block
445  *  Source      [O] Where to start copying from
446  *  Length      [I] Number of bytes to copy
447  *
448  * RETURNS
449  *  Nothing.
450  */
451 #undef RtlMoveMemory
452 VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
453 {
454     memmove(Destination, Source, Length);
455 }
456 
457 /******************************************************************************
458  *  RtlFillMemory   [NTDLL.@]
459  *
460  * Set a block of memory with a value.
461  *
462  * PARAMS
463  *  Destination [O] Block to fill
464  *  Length      [I] Number of bytes to fill
465  *  Fill        [I] Value to set
466  *
467  * RETURNS
468  *  Nothing.
469  */
470 #undef RtlFillMemory
471 VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill )
472 {
473     memset(Destination, Fill, Length);
474 }
475 
476 /******************************************************************************
477  *  RtlZeroMemory   [NTDLL.@]
478  *
479  * Set a block of memory with 0's.
480  *
481  * PARAMS
482  *  Destination [O] Block to fill
483  *  Length      [I] Number of bytes to fill
484  *
485  * RETURNS
486  *  Nothing.
487  */
488 #undef RtlZeroMemory
489 VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
490 {
491     memset(Destination, 0, Length);
492 }
493 
494 /******************************************************************************
495  *  RtlCompareMemory   [NTDLL.@]
496  *
497  * Compare one block of memory with another
498  *
499  * PARAMS
500  *  Source1 [I] Source block
501  *  Source2 [I] Block to compare to Source1
502  *  Length  [I] Number of bytes to compare
503  *
504  * RETURNS
505  *  The length of the first byte at which Source1 and Source2 differ, or Length
506  *  if they are the same.
507  */
508 SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
509 {
510     SIZE_T i;
511     for(i=0; (i<Length) && (((const BYTE*)Source1)[i]==((const BYTE*)Source2)[i]); i++);
512     return i;
513 }
514 
515 /******************************************************************************
516  *  RtlCompareMemoryUlong   [NTDLL.@]
517  *
518  * Compare a block of memory with a value, a ULONG at a time
519  *
520  * PARAMS
521  *  Source1 [I] Source block. This must be ULONG aligned
522  *  Length  [I] Number of bytes to compare. This should be a multiple of 4
523  *  dwVal   [I] Value to compare to
524  *
525  * RETURNS
526  *  The byte position of the first byte at which Source1 is not dwVal.
527  */
528 SIZE_T WINAPI RtlCompareMemoryUlong(const ULONG *Source1, SIZE_T Length, ULONG dwVal)
529 {
530     SIZE_T i;
531     for(i = 0; i < Length/sizeof(ULONG) && Source1[i] == dwVal; i++);
532     return i * sizeof(ULONG);
533 }
534 
535 /******************************************************************************
536  *  RtlAssert                           [NTDLL.@]
537  *
538  * Fail a debug assertion.
539  *
540  * RETURNS
541  *  Nothing. This call does not return control to its caller.
542  *
543  * NOTES
544  * Not implemented in non-debug versions.
545  */
546 void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
547 {
548         FIXME("(%p,%p,0x%08x,0x%08x),stub\n",x1,x2,x3,x4);
549 }
550 
551 /*************************************************************************
552  * RtlFillMemoryUlong   [NTDLL.@]
553  *
554  * Fill memory with a 32 bit (dword) value.
555  *
556  * PARAMS
557  *  lpDest  [I] Bitmap pointer
558  *  ulCount [I] Number of dwords to write
559  *  ulValue [I] Value to fill with
560  *
561  * RETURNS
562  *  Nothing.
563  */
564 VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
565 {
566   TRACE("(%p,%d,%d)\n", lpDest, ulCount, ulValue);
567 
568   ulCount /= sizeof(ULONG);
569   while(ulCount--)
570     *lpDest++ = ulValue;
571 }
572 
573 /*********************************************************************
574  *                  RtlComputeCrc32   [NTDLL.@]
575  *
576  * Calculate the CRC32 checksum of a block of bytes
577  *
578  * PARAMS
579  *  dwInitial [I] Initial CRC value
580  *  pData     [I] Data block
581  *  iLen      [I] Length of the byte block
582  *
583  * RETURNS
584  *  The cumulative CRC32 of dwInitial and iLen bytes of the pData block.
585  */
586 DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, const BYTE *pData, INT iLen)
587 {
588   DWORD crc = ~dwInitial;
589 
590   TRACE("(%d,%p,%d)\n", dwInitial, pData, iLen);
591 
592   while (iLen > 0)
593   {
594     crc = CRC_table[(crc ^ *pData) & 0xff] ^ (crc >> 8);
595     pData++;
596     iLen--;
597   }
598   return ~crc;
599 }
600 
601 
602 /*************************************************************************
603  * RtlUlonglongByteSwap    [NTDLL.@]
604  *
605  * Swap the bytes of an unsigned long long value.
606  *
607  * PARAMS
608  *  i [I] Value to swap bytes of
609  *
610  * RETURNS
611  *  The value with its bytes swapped.
612  */
613 ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG i)
614 {
615   return ((ULONGLONG)RtlUlongByteSwap(i) << 32) | RtlUlongByteSwap(i>>32);
616 }
617 
618 /*************************************************************************
619  * RtlUlongByteSwap    [NTDLL.@]
620  *
621  * Swap the bytes of an unsigned int value.
622  *
623  * NOTES
624  *  ix86 version takes argument in %ecx. Other systems use the inline version.
625  */
626 #ifdef __i386__
627 __ASM_GLOBAL_FUNC(NTDLL_RtlUlongByteSwap,
628                   "movl %ecx,%eax\n\t"
629                   "bswap %eax\n\t"
630                   "ret")
631 #endif
632 
633 /*************************************************************************
634  * RtlUshortByteSwap    [NTDLL.@]
635  *
636  * Swap the bytes of an unsigned short value.
637  *
638  * NOTES
639  *  i386 version takes argument in %cx. Other systems use the inline version.
640  */
641 #ifdef __i386__
642 __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap,
643                   "movb %ch,%al\n\t"
644                   "movb %cl,%ah\n\t"
645                   "ret")
646 #endif
647 
648 
649 /*************************************************************************
650  * RtlUniform   [NTDLL.@]
651  *
652  * Generates an uniform random number
653  *
654  * PARAMS
655  *  seed [O] The seed of the Random function
656  *
657  * RETURNS
658  *  It returns a random number uniformly distributed over [0..MAXLONG-1].
659  *
660  * NOTES
661  *  Generates an uniform random number using D.H. Lehmer's 1948 algorithm.
662  *  In our case the algorithm is:
663  *
664  *|  result = (*seed * 0x7fffffed + 0x7fffffc3) % MAXLONG;
665  *|
666  *|  *seed = result;
667  *
668  * DIFFERENCES
669  *  The native documentation states that the random number is
670  *  uniformly distributed over [0..MAXLONG]. In reality the native
671  *  function and our function return a random number uniformly
672  *  distributed over [0..MAXLONG-1].
673  */
674 ULONG WINAPI RtlUniform (PULONG seed)
675 {
676     ULONG result;
677 
678    /*
679     * Instead of the algorithm stated above, we use the algorithm
680     * below, which is totally equivalent (see the tests), but does
681     * not use a division and therefore is faster.
682     */
683     result = *seed * 0xffffffed + 0x7fffffc3;
684     if (result == 0xffffffff || result == 0x7ffffffe) {
685         result = (result + 2) & MAXLONG;
686     } else if (result == 0x7fffffff) {
687         result = 0;
688     } else if ((result & 0x80000000) == 0) {
689         result = result + (~result & 1);
690     } else {
691         result = (result + (result & 1)) & MAXLONG;
692     } /* if */
693     *seed = result;
694     return result;
695 }
696 
697 
698 /*************************************************************************
699  * RtlRandom   [NTDLL.@]
700  *
701  * Generates a random number
702  *
703  * PARAMS
704  *  seed [O] The seed of the Random function
705  *
706  * RETURNS
707  *  It returns a random number distributed over [0..MAXLONG-1].
708  */
709 ULONG WINAPI RtlRandom (PULONG seed)
710 {
711     static ULONG saved_value[128] =
712     { /*   0 */ 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626, 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa,
713       /*   8 */ 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8, 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09,
714       /*  16 */ 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5, 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311,
715       /*  24 */ 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be, 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82,
716       /*  32 */ 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4, 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd,
717       /*  40 */ 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016, 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52,
718       /*  48 */ 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c, 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb,
719       /*  56 */ 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8, 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e,
720       /*  64 */ 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb, 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0,
721       /*  72 */ 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743, 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd,
722       /*  80 */ 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78, 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35,
723       /*  88 */ 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a, 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379,
724       /*  96 */ 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d, 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd,
725       /* 104 */ 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515, 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b,
726       /* 112 */ 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975, 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b,
727       /* 120 */ 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb, 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d };
728     ULONG rand;
729     int pos;
730     ULONG result;
731 
732     rand = (*seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
733     *seed = (rand * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
734     pos = *seed & 0x7f;
735     result = saved_value[pos];
736     saved_value[pos] = rand;
737     return(result);
738 }
739 
740 
741 /*************************************************************************
742  * RtlAreAllAccessesGranted   [NTDLL.@]
743  *
744  * Check if all desired accesses are granted
745  *
746  * RETURNS
747  *  TRUE: All desired accesses are granted
748  *  FALSE: Otherwise
749  */
750 BOOLEAN WINAPI RtlAreAllAccessesGranted(
751     ACCESS_MASK GrantedAccess,
752     ACCESS_MASK DesiredAccess)
753 {
754     return (GrantedAccess & DesiredAccess) == DesiredAccess;
755 }
756 
757 
758 /*************************************************************************
759  * RtlAreAnyAccessesGranted   [NTDLL.@]
760  *
761  * Check if at least one of the desired accesses is granted
762  *
763  * PARAMS
764  *  GrantedAccess [I] Access mask of granted accesses
765  *  DesiredAccess [I] Access mask of desired accesses
766  *
767  * RETURNS
768  *  TRUE: At least one of the desired accesses is granted
769  *  FALSE: Otherwise
770  */
771 BOOLEAN WINAPI RtlAreAnyAccessesGranted(
772     ACCESS_MASK GrantedAccess,
773     ACCESS_MASK DesiredAccess)
774 {
775     return (GrantedAccess & DesiredAccess) != 0;
776 }
777 
778 
779 /*************************************************************************
780  * RtlMapGenericMask   [NTDLL.@]
781  *
782  * Determine the nongeneric access rights specified by an access mask
783  *
784  * RETURNS
785  *  Nothing.
786  */
787 void WINAPI RtlMapGenericMask(
788     PACCESS_MASK AccessMask,
789     const GENERIC_MAPPING *GenericMapping)
790 {
791     if (*AccessMask & GENERIC_READ) {
792         *AccessMask |= GenericMapping->GenericRead;
793     } /* if */
794 
795     if (*AccessMask & GENERIC_WRITE) {
796         *AccessMask |= GenericMapping->GenericWrite;
797     } /* if */
798 
799     if (*AccessMask & GENERIC_EXECUTE) {
800         *AccessMask |= GenericMapping->GenericExecute;
801     } /* if */
802 
803     if (*AccessMask & GENERIC_ALL) {
804         *AccessMask |= GenericMapping->GenericAll;
805     } /* if */
806 
807     *AccessMask &= 0x0FFFFFFF;
808 }
809 
810 
811 /*************************************************************************
812  * RtlCopyLuid   [NTDLL.@]
813  *
814  * Copy a local unique ID.
815  *
816  * PARAMS
817  *  LuidDest [O] Destination for the copied Luid
818  *  LuidSrc  [I] Source Luid to copy to LuidDest
819  *
820  * RETURNS
821  *  Nothing.
822  */
823 void WINAPI RtlCopyLuid (PLUID LuidDest, const LUID *LuidSrc)
824 {
825     *LuidDest = *LuidSrc;
826 }
827 
828 
829 /*************************************************************************
830  * RtlEqualLuid   [NTDLL.@]
831  *
832  * Compare two local unique IDs.
833  *
834  * PARAMS
835  *  Luid1 [I] First Luid to compare to Luid2
836  *  Luid2 [I] Second Luid to compare to Luid1
837  *
838  * RETURNS
839  *  TRUE: The two LUIDs are equal.
840  *  FALSE: Otherwise
841  */
842 BOOLEAN WINAPI RtlEqualLuid (const LUID *Luid1, const LUID *Luid2)
843 {
844   return (Luid1->LowPart ==  Luid2->LowPart && Luid1->HighPart == Luid2->HighPart);
845 }
846 
847 
848 /*************************************************************************
849  * RtlCopyLuidAndAttributesArray   [NTDLL.@]
850  *
851  * Copy an array of local unique IDs and attributes.
852  *
853  * PARAMS
854  *  Count [I] Number of Luid/attributes in Src
855  *  Src   [I] Source Luid/attributes to copy
856  *  Dest  [O] Destination for copied Luid/attributes
857  *
858  * RETURNS
859  *  Nothing.
860  *
861  * NOTES
862  *  Dest must be large enough to hold Src.
863  */
864 void WINAPI RtlCopyLuidAndAttributesArray(
865     ULONG Count,
866     const LUID_AND_ATTRIBUTES *Src,
867     PLUID_AND_ATTRIBUTES Dest)
868 {
869     ULONG i;
870 
871     for (i = 0; i < Count; i++) Dest[i] = Src[i];
872 }
873 
874 NTSTATUS WINAPI RtlIpv4StringToAddressExW(PULONG IP, PULONG Port,
875                                           LPCWSTR Buffer, PULONG MaxSize)
876 {
877     FIXME("(%p,%p,%p,%p): stub\n", IP, Port, Buffer, MaxSize);
878 
879     return STATUS_SUCCESS;
880 }
881 
882 /***********************************************************************
883  * RtlIpv4AddressToStringExW [NTDLL.@]
884  *
885  * Convert the given ipv4 address and optional the port to a string
886  *
887  * PARAMS
888  *  pin     [I]  PTR to the ip address to convert (network byte order)
889  *  port    [I]  optional port to convert (network byte order)
890  *  buffer  [O]  destination buffer for the result
891  *  psize   [IO] PTR to available/used size of the destination buffer
892  *
893  * RETURNS
894  *  Success: STATUS_SUCCESS
895  *  Failure: STATUS_INVALID_PARAMETER
896  *
897  */
898 NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWSTR buffer, PULONG psize)
899 {
900     WCHAR tmp_ip[32];
901     static const WCHAR fmt_ip[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
902     static const WCHAR fmt_port[] = {':','%','u',0};
903     ULONG needed;
904 
905     if (!pin || !buffer || !psize)
906         return STATUS_INVALID_PARAMETER;
907 
908     TRACE("(%p:0x%x, %d, %p, %p:%d)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
909 
910     needed = sprintfW(tmp_ip, fmt_ip,
911                       pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
912                       pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
913 
914     if (port) needed += sprintfW(tmp_ip + needed, fmt_port, ntohs(port));
915 
916     if (*psize > needed) {
917         *psize = needed + 1;
918         strcpyW(buffer, tmp_ip);
919         return STATUS_SUCCESS;
920     }
921 
922     *psize = needed + 1;
923     return STATUS_INVALID_PARAMETER;
924 }
925 
926 /***********************************************************************
927  * RtlIpv4AddressToStringExA [NTDLL.@]
928  *
929  * Convert the given ipv4 address and optional the port to a string
930  *
931  * See RtlIpv4AddressToStringExW
932  */
933 NTSTATUS WINAPI RtlIpv4AddressToStringExA(const IN_ADDR *pin, USHORT port, LPSTR buffer, PULONG psize)
934 {
935     CHAR tmp_ip[32];
936     ULONG needed;
937 
938     if (!pin || !buffer || !psize)
939         return STATUS_INVALID_PARAMETER;
940 
941     TRACE("(%p:0x%x, %d, %p, %p:%d)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
942 
943     needed = sprintf(tmp_ip, "%u.%u.%u.%u",
944                      pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
945                      pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
946 
947     if (port) needed += sprintf(tmp_ip + needed, ":%u", ntohs(port));
948 
949     if (*psize > needed) {
950         *psize = needed + 1;
951         strcpy(buffer, tmp_ip);
952         return STATUS_SUCCESS;
953     }
954 
955     *psize = needed + 1;
956     return STATUS_INVALID_PARAMETER;
957 }
958 
959 /***********************************************************************
960  * RtlIpv4AddressToStringW [NTDLL.@]
961  *
962  * Convert the given ipv4 address to a string
963  *
964  * PARAMS
965  *  pin     [I]  PTR to the ip address to convert (network byte order)
966  *  buffer  [O]  destination buffer for the result (at least 16 character)
967  *
968  * RETURNS
969  *  PTR to the 0 character at the end of the converted string
970  *
971  */
972 WCHAR * WINAPI RtlIpv4AddressToStringW(const IN_ADDR *pin, LPWSTR buffer)
973 {
974     ULONG size = 16;
975 
976     if (RtlIpv4AddressToStringExW(pin, 0, buffer, &size)) size = 0;
977     return buffer + size - 1;
978 }
979 
980 /***********************************************************************
981  * RtlIpv4AddressToStringA [NTDLL.@]
982  *
983  * Convert the given ipv4 address to a string
984  *
985  * See RtlIpv4AddressToStringW
986  */
987 CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer)
988 {
989     ULONG size = 16;
990 
991     if (RtlIpv4AddressToStringExA(pin, 0, buffer, &size)) size = 0;
992     return buffer + size - 1;
993 }
994 
995 /***********************************************************************
996  * get_pointer_obfuscator (internal)
997  */
998 static DWORD_PTR get_pointer_obfuscator( void )
999 {
1000     static DWORD_PTR pointer_obfuscator;
1001 
1002     if (!pointer_obfuscator)
1003     {
1004         ULONG seed = NtGetTickCount();
1005         ULONG_PTR rand;
1006 
1007         /* generate a random value for the obfuscator */
1008         rand = RtlUniform( &seed );
1009 
1010         /* handle 64bit pointers */
1011         rand ^= (ULONG_PTR)RtlUniform( &seed ) << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
1012 
1013         /* set the high bits so dereferencing obfuscated pointers will (usually) crash */
1014         rand |= (ULONG_PTR)0xc0000000 << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
1015 
1016         interlocked_cmpxchg_ptr( (void**) &pointer_obfuscator, (void*) rand, NULL );
1017     }
1018 
1019     return pointer_obfuscator;
1020 }
1021 
1022 /*************************************************************************
1023  * RtlEncodePointer   [NTDLL.@]
1024  */
1025 PVOID WINAPI RtlEncodePointer( PVOID ptr )
1026 {
1027     DWORD_PTR ptrval = (DWORD_PTR) ptr;
1028     return (PVOID)(ptrval ^ get_pointer_obfuscator());
1029 }
1030 
1031 PVOID WINAPI RtlDecodePointer( PVOID ptr )
1032 {
1033     DWORD_PTR ptrval = (DWORD_PTR) ptr;
1034     return (PVOID)(ptrval ^ get_pointer_obfuscator());
1035 }
1036 
1037 /*************************************************************************
1038  * RtlInitializeSListHead   [NTDLL.@]
1039  */
1040 VOID WINAPI RtlInitializeSListHead(PSLIST_HEADER list)
1041 {
1042 #ifdef _WIN64
1043     list->s.Alignment = list->s.Region = 0;
1044     list->Header16.HeaderType = 1;  /* we use the 16-byte header */
1045 #else
1046     list->Alignment = 0;
1047 #endif
1048 }
1049 
1050 /*************************************************************************
1051  * RtlQueryDepthSList   [NTDLL.@]
1052  */
1053 WORD WINAPI RtlQueryDepthSList(PSLIST_HEADER list)
1054 {
1055 #ifdef _WIN64
1056     return list->Header16.Depth;
1057 #else
1058     return list->s.Depth;
1059 #endif
1060 }
1061 
1062 /*************************************************************************
1063  * RtlFirstEntrySList   [NTDLL.@]
1064  */
1065 PSLIST_ENTRY WINAPI RtlFirstEntrySList(const SLIST_HEADER* list)
1066 {
1067 #ifdef _WIN64
1068     return (SLIST_ENTRY *)((ULONG_PTR)list->Header16.NextEntry << 4);
1069 #else
1070     return list->s.Next.Next;
1071 #endif
1072 }
1073 
1074 /*************************************************************************
1075  * RtlInterlockedFlushSList   [NTDLL.@]
1076  */
1077 PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list)
1078 {
1079     SLIST_HEADER old, new;
1080 
1081 #ifdef _WIN64
1082     if (!list->Header16.Depth) return NULL;
1083     new.s.Alignment = new.s.Region = 0;
1084     new.Header16.HeaderType = 1;  /* we use the 16-byte header */
1085     do
1086     {
1087         old = *list;
1088         new.Header16.Sequence = old.Header16.Sequence + 1;
1089     } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1090     return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1091 #else
1092     if (!list->s.Depth) return NULL;
1093     new.Alignment = 0;
1094     do
1095     {
1096         old = *list;
1097         new.s.Sequence = old.s.Sequence + 1;
1098     } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1099                                    old.Alignment) != old.Alignment);
1100     return old.s.Next.Next;
1101 #endif
1102 }
1103 
1104 /*************************************************************************
1105  * RtlInterlockedPushEntrySList   [NTDLL.@]
1106  */
1107 PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTRY entry)
1108 {
1109     SLIST_HEADER old, new;
1110 
1111 #ifdef _WIN64
1112     new.Header16.NextEntry = (ULONG_PTR)entry >> 4;
1113     do
1114     {
1115         old = *list;
1116         entry->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1117         new.Header16.Depth = old.Header16.Depth + 1;
1118         new.Header16.Sequence = old.Header16.Sequence + 1;
1119     } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1120     return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1121 #else
1122     new.s.Next.Next = entry;
1123     do
1124     {
1125         old = *list;
1126         entry->Next = old.s.Next.Next;
1127         new.s.Depth = old.s.Depth + 1;
1128         new.s.Sequence = old.s.Sequence + 1;
1129     } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1130                                    old.Alignment) != old.Alignment);
1131     return old.s.Next.Next;
1132 #endif
1133 }
1134 
1135 /*************************************************************************
1136  * RtlInterlockedPopEntrySList   [NTDLL.@]
1137  */
1138 PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list)
1139 {
1140     SLIST_HEADER old, new;
1141     PSLIST_ENTRY entry;
1142 
1143 #ifdef _WIN64
1144     do
1145     {
1146         old = *list;
1147         if (!(entry = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4))) return NULL;
1148         /* entry could be deleted by another thread */
1149         __TRY
1150         {
1151             new.Header16.NextEntry = (ULONG_PTR)entry->Next >> 4;
1152             new.Header16.Depth = old.Header16.Depth - 1;
1153             new.Header16.Sequence = old.Header16.Sequence + 1;
1154         }
1155         __EXCEPT_PAGE_FAULT
1156         {
1157         }
1158         __ENDTRY
1159     } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1160 #else
1161     do
1162     {
1163         old = *list;
1164         if (!(entry = old.s.Next.Next)) return NULL;
1165         /* entry could be deleted by another thread */
1166         __TRY
1167         {
1168             new.s.Next.Next = entry->Next;
1169             new.s.Depth = old.s.Depth - 1;
1170             new.s.Sequence = old.s.Sequence + 1;
1171         }
1172         __EXCEPT_PAGE_FAULT
1173         {
1174         }
1175         __ENDTRY
1176     } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1177                                    old.Alignment) != old.Alignment);
1178 #endif
1179     return entry;
1180 }
1181 
1182 /*************************************************************************
1183  * RtlInterlockedPushListSList   [NTDLL.@]
1184  */
1185 PSLIST_ENTRY WINAPI RtlInterlockedPushListSList(PSLIST_HEADER list, PSLIST_ENTRY first,
1186                                                 PSLIST_ENTRY last, ULONG count)
1187 {
1188     SLIST_HEADER old, new;
1189 
1190 #ifdef _WIN64
1191     new.Header16.NextEntry = (ULONG_PTR)first >> 4;
1192     do
1193     {
1194         old = *list;
1195         new.Header16.Depth = old.Header16.Depth + count;
1196         new.Header16.Sequence = old.Header16.Sequence + 1;
1197         last->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1198     } while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
1199     return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
1200 #else
1201     new.s.Next.Next = first;
1202     do
1203     {
1204         old = *list;
1205         new.s.Depth = old.s.Depth + count;
1206         new.s.Sequence = old.s.Sequence + 1;
1207         last->Next = old.s.Next.Next;
1208     } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
1209                                    old.Alignment) != old.Alignment);
1210     return old.s.Next.Next;
1211 #endif
1212 }
1213 
1214 /******************************************************************************
1215  *  RtlGetCompressionWorkSpaceSize              [NTDLL.@]
1216  */
1217 NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT CompressionFormatAndEngine,
1218                                                PULONG CompressBufferWorkSpaceSize,
1219                                                PULONG CompressFragmentWorkSpaceSize)
1220 {
1221     FIXME("0x%04x, %p, %p: stub!\n", CompressionFormatAndEngine, CompressBufferWorkSpaceSize,
1222          CompressFragmentWorkSpaceSize);
1223 
1224     return STATUS_NOT_IMPLEMENTED;
1225 }
1226 
1227 /******************************************************************************
1228  *  RtlCompressBuffer           [NTDLL.@]
1229  */
1230 NTSTATUS WINAPI RtlCompressBuffer(USHORT CompressionFormatAndEngine, PUCHAR UncompressedBuffer,
1231                                   ULONG UncompressedBufferSize, PUCHAR CompressedBuffer,
1232                                   ULONG CompressedBufferSize, ULONG UncompressedChunkSize,
1233                                   PULONG FinalCompressedSize, PVOID WorkSpace)
1234 {
1235     FIXME("0x%04x, %p, %u, %p, %u, %u, %p, %p :stub\n", CompressionFormatAndEngine, UncompressedBuffer,
1236          UncompressedBufferSize, CompressedBuffer, CompressedBufferSize, UncompressedChunkSize,
1237          FinalCompressedSize, WorkSpace);
1238 
1239     return STATUS_NOT_IMPLEMENTED;
1240 }
1241 
1242 /******************************************************************************
1243  *  RtlDecompressBuffer         [NTDLL.@]
1244  */
1245 NTSTATUS WINAPI RtlDecompressBuffer(USHORT CompressionFormat, PUCHAR UncompressedBuffer,
1246                                     ULONG UncompressedBufferSize, PUCHAR CompressedBuffer,
1247                                     ULONG CompressedBufferSize, PULONG FinalUncompressedSize)
1248 {
1249     FIXME("0x%04x, %p, %u, %p, %u, %p :stub\n", CompressionFormat, UncompressedBuffer, UncompressedBufferSize,
1250          CompressedBuffer, CompressedBufferSize, FinalUncompressedSize);
1251 
1252     return STATUS_NOT_IMPLEMENTED;
1253 }
1254 
1255 /***********************************************************************
1256  *  RtlSetThreadErrorMode       [NTDLL.@]
1257  *
1258  * Set the thread local error mode.
1259  *
1260  * PARAMS
1261  *  mode    [I] The new error mode
1262  *  oldmode [O] Destination of the old error mode (may be NULL)
1263  *
1264  * RETURNS
1265  *  Success: STATUS_SUCCESS
1266  *  Failure: STATUS_INVALID_PARAMETER_1
1267  */
1268 NTSTATUS WINAPI RtlSetThreadErrorMode( DWORD mode, LPDWORD oldmode )
1269 {
1270     if (mode & ~0x70)
1271         return STATUS_INVALID_PARAMETER_1;
1272 
1273     if (oldmode)
1274         *oldmode = NtCurrentTeb()->HardErrorDisabled;
1275 
1276     NtCurrentTeb()->HardErrorDisabled = mode;
1277     return STATUS_SUCCESS;
1278 }
1279 
1280 /***********************************************************************
1281  *  RtlGetThreadErrorMode       [NTDLL.@]
1282  *
1283  * Get the thread local error mode.
1284  *
1285  * PARAMS
1286  *  None.
1287  *
1288  * RETURNS
1289  *  The current thread local error mode.
1290  */
1291 DWORD WINAPI RtlGetThreadErrorMode( void )
1292 {
1293     return NtCurrentTeb()->HardErrorDisabled;
1294 }
1295 
1296 /******************************************************************************
1297  * RtlGetCurrentTransaction [NTDLL.@]
1298  */
1299 HANDLE WINAPI RtlGetCurrentTransaction(void)
1300 {
1301     FIXME("() :stub\n");
1302     return NULL;
1303 }
1304 
1305 /******************************************************************************
1306  * RtlSetCurrentTransaction [NTDLL.@]
1307  */
1308 BOOL WINAPI RtlSetCurrentTransaction(HANDLE new_transaction)
1309 {
1310     FIXME("(%p) :stub\n", new_transaction);
1311     return FALSE;
1312 }
1313 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.