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