Moved the module loading/unloading code and the remaining needed
[wine] / dlls / ntdll / nt.c
1 /*
2  * NT basis DLL
3  *
4  * This file contains the Nt* API functions of NTDLL.DLL.
5  * In the original ntdll.dll they all seem to just call int 0x2e (down to the NTOSKRNL)
6  *
7  * Copyright 1996-1998 Marcus Meissner
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 #include "wine/debug.h"
29
30 #include "winternl.h"
31 #include "ntdll_misc.h"
32 #include "wine/server.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
35
36 /* Structures used by NtConnectPort */
37
38 typedef struct LpcSectionInfo
39 {
40   DWORD Length;
41   HANDLE SectionHandle;
42   DWORD Param1;
43   DWORD SectionSize;
44   DWORD ClientBaseAddress;
45   DWORD ServerBaseAddress;
46 } LPCSECTIONINFO, *PLPCSECTIONINFO;
47
48 typedef struct LpcSectionMapInfo
49 {
50   DWORD Length;
51   DWORD SectionSize;
52   DWORD ServerBaseAddress;
53 } LPCSECTIONMAPINFO, *PLPCSECTIONMAPINFO;
54
55 /* Structure used by NtAcceptConnectPort, NtReplyWaitReceivePort */
56
57 #define MAX_MESSAGE_DATA 328
58
59 typedef struct LpcMessage
60 {
61   WORD ActualMessageLength;
62   WORD TotalMessageLength;
63   DWORD MessageType;
64   DWORD ClientProcessId;
65   DWORD ClientThreadId;
66   DWORD MessageId;
67   DWORD SharedSectionSize;
68   BYTE MessageData[MAX_MESSAGE_DATA];
69 } LPCMESSAGE, *PLPCMESSAGE;
70
71 /*
72  *      Timer object
73  */
74
75 /**************************************************************************
76  *              NtCreateTimer                           [NTDLL.@]
77  *              ZwCreateTimer                           [NTDLL.@]
78  */
79 NTSTATUS WINAPI NtCreateTimer(
80         OUT PHANDLE TimerHandle,
81         IN ACCESS_MASK DesiredAccess,
82         IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
83         IN TIMER_TYPE TimerType)
84 {
85         FIXME("(%p,0x%08lx,%p,0x%08x) stub\n",
86         TimerHandle,DesiredAccess,ObjectAttributes, TimerType);
87         dump_ObjectAttributes(ObjectAttributes);
88         return 0;
89 }
90 /**************************************************************************
91  *              NtSetTimer                              [NTDLL.@]
92  *              ZwSetTimer                              [NTDLL.@]
93  */
94 NTSTATUS WINAPI NtSetTimer(
95         IN HANDLE TimerHandle,
96         IN PLARGE_INTEGER DueTime,
97         IN PTIMERAPCROUTINE TimerApcRoutine,
98         IN PVOID TimerContext,
99         IN BOOLEAN WakeTimer,
100         IN ULONG Period OPTIONAL,
101         OUT PBOOLEAN PreviousState OPTIONAL)
102 {
103         FIXME("(%p,%p,%p,%p,%08x,0x%08lx,%p) stub\n",
104         TimerHandle,DueTime,TimerApcRoutine,TimerContext,WakeTimer,Period,PreviousState);
105         return 0;
106 }
107
108 /******************************************************************************
109  * NtQueryTimerResolution [NTDLL.@]
110  */
111 NTSTATUS WINAPI NtQueryTimerResolution(DWORD x1,DWORD x2,DWORD x3)
112 {
113         FIXME("(0x%08lx,0x%08lx,0x%08lx), stub!\n",x1,x2,x3);
114         return 1;
115 }
116
117 /*
118  *      Process object
119  */
120
121 /******************************************************************************
122  *  NtTerminateProcess                  [NTDLL.@]
123  *
124  *  Native applications must kill themselves when done
125  */
126 NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
127 {
128     NTSTATUS ret;
129     BOOL self;
130     SERVER_START_REQ( terminate_process )
131     {
132         req->handle    = handle;
133         req->exit_code = exit_code;
134         ret = wine_server_call( req );
135         self = !ret && reply->self;
136     }
137     SERVER_END_REQ;
138     if (self) exit( exit_code );
139     return ret;
140 }
141
142 /******************************************************************************
143 *  NtQueryInformationProcess            [NTDLL.@]
144 *  ZwQueryInformationProcess            [NTDLL.@]
145 *
146 */
147 NTSTATUS WINAPI NtQueryInformationProcess(
148         IN HANDLE ProcessHandle,
149         IN PROCESSINFOCLASS ProcessInformationClass,
150         OUT PVOID ProcessInformation,
151         IN ULONG ProcessInformationLength,
152         OUT PULONG ReturnLength)
153 {
154         NTSTATUS ret = STATUS_SUCCESS;
155         ULONG len = 0;
156
157         switch (ProcessInformationClass) {
158         case ProcessDebugPort:
159                 /* "These are not the debuggers you are looking for." */
160                 /* set it to 0 aka "no debugger" to satisfy copy protections */
161                 if (ProcessInformationLength == 4)
162                 {
163                         memset(ProcessInformation,0,ProcessInformationLength);
164                         len = 4;
165                 }
166                 else
167                         ret = STATUS_INFO_LENGTH_MISMATCH;
168                 break;
169         default:
170                 FIXME("(%p,0x%08x,%p,0x%08lx,%p),stub!\n",
171                         ProcessHandle,ProcessInformationClass,
172                         ProcessInformation,ProcessInformationLength,
173                         ReturnLength
174                 );
175                 break;
176         }
177
178         if (ReturnLength)
179                 *ReturnLength = len;
180
181         return ret;
182 }
183
184 /******************************************************************************
185  * NtSetInformationProcess [NTDLL.@]
186  * ZwSetInformationProcess [NTDLL.@]
187  */
188 NTSTATUS WINAPI NtSetInformationProcess(
189         IN HANDLE ProcessHandle,
190         IN PROCESSINFOCLASS ProcessInformationClass,
191         IN PVOID ProcessInformation,
192         IN ULONG ProcessInformationLength)
193 {
194         FIXME("(%p,0x%08x,%p,0x%08lx) stub\n",
195         ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength);
196         return 0;
197 }
198
199 /*
200  *      Thread
201  */
202
203 /******************************************************************************
204  *  NtResumeThread      [NTDLL.@]
205  *  ZwResumeThread      [NTDLL.@]
206  */
207 NTSTATUS WINAPI NtResumeThread(
208         IN HANDLE ThreadHandle,
209         IN PULONG SuspendCount)
210 {
211         FIXME("(%p,%p),stub!\n",
212         ThreadHandle,SuspendCount);
213         return 0;
214 }
215
216
217 /******************************************************************************
218  *  NtTerminateThread   [NTDLL.@]
219  *  ZwTerminateThread   [NTDLL.@]
220  */
221 NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
222 {
223     NTSTATUS ret;
224     BOOL self, last;
225
226     SERVER_START_REQ( terminate_thread )
227     {
228         req->handle    = handle;
229         req->exit_code = exit_code;
230         ret = wine_server_call( req );
231         self = !ret && reply->self;
232         last = reply->last;
233     }
234     SERVER_END_REQ;
235
236     if (self)
237     {
238         if (last) exit( exit_code );
239         else SYSDEPS_ExitThread( exit_code );
240     }
241     return ret;
242 }
243
244
245 /******************************************************************************
246 *  NtQueryInformationThread             [NTDLL.@]
247 *  ZwQueryInformationThread             [NTDLL.@]
248 *
249 */
250 NTSTATUS WINAPI NtQueryInformationThread(
251         IN HANDLE ThreadHandle,
252         IN THREADINFOCLASS ThreadInformationClass,
253         OUT PVOID ThreadInformation,
254         IN ULONG ThreadInformationLength,
255         OUT PULONG ReturnLength)
256 {
257         FIXME("(%p,0x%08x,%p,0x%08lx,%p),stub!\n",
258                 ThreadHandle, ThreadInformationClass, ThreadInformation,
259                 ThreadInformationLength, ReturnLength);
260         return 0;
261 }
262
263 /******************************************************************************
264  *  NtSetInformationThread              [NTDLL.@]
265  *  ZwSetInformationThread              [NTDLL.@]
266  */
267 NTSTATUS WINAPI NtSetInformationThread(
268         HANDLE ThreadHandle,
269         THREADINFOCLASS ThreadInformationClass,
270         PVOID ThreadInformation,
271         ULONG ThreadInformationLength)
272 {
273         FIXME("(%p,0x%08x,%p,0x%08lx),stub!\n",
274         ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
275         return 0;
276 }
277
278 /*
279  *      Token
280  */
281
282 /******************************************************************************
283  *  NtDuplicateToken            [NTDLL.@]
284  *  ZwDuplicateToken            [NTDLL.@]
285  */
286 NTSTATUS WINAPI NtDuplicateToken(
287         IN HANDLE ExistingToken,
288         IN ACCESS_MASK DesiredAccess,
289         IN POBJECT_ATTRIBUTES ObjectAttributes,
290         IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
291         IN TOKEN_TYPE TokenType,
292         OUT PHANDLE NewToken)
293 {
294         FIXME("(%p,0x%08lx,%p,0x%08x,0x%08x,%p),stub!\n",
295         ExistingToken, DesiredAccess, ObjectAttributes,
296         ImpersonationLevel, TokenType, NewToken);
297         dump_ObjectAttributes(ObjectAttributes);
298         return 0;
299 }
300
301 /******************************************************************************
302  *  NtOpenProcessToken          [NTDLL.@]
303  *  ZwOpenProcessToken          [NTDLL.@]
304  */
305 NTSTATUS WINAPI NtOpenProcessToken(
306         HANDLE ProcessHandle,
307         DWORD DesiredAccess,
308         HANDLE *TokenHandle)
309 {
310         FIXME("(%p,0x%08lx,%p): stub\n",
311         ProcessHandle,DesiredAccess, TokenHandle);
312         *TokenHandle = (HANDLE)0xcafe;
313         return 0;
314 }
315
316 /******************************************************************************
317  *  NtOpenThreadToken           [NTDLL.@]
318  *  ZwOpenThreadToken           [NTDLL.@]
319  */
320 NTSTATUS WINAPI NtOpenThreadToken(
321         HANDLE ThreadHandle,
322         DWORD DesiredAccess,
323         BOOLEAN OpenAsSelf,
324         HANDLE *TokenHandle)
325 {
326         FIXME("(%p,0x%08lx,0x%08x,%p): stub\n",
327         ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
328         *TokenHandle = (HANDLE)0xcafe;
329         return 0;
330 }
331
332 /******************************************************************************
333  *  NtAdjustPrivilegesToken             [NTDLL.@]
334  *  ZwAdjustGroupsToken         [NTDLL.@]
335  *
336  * FIXME: parameters unsafe
337  */
338 NTSTATUS WINAPI NtAdjustPrivilegesToken(
339         IN HANDLE TokenHandle,
340         IN BOOLEAN DisableAllPrivileges,
341         IN PTOKEN_PRIVILEGES NewState,
342         IN DWORD BufferLength,
343         OUT PTOKEN_PRIVILEGES PreviousState,
344         OUT PDWORD ReturnLength)
345 {
346         FIXME("(%p,0x%08x,%p,0x%08lx,%p,%p),stub!\n",
347         TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
348         return 0;
349 }
350
351 /******************************************************************************
352 *  NtQueryInformationToken              [NTDLL.@]
353 *  ZwQueryInformationToken              [NTDLL.@]
354 *
355 * NOTES
356 *  Buffer for TokenUser:
357 *   0x00 TOKEN_USER the PSID field points to the SID
358 *   0x08 SID
359 *
360 */
361 NTSTATUS WINAPI NtQueryInformationToken(
362         HANDLE token,
363         DWORD tokeninfoclass,
364         LPVOID tokeninfo,
365         DWORD tokeninfolength,
366         LPDWORD retlen )
367 {
368     unsigned int len = 0;
369
370     FIXME("(%p,%ld,%p,%ld,%p): stub\n",
371           token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
372
373     switch (tokeninfoclass)
374     {
375     case TokenUser:
376         len = sizeof(TOKEN_USER) + sizeof(SID);
377         break;
378     case TokenGroups:
379         len = sizeof(TOKEN_GROUPS);
380         break;
381     case TokenPrivileges:
382         len = sizeof(TOKEN_PRIVILEGES);
383         break;
384     case TokenOwner:
385         len = sizeof(TOKEN_OWNER);
386         break;
387     case TokenPrimaryGroup:
388         len = sizeof(TOKEN_PRIMARY_GROUP);
389         break;
390     case TokenDefaultDacl:
391         len = sizeof(TOKEN_DEFAULT_DACL);
392         break;
393     case TokenSource:
394         len = sizeof(TOKEN_SOURCE);
395         break;
396     case TokenType:
397         len = sizeof (TOKEN_TYPE);
398         break;
399 #if 0
400     case TokenImpersonationLevel:
401     case TokenStatistics:
402 #endif /* 0 */
403     }
404
405     /* FIXME: what if retlen == NULL ? */
406     *retlen = len;
407
408     if (tokeninfolength < len)
409         return STATUS_BUFFER_TOO_SMALL;
410
411     switch (tokeninfoclass)
412     {
413     case TokenUser:
414         if( tokeninfo )
415         {
416             TOKEN_USER * tuser = tokeninfo;
417             PSID sid = (PSID) (tuser + 1);
418             SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
419             RtlInitializeSid(sid, &localSidAuthority, 1);
420             *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
421             tuser->User.Sid = sid;
422         }
423         break;
424     case TokenGroups:
425         if (tokeninfo)
426         {
427             TOKEN_GROUPS *tgroups = tokeninfo;
428             SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
429
430             /* we need to show admin privileges ! */
431             tgroups->GroupCount = 1;
432             RtlAllocateAndInitializeSid( &sid,
433                                          2,
434                                          SECURITY_BUILTIN_DOMAIN_RID,
435                                          DOMAIN_ALIAS_RID_ADMINS,
436                                          0, 0, 0, 0, 0, 0,
437                                          &(tgroups->Groups->Sid));
438         }
439         break;
440     case TokenPrivileges:
441         if (tokeninfo)
442         {
443             TOKEN_PRIVILEGES *tpriv = tokeninfo;
444             tpriv->PrivilegeCount = 1;
445         }
446         break;
447     }
448     return 0;
449 }
450
451 /*
452  *      Section
453  */
454
455 /******************************************************************************
456  *  NtQuerySection      [NTDLL.@]
457  */
458 NTSTATUS WINAPI NtQuerySection(
459         IN HANDLE SectionHandle,
460         IN PVOID SectionInformationClass,
461         OUT PVOID SectionInformation,
462         IN ULONG Length,
463         OUT PULONG ResultLength)
464 {
465         FIXME("(%p,%p,%p,0x%08lx,%p) stub!\n",
466         SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
467         return 0;
468 }
469
470 /*
471  *      ports
472  */
473
474 /******************************************************************************
475  *  NtCreatePort                [NTDLL.@]
476  *  ZwCreatePort                [NTDLL.@]
477  */
478 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
479                              DWORD MaxConnectInfoLength,DWORD MaxDataLength,DWORD unknown)
480 {
481   FIXME("(%p,%p,0x%08lx,0x%08lx,0x%08lx),stub!\n",PortHandle,ObjectAttributes,
482         MaxConnectInfoLength,MaxDataLength,unknown);
483   return 0;
484 }
485
486 /******************************************************************************
487  *  NtConnectPort               [NTDLL.@]
488  *  ZwConnectPort               [NTDLL.@]
489  */
490 NTSTATUS WINAPI NtConnectPort(PHANDLE PortHandle,PUNICODE_STRING PortName,PVOID Unknown1,
491                               PLPCSECTIONINFO sectionInfo,PLPCSECTIONMAPINFO mapInfo,PVOID Unknown2,
492                               PVOID ConnectInfo,PDWORD pConnectInfoLength)
493 {
494   FIXME("(%p,%s,%p,%p,%p,%p,%p,%p (%ld)),stub!\n",PortHandle,debugstr_w(PortName->Buffer),Unknown1,
495         sectionInfo,mapInfo,Unknown2,ConnectInfo,pConnectInfoLength,pConnectInfoLength?*pConnectInfoLength:-1);
496   if(ConnectInfo && pConnectInfoLength)
497     TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
498   return 0;
499 }
500
501 /******************************************************************************
502  *  NtListenPort                [NTDLL.@]
503  *  ZwListenPort                [NTDLL.@]
504  */
505 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPCMESSAGE pLpcMessage)
506 {
507   FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
508   return 0;
509 }
510
511 /******************************************************************************
512  *  NtAcceptConnectPort [NTDLL.@]
513  *  ZwAcceptConnectPort [NTDLL.@]
514  */
515 NTSTATUS WINAPI NtAcceptConnectPort(PHANDLE PortHandle,DWORD Unknown,PLPCMESSAGE pLpcMessage,
516                                     DWORD acceptIt,DWORD Unknown2,PLPCSECTIONMAPINFO mapInfo)
517 {
518   FIXME("(%p,0x%08lx,%p,0x%08lx,0x%08lx,%p),stub!\n",PortHandle,Unknown,pLpcMessage,acceptIt,Unknown2,mapInfo);
519   return 0;
520 }
521
522 /******************************************************************************
523  *  NtCompleteConnectPort       [NTDLL.@]
524  *  ZwCompleteConnectPort       [NTDLL.@]
525  */
526 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
527 {
528   FIXME("(%p),stub!\n",PortHandle);
529   return 0;
530 }
531
532 /******************************************************************************
533  *  NtRegisterThreadTerminatePort       [NTDLL.@]
534  *  ZwRegisterThreadTerminatePort       [NTDLL.@]
535  */
536 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
537 {
538   FIXME("(%p),stub!\n",PortHandle);
539   return 0;
540 }
541
542 /******************************************************************************
543  *  NtRequestWaitReplyPort              [NTDLL.@]
544  *  ZwRequestWaitReplyPort              [NTDLL.@]
545  */
546 NTSTATUS WINAPI NtRequestWaitReplyPort(HANDLE PortHandle,PLPCMESSAGE pLpcMessageIn,PLPCMESSAGE pLpcMessageOut)
547 {
548   FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
549   if(pLpcMessageIn)
550   {
551     TRACE("Message to send:\n");
552     TRACE("\tActualMessageLength = %d\n",pLpcMessageIn->ActualMessageLength);
553     TRACE("\tTotalMessageLength  = %d\n",pLpcMessageIn->TotalMessageLength);
554     TRACE("\tMessageType         = %ld\n",pLpcMessageIn->MessageType);
555     TRACE("\tClientProcessId     = %ld\n",pLpcMessageIn->ClientProcessId);
556     TRACE("\tClientThreadId      = %ld\n",pLpcMessageIn->ClientThreadId);
557     TRACE("\tMessageId           = %ld\n",pLpcMessageIn->MessageId);
558     TRACE("\tSharedSectionSize   = %ld\n",pLpcMessageIn->SharedSectionSize);
559     TRACE("\tMessageData         = %s\n",debugstr_an(pLpcMessageIn->MessageData,pLpcMessageIn->ActualMessageLength));
560   }
561   return 0;
562 }
563
564 /******************************************************************************
565  *  NtReplyWaitReceivePort      [NTDLL.@]
566  *  ZwReplyWaitReceivePort      [NTDLL.@]
567  */
568 NTSTATUS WINAPI NtReplyWaitReceivePort(HANDLE PortHandle,PDWORD Unknown,PLPCMESSAGE pLpcMessageOut,PLPCMESSAGE pLpcMessageIn)
569 {
570   FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,Unknown,pLpcMessageOut,pLpcMessageIn);
571   return 0;
572 }
573
574 /*
575  *      Misc
576  */
577
578  /******************************************************************************
579  *  NtSetIntervalProfile        [NTDLL.@]
580  *  ZwSetIntervalProfile        [NTDLL.@]
581  */
582 NTSTATUS WINAPI NtSetIntervalProfile(DWORD x1,DWORD x2) {
583         FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
584         return 0;
585 }
586
587 /******************************************************************************
588  *  NtQueryPerformanceCounter   [NTDLL.@]
589  */
590 NTSTATUS WINAPI NtQueryPerformanceCounter(
591         IN PLARGE_INTEGER Counter,
592         IN PLARGE_INTEGER Frequency)
593 {
594         FIXME("(%p, 0%p) stub\n",
595         Counter, Frequency);
596         return 0;
597 }
598
599 /******************************************************************************
600  *  NtCreateMailslotFile        [NTDLL.@]
601  *  ZwCreateMailslotFile        [NTDLL.@]
602  */
603 NTSTATUS WINAPI NtCreateMailslotFile(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8)
604 {
605         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6,x7,x8);
606         return 0;
607 }
608
609 /******************************************************************************
610  * NtQuerySystemInformation [NTDLL.@]
611  * ZwQuerySystemInformation [NTDLL.@]
612  *
613  * ARGUMENTS:
614  *  SystemInformationClass      Index to a certain information structure
615  *      SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
616  *      SystemCacheInformation          SYSTEM_CACHE_INFORMATION
617  *      SystemConfigurationInformation  CONFIGURATION_INFORMATION
618  *      observed (class/len):
619  *              0x0/0x2c
620  *              0x12/0x18
621  *              0x2/0x138
622  *              0x8/0x600
623  *              0x25/0xc
624  *  SystemInformation   caller supplies storage for the information structure
625  *  Length              size of the structure
626  *  ResultLength        Data written
627  */
628 NTSTATUS WINAPI NtQuerySystemInformation(
629         IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
630         OUT PVOID SystemInformation,
631         IN ULONG Length,
632         OUT PULONG ResultLength)
633 {
634     switch(SystemInformationClass)
635     {
636     case 0x25:
637         /* Something to do with the size of the registry             *
638          * Since we don't have a size limitation, fake it            *
639          * This is almost certainly wrong.                           *
640          * This sets each of the three words in the struct to 32 MB, *
641          * which is enough to make the IE 5 installer happy.         */
642         FIXME("(0x%08x,%p,0x%08lx,%p) faking max registry size of 32 MB\n",
643               SystemInformationClass,SystemInformation,Length,ResultLength);
644         *(DWORD *)SystemInformation = 0x2000000;
645         *(((DWORD *)SystemInformation)+1) = 0x200000;
646         *(((DWORD *)SystemInformation)+2) = 0x200000;
647         break;
648
649     default:
650         FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
651               SystemInformationClass,SystemInformation,Length,ResultLength);
652         ZeroMemory (SystemInformation, Length);
653     }
654
655     return STATUS_SUCCESS;
656 }
657
658
659 /******************************************************************************
660  *  NtCreatePagingFile          [NTDLL.@]
661  *  ZwCreatePagingFile          [NTDLL.@]
662  */
663 NTSTATUS WINAPI NtCreatePagingFile(
664         IN PUNICODE_STRING PageFileName,
665         IN ULONG MiniumSize,
666         IN ULONG MaxiumSize,
667         OUT PULONG ActualSize)
668 {
669         FIXME("(%p(%s),0x%08lx,0x%08lx,%p),stub!\n",
670         PageFileName->Buffer, debugstr_w(PageFileName->Buffer),MiniumSize,MaxiumSize,ActualSize);
671         return 0;
672 }
673
674 /******************************************************************************
675  *  NtDisplayString                             [NTDLL.@]
676  *
677  * writes a string to the nt-textmode screen eg. during startup
678  */
679 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
680 {
681     STRING stringA;
682     NTSTATUS ret;
683
684     if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
685     {
686         MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
687         RtlFreeAnsiString( &stringA );
688     }
689     return ret;
690 }
691
692 /******************************************************************************
693  *  NtPowerInformation                          [NTDLL.@]
694  *
695  */
696 NTSTATUS WINAPI NtPowerInformation(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5)
697 {
698         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4,x5);
699         return 0;
700 }
701
702 /******************************************************************************
703  *  NtAllocateLocallyUniqueId (NTDLL.@)
704  *
705  * FIXME: the server should do that
706  */
707 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
708 {
709     static LUID luid;
710
711     FIXME("%p (0x%08lx%08lx)\n", Luid, luid.HighPart, luid.LowPart);
712
713     luid.LowPart++;
714     if (luid.LowPart==0)
715         luid.HighPart++;
716     Luid->HighPart = luid.HighPart;
717     Luid->LowPart = luid.LowPart;
718
719     return STATUS_SUCCESS;
720 }
721
722 /******************************************************************************
723  *        VerSetConditionMask   (NTDLL.@)
724  */
725 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
726                                       BYTE dwConditionMask)
727 {
728     if(dwTypeBitMask == 0)
729         return dwlConditionMask;
730     dwConditionMask &= 0x07;
731     if(dwConditionMask == 0)
732         return dwlConditionMask;
733
734     if(dwTypeBitMask & VER_PRODUCT_TYPE)
735         dwlConditionMask |= dwConditionMask << 7*3;
736     else if (dwTypeBitMask & VER_SUITENAME)
737         dwlConditionMask |= dwConditionMask << 6*3;
738     else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
739         dwlConditionMask |= dwConditionMask << 5*3;
740     else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
741         dwlConditionMask |= dwConditionMask << 4*3;
742     else if (dwTypeBitMask & VER_PLATFORMID)
743         dwlConditionMask |= dwConditionMask << 3*3;
744     else if (dwTypeBitMask & VER_BUILDNUMBER)
745         dwlConditionMask |= dwConditionMask << 2*3;
746     else if (dwTypeBitMask & VER_MAJORVERSION)
747         dwlConditionMask |= dwConditionMask << 1*3;
748     else if (dwTypeBitMask & VER_MINORVERSION)
749         dwlConditionMask |= dwConditionMask << 0*3;
750     return dwlConditionMask;
751 }