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

Last change on this file since 6666 was 6372, checked in by sandervl, 24 years ago

64 bits math functions replaced

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