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

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

resync with latest wine

File size: 16.7 KB
Line 
1/* $Id: rtl.cpp,v 1.15 2002-05-16 12:16: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 "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
274/*
275 * misc functions
276 */
277
278
279/******************************************************************************
280 * RtlAcquirePebLock [NTDLL]
281 */
282VOID WINAPI RtlAcquirePebLock(void)
283{
284 dprintf(("NTDLL: RtlAcquirePebLock() not implemented.\n"));
285
286 /* enter critical section ? */
287}
288
289
290/******************************************************************************
291 * RtlReleasePebLock [NTDLL]
292 */
293VOID WINAPI RtlReleasePebLock(void)
294{
295 dprintf(("NTDLL: RtlReleasePebLock() not implemented.\n"));
296
297 /* leave critical section ? */
298}
299
300
301/******************************************************************************
302 * RtlIntegerToChar [NTDLL]
303 */
304DWORD WINAPI RtlIntegerToChar(DWORD x1,
305 DWORD x2,
306 DWORD x3,
307 DWORD x4)
308{
309 dprintf(("NTDLL: RtlIntegerToChar(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
310 x1,
311 x2,
312 x3,
313 x4));
314
315 return 0;
316}
317
318
319/******************************************************************************
320 * RtlSetEnvironmentVariable [NTDLL]
321 */
322DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,
323 PUNICODE_STRING key,
324 PUNICODE_STRING val)
325{
326 dprintf(("NTDLL: RtlSetEnvironmentVariable(%08xh,%08xh,%08xh) not implemented.\n",
327 x1,
328 key,
329 val));
330
331 return 0;
332}
333
334
335/******************************************************************************
336 * RtlNewSecurityObject [NTDLL]
337 */
338DWORD WINAPI RtlNewSecurityObject(DWORD x1,
339 DWORD x2,
340 DWORD x3,
341 DWORD x4,
342 DWORD x5,
343 DWORD x6)
344{
345 dprintf(("NTDLL: RtlNewSecurityObject(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
346 x1,
347 x2,
348 x3,
349 x4,
350 x5,
351 x6));
352
353 return 0;
354}
355
356
357/******************************************************************************
358 * RtlDeleteSecurityObject [NTDLL]
359 */
360DWORD WINAPI RtlDeleteSecurityObject(DWORD x1)
361{
362 dprintf(("NTDLL: RtlDeleteSecurityObject(%08xh) not implemented.\n",
363 x1));
364
365 return 0;
366}
367
368
369/**************************************************************************
370 * RtlNormalizeProcessParams [NTDLL.441]
371 */
372LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
373{
374 dprintf(("NTDLL: RtlNormalizeProcessParams(%08xh) not implemented.\n",
375 x));
376
377 return x;
378}
379
380
381
382/**************************************************************************
383 * RtlGetNtProductType [NTDLL.390]
384 */
385BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
386{
387 dprintf(("NTDLL: RtlGetNtProductType(%08xh) not correctly implemented.\n",
388 type));
389
390 *type=3; /* dunno. 1 for client, 3 for server? */
391 return 1;
392}
393
394
395
396/******************************************************************************
397 * RtlFormatCurrentUserKeyPath [NTDLL.371]
398 */
399NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING pustrKeyPath)
400{
401 dprintf(("NTDLL: RtlFormatCurrentUserKeyPath(%08xh) not correctly implemented.\n",
402 pustrKeyPath));
403
404 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
405 ANSI_STRING AnsiPath;
406
407 RtlInitAnsiString(&AnsiPath, Path);
408 return RtlAnsiStringToUnicodeString(pustrKeyPath, &AnsiPath, TRUE);
409}
410
411
412/******************************************************************************
413 * RtlOpenCurrentUser [NTDLL]
414 */
415ODINFUNCTION2(DWORD, RtlOpenCurrentUser,
416 ACCESS_MASK,DesiredAccess,
417 PHANDLE, pKeyHandle)
418{
419 /* Note: this is not the correct solution,
420 * But this works pretty good on wine and NT4.0 binaries
421 */
422
423 if (DesiredAccess == 0x2000000 )
424 {
425 *pKeyHandle = HKEY_CURRENT_USER;
426 return TRUE;
427 }
428
429 return FALSE;
430/* PH 2000/08/18 currently disabled
431 OBJECT_ATTRIBUTES ObjectAttributes;
432 UNICODE_STRING ObjectName;
433 NTSTATUS ret;
434
435 RtlFormatCurrentUserKeyPath(&ObjectName);
436 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
437 ret = NtOpenKey(pKeyHandle, DesiredAccess, &ObjectAttributes);
438 RtlFreeUnicodeString(&ObjectName);
439 return ret;
440 */
441}
442
443
444/**************************************************************************
445 * RtlDosPathNameToNtPathName_U [NTDLL.338]
446 *
447 * FIXME: convert to UNC or whatever is expected here
448 */
449BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR from,
450 PUNICODE_STRING us,
451 DWORD x2,
452 DWORD x3)
453{
454 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
455
456 dprintf(("NTDLL: RtlDosPathNameToNtPathName_U(%08xh,%08h,%08xh,%08xh) not implemented.\n",
457 from,
458 us,
459 x2,
460 x3));
461
462 if (us)
463 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
464
465 return TRUE;
466}
467
468
469/***********************************************************************
470 * RtlImageNtHeader (NTDLL)
471 */
472PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
473{
474 IMAGE_NT_HEADERS *ret = NULL;
475 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
476
477 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
478 {
479 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
480 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
481 }
482 return ret;
483}
484
485/******************************************************************************
486 * RtlCreateEnvironment [NTDLL]
487 */
488DWORD WINAPI RtlCreateEnvironment(DWORD x1,
489 DWORD x2)
490{
491 dprintf(("NTDLL: RtlCreateEnvironment(%08xh, %08xh) not implemented.\n",
492 x1,
493 x2));
494
495 return 0;
496}
497
498
499/******************************************************************************
500 * RtlDestroyEnvironment [NTDLL]
501 */
502DWORD WINAPI RtlDestroyEnvironment(DWORD x)
503{
504 dprintf(("NTDLL: RtlDestroyEnvironment(%08xh) not implemented.\n",
505 x));
506
507 return 0;
508}
509
510
511/******************************************************************************
512 * RtlQueryEnvironmentVariable_U [NTDLL]
513 */
514DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,
515 PUNICODE_STRING key,
516 PUNICODE_STRING val)
517{
518 dprintf(("NTDLL: RtlQueryEnvironmentVariable_U(%08xh,%08xh,%08xh) not implemented.\n",
519 x1,
520 key,
521 val));
522
523 return 0;
524}
525
526/******************************************************************************
527 * RtlInitializeGenericTable [NTDLL]
528 */
529DWORD WINAPI RtlInitializeGenericTable(void)
530{
531 FIXME("\n");
532 return 0;
533}
534
535/******************************************************************************
536 * RtlInitializeBitMap [NTDLL]
537 *
538 */
539NTSTATUS WINAPI RtlInitializeBitMap(DWORD x1,DWORD x2,DWORD x3)
540{
541 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
542 return 0;
543}
544
545/******************************************************************************
546 * RtlSetBits [NTDLL]
547 *
548 */
549NTSTATUS WINAPI RtlSetBits(DWORD x1,DWORD x2,DWORD x3)
550{
551 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
552 return 0;
553}
554
555/******************************************************************************
556 * RtlFindClearBits [NTDLL]
557 *
558 */
559NTSTATUS WINAPI RtlFindClearBits(DWORD x1,DWORD x2,DWORD x3)
560{
561 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
562 return 0;
563}
564
565/******************************************************************************
566 * RtlClearBits [NTDLL]
567 *
568 */
569NTSTATUS WINAPI RtlClearBits(DWORD x1,DWORD x2,DWORD x3)
570{
571 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3);
572 return 0;
573}
574
575/******************************************************************************
576 * RtlCopyMemory [NTDLL]
577 *
578 */
579#undef RtlCopyMemory
580VOID WINAPI RtlCopyMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
581{
582 memcpy(Destination, Source, Length);
583}
584
585/******************************************************************************
586 * RtlMoveMemory [NTDLL]
587 */
588#undef RtlMoveMemory
589VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length )
590{
591 memmove(Destination, Source, Length);
592}
593
594/******************************************************************************
595 * RtlFillMemory [NTDLL]
596 */
597#undef RtlFillMemory
598VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, UINT Fill )
599{
600 memset(Destination, Fill, Length);
601}
602
603/******************************************************************************
604 * RtlZeroMemory [NTDLL]
605 */
606#undef RtlZeroMemory
607VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length )
608{
609 memset(Destination, 0, Length);
610}
611
612/******************************************************************************
613 * RtlCompareMemory [NTDLL]
614 */
615SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length)
616{
617 int i;
618 for(i=0; (i<Length) && (((LPBYTE)Source1)[i]==((LPBYTE)Source2)[i]); i++);
619 return i;
620}
621
622/******************************************************************************
623 * RtlAssert [NTDLL]
624 *
625 * Not implemented in non-debug versions.
626 */
627void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
628{
629 FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
630}
631
632/*****************************************************************************
633 * Name : RtlCopyLuid
634 * Purpose : copy local unique identifier?
635 * Parameters: PLUID pluid1
636 * PLUID pluid2
637 * Variables :
638 * Result :
639 * Remark : NTDLL.321
640 * Status : COMPLETELY ? IMPLEMENTED TESTED ?
641 *
642 * Author : Patrick Haller [Tue, 1999/11/09 09:00]
643 *****************************************************************************/
644
645PLUID WINAPI RtlCopyLuid(PLUID pluid1,
646 PLUID pluid2)
647{
648 pluid2->LowPart = pluid1->LowPart;
649 pluid2->HighPart = pluid1->HighPart;
650 return (pluid1);
651}
Note: See TracBrowser for help on using the repository browser.