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

Last change on this file since 568 was 568, checked in by phaller, 26 years ago

Add: RtlSizeHeap added

File size: 17.1 KB
Line 
1/* $Id: rtl.cpp,v 1.6 1999-08-19 02:12:17 phaller 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 <string.h>
20#include <odinwrap.h>
21
22#include "ntdll.h"
23
24#include "winuser.h"
25#include "winerror.h"
26#include "winreg.h"
27
28
29ODINDEBUGCHANNEL(NTDLL-RTL)
30
31/*
32 * resource functions
33 */
34
35/***********************************************************************
36 * RtlInitializeResource (NTDLL.409)
37 *
38 * xxxResource() functions implement multiple-reader-single-writer lock.
39 * The code is based on information published in WDJ January 1999 issue.
40 */
41void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
42{
43 dprintf(("NTDLL: RtlInitializeResource(%08xh)\n",
44 rwl));
45
46 if( rwl )
47 {
48 rwl->iNumberActive = 0;
49 rwl->uExclusiveWaiters = 0;
50 rwl->uSharedWaiters = 0;
51 rwl->hOwningThreadId = 0;
52 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
53 InitializeCriticalSection( &rwl->rtlCS );
54 rwl->hExclusiveReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
55 rwl->hSharedReleaseSemaphore = CreateSemaphoreA( NULL, 0, 65535, NULL );
56 }
57}
58
59
60/***********************************************************************
61 * RtlDeleteResource (NTDLL.330)
62 */
63void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
64{
65 dprintf(("NTDLL: RtlDeleteResource(%08xh)\n",
66 rwl));
67
68 if( rwl )
69 {
70 EnterCriticalSection( &rwl->rtlCS );
71 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
72 dprintf(("NTDLL: RtlDeleteResource active MRSW lock (%p), expect failure\n",
73 rwl));
74
75 rwl->hOwningThreadId = 0;
76 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
77 rwl->iNumberActive = 0;
78 CloseHandle( rwl->hExclusiveReleaseSemaphore );
79 CloseHandle( rwl->hSharedReleaseSemaphore );
80 LeaveCriticalSection( &rwl->rtlCS );
81 DeleteCriticalSection( &rwl->rtlCS );
82 }
83}
84
85
86/***********************************************************************
87 * RtlAcquireResourceExclusive (NTDLL.256)
88 */
89BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl,
90 BYTE fWait)
91{
92 BYTE retVal = 0;
93
94 if( !rwl )
95 return 0;
96
97 dprintf(("NTDLL: RtlAcquireResourceExclusive(%08xh,%08xh)\n",
98 rwl,
99 fWait));
100
101start:
102 EnterCriticalSection( &rwl->rtlCS );
103 if( rwl->iNumberActive == 0 ) /* lock is free */
104 {
105 rwl->iNumberActive = -1;
106 retVal = 1;
107 }
108 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
109 {
110 if( rwl->hOwningThreadId == GetCurrentThreadId() )
111 {
112 retVal = 1;
113 rwl->iNumberActive--;
114 goto done;
115 }
116wait:
117 if( fWait )
118 {
119 rwl->uExclusiveWaiters++;
120
121 LeaveCriticalSection( &rwl->rtlCS );
122 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE ) == WAIT_FAILED )
123 goto done;
124 goto start; /* restart the acquisition to avoid deadlocks */
125 }
126 }
127 else /* one or more shared locks are in progress */
128 if( fWait )
129 goto wait;
130
131 if( retVal == 1 )
132 rwl->hOwningThreadId = GetCurrentThreadId();
133done:
134 LeaveCriticalSection( &rwl->rtlCS );
135 return retVal;
136}
137
138/***********************************************************************
139 * RtlAcquireResourceShared (NTDLL.257)
140 */
141BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl,
142 BYTE fWait)
143{
144 DWORD dwWait = WAIT_FAILED;
145 BYTE retVal = 0;
146
147 if( !rwl )
148 return 0;
149
150 dprintf(("NTDLL: RtlAcquireResourceShared(%08xh,%08xh)\n",
151 rwl,
152 fWait));
153
154start:
155 EnterCriticalSection( &rwl->rtlCS );
156 if( rwl->iNumberActive < 0 )
157 {
158 if( rwl->hOwningThreadId == GetCurrentThreadId() )
159 {
160 rwl->iNumberActive--;
161 retVal = 1;
162 goto done;
163 }
164
165 if( fWait )
166 {
167 rwl->uSharedWaiters++;
168 LeaveCriticalSection( &rwl->rtlCS );
169 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE )) == WAIT_FAILED )
170 goto done;
171 goto start;
172 }
173 }
174 else
175 {
176 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
177 rwl->iNumberActive++;
178 retVal = 1;
179 }
180done:
181 LeaveCriticalSection( &rwl->rtlCS );
182 return retVal;
183}
184
185
186/***********************************************************************
187 * RtlReleaseResource (NTDLL.471)
188 */
189void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
190{
191 dprintf(("NTDLL: RtlReleaseResource(%08xh)\n",
192 rwl));
193
194 EnterCriticalSection( &rwl->rtlCS );
195
196 if( rwl->iNumberActive > 0 ) /* have one or more readers */
197 {
198 if( --rwl->iNumberActive == 0 )
199 {
200 if( rwl->uExclusiveWaiters )
201 {
202wake_exclusive:
203 rwl->uExclusiveWaiters--;
204 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
205 }
206 }
207 }
208 else
209 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
210 {
211 if( ++rwl->iNumberActive == 0 )
212 {
213 rwl->hOwningThreadId = 0;
214 if( rwl->uExclusiveWaiters )
215 goto wake_exclusive;
216 else
217 if( rwl->uSharedWaiters )
218 {
219 UINT n = rwl->uSharedWaiters;
220 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
221 * all queued readers have done their thing */
222 rwl->uSharedWaiters = 0;
223 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
224 }
225 }
226 }
227 LeaveCriticalSection( &rwl->rtlCS );
228}
229
230
231/***********************************************************************
232 * RtlDumpResource (NTDLL.340)
233 */
234void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
235{
236 dprintf(("NTDLL: RtlDumpResource(%08x)\n",
237 rwl));
238
239 if( rwl )
240 {
241 dprintf(("NTDLL: RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
242 rwl,
243 rwl->iNumberActive,
244 rwl->uSharedWaiters,
245 rwl->uExclusiveWaiters));
246
247 if( rwl->iNumberActive )
248 dprintf(("NTDLL: \towner thread = %08x\n",
249 rwl->hOwningThreadId ));
250 }
251}
252
253
254/*
255 * heap functions
256 */
257
258/******************************************************************************
259 * RtlCreateHeap [NTDLL]
260 */
261HANDLE WINAPI RtlCreateHeap(ULONG Flags,
262 PVOID BaseAddress,
263 ULONG SizeToReserve,
264 ULONG SizeToCommit,
265 PVOID Unknown,
266 PRTL_HEAP_DEFINITION Definition)
267{
268 dprintf(("NTDLL: RtlCreateHeap(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh).\n",
269 Flags,
270 BaseAddress,
271 SizeToReserve,
272 SizeToCommit,
273 Unknown,
274 Definition));
275
276 return HeapCreate(Flags,
277 SizeToCommit,
278 SizeToReserve);
279}
280
281
282/******************************************************************************
283 * RtlAllocateHeap [NTDLL]
284 */
285PVOID WINAPI RtlAllocateHeap(HANDLE Heap,
286 ULONG Flags,
287 ULONG Size)
288{
289 dprintf(("NTDLL: RtlAllocateHeap(%08xh,%08xh,%08xh).\n",
290 Heap,
291 Flags,
292 Size));
293
294 return HeapAlloc(Heap,
295 Flags,
296 Size);
297}
298
299
300/******************************************************************************
301 * RtlFreeHeap [NTDLL]
302 */
303BOOLEAN WINAPI RtlFreeHeap(HANDLE Heap,
304 ULONG Flags,
305 PVOID Address)
306{
307 dprintf(("NTDLL: RtlFreeHeap(%08xh,%08xh,%08xh)\n",
308 Heap,
309 Flags,
310 Address));
311
312 return HeapFree(Heap, Flags, Address);
313}
314
315
316/******************************************************************************
317 * RtlDestroyHeap [NTDLL]
318 *
319 * FIXME: prototype guessed
320 */
321BOOLEAN WINAPI RtlDestroyHeap(HANDLE Heap)
322{
323 dprintf(("NTDLL: RtlDestroyHeap(%08xh)\n",
324 Heap));
325
326 return HeapDestroy(Heap);
327}
328
329
330
331/******************************************************************************
332 * RtlSizeHeap [NTDLL]
333 */
334
335ODINFUNCTION3(DWORD,RtlSizeHeap,HANDLE,hHeap,
336 DWORD, dwFlags,
337 PVOID, pAddress)
338{
339 return HeapSize(hHeap,
340 dwFlags,
341 pAddress);
342}
343
344
345
346/*
347 * misc functions
348 */
349
350
351/******************************************************************************
352 * RtlAcquirePebLock [NTDLL]
353 */
354VOID WINAPI RtlAcquirePebLock(void)
355{
356 dprintf(("NTDLL: RtlAcquirePebLock() not implemented.\n"));
357
358 /* enter critical section ? */
359}
360
361
362/******************************************************************************
363 * RtlReleasePebLock [NTDLL]
364 */
365VOID WINAPI RtlReleasePebLock(void)
366{
367 dprintf(("NTDLL: RtlReleasePebLock() not implemented.\n"));
368
369 /* leave critical section ? */
370}
371
372
373/******************************************************************************
374 * RtlIntegerToChar [NTDLL]
375 */
376DWORD WINAPI RtlIntegerToChar(DWORD x1,
377 DWORD x2,
378 DWORD x3,
379 DWORD x4)
380{
381 dprintf(("NTDLL: RtlIntegerToChar(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
382 x1,
383 x2,
384 x3,
385 x4));
386
387 return 0;
388}
389
390
391/******************************************************************************
392 * RtlSetEnvironmentVariable [NTDLL]
393 */
394DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,
395 PUNICODE_STRING key,
396 PUNICODE_STRING val)
397{
398 dprintf(("NTDLL: RtlSetEnvironmentVariable(%08xh,%08xh,%08xh) not implemented.\n",
399 x1,
400 key,
401 val));
402
403 return 0;
404}
405
406
407/******************************************************************************
408 * RtlNewSecurityObject [NTDLL]
409 */
410DWORD WINAPI RtlNewSecurityObject(DWORD x1,
411 DWORD x2,
412 DWORD x3,
413 DWORD x4,
414 DWORD x5,
415 DWORD x6)
416{
417 dprintf(("NTDLL: RtlNewSecurityObject(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
418 x1,
419 x2,
420 x3,
421 x4,
422 x5,
423 x6));
424
425 return 0;
426}
427
428
429/******************************************************************************
430 * RtlDeleteSecurityObject [NTDLL]
431 */
432DWORD WINAPI RtlDeleteSecurityObject(DWORD x1)
433{
434 dprintf(("NTDLL: RtlDeleteSecurityObject(%08xh) not implemented.\n",
435 x1));
436
437 return 0;
438}
439
440
441/**************************************************************************
442 * RtlNormalizeProcessParams [NTDLL.441]
443 */
444LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
445{
446 dprintf(("NTDLL: RtlNormalizeProcessParams(%08xh) not implemented.\n",
447 x));
448
449 return x;
450}
451
452
453/**************************************************************************
454 * RtlNtStatusToDosError [NTDLL.442]
455 */
456DWORD WINAPI RtlNtStatusToDosError(DWORD error)
457{
458 dprintf(("NTDLL: RtlNtStatusToDosError(%08xh) partially implemented.\n",
459 error));
460
461 switch (error)
462 {
463 case STATUS_SUCCESS: return ERROR_SUCCESS;
464 case STATUS_INVALID_PARAMETER: return ERROR_BAD_ARGUMENTS;
465 case STATUS_BUFFER_TOO_SMALL: return ERROR_INSUFFICIENT_BUFFER;
466/* case STATUS_INVALID_SECURITY_DESCR: return ERROR_INVALID_SECURITY_DESCR;*/
467 case STATUS_NO_MEMORY: return ERROR_NOT_ENOUGH_MEMORY;
468/* case STATUS_UNKNOWN_REVISION:
469 case STATUS_BUFFER_OVERFLOW:*/
470 }
471
472 dprintf(("NTDLL: RtlNtStatusToDosError(%08xh is unknown !)\n",
473 error));
474
475 return ERROR_SUCCESS;
476}
477
478
479/**************************************************************************
480 * RtlGetNtProductType [NTDLL.390]
481 */
482BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
483{
484 dprintf(("NTDLL: RtlGetNtProductType(%08xh) not correctly implemented.\n",
485 type));
486
487 *type=3; /* dunno. 1 for client, 3 for server? */
488 return 1;
489}
490
491
492/******************************************************************************
493 * RtlEnlargedIntegerMultiply [NTDLL.341]
494 * Note: This even works, since gcc returns 64bit values in eax/edx just like
495 * the caller expects. However... The relay code won't grok this I think.
496 *
497 * @@@PH: Parameters are unknown
498 */
499/* longlong in VAC++ ? */
500
501INT WINAPI RtlEnlargedIntegerMultiply(INT factor1,
502 INT factor2)
503{
504 dprintf(("NTDLL: RtlEnlargedIntegerMultiply(%08xh,%08xh) not implemented.\n",
505 factor1,
506 factor2));
507
508 return factor1 * factor2;
509}
510
511
512/******************************************************************************
513 * RtlExtendedLargeIntegerDivide [NTDLL.359]
514 */
515INT WINAPI RtlExtendedLargeIntegerDivide(LARGE_INTEGER dividend,
516 DWORD divisor,
517 LPDWORD rest)
518{
519#if SIZEOF_LONG_LONG==8
520 long long x1 = *(long long*)&dividend;
521
522 if (*rest)
523 *rest = x1 % divisor;
524 return x1/divisor;
525#else
526 dprintf(("NTDLL: RtlExtendedLargeIntegerDevice(%08xh,%08xh,%08xh) not implemented.\n",
527 dividend,
528 divisor,
529 rest));
530
531 return 0;
532#endif
533}
534
535/******************************************************************************
536 * RtlExtendedLargeIntegerMultiply [NTDLL.358]
537 * Note: This even works, since gcc returns 64bit values in eax/edx just like
538 * the caller expects. However... The relay code won't grok this I think.
539 */
540/* longlong in VAC++ ? */
541
542LARGE_INTEGER WINAPI RtlExtendedIntegerMultiply(LARGE_INTEGER factor1,
543 INT factor2)
544{
545 LARGE_INTEGER li;
546
547 dprintf(("NTDLL: RtlExtendedIntegerMultiply(%08xh,%08xh) not implemented.\n",
548 factor1,
549 factor2));
550
551 li.LowPart = factor1.LowPart * factor2;
552 li.HighPart = factor1.HighPart * factor2;
553 // note: overflow from LowPart To HighPart NOT handled !
554
555 return li;
556}
557
558
559/******************************************************************************
560 * RtlFormatCurrentUserKeyPath [NTDLL.371]
561 */
562DWORD WINAPI RtlFormatCurrentUserKeyPath(DWORD x)
563{
564 dprintf(("NTDLL: RtlFormatCurrentUserKeyPath(%08xh) not implemented.\n",
565 x));
566
567 return 1;
568}
569
570
571/******************************************************************************
572 * RtlOpenCurrentUser [NTDLL]
573 */
574DWORD WINAPI RtlOpenCurrentUser(DWORD x1,
575 DWORD *x2)
576{
577 /* Note: this is not the correct solution,
578 * But this works pretty good on wine and NT4.0 binaries
579 */
580 if (x1 == 0x2000000 )
581 {
582 *x2 = HKEY_CURRENT_USER;
583 return TRUE;
584 }
585
586 return FALSE;
587}
588
589
590/**************************************************************************
591 * RtlDosPathNameToNtPathName_U [NTDLL.338]
592 *
593 * FIXME: convert to UNC or whatever is expected here
594 */
595BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR from,
596 PUNICODE_STRING us,
597 DWORD x2,
598 DWORD x3)
599{
600 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
601
602 dprintf(("NTDLL: RtlDosPathNameToNtPathName_U(%08xh,%08h,%08xh,%08xh) not implemented.\n",
603 from,
604 us,
605 x2,
606 x3));
607
608 if (us)
609 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
610
611 return TRUE;
612}
613
614
615/******************************************************************************
616 * RtlCreateEnvironment [NTDLL]
617 */
618DWORD WINAPI RtlCreateEnvironment(DWORD x1,
619 DWORD x2)
620{
621 dprintf(("NTDLL: RtlCreateEnvironment(%08xh, %08xh) not implemented.\n",
622 x1,
623 x2));
624
625 return 0;
626}
627
628
629/******************************************************************************
630 * RtlDestroyEnvironment [NTDLL]
631 */
632DWORD WINAPI RtlDestroyEnvironment(DWORD x)
633{
634 dprintf(("NTDLL: RtlDestroyEnvironment(%08xh) not implemented.\n",
635 x));
636
637 return 0;
638}
639
640
641/******************************************************************************
642 * RtlQueryEnvironmentVariable_U [NTDLL]
643 */
644DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,
645 PUNICODE_STRING key,
646 PUNICODE_STRING val)
647{
648 dprintf(("NTDLL: RtlQueryEnvironmentVariable_U(%08xh,%08xh,%08xh) not implemented.\n",
649 x1,
650 key,
651 val));
652
653 return 0;
654}
655
Note: See TracBrowser for help on using the repository browser.