ntdll: Add stub for NtSecureConnectPort.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29
30 #define NONAMELESSUNION
31 #include "ntstatus.h"
32 #define WIN32_NO_STATUS
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35 #include "windef.h"
36 #include "winternl.h"
37 #include "ntdll_misc.h"
38 #include "wine/server.h"
39
40 #ifdef __APPLE__
41 #include <mach/mach_init.h>
42 #include <mach/mach_host.h>
43 #include <mach/vm_map.h>
44 #endif
45
46 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
47
48 /*
49  *      Token
50  */
51
52 /******************************************************************************
53  *  NtDuplicateToken            [NTDLL.@]
54  *  ZwDuplicateToken            [NTDLL.@]
55  */
56 NTSTATUS WINAPI NtDuplicateToken(
57         IN HANDLE ExistingToken,
58         IN ACCESS_MASK DesiredAccess,
59         IN POBJECT_ATTRIBUTES ObjectAttributes,
60         IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
61         IN TOKEN_TYPE TokenType,
62         OUT PHANDLE NewToken)
63 {
64     NTSTATUS status;
65
66     TRACE("(%p,0x%08x,%s,0x%08x,0x%08x,%p)\n",
67           ExistingToken, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes),
68           ImpersonationLevel, TokenType, NewToken);
69
70     if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
71     {
72         SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
73         TRACE("ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
74             SecurityQOS->Length, SecurityQOS->ImpersonationLevel,
75             SecurityQOS->ContextTrackingMode,
76             SecurityQOS->EffectiveOnly ? "TRUE" : "FALSE");
77         ImpersonationLevel = SecurityQOS->ImpersonationLevel;
78     }
79
80     SERVER_START_REQ( duplicate_token )
81     {
82         req->handle              = wine_server_obj_handle( ExistingToken );
83         req->access              = DesiredAccess;
84         req->attributes          = ObjectAttributes ? ObjectAttributes->Attributes : 0;
85         req->primary             = (TokenType == TokenPrimary);
86         req->impersonation_level = ImpersonationLevel;
87         status = wine_server_call( req );
88         if (!status) *NewToken = wine_server_ptr_handle( reply->new_handle );
89     }
90     SERVER_END_REQ;
91
92     return status;
93 }
94
95 /******************************************************************************
96  *  NtOpenProcessToken          [NTDLL.@]
97  *  ZwOpenProcessToken          [NTDLL.@]
98  */
99 NTSTATUS WINAPI NtOpenProcessToken(
100         HANDLE ProcessHandle,
101         DWORD DesiredAccess,
102         HANDLE *TokenHandle)
103 {
104     return NtOpenProcessTokenEx( ProcessHandle, DesiredAccess, 0, TokenHandle );
105 }
106
107 /******************************************************************************
108  *  NtOpenProcessTokenEx   [NTDLL.@]
109  *  ZwOpenProcessTokenEx   [NTDLL.@]
110  */
111 NTSTATUS WINAPI NtOpenProcessTokenEx( HANDLE process, DWORD access, DWORD attributes,
112                                       HANDLE *handle )
113 {
114     NTSTATUS ret;
115
116     TRACE("(%p,0x%08x,0x%08x,%p)\n", process, access, attributes, handle);
117
118     SERVER_START_REQ( open_token )
119     {
120         req->handle     = wine_server_obj_handle( process );
121         req->access     = access;
122         req->attributes = attributes;
123         req->flags      = 0;
124         ret = wine_server_call( req );
125         if (!ret) *handle = wine_server_ptr_handle( reply->token );
126     }
127     SERVER_END_REQ;
128     return ret;
129 }
130
131 /******************************************************************************
132  *  NtOpenThreadToken           [NTDLL.@]
133  *  ZwOpenThreadToken           [NTDLL.@]
134  */
135 NTSTATUS WINAPI NtOpenThreadToken(
136         HANDLE ThreadHandle,
137         DWORD DesiredAccess,
138         BOOLEAN OpenAsSelf,
139         HANDLE *TokenHandle)
140 {
141     return NtOpenThreadTokenEx( ThreadHandle, DesiredAccess, OpenAsSelf, 0, TokenHandle );
142 }
143
144 /******************************************************************************
145  *  NtOpenThreadTokenEx   [NTDLL.@]
146  *  ZwOpenThreadTokenEx   [NTDLL.@]
147  */
148 NTSTATUS WINAPI NtOpenThreadTokenEx( HANDLE thread, DWORD access, BOOLEAN as_self, DWORD attributes,
149                                      HANDLE *handle )
150 {
151     NTSTATUS ret;
152
153     TRACE("(%p,0x%08x,%u,0x%08x,%p)\n", thread, access, as_self, attributes, handle );
154
155     SERVER_START_REQ( open_token )
156     {
157         req->handle     = wine_server_obj_handle( thread );
158         req->access     = access;
159         req->attributes = attributes;
160         req->flags      = OPEN_TOKEN_THREAD;
161         if (as_self) req->flags |= OPEN_TOKEN_AS_SELF;
162         ret = wine_server_call( req );
163         if (!ret) *handle = wine_server_ptr_handle( reply->token );
164     }
165     SERVER_END_REQ;
166
167     return ret;
168 }
169
170 /******************************************************************************
171  *  NtAdjustPrivilegesToken             [NTDLL.@]
172  *  ZwAdjustPrivilegesToken             [NTDLL.@]
173  *
174  * FIXME: parameters unsafe
175  */
176 NTSTATUS WINAPI NtAdjustPrivilegesToken(
177         IN HANDLE TokenHandle,
178         IN BOOLEAN DisableAllPrivileges,
179         IN PTOKEN_PRIVILEGES NewState,
180         IN DWORD BufferLength,
181         OUT PTOKEN_PRIVILEGES PreviousState,
182         OUT PDWORD ReturnLength)
183 {
184     NTSTATUS ret;
185
186     TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
187         TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
188
189     SERVER_START_REQ( adjust_token_privileges )
190     {
191         req->handle = wine_server_obj_handle( TokenHandle );
192         req->disable_all = DisableAllPrivileges;
193         req->get_modified_state = (PreviousState != NULL);
194         if (!DisableAllPrivileges)
195         {
196             wine_server_add_data( req, NewState->Privileges,
197                                   NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
198         }
199         if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
200             wine_server_set_reply( req, PreviousState->Privileges,
201                                    BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
202         ret = wine_server_call( req );
203         if (PreviousState)
204         {
205             *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
206             PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
207         }
208     }
209     SERVER_END_REQ;
210
211     return ret;
212 }
213
214 /******************************************************************************
215 *  NtQueryInformationToken              [NTDLL.@]
216 *  ZwQueryInformationToken              [NTDLL.@]
217 *
218 * NOTES
219 *  Buffer for TokenUser:
220 *   0x00 TOKEN_USER the PSID field points to the SID
221 *   0x08 SID
222 *
223 */
224 NTSTATUS WINAPI NtQueryInformationToken(
225         HANDLE token,
226         TOKEN_INFORMATION_CLASS tokeninfoclass,
227         PVOID tokeninfo,
228         ULONG tokeninfolength,
229         PULONG retlen )
230 {
231     ULONG len;
232     NTSTATUS status = STATUS_SUCCESS;
233
234     TRACE("(%p,%d,%p,%d,%p)\n",
235           token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
236
237     switch (tokeninfoclass)
238     {
239     case TokenOwner:
240         len = sizeof(TOKEN_OWNER) + sizeof(SID);
241         break;
242     case TokenPrimaryGroup:
243         len = sizeof(TOKEN_PRIMARY_GROUP);
244         break;
245     case TokenSource:
246         len = sizeof(TOKEN_SOURCE);
247         break;
248     case TokenType:
249         len = sizeof (TOKEN_TYPE);
250         break;
251     case TokenImpersonationLevel:
252         len = sizeof(SECURITY_IMPERSONATION_LEVEL);
253         break;
254     case TokenStatistics:
255         len = sizeof(TOKEN_STATISTICS);
256         break;
257     default:
258         len = 0;
259     }
260
261     if (retlen) *retlen = len;
262
263     if (tokeninfolength < len)
264         return STATUS_BUFFER_TOO_SMALL;
265
266     switch (tokeninfoclass)
267     {
268     case TokenUser:
269         SERVER_START_REQ( get_token_user )
270         {
271             TOKEN_USER * tuser = tokeninfo;
272             PSID sid = tuser + 1;
273             DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
274
275             req->handle = wine_server_obj_handle( token );
276             wine_server_set_reply( req, sid, sid_len );
277             status = wine_server_call( req );
278             if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
279             if (status == STATUS_SUCCESS)
280             {
281                 tuser->User.Sid = sid;
282                 tuser->User.Attributes = 0;
283             }
284         }
285         SERVER_END_REQ;
286         break;
287     case TokenGroups:
288     {
289         char stack_buffer[256];
290         unsigned int server_buf_len = sizeof(stack_buffer);
291         void *buffer = stack_buffer;
292         BOOLEAN need_more_memory;
293
294         /* we cannot work out the size of the server buffer required for the
295          * input size, since there are two factors affecting how much can be
296          * stored in the buffer - number of groups and lengths of sids */
297         do
298         {
299             need_more_memory = FALSE;
300
301             SERVER_START_REQ( get_token_groups )
302             {
303                 TOKEN_GROUPS *groups = tokeninfo;
304
305                 req->handle = wine_server_obj_handle( token );
306                 wine_server_set_reply( req, buffer, server_buf_len );
307                 status = wine_server_call( req );
308                 if (status == STATUS_BUFFER_TOO_SMALL)
309                 {
310                     if (buffer == stack_buffer)
311                         buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
312                     else
313                         buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
314                     if (!buffer) return STATUS_NO_MEMORY;
315
316                     server_buf_len = reply->user_len;
317                     need_more_memory = TRUE;
318                 }
319                 else if (status == STATUS_SUCCESS)
320                 {
321                     struct token_groups *tg = buffer;
322                     unsigned int *attr = (unsigned int *)(tg + 1);
323                     ULONG i;
324                     const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
325                     SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
326                     ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
327                         reply->user_len - non_sid_portion;
328
329                     if (retlen) *retlen = needed_bytes;
330
331                     if (needed_bytes <= tokeninfolength)
332                     {
333                         groups->GroupCount = tg->count;
334                         memcpy( sids, (char *)buffer + non_sid_portion,
335                                 reply->user_len - non_sid_portion );
336
337                         for (i = 0; i < tg->count; i++)
338                         {
339                             groups->Groups[i].Attributes = attr[i];
340                             groups->Groups[i].Sid = sids;
341                             sids = (SID *)((char *)sids + RtlLengthSid(sids));
342                         }
343                     }
344                     else status = STATUS_BUFFER_TOO_SMALL;
345                 }
346                 else if (retlen) *retlen = 0;
347             }
348             SERVER_END_REQ;
349         } while (need_more_memory);
350         if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
351         break;
352     }
353     case TokenPrimaryGroup:
354         if (tokeninfo)
355         {
356             TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
357             SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
358             RtlAllocateAndInitializeSid( &sid,
359                                          2,
360                                          SECURITY_BUILTIN_DOMAIN_RID,
361                                          DOMAIN_ALIAS_RID_ADMINS,
362                                          0, 0, 0, 0, 0, 0,
363                                          &(tgroup->PrimaryGroup));
364         }
365         break;
366     case TokenPrivileges:
367         SERVER_START_REQ( get_token_privileges )
368         {
369             TOKEN_PRIVILEGES *tpriv = tokeninfo;
370             req->handle = wine_server_obj_handle( token );
371             if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
372                 wine_server_set_reply( req, tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
373             status = wine_server_call( req );
374             if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
375             if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
376         }
377         SERVER_END_REQ;
378         break;
379     case TokenOwner:
380         if (tokeninfo)
381         {
382             TOKEN_OWNER *owner = tokeninfo;
383             PSID sid = owner + 1;
384             SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
385             RtlInitializeSid(sid, &localSidAuthority, 1);
386             *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
387             owner->Owner = sid;
388         }
389         break;
390     case TokenImpersonationLevel:
391         SERVER_START_REQ( get_token_impersonation_level )
392         {
393             SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
394             req->handle = wine_server_obj_handle( token );
395             status = wine_server_call( req );
396             if (status == STATUS_SUCCESS)
397                 *impersonation_level = reply->impersonation_level;
398         }
399         SERVER_END_REQ;
400         break;
401     case TokenStatistics:
402         SERVER_START_REQ( get_token_statistics )
403         {
404             TOKEN_STATISTICS *statistics = tokeninfo;
405             req->handle = wine_server_obj_handle( token );
406             status = wine_server_call( req );
407             if (status == STATUS_SUCCESS)
408             {
409                 statistics->TokenId.LowPart  = reply->token_id.low_part;
410                 statistics->TokenId.HighPart = reply->token_id.high_part;
411                 statistics->AuthenticationId.LowPart  = 0; /* FIXME */
412                 statistics->AuthenticationId.HighPart = 0; /* FIXME */
413                 statistics->ExpirationTime.u.HighPart = 0x7fffffff;
414                 statistics->ExpirationTime.u.LowPart  = 0xffffffff;
415                 statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
416                 statistics->ImpersonationLevel = reply->impersonation_level;
417
418                 /* kernel information not relevant to us */
419                 statistics->DynamicCharged = 0;
420                 statistics->DynamicAvailable = 0;
421
422                 statistics->GroupCount = reply->group_count;
423                 statistics->PrivilegeCount = reply->privilege_count;
424                 statistics->ModifiedId.LowPart  = reply->modified_id.low_part;
425                 statistics->ModifiedId.HighPart = reply->modified_id.high_part;
426             }
427         }
428         SERVER_END_REQ;
429         break;
430     case TokenType:
431         SERVER_START_REQ( get_token_statistics )
432         {
433             TOKEN_TYPE *token_type = tokeninfo;
434             req->handle = wine_server_obj_handle( token );
435             status = wine_server_call( req );
436             if (status == STATUS_SUCCESS)
437                 *token_type = reply->primary ? TokenPrimary : TokenImpersonation;
438         }
439         SERVER_END_REQ;
440         break;
441     case TokenDefaultDacl:
442         SERVER_START_REQ( get_token_default_dacl )
443         {
444             TOKEN_DEFAULT_DACL *default_dacl = tokeninfo;
445             ACL *acl = (ACL *)(default_dacl + 1);
446             DWORD acl_len;
447
448             if (tokeninfolength < sizeof(TOKEN_DEFAULT_DACL)) acl_len = 0;
449             else acl_len = tokeninfolength - sizeof(TOKEN_DEFAULT_DACL);
450
451             req->handle = wine_server_obj_handle( token );
452             wine_server_set_reply( req, acl, acl_len );
453             status = wine_server_call( req );
454
455             if (retlen) *retlen = reply->acl_len + sizeof(TOKEN_DEFAULT_DACL);
456             if (status == STATUS_SUCCESS)
457             {
458                 if (reply->acl_len)
459                     default_dacl->DefaultDacl = acl;
460                 else
461                     default_dacl->DefaultDacl = NULL;
462             }
463         }
464         SERVER_END_REQ;
465         break;
466     default:
467         {
468             ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
469             return STATUS_NOT_IMPLEMENTED;
470         }
471     }
472     return status;
473 }
474
475 /******************************************************************************
476 *  NtSetInformationToken                [NTDLL.@]
477 *  ZwSetInformationToken                [NTDLL.@]
478 */
479 NTSTATUS WINAPI NtSetInformationToken(
480         HANDLE TokenHandle,
481         TOKEN_INFORMATION_CLASS TokenInformationClass,
482         PVOID TokenInformation,
483         ULONG TokenInformationLength)
484 {
485     NTSTATUS ret = STATUS_NOT_IMPLEMENTED;
486
487     TRACE("%p %d %p %u\n", TokenHandle, TokenInformationClass,
488            TokenInformation, TokenInformationLength);
489
490     switch (TokenInformationClass)
491     {
492     case TokenDefaultDacl:
493         if (TokenInformationLength < sizeof(TOKEN_DEFAULT_DACL))
494         {
495             ret = STATUS_INFO_LENGTH_MISMATCH;
496             break;
497         }
498         if (!TokenInformation)
499         {
500             ret = STATUS_ACCESS_VIOLATION;
501             break;
502         }
503         SERVER_START_REQ( set_token_default_dacl )
504         {
505             ACL *acl = ((TOKEN_DEFAULT_DACL *)TokenInformation)->DefaultDacl;
506             WORD size;
507
508             if (acl) size = acl->AclSize;
509             else size = 0;
510
511             req->handle = wine_server_obj_handle( TokenHandle );
512             wine_server_add_data( req, acl, size );
513             ret = wine_server_call( req );
514         }
515         SERVER_END_REQ;
516         break;
517     default:
518         FIXME("unimplemented class %u\n", TokenInformationClass);
519         break;
520     }
521
522     return ret;
523 }
524
525 /******************************************************************************
526 *  NtAdjustGroupsToken          [NTDLL.@]
527 *  ZwAdjustGroupsToken          [NTDLL.@]
528 */
529 NTSTATUS WINAPI NtAdjustGroupsToken(
530         HANDLE TokenHandle,
531         BOOLEAN ResetToDefault,
532         PTOKEN_GROUPS NewState,
533         ULONG BufferLength,
534         PTOKEN_GROUPS PreviousState,
535         PULONG ReturnLength)
536 {
537     FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
538           NewState, BufferLength, PreviousState, ReturnLength);
539     return STATUS_NOT_IMPLEMENTED;
540 }
541
542 /******************************************************************************
543 *  NtPrivilegeCheck             [NTDLL.@]
544 *  ZwPrivilegeCheck             [NTDLL.@]
545 */
546 NTSTATUS WINAPI NtPrivilegeCheck(
547     HANDLE ClientToken,
548     PPRIVILEGE_SET RequiredPrivileges,
549     PBOOLEAN Result)
550 {
551     NTSTATUS status;
552     SERVER_START_REQ( check_token_privileges )
553     {
554         req->handle = wine_server_obj_handle( ClientToken );
555         req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
556         wine_server_add_data( req, RequiredPrivileges->Privilege,
557             RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
558         wine_server_set_reply( req, RequiredPrivileges->Privilege,
559             RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
560
561         status = wine_server_call( req );
562
563         if (status == STATUS_SUCCESS)
564             *Result = (reply->has_privileges ? TRUE : FALSE);
565     }
566     SERVER_END_REQ;
567     return status;
568 }
569
570 /*
571  *      Section
572  */
573
574 /******************************************************************************
575  *  NtQuerySection      [NTDLL.@]
576  */
577 NTSTATUS WINAPI NtQuerySection(
578         IN HANDLE SectionHandle,
579         IN SECTION_INFORMATION_CLASS SectionInformationClass,
580         OUT PVOID SectionInformation,
581         IN ULONG Length,
582         OUT PULONG ResultLength)
583 {
584         FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
585         SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
586         return 0;
587 }
588
589 /*
590  *      ports
591  */
592
593 /******************************************************************************
594  *  NtCreatePort                [NTDLL.@]
595  *  ZwCreatePort                [NTDLL.@]
596  */
597 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
598                              ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
599 {
600   FIXME("(%p,%p,%u,%u,%p),stub!\n",PortHandle,ObjectAttributes,
601         MaxConnectInfoLength,MaxDataLength,reserved);
602   return STATUS_NOT_IMPLEMENTED;
603 }
604
605 /******************************************************************************
606  *  NtConnectPort               [NTDLL.@]
607  *  ZwConnectPort               [NTDLL.@]
608  */
609 NTSTATUS WINAPI NtConnectPort(
610         PHANDLE PortHandle,
611         PUNICODE_STRING PortName,
612         PSECURITY_QUALITY_OF_SERVICE SecurityQos,
613         PLPC_SECTION_WRITE WriteSection,
614         PLPC_SECTION_READ ReadSection,
615         PULONG MaximumMessageLength,
616         PVOID ConnectInfo,
617         PULONG pConnectInfoLength)
618 {
619     FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
620           PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
621           WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
622           pConnectInfoLength);
623     if (ConnectInfo && pConnectInfoLength)
624         TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
625     return STATUS_NOT_IMPLEMENTED;
626 }
627
628 /******************************************************************************
629  *  NtSecureConnectPort                (NTDLL.@)
630  *  ZwSecureConnectPort                (NTDLL.@)
631  */
632 NTSTATUS WINAPI NtSecureConnectPort(
633         PHANDLE PortHandle,
634         PUNICODE_STRING PortName,
635         PSECURITY_QUALITY_OF_SERVICE SecurityQos,
636         PLPC_SECTION_WRITE WriteSection,
637         PSID pSid,
638         PLPC_SECTION_READ ReadSection,
639         PULONG MaximumMessageLength,
640         PVOID ConnectInfo,
641         PULONG pConnectInfoLength)
642 {
643     FIXME("(%p,%s,%p,%p,%p,%p,%p,%p,%p),stub!\n",
644           PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
645           WriteSection,pSid,ReadSection,MaximumMessageLength,ConnectInfo,
646           pConnectInfoLength);
647     return STATUS_NOT_IMPLEMENTED;
648 }
649
650 /******************************************************************************
651  *  NtListenPort                [NTDLL.@]
652  *  ZwListenPort                [NTDLL.@]
653  */
654 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
655 {
656   FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
657   return STATUS_NOT_IMPLEMENTED;
658 }
659
660 /******************************************************************************
661  *  NtAcceptConnectPort [NTDLL.@]
662  *  ZwAcceptConnectPort [NTDLL.@]
663  */
664 NTSTATUS WINAPI NtAcceptConnectPort(
665         PHANDLE PortHandle,
666         ULONG PortIdentifier,
667         PLPC_MESSAGE pLpcMessage,
668         BOOLEAN Accept,
669         PLPC_SECTION_WRITE WriteSection,
670         PLPC_SECTION_READ ReadSection)
671 {
672   FIXME("(%p,%u,%p,%d,%p,%p),stub!\n",
673         PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
674   return STATUS_NOT_IMPLEMENTED;
675 }
676
677 /******************************************************************************
678  *  NtCompleteConnectPort       [NTDLL.@]
679  *  ZwCompleteConnectPort       [NTDLL.@]
680  */
681 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
682 {
683   FIXME("(%p),stub!\n",PortHandle);
684   return STATUS_NOT_IMPLEMENTED;
685 }
686
687 /******************************************************************************
688  *  NtRegisterThreadTerminatePort       [NTDLL.@]
689  *  ZwRegisterThreadTerminatePort       [NTDLL.@]
690  */
691 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
692 {
693   FIXME("(%p),stub!\n",PortHandle);
694   return STATUS_NOT_IMPLEMENTED;
695 }
696
697 /******************************************************************************
698  *  NtRequestWaitReplyPort              [NTDLL.@]
699  *  ZwRequestWaitReplyPort              [NTDLL.@]
700  */
701 NTSTATUS WINAPI NtRequestWaitReplyPort(
702         HANDLE PortHandle,
703         PLPC_MESSAGE pLpcMessageIn,
704         PLPC_MESSAGE pLpcMessageOut)
705 {
706   FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
707   if(pLpcMessageIn)
708   {
709     TRACE("Message to send:\n");
710     TRACE("\tDataSize            = %u\n",pLpcMessageIn->DataSize);
711     TRACE("\tMessageSize         = %u\n",pLpcMessageIn->MessageSize);
712     TRACE("\tMessageType         = %u\n",pLpcMessageIn->MessageType);
713     TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
714     TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
715     TRACE("\tClientId.UniqueThread  = %p\n",pLpcMessageIn->ClientId.UniqueThread);
716     TRACE("\tMessageId           = %lu\n",pLpcMessageIn->MessageId);
717     TRACE("\tSectionSize         = %lu\n",pLpcMessageIn->SectionSize);
718     TRACE("\tData                = %s\n",
719       debugstr_an((const char*)pLpcMessageIn->Data,pLpcMessageIn->DataSize));
720   }
721   return STATUS_NOT_IMPLEMENTED;
722 }
723
724 /******************************************************************************
725  *  NtReplyWaitReceivePort      [NTDLL.@]
726  *  ZwReplyWaitReceivePort      [NTDLL.@]
727  */
728 NTSTATUS WINAPI NtReplyWaitReceivePort(
729         HANDLE PortHandle,
730         PULONG PortIdentifier,
731         PLPC_MESSAGE ReplyMessage,
732         PLPC_MESSAGE Message)
733 {
734   FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
735   return STATUS_NOT_IMPLEMENTED;
736 }
737
738 /*
739  *      Misc
740  */
741
742  /******************************************************************************
743  *  NtSetIntervalProfile        [NTDLL.@]
744  *  ZwSetIntervalProfile        [NTDLL.@]
745  */
746 NTSTATUS WINAPI NtSetIntervalProfile(
747         ULONG Interval,
748         KPROFILE_SOURCE Source)
749 {
750     FIXME("%u,%d\n", Interval, Source);
751     return STATUS_SUCCESS;
752 }
753
754 /******************************************************************************
755  * NtQuerySystemInformation [NTDLL.@]
756  * ZwQuerySystemInformation [NTDLL.@]
757  *
758  * ARGUMENTS:
759  *  SystemInformationClass      Index to a certain information structure
760  *      SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
761  *      SystemCacheInformation          SYSTEM_CACHE_INFORMATION
762  *      SystemConfigurationInformation  CONFIGURATION_INFORMATION
763  *      observed (class/len):
764  *              0x0/0x2c
765  *              0x12/0x18
766  *              0x2/0x138
767  *              0x8/0x600
768  *              0x25/0xc
769  *  SystemInformation   caller supplies storage for the information structure
770  *  Length              size of the structure
771  *  ResultLength        Data written
772  */
773 NTSTATUS WINAPI NtQuerySystemInformation(
774         IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
775         OUT PVOID SystemInformation,
776         IN ULONG Length,
777         OUT PULONG ResultLength)
778 {
779     NTSTATUS    ret = STATUS_SUCCESS;
780     ULONG       len = 0;
781
782     TRACE("(0x%08x,%p,0x%08x,%p)\n",
783           SystemInformationClass,SystemInformation,Length,ResultLength);
784
785     switch (SystemInformationClass)
786     {
787     case SystemBasicInformation:
788         {
789             SYSTEM_BASIC_INFORMATION sbi;
790
791             virtual_get_system_info( &sbi );
792             len = sizeof(sbi);
793
794             if ( Length == len)
795             {
796                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
797                 else memcpy( SystemInformation, &sbi, len);
798             }
799             else ret = STATUS_INFO_LENGTH_MISMATCH;
800         }
801         break;
802     case SystemCpuInformation:
803         {
804             SYSTEM_CPU_INFORMATION sci;
805
806             /* FIXME: move some code from kernel/cpu.c to process this */
807             sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
808             sci.Level = 6; /* 686, aka Pentium II+ */
809             sci.Revision = 0;
810             sci.Reserved = 0;
811             sci.FeatureSet = 0x1fff;
812             len = sizeof(sci);
813
814             if ( Length >= len)
815             {
816                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
817                 else memcpy( SystemInformation, &sci, len);
818             }
819             else ret = STATUS_INFO_LENGTH_MISMATCH;
820         }
821         break;
822     case SystemPerformanceInformation:
823         {
824             SYSTEM_PERFORMANCE_INFORMATION spi;
825             static BOOL fixme_written = FALSE;
826
827             memset(&spi, 0 , sizeof(spi));
828             len = sizeof(spi);
829
830             if (Length >= len)
831             {
832                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
833                 else memcpy( SystemInformation, &spi, len);
834             }
835             else ret = STATUS_INFO_LENGTH_MISMATCH;
836             if(!fixme_written) {
837                 FIXME("info_class SYSTEM_PERFORMANCE_INFORMATION\n");
838                 fixme_written = TRUE;
839             }
840         }
841         break;
842     case SystemTimeOfDayInformation:
843         {
844             SYSTEM_TIMEOFDAY_INFORMATION sti;
845
846             memset(&sti, 0 , sizeof(sti));
847
848             /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
849             sti.liKeBootTime.QuadPart = server_start_time;
850
851             if (Length <= sizeof(sti))
852             {
853                 len = Length;
854                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
855                 else memcpy( SystemInformation, &sti, Length);
856             }
857             else ret = STATUS_INFO_LENGTH_MISMATCH;
858         }
859         break;
860     case SystemProcessInformation:
861         {
862             SYSTEM_PROCESS_INFORMATION* spi = SystemInformation;
863             SYSTEM_PROCESS_INFORMATION* last = NULL;
864             HANDLE hSnap = 0;
865             WCHAR procname[1024];
866             WCHAR* exename;
867             DWORD wlen = 0;
868             DWORD procstructlen = 0;
869
870             SERVER_START_REQ( create_snapshot )
871             {
872                 req->flags      = SNAP_PROCESS | SNAP_THREAD;
873                 req->attributes = 0;
874                 if (!(ret = wine_server_call( req )))
875                     hSnap = wine_server_ptr_handle( reply->handle );
876             }
877             SERVER_END_REQ;
878             len = 0;
879             while (ret == STATUS_SUCCESS)
880             {
881                 SERVER_START_REQ( next_process )
882                 {
883                     req->handle = wine_server_obj_handle( hSnap );
884                     req->reset = (len == 0);
885                     wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
886                     if (!(ret = wine_server_call( req )))
887                     {
888                         /* Make sure procname is 0 terminated */
889                         procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
890
891                         /* Get only the executable name, not the path */
892                         if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
893                         else exename = procname;
894
895                         wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
896
897                         procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
898
899                         if (Length >= len + procstructlen)
900                         {
901                             /* ftCreationTime, ftUserTime, ftKernelTime;
902                              * vmCounters, ioCounters
903                              */
904  
905                             memset(spi, 0, sizeof(*spi));
906
907                             spi->NextEntryOffset = procstructlen - wlen;
908                             spi->dwThreadCount = reply->threads;
909
910                             /* spi->pszProcessName will be set later on */
911
912                             spi->dwBasePriority = reply->priority;
913                             spi->UniqueProcessId = UlongToHandle(reply->pid);
914                             spi->ParentProcessId = UlongToHandle(reply->ppid);
915                             spi->HandleCount = reply->handles;
916
917                             /* spi->ti will be set later on */
918
919                             len += procstructlen;
920                         }
921                         else ret = STATUS_INFO_LENGTH_MISMATCH;
922                     }
923                 }
924                 SERVER_END_REQ;
925  
926                 if (ret != STATUS_SUCCESS)
927                 {
928                     if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
929                     break;
930                 }
931                 else /* Length is already checked for */
932                 {
933                     int     i, j;
934
935                     /* set thread info */
936                     i = j = 0;
937                     while (ret == STATUS_SUCCESS)
938                     {
939                         SERVER_START_REQ( next_thread )
940                         {
941                             req->handle = wine_server_obj_handle( hSnap );
942                             req->reset = (j == 0);
943                             if (!(ret = wine_server_call( req )))
944                             {
945                                 j++;
946                                 if (UlongToHandle(reply->pid) == spi->UniqueProcessId)
947                                 {
948                                     /* ftKernelTime, ftUserTime, ftCreateTime;
949                                      * dwTickCount, dwStartAddress
950                                      */
951
952                                     memset(&spi->ti[i], 0, sizeof(spi->ti));
953
954                                     spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
955                                     spi->ti[i].ClientId.UniqueProcess = UlongToHandle(reply->pid);
956                                     spi->ti[i].ClientId.UniqueThread  = UlongToHandle(reply->tid);
957                                     spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
958                                     spi->ti[i].dwBasePriority = reply->base_pri;
959                                     i++;
960                                 }
961                             }
962                         }
963                         SERVER_END_REQ;
964                     }
965                     if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
966
967                     /* now append process name */
968                     spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->NextEntryOffset);
969                     spi->ProcessName.Length = wlen - sizeof(WCHAR);
970                     spi->ProcessName.MaximumLength = wlen;
971                     memcpy( spi->ProcessName.Buffer, exename, wlen );
972                     spi->NextEntryOffset += wlen;
973
974                     last = spi;
975                     spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
976                 }
977             }
978             if (ret == STATUS_SUCCESS && last) last->NextEntryOffset = 0;
979             if (hSnap) NtClose(hSnap);
980         }
981         break;
982     case SystemProcessorPerformanceInformation:
983         {
984             SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
985             unsigned int cpus = 0;
986             int out_cpus = Length / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
987
988             if (out_cpus == 0)
989             {
990                 len = 0;
991                 ret = STATUS_INFO_LENGTH_MISMATCH;
992                 break;
993             }
994             else
995 #ifdef __APPLE__
996             {
997                 processor_cpu_load_info_data_t *pinfo;
998                 mach_msg_type_number_t info_count;
999
1000                 if (host_processor_info (mach_host_self (),
1001                                          PROCESSOR_CPU_LOAD_INFO,
1002                                          &cpus,
1003                                          (processor_info_array_t*)&pinfo,
1004                                          &info_count) == 0)
1005                 {
1006                     int i;
1007                     cpus = min(cpus,out_cpus);
1008                     len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus;
1009                     sppi = RtlAllocateHeap(GetProcessHeap(), 0,len);
1010                     for (i = 0; i < cpus; i++)
1011                     {
1012                         sppi[i].liIdleTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_IDLE];
1013                         sppi[i].liKernelTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_SYSTEM];
1014                         sppi[i].liUserTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_USER];
1015                     }
1016                     vm_deallocate (mach_task_self (), (vm_address_t) pinfo, info_count * sizeof(natural_t));
1017                 }
1018             }
1019 #else
1020             {
1021                 FILE *cpuinfo = fopen("/proc/stat","r");
1022                 if (cpuinfo)
1023                 {
1024                     unsigned usr,nice,sys;
1025                     unsigned long idle;
1026                     int count;
1027                     char name[10];
1028                     char line[255];
1029
1030                     /* first line is combined usage */
1031                     if (fgets(line,255,cpuinfo))
1032                         count = sscanf(line,"%s %u %u %u %lu",name, &usr, &nice,
1033                                    &sys, &idle);
1034                     else
1035                         count = 0;
1036                     /* we set this up in the for older non-smp enabled kernels */
1037                     if (count == 5 && strcmp(name,"cpu")==0)
1038                     {
1039                         sppi = RtlAllocateHeap(GetProcessHeap(), 0,
1040                                                sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
1041                         sppi->liIdleTime.QuadPart = idle;
1042                         sppi->liKernelTime.QuadPart = sys;
1043                         sppi->liUserTime.QuadPart = usr;
1044                         cpus = 1;
1045                         len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
1046                     }
1047
1048                     do
1049                     {
1050                         if (fgets(line,255,cpuinfo))
1051                             count = sscanf(line,"%s %u %u %u %lu",name, &usr,
1052                                        &nice, &sys, &idle);
1053                         else
1054                             count = 0;
1055                         if (count == 5 && strncmp(name,"cpu",3)==0)
1056                         {
1057                             out_cpus --;
1058                             if (name[3]=='0') /* first cpu */
1059                             {
1060                                 sppi->liIdleTime.QuadPart = idle;
1061                                 sppi->liKernelTime.QuadPart = sys;
1062                                 sppi->liUserTime.QuadPart = usr;
1063                             }
1064                             else /* new cpu */
1065                             {
1066                                 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (cpus+1);
1067                                 sppi = RtlReAllocateHeap(GetProcessHeap(), 0, sppi, len);
1068                                 sppi[cpus].liIdleTime.QuadPart = idle;
1069                                 sppi[cpus].liKernelTime.QuadPart = sys;
1070                                 sppi[cpus].liUserTime.QuadPart = usr;
1071                                 cpus++;
1072                             }
1073                         }
1074                         else
1075                             break;
1076                     } while (out_cpus > 0);
1077                     fclose(cpuinfo);
1078                 }
1079             }
1080 #endif
1081
1082             if (cpus == 0)
1083             {
1084                 static int i = 1;
1085
1086                 sppi = RtlAllocateHeap(GetProcessHeap(),0,sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
1087
1088                 memset(sppi, 0 , sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
1089                 FIXME("stub info_class SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n");
1090
1091                 /* many programs expect these values to change so fake change */
1092                 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
1093                 sppi->liKernelTime.QuadPart = 1 * i;
1094                 sppi->liUserTime.QuadPart = 2 * i;
1095                 sppi->liIdleTime.QuadPart = 3 * i;
1096                 i++;
1097             }
1098
1099             if (Length >= len)
1100             {
1101                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1102                 else memcpy( SystemInformation, sppi, len);
1103             }
1104             else ret = STATUS_INFO_LENGTH_MISMATCH;
1105
1106             RtlFreeHeap(GetProcessHeap(),0,sppi);
1107         }
1108         break;
1109     case SystemModuleInformation:
1110         /* FIXME: should be system-wide */
1111         if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1112         else ret = LdrQueryProcessModuleInformation( SystemInformation, Length, &len );
1113         break;
1114     case SystemHandleInformation:
1115         {
1116             SYSTEM_HANDLE_INFORMATION shi;
1117
1118             memset(&shi, 0, sizeof(shi));
1119             len = sizeof(shi);
1120
1121             if ( Length >= len)
1122             {
1123                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1124                 else memcpy( SystemInformation, &shi, len);
1125             }
1126             else ret = STATUS_INFO_LENGTH_MISMATCH;
1127             FIXME("info_class SYSTEM_HANDLE_INFORMATION\n");
1128         }
1129         break;
1130     case SystemCacheInformation:
1131         {
1132             SYSTEM_CACHE_INFORMATION sci;
1133
1134             memset(&sci, 0, sizeof(sci)); /* FIXME */
1135             len = sizeof(sci);
1136
1137             if ( Length >= len)
1138             {
1139                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1140                 else memcpy( SystemInformation, &sci, len);
1141             }
1142             else ret = STATUS_INFO_LENGTH_MISMATCH;
1143             FIXME("info_class SYSTEM_CACHE_INFORMATION\n");
1144         }
1145         break;
1146     case SystemInterruptInformation:
1147         {
1148             SYSTEM_INTERRUPT_INFORMATION sii;
1149
1150             memset(&sii, 0, sizeof(sii));
1151             len = sizeof(sii);
1152
1153             if ( Length >= len)
1154             {
1155                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1156                 else memcpy( SystemInformation, &sii, len);
1157             }
1158             else ret = STATUS_INFO_LENGTH_MISMATCH;
1159             FIXME("info_class SYSTEM_INTERRUPT_INFORMATION\n");
1160         }
1161         break;
1162     case SystemKernelDebuggerInformation:
1163         {
1164             SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
1165
1166             skdi.DebuggerEnabled = FALSE;
1167             skdi.DebuggerNotPresent = TRUE;
1168             len = sizeof(skdi);
1169
1170             if ( Length >= len)
1171             {
1172                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1173                 else memcpy( SystemInformation, &skdi, len);
1174             }
1175             else ret = STATUS_INFO_LENGTH_MISMATCH;
1176         }
1177         break;
1178     case SystemRegistryQuotaInformation:
1179         {
1180             /* Something to do with the size of the registry             *
1181              * Since we don't have a size limitation, fake it            *
1182              * This is almost certainly wrong.                           *
1183              * This sets each of the three words in the struct to 32 MB, *
1184              * which is enough to make the IE 5 installer happy.         */
1185             SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
1186
1187             srqi.RegistryQuotaAllowed = 0x2000000;
1188             srqi.RegistryQuotaUsed = 0x200000;
1189             srqi.Reserved1 = (void*)0x200000;
1190             len = sizeof(srqi);
1191
1192             if ( Length >= len)
1193             {
1194                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1195                 else
1196                 {
1197                     FIXME("SystemRegistryQuotaInformation: faking max registry size of 32 MB\n");
1198                     memcpy( SystemInformation, &srqi, len);
1199                 }
1200             }
1201             else ret = STATUS_INFO_LENGTH_MISMATCH;
1202         }
1203         break;
1204     default:
1205         FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
1206               SystemInformationClass,SystemInformation,Length,ResultLength);
1207
1208         /* Several Information Classes are not implemented on Windows and return 2 different values 
1209          * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
1210          * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
1211         */
1212         ret = STATUS_INVALID_INFO_CLASS;
1213     }
1214
1215     if (ResultLength) *ResultLength = len;
1216
1217     return ret;
1218 }
1219
1220 /******************************************************************************
1221  * NtSetSystemInformation [NTDLL.@]
1222  * ZwSetSystemInformation [NTDLL.@]
1223  */
1224 NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG Length)
1225 {
1226     FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length);
1227     return STATUS_SUCCESS;
1228 }
1229
1230 /******************************************************************************
1231  *  NtCreatePagingFile          [NTDLL.@]
1232  *  ZwCreatePagingFile          [NTDLL.@]
1233  */
1234 NTSTATUS WINAPI NtCreatePagingFile(
1235         PUNICODE_STRING PageFileName,
1236         PLARGE_INTEGER MinimumSize,
1237         PLARGE_INTEGER MaximumSize,
1238         PLARGE_INTEGER ActualSize)
1239 {
1240     FIXME("(%p %p %p %p) stub\n", PageFileName, MinimumSize, MaximumSize, ActualSize);
1241     return STATUS_SUCCESS;
1242 }
1243
1244 /******************************************************************************
1245  *  NtDisplayString                             [NTDLL.@]
1246  *
1247  * writes a string to the nt-textmode screen eg. during startup
1248  */
1249 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
1250 {
1251     STRING stringA;
1252     NTSTATUS ret;
1253
1254     if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
1255     {
1256         MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
1257         RtlFreeAnsiString( &stringA );
1258     }
1259     return ret;
1260 }
1261
1262 /******************************************************************************
1263  *  NtInitiatePowerAction                       [NTDLL.@]
1264  *
1265  */
1266 NTSTATUS WINAPI NtInitiatePowerAction(
1267         IN POWER_ACTION SystemAction,
1268         IN SYSTEM_POWER_STATE MinSystemState,
1269         IN ULONG Flags,
1270         IN BOOLEAN Asynchronous)
1271 {
1272         FIXME("(%d,%d,0x%08x,%d),stub\n",
1273                 SystemAction,MinSystemState,Flags,Asynchronous);
1274         return STATUS_NOT_IMPLEMENTED;
1275 }
1276         
1277
1278 /******************************************************************************
1279  *  NtPowerInformation                          [NTDLL.@]
1280  *
1281  */
1282 NTSTATUS WINAPI NtPowerInformation(
1283         IN POWER_INFORMATION_LEVEL InformationLevel,
1284         IN PVOID lpInputBuffer,
1285         IN ULONG nInputBufferSize,
1286         IN PVOID lpOutputBuffer,
1287         IN ULONG nOutputBufferSize)
1288 {
1289         TRACE("(%d,%p,%d,%p,%d)\n",
1290                 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
1291         switch(InformationLevel) {
1292                 case SystemPowerCapabilities: {
1293                         PSYSTEM_POWER_CAPABILITIES PowerCaps = lpOutputBuffer;
1294                         FIXME("semi-stub: SystemPowerCapabilities\n");
1295                         if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
1296                                 return STATUS_BUFFER_TOO_SMALL;
1297                         /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
1298                         PowerCaps->PowerButtonPresent = TRUE;
1299                         PowerCaps->SleepButtonPresent = FALSE;
1300                         PowerCaps->LidPresent = FALSE;
1301                         PowerCaps->SystemS1 = TRUE;
1302                         PowerCaps->SystemS2 = FALSE;
1303                         PowerCaps->SystemS3 = FALSE;
1304                         PowerCaps->SystemS4 = TRUE;
1305                         PowerCaps->SystemS5 = TRUE;
1306                         PowerCaps->HiberFilePresent = TRUE;
1307                         PowerCaps->FullWake = TRUE;
1308                         PowerCaps->VideoDimPresent = FALSE;
1309                         PowerCaps->ApmPresent = FALSE;
1310                         PowerCaps->UpsPresent = FALSE;
1311                         PowerCaps->ThermalControl = FALSE;
1312                         PowerCaps->ProcessorThrottle = FALSE;
1313                         PowerCaps->ProcessorMinThrottle = 100;
1314                         PowerCaps->ProcessorMaxThrottle = 100;
1315                         PowerCaps->DiskSpinDown = TRUE;
1316                         PowerCaps->SystemBatteriesPresent = FALSE;
1317                         PowerCaps->BatteriesAreShortTerm = FALSE;
1318                         PowerCaps->BatteryScale[0].Granularity = 0;
1319                         PowerCaps->BatteryScale[0].Capacity = 0;
1320                         PowerCaps->BatteryScale[1].Granularity = 0;
1321                         PowerCaps->BatteryScale[1].Capacity = 0;
1322                         PowerCaps->BatteryScale[2].Granularity = 0;
1323                         PowerCaps->BatteryScale[2].Capacity = 0;
1324                         PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1325                         PowerCaps->SoftLidWake = PowerSystemUnspecified;
1326                         PowerCaps->RtcWake = PowerSystemSleeping1;
1327                         PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1328                         PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1329                         return STATUS_SUCCESS;
1330                 }
1331                 default:
1332                         /* FIXME: Needed by .NET Framework */
1333                         WARN("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1334                         return STATUS_NOT_IMPLEMENTED;
1335         }
1336 }
1337
1338 /******************************************************************************
1339  *  NtShutdownSystem                            [NTDLL.@]
1340  *
1341  */
1342 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1343 {
1344     FIXME("%d\n",Action);
1345     return STATUS_SUCCESS;
1346 }
1347
1348 /******************************************************************************
1349  *  NtAllocateLocallyUniqueId (NTDLL.@)
1350  */
1351 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1352 {
1353     NTSTATUS status;
1354
1355     TRACE("%p\n", Luid);
1356
1357     if (!Luid)
1358         return STATUS_ACCESS_VIOLATION;
1359
1360     SERVER_START_REQ( allocate_locally_unique_id )
1361     {
1362         status = wine_server_call( req );
1363         if (!status)
1364         {
1365             Luid->LowPart = reply->luid.low_part;
1366             Luid->HighPart = reply->luid.high_part;
1367         }
1368     }
1369     SERVER_END_REQ;
1370
1371     return status;
1372 }
1373
1374 /******************************************************************************
1375  *        VerSetConditionMask   (NTDLL.@)
1376  */
1377 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1378                                       BYTE dwConditionMask)
1379 {
1380     if(dwTypeBitMask == 0)
1381         return dwlConditionMask;
1382     dwConditionMask &= 0x07;
1383     if(dwConditionMask == 0)
1384         return dwlConditionMask;
1385
1386     if(dwTypeBitMask & VER_PRODUCT_TYPE)
1387         dwlConditionMask |= dwConditionMask << 7*3;
1388     else if (dwTypeBitMask & VER_SUITENAME)
1389         dwlConditionMask |= dwConditionMask << 6*3;
1390     else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1391         dwlConditionMask |= dwConditionMask << 5*3;
1392     else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1393         dwlConditionMask |= dwConditionMask << 4*3;
1394     else if (dwTypeBitMask & VER_PLATFORMID)
1395         dwlConditionMask |= dwConditionMask << 3*3;
1396     else if (dwTypeBitMask & VER_BUILDNUMBER)
1397         dwlConditionMask |= dwConditionMask << 2*3;
1398     else if (dwTypeBitMask & VER_MAJORVERSION)
1399         dwlConditionMask |= dwConditionMask << 1*3;
1400     else if (dwTypeBitMask & VER_MINORVERSION)
1401         dwlConditionMask |= dwConditionMask << 0*3;
1402     return dwlConditionMask;
1403 }
1404
1405 /******************************************************************************
1406  *  NtAccessCheckAndAuditAlarm   (NTDLL.@)
1407  *  ZwAccessCheckAndAuditAlarm   (NTDLL.@)
1408  */
1409 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
1410                                            PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
1411                                            ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
1412                                            PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
1413 {
1414     FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
1415           debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
1416           GrantedAccess, AccessStatus, GenerateOnClose);
1417
1418     return STATUS_NOT_IMPLEMENTED;
1419 }