source: trunk/src/NTDLL/rtl.c@ 9731

Last change on this file since 9731 was 9731, checked in by sandervl, 23 years ago

PF: update

File size: 17.1 KB
Line 
1/* $Id: rtl.c,v 1.4 2003-01-23 20:22:00 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#include <odinwrap.h>
22
23#include "debugtools.h"
24
25#include "winuser.h"
26#include "windef.h"
27#include "winerror.h"
28#include "stackframe.h"
29#include "ntddk.h"
30#include "winreg.h"
31#include "heapstring.h"
32
33#include <misc.h>
34
35
36ODINDEBUGCHANNEL(NTDLL-RTL)
37
38
39/*
40 * WINE Adoption - we won't support the Win64 model.
41 */
42#define SIZE_T UINT
43
44/*
45 * resource functions
46 */
47
48/***********************************************************************
49 * RtlInitializeResource (NTDLL.409)
50 *
51 * xxxResource() functions implement multiple-reader-single-writer lock.
52 * The code is based on information published in WDJ January 1999 issue.
53 */
54void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
55{
56 dprintf(("NTDLL: RtlInitializeResource(%08xh)\n",
57 rwl));
58
59 if( rwl )
60 {
61 rwl->iNumberActive = 0;
62 rwl->uExclusiveWaiters = 0;
63 rwl->uSharedWaiters = 0;
64 rwl->hOwningThreadId = 0;
65 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
66 InitializeCriticalSection( &rwl->rtlCS );
67 rwl->hExclusiveReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
68 rwl->hSharedReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
69 }
70}
71
72
73/***********************************************************************
74 * RtlDeleteResource (NTDLL.330)
75 */
76void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
77{
78 dprintf(("NTDLL: RtlDeleteResource(%08xh)\n",
79 rwl));
80
81 if( rwl )
82 {
83 EnterCriticalSection( &rwl->rtlCS );
84 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
85 dprintf(("NTDLL: RtlDeleteResource active MRSW lock (%p), expect failure\n",
86 rwl));
87
88 rwl->hOwningThreadId = 0;
89 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
90 rwl->iNumberActive = 0;
91 CloseHandle( rwl->hExclusiveReleaseSemaphore );
92 CloseHandle( rwl->hSharedReleaseSemaphore );
93 LeaveCriticalSection( &rwl->rtlCS );
94 DeleteCriticalSection( &rwl->rtlCS );
95 }
96}
97
98
99/***********************************************************************
100 * RtlAcquireResourceExclusive (NTDLL.256)
101 */
102BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl,
103 BYTE fWait)
104{
105 BYTE retVal = 0;
106
107 if( !rwl )
108 return 0;
109
110 dprintf(("NTDLL: RtlAcquireResourceExclusive(%08xh,%08xh)\n",
111 rwl,
112 fWait));
113
114start:
115 EnterCriticalSection( &rwl->rtlCS );
116 if( rwl->iNumberActive == 0 ) /* lock is free */
117 {
118 rwl->iNumberActive = -1;
119 retVal = 1;
120 }
121 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
122 {
123 if( rwl->hOwningThreadId == GetCurrentThreadId() )
124 {
125 retVal = 1;
126 rwl->iNumberActive--;
127 goto done;
128 }
129wait:
130 if( fWait )
131 {
132 rwl->uExclusiveWaiters++;
133
134 LeaveCriticalSection( &rwl->rtlCS );
135 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
136 goto done;
137 goto start; /* restart the acquisition to avoid deadlocks */
138 }
139 }
140 else /* one or more shared locks are in progress */
141 if( fWait )
142 goto wait;
143
144 if( retVal == 1 )
145 rwl->hOwningThreadId = GetCurrentThreadId();
146done:
147 LeaveCriticalSection( &rwl->rtlCS );
148 return retVal;
149}
150
151/***********************************************************************
152 * RtlAcquireResourceShared (NTDLL.257)
153 */
154BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl,
155 BYTE fWait)
156{
157 DWORD dwWait = WAIT_FAILED;
158 BYTE retVal = 0;
159
160 if( !rwl )
161 return 0;
162
163 dprintf(("NTDLL: RtlAcquireResourceShared(%08xh,%08xh)\n",
164 rwl,
165 fWait));
166
167start:
168 EnterCriticalSection( &rwl->rtlCS );
169 if( rwl->iNumberActive < 0 )
170 {
171 if( rwl->hOwningThreadId == GetCurrentThreadId() )
172 {
173 rwl->iNumberActive--;
174 retVal = 1;
175 goto done;
176 }
177
178 if( fWait )
179 {
180 rwl->uSharedWaiters++;
181 LeaveCriticalSection( &rwl->rtlCS );
182 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
183 goto done;
184 goto start;
185 }
186 }
187 else
188 {
189 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
190 rwl->iNumberActive++;
191 retVal = 1;
192 }
193done:
194 LeaveCriticalSection( &rwl->rtlCS );
195 return retVal;
196}
197
198
199/***********************************************************************
200 * RtlReleaseResource (NTDLL.471)
201 */
202void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
203{
204 dprintf(("NTDLL: RtlReleaseResource(%08xh)\n",
205 rwl));
206
207 EnterCriticalSection( &rwl->rtlCS );
208
209 if( rwl->iNumberActive > 0 ) /* have one or more readers */
210 {
211 if( --rwl->iNumberActive == 0 )
212 {
213 if( rwl->uExclusiveWaiters )
214 {
215wake_exclusive:
216 rwl->uExclusiveWaiters--;
217 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
218 }
219 }
220 }
221 else
222 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
223 {
224 if( ++rwl->iNumberActive == 0 )
225 {
226 rwl->hOwningThreadId = 0;
227 if( rwl->uExclusiveWaiters )
228 goto wake_exclusive;
229 else
230 if( rwl->uSharedWaiters )
231 {
232 UINT n = rwl->uSharedWaiters;
233 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
234 * all queued readers have done their thing */
235 rwl->uSharedWaiters = 0;
236 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
237 }
238 }
239 }
240 LeaveCriticalSection( &rwl->rtlCS );
241}
242
243
244/***********************************************************************
245 * RtlDumpResource (NTDLL.340)
246 */
247void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
248{
249 dprintf(("NTDLL: RtlDumpResource(%08x)\n",
250 rwl));
251
252 if( rwl )
253 {
254 dprintf(("NTDLL: RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
255 rwl,
256 rwl->iNumberActive,
257 rwl->uSharedWaiters,
258 rwl->uExclusiveWaiters));
259
260 if( rwl->iNumberActive )
261 dprintf(("NTDLL: \towner thread = %08x\n",
262 rwl->hOwningThreadId ));
263 }
264}
265
266
267/*
268 * heap functions
269 */
270
271
272
273/*
274 * misc functions
275 */
276
277
278/******************************************************************************
279 * RtlAcquirePebLock [NTDLL]
280 */
281VOID WINAPI RtlAcquirePebLock(void)
282{
283 dprintf(("NTDLL: RtlAcquirePebLock() not implemented.\n"));
284
285 /* enter critical section ? */
286}
287
288
289/******************************************************************************
290 * RtlReleasePebLock [NTDLL]
291 */
292VOID WINAPI RtlReleasePebLock(void)
293{
294 dprintf(("NTDLL: RtlReleasePebLock() not implemented.\n"));
295
296 /* leave critical section ? */
297}
298
299
300/******************************************************************************
301 * RtlIntegerToChar [NTDLL]
302 */
303DWORD WINAPI RtlIntegerToChar(DWORD x1,
304 DWORD x2,
305 DWORD x3,
306 DWORD x4)
307{
308 dprintf(("NTDLL: RtlIntegerToChar(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
309 x1,
310 x2,
311 x3,
312 x4));
313
314 return 0;
315}
316
317
318/******************************************************************************
319 * RtlSetEnvironmentVariable [NTDLL]
320 */
321DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,
322 PUNICODE_STRING key,
323 PUNICODE_STRING val)
324{
325 dprintf(("NTDLL: RtlSetEnvironmentVariable(%08xh,%08xh,%08xh) not implemented.\n",
326 x1,
327 key,
328 val));
329
330 return 0;
331}
332
333
334/******************************************************************************
335 * RtlNewSecurityObject [NTDLL]
336 */
337DWORD WINAPI RtlNewSecurityObject(DWORD x1,
338 DWORD x2,
339 DWORD x3,
340 DWORD x4,
341 DWORD x5,
342 DWORD x6)
343{
344 dprintf(("NTDLL: RtlNewSecurityObject(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
345 x1,
346 x2,
347 x3,
348 x4,
349 x5,
350 x6));
351
352 return 0;
353}
354
355
356/******************************************************************************
357 * RtlDeleteSecurityObject [NTDLL]
358 */
359DWORD WINAPI RtlDeleteSecurityObject(DWORD x1)
360{
361 dprintf(("NTDLL: RtlDeleteSecurityObject(%08xh) not implemented.\n",
362 x1));
363
364 return 0;
365}
366
367
368/**************************************************************************
369 * RtlNormalizeProcessParams [NTDLL.441]
370 */
371LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
372{
373 dprintf(("NTDLL: RtlNormalizeProcessParams(%08xh) not implemented.\n",
374 x));
375
376 return x;
377}
378
379
380
381/**************************************************************************
382 * RtlGetNtProductType [NTDLL.390]
383 */
384BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
385{
386 dprintf(("NTDLL: RtlGetNtProductType(%08xh) not correctly implemented.\n",
387 type));
388
389 *type=3; /* dunno. 1 for client, 3 for server? */
390 return 1;
391}
392
393
394
395/******************************************************************************
396 * RtlFormatCurrentUserKeyPath [NTDLL.371]
397 */
398NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING pustrKeyPath)
399{
400 dprintf(("NTDLL: RtlFormatCurrentUserKeyPath(%08xh) not correctly implemented.\n",
401 pustrKeyPath));
402
403 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
404 ANSI_STRING AnsiPath;
405
406 RtlInitAnsiString(&AnsiPath, Path);
407 return RtlAnsiStringToUnicodeString(pustrKeyPath, &AnsiPath, TRUE);
408}
409
410
411/******************************************************************************
412 * RtlOpenCurrentUser [NTDLL]
413 */
414DWORD WINAPI RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, OUT PHANDLE pKeyHandle)
415{
416 /* Note: this is not the correct solution,
417 * But this works pretty good on wine and NT4.0 binaries
418 */
419
420 if (DesiredAccess == 0x2000000 )
421 {
422 *pKeyHandle = HKEY_CURRENT_USER;
423 return TRUE;
424 }
425
426 return FALSE;
427/* PH 2000/08/18 currently disabled
428 OBJECT_ATTRIBUTES ObjectAttributes;
429 UNICODE_STRING ObjectName;
430 NTSTATUS ret;
431
432 RtlFormatCurrentUserKeyPath(&ObjectName);
433 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
434 ret = NtOpenKey(pKeyHandle, DesiredAccess, &ObjectAttributes);
435 RtlFreeUnicodeString(&ObjectName);
436 return ret;
437 */
438}
439
440
441/**************************************************************************
442 * RtlDosPathNameToNtPathName_U [NTDLL.338]
443 *
444 * FIXME: convert to UNC or whatever is expected here
445 */
446BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR from,
447 PUNICODE_STRING us,
448 DWORD x2,
449 DWORD x3)
450{
451 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
452
453 dprintf(("NTDLL: RtlDosPathNameToNtPathName_U(%08xh,%08h,%08xh,%08xh) not implemented.\n",
454 from,
455 us,
456 x2,
457 x3));
458
459 if (us)
460 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
461
462 return TRUE;
463}
464
465
466/***********************************************************************
467 * RtlImageNtHeader (NTDLL)
468 */
469PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
470{
471 IMAGE_NT_HEADERS *ret = NULL;
472 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
473
474 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
475 {
476 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
477 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
478 }
479 return ret;
480}
481
482/******************************************************************************
483 * RtlCreateEnvironment [NTDLL]
484 */
485DWORD WINAPI RtlCreateEnvironment(DWORD x1,
486 DWORD x2)
487{
488 dprintf(("NTDLL: RtlCreateEnvironment(%08xh, %08xh) not implemented.\n",
489 x1,
490 x2));
491
492 return 0;
493}
494
495
496/******************************************************************************
497 * RtlDestroyEnvironment [NTDLL]
498 */
499DWORD WINAPI RtlDestroyEnvironment(DWORD x)
500{
501 dprintf(("NTDLL: RtlDestroyEnvironment(%08xh) not implemented.\n",
502 x));
503
504 return 0;
505}
506
507
508/******************************************************************************
509 * RtlQueryEnvironmentVariable_U [NTDLL]
510 */
511DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,
512 PUNICODE_STRING key,
513 PUNICODE_STRING val)
514{
515 dprintf(("NTDLL: RtlQueryEnvironmentVariable_U(%08xh,%08xh,%08xh) not implemented.\n",
516 x1,
517 key,
518 val));
519
520 return 0;
521}
522
523/******************************************************************************
524 * RtlInitializeGenericTable [NTDLL]
525 */
526DWORD WINAPI RtlInitializeGenericTable(void)
527{
528 FIXME("\n");
529 return 0;
530}
531
532
533
534
535/******************************************************************************
536 * RtlCopyMemory [NTDLL]
537 *
538 */
539#undef RtlCopyMemory
540VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
541{
542 memcpy(Destination, Source, Length);
543}
544
545/******************************************************************************
546 * RtlMoveMemory [NTDLL]
547 */
548#undef RtlMoveMemory
549VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
550{
551 memmove(Destination, Source, Length);
552}
553
554/******************************************************************************
555 * RtlFillMemory [NTDLL]
556 */
557#undef RtlFillMemory
558VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, UINT Fill )
559{
560 memset(Destination, Fill, Length);
561}
562
563/******************************************************************************
564 * RtlZeroMemory [NTDLL]
565 */
566#undef RtlZeroMemory
567VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
568{
569 memset(Destination, 0, Length);
570}
571
572/******************************************************************************
573 * RtlCompareMemory [NTDLL]
574 */
575SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
576{
577 int i;
578 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
579 return i;
580}
581
582/******************************************************************************
583 * RtlAssert [NTDLL]
584 *
585 * Not implemented in non-debug versions.
586 */
587void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
588{
589 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
590}
591
592/*****************************************************************************
593 * Name : RtlCopyLuid
594 * Purpose : copy local unique identifier?
595 * Parameters: PLUID pluid1
596 * PLUID pluid2
597 * Variables :
598 * Result :
599 * Remark : NTDLL.321
600 * Status : COMPLETELY ? IMPLEMENTED TESTED ?
601 *
602 * Author : Patrick Haller [Tue, 1999/11/09 09:00]
603 *****************************************************************************/
604
605PLUID WINAPI RtlCopyLuid(PLUID pluid1,
606 PLUID pluid2)
607{
608 pluid2->LowPart = pluid1->LowPart;
609 pluid2->HighPart = pluid1->HighPart;
610 return (pluid1);
611}
612
613/******************************************************************************
614 * RtlGetNtVersionNumbers [NTDLL.@]
615 *
616 * Introduced in Windows XP (NT5.1)
617 */
618void WINAPI RtlGetNtVersionNumbers(LPDWORD major, LPDWORD minor, LPDWORD build)
619{
620 OSVERSIONINFOEXW versionInfo;
621 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
622 GetVersionExW((OSVERSIONINFOW*)&versionInfo);
623
624 if (major)
625 {
626 *major = versionInfo.dwMajorVersion;
627 }
628
629 if (minor)
630 {
631 *minor = versionInfo.dwMinorVersion;
632 }
633
634 if (build)
635 {
636 /* FIXME: Does anybody know the real formula? */
637 *build = (0xF0000000 | versionInfo.dwBuildNumber);
638 }
639}
640
641/*************************************************************************
642 * RtlFillMemoryUlong [NTDLL.@]
643 *
644 * Fill memory with a 32 bit (dword) value.
645 *
646 * PARAMS
647 * lpDest [I] Bitmap pointer
648 * ulCount [I] Number of dwords to write
649 * ulValue [I] Value to fill with
650 *
651 * RETURNS
652 * Nothing.
653 */
654VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue)
655{
656 TRACE("(%p,%ld,%ld)\n", lpDest, ulCount, ulValue);
657
658 while(ulCount--)
659 *lpDest++ = ulValue;
660}
661
662/*************************************************************************
663 * RtlGetLongestNtPathLength [NTDLL.@]
664 *
665 * Get the longest allowed path length
666 *
667 * PARAMS
668 * None.
669 *
670 * RETURNS
671 * The longest allowed path length (277 characters under Win2k).
672 */
673DWORD WINAPI RtlGetLongestNtPathLength(void)
674{
675 TRACE("()\n");
676 return 277;
677}
Note: See TracBrowser for help on using the repository browser.