source: trunk/src/ntdll/rtl.c@ 22018

Last change on this file since 22018 was 22018, checked in by abwillis, 13 years ago

Ticket #89 InitializeSListHead

File size: 23.0 KB
Line 
1/* $Id: rtl.c,v 1.6 2003-04-08 12:47:07 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 * Win32 NT Runtime / NTDLL for OS/2
6 *
7 * Copyright 1998 original WINE Author
8 * Copyright 1998, 1999 Patrick Haller (phaller@gmx.net)
9 *
10 * NT basis DLL
11 *
12 * This file contains the Rtl* API functions. These should be implementable.
13 *
14 * Copyright 1996-1998 Marcus Meissner
15 * 1999 Alex Korobka
16 */
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21
22#include <odinwrap.h>
23
24#include "debugtools.h"
25
26#include "winuser.h"
27#include "windef.h"
28#include "winerror.h"
29#include "stackframe.h"
30#include "ntddk.h"
31#include "winreg.h"
32#include "heapstring.h"
33#include "win/winnt.h"
34#include "win/wine/exception.h"
35
36#include <misc.h>
37
38
39ODINDEBUGCHANNEL(NTDLL-RTL)
40
41static CRITICAL_SECTION peb_lock = CRITICAL_SECTION_INIT("peb_lock");
42
43/* CRC polynomial 0xedb88320 */
44static const DWORD CRC_table[256] =
45{
46 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
47 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
48 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
49 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
50 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
51 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
52 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
53 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
54 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
55 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
56 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
57 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
58 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
59 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
60 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
61 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
62 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
63 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
64 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
65 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
66 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
67 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
68 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
69 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
70 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
71 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
72 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
73 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
74 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
75 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
76 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
77 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
78 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
79 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
80 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
81 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
82 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
83 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
84 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
85 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
86 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
87 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
88 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
89};
90
91
92/*
93 * WINE Adoption - we won't support the Win64 model.
94 */
95#define SIZE_T UINT
96
97/*
98 * resource functions
99 */
100
101/***********************************************************************
102 * RtlInitializeResource (NTDLL.409)
103 *
104 * xxxResource() functions implement multiple-reader-single-writer lock.
105 * The code is based on information published in WDJ January 1999 issue.
106 */
107void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
108{
109 dprintf(("NTDLL: RtlInitializeResource(%08xh)\n", rwl));
110
111 if( rwl )
112 {
113 rwl->iNumberActive = 0;
114 rwl->uExclusiveWaiters = 0;
115 rwl->uSharedWaiters = 0;
116 rwl->hOwningThreadId = 0;
117 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
118 InitializeCriticalSection( &rwl->rtlCS );
119 rwl->hExclusiveReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
120 rwl->hSharedReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
121 }
122}
123
124
125/***********************************************************************
126 * RtlDeleteResource (NTDLL.330)
127 */
128void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
129{
130 dprintf(("NTDLL: RtlDeleteResource(%08xh)\n",
131 rwl));
132
133 if( rwl )
134 {
135 EnterCriticalSection( &rwl->rtlCS );
136 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
137 dprintf(("NTDLL: RtlDeleteResource active MRSW lock (%p), expect failure\n",
138 rwl));
139
140 rwl->hOwningThreadId = 0;
141 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
142 rwl->iNumberActive = 0;
143 CloseHandle( rwl->hExclusiveReleaseSemaphore );
144 CloseHandle( rwl->hSharedReleaseSemaphore );
145 LeaveCriticalSection( &rwl->rtlCS );
146 DeleteCriticalSection( &rwl->rtlCS );
147 }
148}
149
150
151/***********************************************************************
152 * RtlAcquireResourceExclusive (NTDLL.256)
153 */
154BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl,
155 BYTE fWait)
156{
157 BYTE retVal = 0;
158
159 if( !rwl )
160 return 0;
161
162 dprintf(("NTDLL: RtlAcquireResourceExclusive(%08xh,%08xh)\n",
163 rwl,
164 fWait));
165
166start:
167 EnterCriticalSection( &rwl->rtlCS );
168 if( rwl->iNumberActive == 0 ) /* lock is free */
169 {
170 rwl->iNumberActive = -1;
171 retVal = 1;
172 }
173 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
174 {
175 if( rwl->hOwningThreadId == GetCurrentThreadId() )
176 {
177 retVal = 1;
178 rwl->iNumberActive--;
179 goto done;
180 }
181wait:
182 if( fWait )
183 {
184 rwl->uExclusiveWaiters++;
185
186 LeaveCriticalSection( &rwl->rtlCS );
187 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
188 goto done;
189 goto start; /* restart the acquisition to avoid deadlocks */
190 }
191 }
192 else /* one or more shared locks are in progress */
193 if( fWait )
194 goto wait;
195
196 if( retVal == 1 )
197 rwl->hOwningThreadId = GetCurrentThreadId();
198done:
199 LeaveCriticalSection( &rwl->rtlCS );
200 return retVal;
201}
202
203/***********************************************************************
204 * RtlAcquireResourceShared (NTDLL.257)
205 */
206BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl,
207 BYTE fWait)
208{
209 DWORD dwWait = WAIT_FAILED;
210 BYTE retVal = 0;
211
212 if( !rwl )
213 return 0;
214
215 dprintf(("NTDLL: RtlAcquireResourceShared(%08xh,%08xh)\n",
216 rwl,
217 fWait));
218
219start:
220 EnterCriticalSection( &rwl->rtlCS );
221 if( rwl->iNumberActive < 0 )
222 {
223 if( rwl->hOwningThreadId == GetCurrentThreadId() )
224 {
225 rwl->iNumberActive--;
226 retVal = 1;
227 goto done;
228 }
229
230 if( fWait )
231 {
232 rwl->uSharedWaiters++;
233 LeaveCriticalSection( &rwl->rtlCS );
234 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
235 goto done;
236 goto start;
237 }
238 }
239 else
240 {
241 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
242 rwl->iNumberActive++;
243 retVal = 1;
244 }
245done:
246 LeaveCriticalSection( &rwl->rtlCS );
247 return retVal;
248}
249
250
251/***********************************************************************
252 * RtlReleaseResource (NTDLL.471)
253 */
254void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
255{
256 dprintf(("NTDLL: RtlReleaseResource(%08xh)\n",
257 rwl));
258
259 EnterCriticalSection( &rwl->rtlCS );
260
261 if( rwl->iNumberActive > 0 ) /* have one or more readers */
262 {
263 if( --rwl->iNumberActive == 0 )
264 {
265 if( rwl->uExclusiveWaiters )
266 {
267wake_exclusive:
268 rwl->uExclusiveWaiters--;
269 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
270 }
271 }
272 }
273 else
274 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
275 {
276 if( ++rwl->iNumberActive == 0 )
277 {
278 rwl->hOwningThreadId = 0;
279 if( rwl->uExclusiveWaiters )
280 goto wake_exclusive;
281 else
282 if( rwl->uSharedWaiters )
283 {
284 UINT n = rwl->uSharedWaiters;
285 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
286 * all queued readers have done their thing */
287 rwl->uSharedWaiters = 0;
288 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
289 }
290 }
291 }
292 LeaveCriticalSection( &rwl->rtlCS );
293}
294
295
296/***********************************************************************
297 * RtlDumpResource (NTDLL.340)
298 */
299void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
300{
301 dprintf(("NTDLL: RtlDumpResource(%08x)\n",
302 rwl));
303
304 if( rwl )
305 {
306 dprintf(("NTDLL: RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
307 rwl,
308 rwl->iNumberActive,
309 rwl->uSharedWaiters,
310 rwl->uExclusiveWaiters));
311
312 if( rwl->iNumberActive )
313 dprintf(("NTDLL: \towner thread = %08x\n",
314 rwl->hOwningThreadId ));
315 }
316}
317
318
319/*
320 * heap functions
321 */
322
323
324
325/*
326 * misc functions
327 */
328
329
330/******************************************************************************
331 * RtlAcquirePebLock [NTDLL]
332 */
333VOID WINAPI RtlAcquirePebLock(void)
334{
335 EnterCriticalSection( &peb_lock );
336}
337
338
339/******************************************************************************
340 * RtlReleasePebLock [NTDLL]
341 */
342VOID WINAPI RtlReleasePebLock(void)
343{
344 LeaveCriticalSection( &peb_lock );
345}
346
347/******************************************************************************
348 * RtlSetEnvironmentVariable [NTDLL.@]
349 */
350DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
351 FIXME("(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
352 return 0;
353}
354
355/******************************************************************************
356 * RtlNewSecurityObject [NTDLL.@]
357 */
358DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
359 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
360 return 0;
361}
362
363/******************************************************************************
364 * RtlDeleteSecurityObject [NTDLL.@]
365 */
366DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
367 FIXME("(0x%08lx),stub!\n",x1);
368 return 0;
369}
370
371/**************************************************************************
372 * RtlNormalizeProcessParams [NTDLL.@]
373 */
374LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
375{
376 FIXME("(%p), stub\n",x);
377 return x;
378}
379
380/**************************************************************************
381 * RtlGetNtProductType [NTDLL.@]
382 */
383BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
384{
385 FIXME("(%p): stub\n", type);
386 *type=3; /* dunno. 1 for client, 3 for server? */
387 return 1;
388}
389
390
391/******************************************************************************
392 * RtlFormatCurrentUserKeyPath [NTDLL.371]
393 */
394NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING pustrKeyPath)
395{
396 dprintf(("NTDLL: RtlFormatCurrentUserKeyPath(%08xh) not correctly implemented.\n",
397 pustrKeyPath));
398
399 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
400 ANSI_STRING AnsiPath;
401
402 RtlInitAnsiString(&AnsiPath, Path);
403 return RtlAnsiStringToUnicodeString(pustrKeyPath, &AnsiPath, TRUE);
404}
405
406
407/******************************************************************************
408 * RtlOpenCurrentUser [NTDLL]
409 */
410DWORD WINAPI RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, OUT PHANDLE pKeyHandle)
411{
412 /* Note: this is not the correct solution,
413 * But this works pretty good on wine and NT4.0 binaries
414 */
415
416 if (DesiredAccess == 0x2000000 )
417 {
418 *pKeyHandle = HKEY_CURRENT_USER;
419 return TRUE;
420 }
421
422 return FALSE;
423/* PH 2000/08/18 currently disabled
424 OBJECT_ATTRIBUTES ObjectAttributes;
425 UNICODE_STRING ObjectName;
426 NTSTATUS ret;
427
428 RtlFormatCurrentUserKeyPath(&ObjectName);
429 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
430 ret = NtOpenKey(pKeyHandle, DesiredAccess, &ObjectAttributes);
431 RtlFreeUnicodeString(&ObjectName);
432 return ret;
433 */
434}
435
436
437/**************************************************************************
438 * RtlDosPathNameToNtPathName_U [NTDLL.338]
439 *
440 * FIXME: convert to UNC or whatever is expected here
441 */
442BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR from,
443 PUNICODE_STRING us,
444 DWORD x2,
445 DWORD x3)
446{
447// LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
448
449 dprintf(("NTDLL: RtlDosPathNameToNtPathName_U(%08xh,%08h,%08xh,%08xh) not implemented.\n",
450 from,
451 us,
452 x2,
453 x3));
454
455 if (us)
456 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
457
458 return TRUE;
459}
460
461
462/***********************************************************************
463 * RtlImageNtHeader (NTDLL)
464 */
465PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
466{
467 IMAGE_NT_HEADERS *ret = NULL;
468 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
469
470 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
471 {
472 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
473 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
474 }
475 return ret;
476}
477
478/******************************************************************************
479 * RtlCreateEnvironment [NTDLL]
480 */
481DWORD WINAPI RtlCreateEnvironment(DWORD x1,
482 DWORD x2)
483{
484 dprintf(("NTDLL: RtlCreateEnvironment(%08xh, %08xh) not implemented.\n",
485 x1,
486 x2));
487
488 return 0;
489}
490
491
492/******************************************************************************
493 * RtlDestroyEnvironment [NTDLL]
494 */
495DWORD WINAPI RtlDestroyEnvironment(DWORD x)
496{
497 dprintf(("NTDLL: RtlDestroyEnvironment(%08xh) not implemented.\n",
498 x));
499
500 return 0;
501}
502
503
504/******************************************************************************
505 * RtlQueryEnvironmentVariable_U [NTDLL]
506 */
507DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,
508 PUNICODE_STRING key,
509 PUNICODE_STRING val)
510{
511 dprintf(("NTDLL: RtlQueryEnvironmentVariable_U(%08xh,%08xh,%08xh) not implemented.\n",
512 x1,
513 key,
514 val));
515
516 return 0;
517}
518
519/******************************************************************************
520 * RtlInitializeGenericTable [NTDLL]
521 */
522DWORD WINAPI RtlInitializeGenericTable(void)
523{
524 FIXME("\n");
525 return 0;
526}
527
528
529
530
531/******************************************************************************
532 * RtlCopyMemory [NTDLL]
533 *
534 */
535#undef RtlCopyMemory
536VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
537{
538 memcpy(Destination, Source, Length);
539}
540
541/******************************************************************************
542 * RtlMoveMemory [NTDLL]
543 */
544#undef RtlMoveMemory
545VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
546{
547 memmove(Destination, Source, Length);
548}
549
550/******************************************************************************
551 * RtlFillMemory [NTDLL]
552 */
553#undef RtlFillMemory
554VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, UINT Fill )
555{
556 memset(Destination, Fill, Length);
557}
558
559/******************************************************************************
560 * RtlZeroMemory [NTDLL]
561 */
562#undef RtlZeroMemory
563VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
564{
565 memset(Destination, 0, Length);
566}
567
568/******************************************************************************
569 * RtlCompareMemory [NTDLL]
570 */
571SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
572{
573 int i;
574 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
575 return i;
576}
577
578/******************************************************************************
579 * RtlAssert [NTDLL]
580 *
581 * Not implemented in non-debug versions.
582 */
583void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
584{
585 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
586}
587
588/*****************************************************************************
589 * Name : RtlCopyLuid
590 * Purpose : copy local unique identifier?
591 * Parameters: PLUID pluid1
592 * PLUID pluid2
593 * Variables :
594 * Result :
595 * Remark : NTDLL.321
596 * Status : COMPLETELY ? IMPLEMENTED TESTED ?
597 *
598 * Author : Patrick Haller [Tue, 1999/11/09 09:00]
599 *****************************************************************************/
600
601PLUID WINAPI RtlCopyLuid(PLUID pluid1,
602 PLUID pluid2)
603{
604 pluid2->LowPart = pluid1->LowPart;
605 pluid2->HighPart = pluid1->HighPart;
606 return (pluid1);
607}
608
609/******************************************************************************
610 * RtlGetNtVersionNumbers [NTDLL.@]
611 *
612 * Introduced in Windows XP (NT5.1)
613 */
614void WINAPI RtlGetNtVersionNumbers(LPDWORD major, LPDWORD minor, LPDWORD build)
615{
616 OSVERSIONINFOEXW versionInfo;
617 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
618 GetVersionExW((OSVERSIONINFOW*)((void*)&versionInfo));
619
620 if (major)
621 {
622 *major = versionInfo.dwMajorVersion;
623 }
624
625 if (minor)
626 {
627 *minor = versionInfo.dwMinorVersion;
628 }
629
630 if (build)
631 {
632 /* FIXME: Does anybody know the real formula? */
633 *build = (0xF0000000 | versionInfo.dwBuildNumber);
634 }
635}
636
637/*************************************************************************
638 * RtlFillMemoryUlong [NTDLL.@]
639 *
640 * Fill memory with a 32 bit (dword) value.
641 *
642 * PARAMS
643 * lpDest [I] Bitmap pointer
644 * ulCount [I] Number of dwords to write
645 * ulValue [I] Value to fill with
646 *
647 * RETURNS
648 * Nothing.
649 */
650VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
651{
652 TRACE("(%p,%ld,%ld)\n", lpDest, ulCount, ulValue);
653
654 while(ulCount--)
655 *lpDest++ = ulValue;
656}
657
658/*************************************************************************
659 * RtlGetLongestNtPathLength [NTDLL.@]
660 *
661 * Get the longest allowed path length
662 *
663 * PARAMS
664 * None.
665 *
666 * RETURNS
667 * The longest allowed path length (277 characters under Win2k).
668 */
669DWORD WINAPI RtlGetLongestNtPathLength(void)
670{
671 TRACE("()\n");
672 return 277;
673}
674
675/*********************************************************************
676 * RtlComputeCrc32 [NTDLL.@]
677 *
678 * Calculate the CRC32 checksum of a block of bytes
679 *
680 * PARAMS
681 * dwInitial [I] Initial CRC value
682 * pData [I] Data block
683 * iLen [I] Length of the byte block
684 *
685 * RETURNS
686 * The cumulative CRC32 of dwInitial and iLen bytes of the pData block.
687 */
688DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, PBYTE pData, INT iLen)
689{
690 DWORD crc = ~dwInitial;
691
692 TRACE("(%ld,%p,%d)\n", dwInitial, pData, iLen);
693
694 while (iLen > 0)
695 {
696 crc = CRC_table[(crc ^ *pData) & 0xff] ^ (crc >> 8);
697 pData++;
698 iLen--;
699 }
700 return ~crc;
701}
702
703/*************************************************************************
704 * RtlInitializeSListHead [NTDLL.@]
705 */
706VOID WINAPI RtlInitializeSListHead(PSLIST_HEADER list)
707{
708 list->Alignment = 0;
709}
710
711/*************************************************************************
712 * RtlQueryDepthSList [NTDLL.@]
713 */
714WORD WINAPI RtlQueryDepthSList(PSLIST_HEADER list)
715{
716 return list->Depth;
717}
718
719/*************************************************************************
720 * RtlFirstEntrySList [NTDLL.@]
721 */
722PSLIST_ENTRY WINAPI RtlFirstEntrySList(const SLIST_HEADER* list)
723{
724 return list->Next.Next;
725}
726
727/*************************************************************************
728 * RtlInterlockedFlushSList [NTDLL.@]
729 */
730PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list)
731{
732 SLIST_HEADER old, new;
733
734 if (!list->Depth) return NULL;
735 new.Alignment = 0;
736 do
737 {
738 old = *list;
739 new.Sequence = old.Sequence + 1;
740 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
741 old.Alignment) != old.Alignment);
742 return old.Next.Next;
743}
744
745/*************************************************************************
746 * RtlInterlockedPushEntrySList [NTDLL.@]
747 */
748PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTRY entry)
749{
750 SLIST_HEADER old, new;
751
752 new.Next.Next = entry;
753 do
754 {
755 old = *list;
756 entry->Next = old.Next.Next;
757 new.Depth = old.Depth + 1;
758 new.Sequence = old.Sequence + 1;
759 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
760 old.Alignment) != old.Alignment);
761 return old.Next.Next;
762}
763
764/*************************************************************************
765 * RtlInterlockedPopEntrySList [NTDLL.@]
766 */
767PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list)
768{
769 SLIST_HEADER old, new;
770 PSLIST_ENTRY entry;
771
772 do
773 {
774 old = *list;
775 if (!(entry = old.Next.Next)) return NULL;
776 /* entry could be deleted by another thread */
777 __TRY
778 {
779 new.Next.Next = entry->Next;
780 new.Depth = old.Depth - 1;
781 new.Sequence = old.Sequence + 1;
782 }
783 __EXCEPT_PAGE_FAULT
784 {
785 }
786 __ENDTRY
787 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
788 old.Alignment) != old.Alignment);
789 return entry;
790}
791
792/*************************************************************************
793 * RtlInterlockedPushListSList [NTDLL.@]
794 */
795PSLIST_ENTRY WINAPI RtlInterlockedPushListSList(PSLIST_HEADER list, PSLIST_ENTRY first,
796 PSLIST_ENTRY last, ULONG count)
797{
798 SLIST_HEADER old, new;
799
800 new.Next.Next = first;
801 do
802 {
803 old = *list;
804 new.Depth = old.Depth + count;
805 new.Sequence = old.Sequence + 1;
806 last->Next = old.Next.Next;
807 } while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
808 old.Alignment) != old.Alignment);
809 return old.Next.Next;
810}
Note: See TracBrowser for help on using the repository browser.