source: trunk/src/NTDLL/rtl.cpp@ 8266

Last change on this file since 8266 was 7983, checked in by sandervl, 24 years ago

update

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