Changed some treeview related definitions.
[wine] / dlls / ntdll / rtl.c
1 /*
2  * NT basis DLL
3  * 
4  * This file contains the Rtl* API functions. These should be implementable.
5  * 
6  * Copyright 1996-1998 Marcus Meissner
7  */
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <ctype.h>
13 #include <math.h>
14 #include "win.h"
15 #include "stackframe.h"
16 #include "file.h"
17 #include "windows.h"
18 #include "winnls.h"
19 #include "ntdll.h"
20 #include "heap.h"
21 #include "debug.h"
22 #include "module.h"
23 #include "heap.h"
24 #include "debugstr.h"
25 #include "winreg.h"
26
27 /**************************************************************************
28  *                 RtlLengthRequiredSid                 [NTDLL.427]
29  */
30 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
31 {
32         return sizeof(DWORD)*nrofsubauths+sizeof(SID);
33 }
34
35 /**************************************************************************
36  *                 RtlLengthSid                         [NTDLL.429]
37  */
38 DWORD WINAPI RtlLengthSid(LPSID sid)
39 {       TRACE(ntdll,"sid=%p\n",sid);
40         if (!sid)
41           return FALSE; 
42         return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
43 }
44
45 /**************************************************************************
46  *                 RtlCreateAcl                         [NTDLL.306]
47  *
48  * NOTES
49  *    This should return NTSTATUS
50  */
51 DWORD WINAPI RtlCreateAcl(LPACL acl,DWORD size,DWORD rev)
52 {
53         if (rev!=ACL_REVISION)
54                 return STATUS_INVALID_PARAMETER;
55         if (size<sizeof(ACL))
56                 return STATUS_BUFFER_TOO_SMALL;
57         if (size>0xFFFF)
58                 return STATUS_INVALID_PARAMETER;
59
60         memset(acl,'\0',sizeof(ACL));
61         acl->AclRevision        = rev;
62         acl->AclSize            = size;
63         acl->AceCount           = 0;
64         return 0;
65 }
66
67 /**************************************************************************
68  *                 RtlFirstFreeAce                      [NTDLL.370]
69  * looks for the AceCount+1 ACE, and if it is still within the alloced
70  * ACL, return a pointer to it
71  */
72 BOOL32 WINAPI RtlFirstFreeAce(LPACL acl,LPACE_HEADER *x)
73 {
74         LPACE_HEADER    ace;
75         int             i;
76
77         *x = 0;
78         ace = (LPACE_HEADER)(acl+1);
79         for (i=0;i<acl->AceCount;i++) {
80                 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
81                         return 0;
82                 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
83         }
84         if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
85                 return 0;
86         *x = ace;
87         return 1;
88 }
89
90 /**************************************************************************
91  *                 RtlAddAce                            [NTDLL.260]
92  */
93 DWORD /* NTSTATUS */  
94 WINAPI RtlAddAce(LPACL acl,DWORD rev,DWORD xnrofaces,
95                                        LPACE_HEADER acestart,DWORD acelen)
96 {
97         LPACE_HEADER    ace,targetace;
98         int             nrofaces;
99
100         if (acl->AclRevision != ACL_REVISION)
101                 return STATUS_INVALID_PARAMETER;
102         if (!RtlFirstFreeAce(acl,&targetace))
103                 return STATUS_INVALID_PARAMETER;
104         nrofaces=0;ace=acestart;
105         while (((DWORD)ace-(DWORD)acestart)<acelen) {
106                 nrofaces++;
107                 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
108         }
109         if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
110                 return STATUS_INVALID_PARAMETER;
111         memcpy((LPBYTE)targetace,acestart,acelen);
112         acl->AceCount+=nrofaces;
113         return 0;
114 }
115
116 /**************************************************************************
117  *                 RtlCreateSecurityDescriptor          [NTDLL.313]
118  */
119 DWORD /* NTSTATUS */ 
120 WINAPI RtlCreateSecurityDescriptor(LPSECURITY_DESCRIPTOR lpsd,DWORD rev)
121 {
122         if (rev!=SECURITY_DESCRIPTOR_REVISION)
123                 return STATUS_UNKNOWN_REVISION;
124         memset(lpsd,'\0',sizeof(*lpsd));
125         lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
126         return 0;
127 }
128
129 /**************************************************************************
130  *                 RtlSetDaclSecurityDescriptor         [NTDLL.483]
131  */
132 DWORD /* NTSTATUS */ 
133 WINAPI RtlSetDaclSecurityDescriptor ( LPSECURITY_DESCRIPTOR lpsd,BOOL32 daclpresent,LPACL dacl,BOOL32 dacldefaulted )
134 {
135         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
136                 return STATUS_UNKNOWN_REVISION;
137         if (lpsd->Control & SE_SELF_RELATIVE)
138                 return STATUS_INVALID_SECURITY_DESCR;
139         if (!daclpresent) {
140                 lpsd->Control &= ~SE_DACL_PRESENT;
141                 return 0;
142         }
143         lpsd->Control |= SE_DACL_PRESENT;
144         lpsd->Dacl = dacl;
145         if (dacldefaulted)
146                 lpsd->Control |= SE_DACL_DEFAULTED;
147         else
148                 lpsd->Control &= ~SE_DACL_DEFAULTED;
149         return 0;
150 }
151
152 /**************************************************************************
153  *                 RtlSetSaclSecurityDescriptor         [NTDLL.488]
154  */
155 DWORD /* NTSTATUS */ 
156 WINAPI RtlSetSaclSecurityDescriptor (
157 LPSECURITY_DESCRIPTOR lpsd,BOOL32 saclpresent,LPACL sacl,BOOL32 sacldefaulted
158 )
159 {
160         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
161                 return STATUS_UNKNOWN_REVISION;
162         if (lpsd->Control & SE_SELF_RELATIVE)
163                 return STATUS_INVALID_SECURITY_DESCR;
164         if (!saclpresent) {
165                 lpsd->Control &= ~SE_SACL_PRESENT;
166                 return 0;
167         }
168         lpsd->Control |= SE_SACL_PRESENT;
169         lpsd->Sacl = sacl;
170         if (sacldefaulted)
171                 lpsd->Control |= SE_SACL_DEFAULTED;
172         else
173                 lpsd->Control &= ~SE_SACL_DEFAULTED;
174         return 0;
175 }
176
177 /**************************************************************************
178  *                 RtlSetOwnerSecurityDescriptor                [NTDLL.487]
179  */
180 DWORD /* NTSTATUS */ 
181 WINAPI RtlSetOwnerSecurityDescriptor (LPSECURITY_DESCRIPTOR lpsd,LPSID owner,BOOL32 ownerdefaulted)
182 {
183         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
184                 return STATUS_UNKNOWN_REVISION;
185         if (lpsd->Control & SE_SELF_RELATIVE)
186                 return STATUS_INVALID_SECURITY_DESCR;
187
188         lpsd->Owner = owner;
189         if (ownerdefaulted)
190                 lpsd->Control |= SE_OWNER_DEFAULTED;
191         else
192                 lpsd->Control &= ~SE_OWNER_DEFAULTED;
193         return 0;
194 }
195
196 /**************************************************************************
197  *                 RtlSetGroupSecurityDescriptor                [NTDLL.485]
198  */
199 DWORD /* NTSTATUS */ 
200 WINAPI RtlSetGroupSecurityDescriptor (LPSECURITY_DESCRIPTOR lpsd,LPSID group,BOOL32 groupdefaulted)
201 {
202         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
203                 return STATUS_UNKNOWN_REVISION;
204         if (lpsd->Control & SE_SELF_RELATIVE)
205                 return STATUS_INVALID_SECURITY_DESCR;
206
207         lpsd->Group = group;
208         if (groupdefaulted)
209                 lpsd->Control |= SE_GROUP_DEFAULTED;
210         else
211                 lpsd->Control &= ~SE_GROUP_DEFAULTED;
212         return 0;
213 }
214
215
216 /**************************************************************************
217  *                 RtlNormalizeProcessParams            [NTDLL.441]
218  */
219 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
220 {
221     FIXME(ntdll,"(%p), stub\n",x);
222     return x;
223 }
224
225 /**************************************************************************
226  *                 RtlInitializeSid                     [NTDLL.410]
227  */
228 DWORD WINAPI RtlInitializeSid(LPSID lpsid,LPSID_IDENTIFIER_AUTHORITY lpsidauth,
229                               DWORD c)
230 {
231         BYTE    a = c&0xff;
232
233         if (a>=SID_MAX_SUB_AUTHORITIES)
234                 return a;
235         lpsid->SubAuthorityCount = a;
236         lpsid->Revision          = SID_REVISION;
237         memcpy(&(lpsid->IdentifierAuthority),lpsidauth,sizeof(SID_IDENTIFIER_AUTHORITY));
238         return 0;
239 }
240
241 /**************************************************************************
242  *                 RtlSubAuthoritySid                   [NTDLL.497]
243  */
244 LPDWORD WINAPI RtlSubAuthoritySid(LPSID lpsid,DWORD nr)
245 {
246         return &(lpsid->SubAuthority[nr]);
247 }
248
249 /**************************************************************************
250  *                 RtlSubAuthorityCountSid              [NTDLL.496]
251  */
252 LPBYTE WINAPI RtlSubAuthorityCountSid(LPSID lpsid)
253 {
254         return ((LPBYTE)lpsid)+1;
255 }
256
257 /**************************************************************************
258  *                 RtlCopySid                           [NTDLL.302]
259  */
260 DWORD WINAPI RtlCopySid(DWORD len,LPSID to,LPSID from)
261 {       if (!from)
262                 return 0;
263         if (len<(from->SubAuthorityCount*4+8))
264                 return STATUS_BUFFER_TOO_SMALL;
265         memmove(to,from,from->SubAuthorityCount*4+8);
266         return STATUS_SUCCESS;
267 }
268
269 /**************************************************************************
270  *                 RtlAnsiStringToUnicodeString         [NTDLL.269]
271  */
272 DWORD /* NTSTATUS */ 
273 WINAPI RtlAnsiStringToUnicodeString(LPUNICODE_STRING uni,LPANSI_STRING ansi,BOOL32 doalloc)
274 {
275         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
276
277         if (unilen>0xFFFF)
278                 return STATUS_INVALID_PARAMETER_2;
279         uni->Length = unilen;
280         if (doalloc) {
281                 uni->MaximumLength = unilen;
282                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
283                 if (!uni->Buffer)
284                         return STATUS_NO_MEMORY;
285         }
286         if (unilen>uni->MaximumLength)
287                 return STATUS_BUFFER_OVERFLOW;
288         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
289         return STATUS_SUCCESS;
290 }
291
292 /**************************************************************************
293  *                 RtlOemStringToUnicodeString          [NTDLL.447]
294  */
295 DWORD /* NTSTATUS */ 
296 WINAPI RtlOemStringToUnicodeString(LPUNICODE_STRING uni,LPSTRING ansi,BOOL32 doalloc)
297 {
298         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
299
300         if (unilen>0xFFFF)
301                 return STATUS_INVALID_PARAMETER_2;
302         uni->Length = unilen;
303         if (doalloc) {
304                 uni->MaximumLength = unilen;
305                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
306                 if (!uni->Buffer)
307                         return STATUS_NO_MEMORY;
308         }
309         if (unilen>uni->MaximumLength)
310                 return STATUS_BUFFER_OVERFLOW;
311         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
312         return STATUS_SUCCESS;
313 }
314 /**************************************************************************
315  *                 RtlMultiByteToUnicodeN               [NTDLL.436]
316  * FIXME: multibyte support
317  */
318 DWORD /* NTSTATUS */ 
319 WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
320 {
321         DWORD   len;
322         LPWSTR  x;
323
324         len = oemlen;
325         if (unilen/2 < len)
326                 len = unilen/2;
327         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
328         lstrcpynAtoW(x,oemstr,len+1);
329         memcpy(unistr,x,len*2);
330         if (reslen) *reslen = len*2;
331         return 0;
332 }
333
334 /**************************************************************************
335  *                 RtlOemToUnicodeN                     [NTDLL.448]
336  */
337 DWORD /* NTSTATUS */ 
338 WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
339 {
340         DWORD   len;
341         LPWSTR  x;
342
343         len = oemlen;
344         if (unilen/2 < len)
345                 len = unilen/2;
346         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
347         lstrcpynAtoW(x,oemstr,len+1);
348         memcpy(unistr,x,len*2);
349         if (reslen) *reslen = len*2;
350         return 0;
351 }
352
353 /**************************************************************************
354  *                 RtlInitAnsiString                    [NTDLL.399]
355  */
356 VOID WINAPI RtlInitAnsiString(LPANSI_STRING target,LPCSTR source)
357 {
358         target->Length = target->MaximumLength = 0;
359         target->Buffer = (LPSTR)source;
360         if (!source)
361                 return;
362         target->Length = lstrlen32A(target->Buffer);
363         target->MaximumLength = target->Length+1;
364 }
365 /**************************************************************************
366  *                 RtlInitString                        [NTDLL.402]
367  */
368 VOID WINAPI RtlInitString(LPSTRING target,LPCSTR source)
369 {
370         target->Length = target->MaximumLength = 0;
371         target->Buffer = (LPSTR)source;
372         if (!source)
373                 return;
374         target->Length = lstrlen32A(target->Buffer);
375         target->MaximumLength = target->Length+1;
376 }
377
378 /**************************************************************************
379  *                 RtlInitUnicodeString                 [NTDLL.403]
380  */
381 VOID WINAPI RtlInitUnicodeString(LPUNICODE_STRING target,LPCWSTR source)
382 {
383         target->Length = target->MaximumLength = 0;
384         target->Buffer = (LPWSTR)source;
385         if (!source)
386                 return;
387         target->Length = lstrlen32W(target->Buffer)*2;
388         target->MaximumLength = target->Length+2;
389 }
390
391 /**************************************************************************
392  *                 RtlFreeUnicodeString                 [NTDLL.377]
393  */
394 VOID WINAPI RtlFreeUnicodeString(LPUNICODE_STRING str)
395 {
396         if (str->Buffer)
397                 HeapFree(GetProcessHeap(),0,str->Buffer);
398 }
399
400 /**************************************************************************
401  * RtlFreeAnsiString [NTDLL.373]
402  */
403 VOID WINAPI RtlFreeAnsiString(LPANSI_STRING AnsiString)
404 {
405     if( AnsiString->Buffer )
406         HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
407 }
408
409
410 /**************************************************************************
411  *                 RtlUnicodeToOemN                     [NTDLL.515]
412  */
413 DWORD /* NTSTATUS */ 
414 WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
415 {
416         DWORD   len;
417         LPSTR   x;
418
419         len = oemlen;
420         if (unilen/2 < len)
421                 len = unilen/2;
422         x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
423         lstrcpynWtoA(x,unistr,len+1);
424         memcpy(oemstr,x,len);
425         if (reslen) *reslen = len;
426         return 0;
427 }
428
429 /**************************************************************************
430  *                 RtlUnicodeStringToOemString          [NTDLL.511]
431  */
432 DWORD /* NTSTATUS */ 
433 WINAPI RtlUnicodeStringToOemString(LPANSI_STRING oem,LPUNICODE_STRING uni,BOOL32 alloc)
434 {
435         if (alloc) {
436                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
437                 oem->MaximumLength = uni->Length/2+1;
438         }
439         oem->Length = uni->Length/2;
440         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
441         return 0;
442 }
443
444 /**************************************************************************
445  *                 RtlUnicodeStringToAnsiString         [NTDLL.507]
446  */
447 DWORD /* NTSTATUS */ 
448 WINAPI RtlUnicodeStringToAnsiString(LPANSI_STRING oem,LPUNICODE_STRING uni,BOOL32 alloc)
449 {
450         if (alloc) {
451                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
452                 oem->MaximumLength = uni->Length/2+1;
453         }
454         oem->Length = uni->Length/2;
455         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
456         return 0;
457 }
458
459 /**************************************************************************
460  *                 RtlEqualUnicodeString                [NTDLL]
461  */
462 DWORD WINAPI RtlEqualUnicodeString(LPUNICODE_STRING s1,LPUNICODE_STRING s2,DWORD x) {
463         FIXME(ntdll,"(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x);
464         return 0;
465         if (s1->Length != s2->Length)
466                 return 1;
467         return !lstrncmp32W(s1->Buffer,s2->Buffer,s1->Length/2);
468 }
469
470 /**************************************************************************
471  *                 RtlNtStatusToDosErro                 [NTDLL.442]
472  */
473 DWORD WINAPI RtlNtStatusToDosError(DWORD error)
474 {
475     FIXME(ntdll, "(%lx): map STATUS_ to ERROR_\n",error);
476     return error;
477 }
478
479 /**************************************************************************
480  *                 RtlGetNtProductType                  [NTDLL.390]
481  */
482 BOOL32 WINAPI RtlGetNtProductType(LPDWORD type)
483 {
484     FIXME(ntdll, "(%p): stub\n", type);
485     *type=3; /* dunno. 1 for client, 3 for server? */
486     return 1;
487 }
488
489 /**************************************************************************
490  *                 RtlUpcaseUnicodeString               [NTDLL.520]
491  */
492 DWORD WINAPI RtlUpcaseUnicodeString(LPUNICODE_STRING dest,LPUNICODE_STRING src,BOOL32 doalloc)
493 {
494         LPWSTR  s,t;
495         DWORD   i,len;
496
497         len = src->Length;
498         if (doalloc) {
499                 dest->MaximumLength = len; 
500                 dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
501                 if (!dest->Buffer)
502                         return STATUS_NO_MEMORY;
503
504         }
505         if (dest->MaximumLength < len)
506                 return STATUS_BUFFER_OVERFLOW;
507         s=dest->Buffer;t=src->Buffer;
508         /* len is in bytes */
509         for (i=0;i<len/2;i++)
510                 s[i] = towupper(t[i]);
511         return STATUS_SUCCESS;
512 }
513
514 /**************************************************************************
515  *                 RtlxOemStringToUnicodeSize           [NTDLL.549]
516  */
517 UINT32 WINAPI RtlxOemStringToUnicodeSize(LPSTRING str)
518 {
519         return str->Length*2+2;
520 }
521
522 /**************************************************************************
523  *                 RtlxAnsiStringToUnicodeSize          [NTDLL.548]
524  */
525 UINT32 WINAPI RtlxAnsiStringToUnicodeSize(LPANSI_STRING str)
526 {
527         return str->Length*2+2;
528 }
529
530 /**************************************************************************
531  *                 RtlIsTextUnicode                     [NTDLL.417]
532  *
533  *      Apply various feeble heuristics to guess whether
534  *      the text buffer contains Unicode.
535  *      FIXME: should implement more tests.
536  */
537 DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
538 {
539         LPWSTR s = buf;
540         DWORD flags = -1, out_flags = 0;
541
542         if (!len)
543                 goto out;
544         if (pf)
545                 flags = *pf;
546         /*
547          * Apply various tests to the text string. According to the
548          * docs, each test "passed" sets the corresponding flag in
549          * the output flags. But some of the tests are mutually
550          * exclusive, so I don't see how you could pass all tests ...
551          */
552
553         /* Check for an odd length ... pass if even. */
554         if (!(len & 1))
555                 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
556
557         /* Check for the special unicode marker byte. */
558         if (*s == 0xFEFF)
559                 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
560
561         /*
562          * Check whether the string passed all of the tests.
563          */
564         flags &= ITU_IMPLEMENTED_TESTS;
565         if ((out_flags & flags) != flags)
566                 len = 0;
567 out:
568         if (pf)
569                 *pf = out_flags;
570         return len;
571 }
572
573 /**************************************************************************
574  *                 RtlDosPathNameToNtPathName_U         [NTDLL.338]
575  *
576  * FIXME: convert to UNC or whatever is expected here
577  */
578 BOOL32  WINAPI RtlDosPathNameToNtPathName_U(
579         LPWSTR from,LPUNICODE_STRING us,DWORD x2,DWORD x3)
580 {
581         LPSTR   fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
582
583         FIXME(ntdll,"(%s,%p,%08lx,%08lx)\n",fromA,us,x2,x3);
584         if (us)
585                 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
586         return TRUE;
587 }
588
589 /**************************************************************************
590  *                 NTDLL_chkstk                         [NTDLL.862]
591  *                 NTDLL_alloca_probe                           [NTDLL.861]
592  * Glorified "enter xxxx".
593  */
594 REGS_ENTRYPOINT(NTDLL_chkstk)
595 {
596     ESP_reg(context) -= EAX_reg(context);
597 }
598 REGS_ENTRYPOINT(NTDLL_alloca_probe)
599 {
600     ESP_reg(context) -= EAX_reg(context);
601 }
602
603 /******************************************************************************
604  * RtlTimeToElapsedTimeFields [NTDLL.502]
605  */
606 DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1, DWORD x2 )
607 {
608     FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
609     return 0;
610 }
611
612
613 /******************************************************************************
614  * RtlExtendedLargeIntegerDivide [NTDLL.359]
615  */
616 INT32 WINAPI RtlExtendedLargeIntegerDivide(
617         LARGE_INTEGER dividend,
618         DWORD divisor,
619         LPDWORD rest
620 ) {
621 #if SIZEOF_LONG_LONG==8
622         long long x1 = *(long long*)&dividend;
623
624         if (*rest)
625                 *rest = x1 % divisor;
626         return x1/divisor;
627 #else
628         FIXME(ntdll,"((%d<<32)+%d,%d,%p), implement this using normal integer arithmetic!\n",dividend.HighPart,dividend.LowPart,divisor,rest);
629         return 0;
630 #endif
631 }
632
633 /******************************************************************************
634  * RtlExtendedLargeIntegerMultiply [NTDLL.359]
635  * Note: This even works, since gcc returns 64bit values in eax/edx just like
636  * the caller expects. However... The relay code won't grok this I think.
637  */
638 long long /*LARGE_INTEGER*/ 
639 WINAPI RtlExtendedIntegerMultiply(
640         LARGE_INTEGER factor1,INT32 factor2
641 ) {
642 #if SIZEOF_LONG_LONG==8
643         return (*(long long*)&factor1)*factor2;
644 #else
645         FIXME(ntdll,"((%d<<32)+%d,%ld), implement this using normal integer arithmetic!\n",factor1.HighPart,factor1.LowPart,factor2);
646         return 0;
647 #endif
648 }
649
650 /******************************************************************************
651  *  RtlFormatCurrentUserKeyPath         [NTDLL.371] 
652  */
653 DWORD WINAPI RtlFormatCurrentUserKeyPath(DWORD x)
654 {
655     FIXME(ntdll,"(0x%08lx): stub\n",x);
656     return 1;
657 }
658
659 /******************************************************************************
660  *  RtlOpenCurrentUser          [NTDLL] 
661  */
662 DWORD WINAPI RtlOpenCurrentUser(DWORD x1, DWORD *x2)
663 {
664 /* Note: this is not the correct solution, 
665  * But this works pretty good on wine and NT4.0 binaries
666  */
667         if  ( x1 == 0x2000000 )  {
668                 *x2 = HKEY_CURRENT_USER; 
669                 return TRUE;
670         }
671                 
672         return FALSE;
673 }
674 /******************************************************************************
675  *  RtlAllocateAndInitializeSid         [NTDLL.265] 
676  *
677  */
678 BOOL32 WINAPI RtlAllocateAndInitializeSid (LPSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,DWORD nSubAuthorityCount,
679                 DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9,DWORD x10, LPSID pSid) 
680 {       FIXME(ntdll,"(%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p),stub!\n",
681                 pIdentifierAuthority,nSubAuthorityCount,x3,x4,x5,x6,x7,x8,x9,x10,pSid);
682         return 0;
683 }
684 /******************************************************************************
685  *  RtlEqualSid         [NTDLL.352] 
686  *
687  */
688 DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2) {   
689         FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n", x1,x2);
690         return TRUE;
691 }
692
693 /******************************************************************************
694  *  RtlFreeSid          [NTDLL.376] 
695  */
696 DWORD WINAPI RtlFreeSid(DWORD x1) 
697 {       FIXME(ntdll,"(0x%08lx),stub!\n", x1);
698         return TRUE;
699 }
700
701 /******************************************************************************
702  *  RtlGetDaclSecurityDescriptor                [NTDLL] 
703  */
704 DWORD WINAPI RtlGetDaclSecurityDescriptor(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
705         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
706         return 0;
707 }
708
709 /******************************************************************************
710  *  RtlCreateEnvironment                [NTDLL] 
711  */
712 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
713         FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
714         return 0;
715 }
716
717
718 /******************************************************************************
719  *  RtlDestroyEnvironment               [NTDLL] 
720  */
721 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
722         FIXME(ntdll,"(0x%08lx),stub!\n",x);
723         return 0;
724 }
725
726 /******************************************************************************
727  *  RtlQueryEnvironmentVariable_U               [NTDLL] 
728  */
729 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,LPUNICODE_STRING key,LPUNICODE_STRING val) {
730         FIXME(ntdll,"(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
731         return 0;
732 }
733
734 /******************************************************************************
735  *  RtlSetEnvironmentVariable           [NTDLL] 
736  */
737 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,LPUNICODE_STRING key,LPUNICODE_STRING val) {
738         FIXME(ntdll,"(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
739         return 0;
740 }
741
742 /******************************************************************************
743  *  RtlNewSecurityObject                [NTDLL] 
744  */
745 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
746         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
747         return 0;
748 }
749
750 /******************************************************************************
751  *  RtlDeleteSecurityObject             [NTDLL] 
752  */
753 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
754         FIXME(ntdll,"(0x%08lx),stub!\n",x1);
755         return 0;
756 }
757
758 /******************************************************************************
759  *  RtlToTimeInSecondsSince1980         [NTDLL] 
760  */
761 BOOL32 WINAPI RtlTimeToSecondsSince1980(LPFILETIME ft,LPDWORD timeret) {
762         /* 1980 = 1970+10*365 days +  29. februar 1972 + 29.februar 1976 */
763         *timeret = DOSFS_FileTimeToUnixTime(ft,NULL) - (10*365+2)*24*3600;
764         return 1;
765 }
766
767 /******************************************************************************
768  *  RtlToTimeInSecondsSince1970         [NTDLL] 
769  */
770 BOOL32 WINAPI RtlTimeToSecondsSince1970(LPFILETIME ft,LPDWORD timeret) {
771         *timeret = DOSFS_FileTimeToUnixTime(ft,NULL);
772         return 1;
773 }
774
775 /******************************************************************************
776  *  RtlAcquirePebLock           [NTDLL] 
777  */
778 VOID WINAPI RtlAcquirePebLock(void) {
779         FIXME(ntdll,"()\n");
780         /* enter critical section ? */
781 }
782
783 /******************************************************************************
784  *  RtlReleasePebLock           [NTDLL] 
785  */
786 VOID WINAPI RtlReleasePebLock(void) {
787         FIXME(ntdll,"()\n");
788         /* leave critical section ? */
789 }
790
791 /******************************************************************************
792  *  RtlAddAccessAllowedAce              [NTDLL] 
793  */
794 DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
795         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
796         return 0;
797 }
798
799 /******************************************************************************
800  *  RtlGetAce           [NTDLL] 
801  */
802 DWORD WINAPI RtlGetAce(LPACL pAcl,DWORD dwAceIndex,LPVOID *pAce ) {
803         FIXME(ntdll,"(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
804         return 0;
805 }
806
807 /******************************************************************************
808  *  RtlAdjustPrivilege          [NTDLL] 
809  */
810 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
811         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
812         return 0;
813 }
814
815 /******************************************************************************
816  *  RtlIntegerToChar    [NTDLL] 
817  */
818 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
819         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
820         return 0;
821 }
822 /******************************************************************************
823  *  RtlSystemTimeToLocalTime    [NTDLL] 
824  */
825 DWORD WINAPI RtlSystemTimeToLocalTime(DWORD x1,DWORD x2) {
826         FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
827         return 0;
828 }
829 /******************************************************************************
830  *  RtlTimeToTimeFields         [NTDLL] 
831  */
832 DWORD WINAPI RtlTimeToTimeFields(DWORD x1,DWORD x2) {
833         FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
834         return 0;
835 }
836 /******************************************************************************
837  *  RtlInitializeResource       [NTDLL] 
838  */
839 NTSTATUS WINAPI RtlInitializeResource(DWORD x1) {
840         FIXME(ntdll,"(0x%08lx),stub!\n",x1);
841         return 0;
842 }
843 /******************************************************************************
844  *      RtlCompareUnicodeString [NTDLL] 
845  */
846 NTSTATUS WINAPI RtlCompareUnicodeString(LPUNICODE_STRING x1,LPUNICODE_STRING x2,DWORD x3) {
847         FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",debugstr_w(x1->Buffer),debugstr_w(x2->Buffer),x3);
848         return 0;
849 }
850
851 /******************************************************************************
852  *      DbgPrint        [NTDLL] 
853  */
854 void __cdecl DbgPrint(LPCSTR fmt,LPVOID args) {
855         char buf[512];
856
857         wvsprintf32A(buf,fmt,&args);
858         MSG("DbgPrint says: %s",buf);
859         /* hmm, raise exception? */
860 }