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