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

Last change on this file since 51 was 51, checked in by sandervl, 26 years ago

* empty log message *

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