Set SE_GROUP_ENABLED in Attributes of Administrators SID during
[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  *      Process object
73  */
74
75 /******************************************************************************
76  *  NtTerminateProcess                  [NTDLL.@]
77  *
78  *  Native applications must kill themselves when done
79  */
80 NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
81 {
82     NTSTATUS ret;
83     BOOL self;
84     SERVER_START_REQ( terminate_process )
85     {
86         req->handle    = handle;
87         req->exit_code = exit_code;
88         ret = wine_server_call( req );
89         self = !ret && reply->self;
90     }
91     SERVER_END_REQ;
92     if (self) exit( exit_code );
93     return ret;
94 }
95
96 /******************************************************************************
97 *  NtQueryInformationProcess            [NTDLL.@]
98 *  ZwQueryInformationProcess            [NTDLL.@]
99 *
100 */
101 NTSTATUS WINAPI NtQueryInformationProcess(
102         IN HANDLE ProcessHandle,
103         IN PROCESSINFOCLASS ProcessInformationClass,
104         OUT PVOID ProcessInformation,
105         IN ULONG ProcessInformationLength,
106         OUT PULONG ReturnLength)
107 {
108         NTSTATUS ret = STATUS_SUCCESS;
109         ULONG len = 0;
110
111         switch (ProcessInformationClass) {
112         case ProcessDebugPort:
113                 /* "These are not the debuggers you are looking for." */
114                 /* set it to 0 aka "no debugger" to satisfy copy protections */
115                 if (ProcessInformationLength == 4)
116                 {
117                         memset(ProcessInformation,0,ProcessInformationLength);
118                         len = 4;
119                 }
120                 else
121                         ret = STATUS_INFO_LENGTH_MISMATCH;
122                 break;
123         case ProcessWow64Information:
124                 if (ProcessInformationLength == 4)
125                 {
126                         memset(ProcessInformation,0,ProcessInformationLength);
127                         len = 4;
128                 }
129                 else
130                         ret = STATUS_INFO_LENGTH_MISMATCH;
131                 break;
132         default:
133                 FIXME("(%p,0x%08x,%p,0x%08lx,%p),stub!\n",
134                         ProcessHandle,ProcessInformationClass,
135                         ProcessInformation,ProcessInformationLength,
136                         ReturnLength
137                 );
138                 break;
139         }
140
141         if (ReturnLength)
142                 *ReturnLength = len;
143
144         return ret;
145 }
146
147 /******************************************************************************
148  * NtSetInformationProcess [NTDLL.@]
149  * ZwSetInformationProcess [NTDLL.@]
150  */
151 NTSTATUS WINAPI NtSetInformationProcess(
152         IN HANDLE ProcessHandle,
153         IN PROCESSINFOCLASS ProcessInformationClass,
154         IN PVOID ProcessInformation,
155         IN ULONG ProcessInformationLength)
156 {
157         FIXME("(%p,0x%08x,%p,0x%08lx) stub\n",
158         ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength);
159         return 0;
160 }
161
162 /*
163  *      Thread
164  */
165
166 /******************************************************************************
167  *  NtSetInformationThread              [NTDLL.@]
168  *  ZwSetInformationThread              [NTDLL.@]
169  */
170 NTSTATUS WINAPI NtSetInformationThread(
171         HANDLE ThreadHandle,
172         THREADINFOCLASS ThreadInformationClass,
173         PVOID ThreadInformation,
174         ULONG ThreadInformationLength)
175 {
176         FIXME("(%p,0x%08x,%p,0x%08lx),stub!\n",
177         ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
178         return 0;
179 }
180
181 /*
182  *      Token
183  */
184
185 /******************************************************************************
186  *  NtDuplicateToken            [NTDLL.@]
187  *  ZwDuplicateToken            [NTDLL.@]
188  */
189 NTSTATUS WINAPI NtDuplicateToken(
190         IN HANDLE ExistingToken,
191         IN ACCESS_MASK DesiredAccess,
192         IN POBJECT_ATTRIBUTES ObjectAttributes,
193         IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
194         IN TOKEN_TYPE TokenType,
195         OUT PHANDLE NewToken)
196 {
197         FIXME("(%p,0x%08lx,%p,0x%08x,0x%08x,%p),stub!\n",
198         ExistingToken, DesiredAccess, ObjectAttributes,
199         ImpersonationLevel, TokenType, NewToken);
200         dump_ObjectAttributes(ObjectAttributes);
201         return 0;
202 }
203
204 /******************************************************************************
205  *  NtOpenProcessToken          [NTDLL.@]
206  *  ZwOpenProcessToken          [NTDLL.@]
207  */
208 NTSTATUS WINAPI NtOpenProcessToken(
209         HANDLE ProcessHandle,
210         DWORD DesiredAccess,
211         HANDLE *TokenHandle)
212 {
213     NTSTATUS ret;
214
215     TRACE("(%p,0x%08lx,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
216
217     SERVER_START_REQ( open_token )
218     {
219         req->handle = ProcessHandle;
220         req->flags  = 0;
221         ret = wine_server_call( req );
222         if (!ret) *TokenHandle = reply->token;
223     }
224     SERVER_END_REQ;
225
226     return ret;
227 }
228
229 /******************************************************************************
230  *  NtOpenThreadToken           [NTDLL.@]
231  *  ZwOpenThreadToken           [NTDLL.@]
232  */
233 NTSTATUS WINAPI NtOpenThreadToken(
234         HANDLE ThreadHandle,
235         DWORD DesiredAccess,
236         BOOLEAN OpenAsSelf,
237         HANDLE *TokenHandle)
238 {
239     NTSTATUS ret;
240
241     TRACE("(%p,0x%08lx,0x%08x,%p)\n",
242           ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
243
244     SERVER_START_REQ( open_token )
245     {
246         req->handle = ThreadHandle;
247         req->flags  = OPEN_TOKEN_THREAD;
248         if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
249         ret = wine_server_call( req );
250         if (!ret) *TokenHandle = reply->token;
251     }
252     SERVER_END_REQ;
253
254     return ret;
255 }
256
257 /******************************************************************************
258  *  NtAdjustPrivilegesToken             [NTDLL.@]
259  *  ZwAdjustGroupsToken         [NTDLL.@]
260  *
261  * FIXME: parameters unsafe
262  */
263 NTSTATUS WINAPI NtAdjustPrivilegesToken(
264         IN HANDLE TokenHandle,
265         IN BOOLEAN DisableAllPrivileges,
266         IN PTOKEN_PRIVILEGES NewState,
267         IN DWORD BufferLength,
268         OUT PTOKEN_PRIVILEGES PreviousState,
269         OUT PDWORD ReturnLength)
270 {
271         FIXME("(%p,0x%08x,%p,0x%08lx,%p,%p),stub!\n",
272         TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
273         return 0;
274 }
275
276 /******************************************************************************
277 *  NtQueryInformationToken              [NTDLL.@]
278 *  ZwQueryInformationToken              [NTDLL.@]
279 *
280 * NOTES
281 *  Buffer for TokenUser:
282 *   0x00 TOKEN_USER the PSID field points to the SID
283 *   0x08 SID
284 *
285 */
286 NTSTATUS WINAPI NtQueryInformationToken(
287         HANDLE token,
288         DWORD tokeninfoclass,
289         LPVOID tokeninfo,
290         DWORD tokeninfolength,
291         LPDWORD retlen )
292 {
293     unsigned int len = 0;
294
295     FIXME("(%p,%ld,%p,%ld,%p): stub\n",
296           token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
297
298     switch (tokeninfoclass)
299     {
300     case TokenUser:
301         len = sizeof(TOKEN_USER) + sizeof(SID);
302         break;
303     case TokenGroups:
304         len = sizeof(TOKEN_GROUPS);
305         break;
306     case TokenPrivileges:
307         len = sizeof(TOKEN_PRIVILEGES);
308         break;
309     case TokenOwner:
310         len = sizeof(TOKEN_OWNER);
311         break;
312     case TokenPrimaryGroup:
313         len = sizeof(TOKEN_PRIMARY_GROUP);
314         break;
315     case TokenDefaultDacl:
316         len = sizeof(TOKEN_DEFAULT_DACL);
317         break;
318     case TokenSource:
319         len = sizeof(TOKEN_SOURCE);
320         break;
321     case TokenType:
322         len = sizeof (TOKEN_TYPE);
323         break;
324 #if 0
325     case TokenImpersonationLevel:
326     case TokenStatistics:
327 #endif /* 0 */
328     }
329
330     /* FIXME: what if retlen == NULL ? */
331     *retlen = len;
332
333     if (tokeninfolength < len)
334         return STATUS_BUFFER_TOO_SMALL;
335
336     switch (tokeninfoclass)
337     {
338     case TokenUser:
339         if( tokeninfo )
340         {
341             TOKEN_USER * tuser = tokeninfo;
342             PSID sid = (PSID) (tuser + 1);
343             SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
344             RtlInitializeSid(sid, &localSidAuthority, 1);
345             *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
346             tuser->User.Sid = sid;
347         }
348         break;
349     case TokenGroups:
350         if (tokeninfo)
351         {
352             TOKEN_GROUPS *tgroups = tokeninfo;
353             SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
354
355             /* we need to show admin privileges ! */
356             tgroups->GroupCount = 1;
357             tgroups->Groups->Attributes = SE_GROUP_ENABLED;
358             RtlAllocateAndInitializeSid( &sid,
359                                          2,
360                                          SECURITY_BUILTIN_DOMAIN_RID,
361                                          DOMAIN_ALIAS_RID_ADMINS,
362                                          0, 0, 0, 0, 0, 0,
363                                          &(tgroups->Groups->Sid));
364         }
365         break;
366     case TokenPrivileges:
367         if (tokeninfo)
368         {
369             TOKEN_PRIVILEGES *tpriv = tokeninfo;
370             tpriv->PrivilegeCount = 1;
371         }
372         break;
373     }
374     return 0;
375 }
376
377 /*
378  *      Section
379  */
380
381 /******************************************************************************
382  *  NtQuerySection      [NTDLL.@]
383  */
384 NTSTATUS WINAPI NtQuerySection(
385         IN HANDLE SectionHandle,
386         IN PVOID SectionInformationClass,
387         OUT PVOID SectionInformation,
388         IN ULONG Length,
389         OUT PULONG ResultLength)
390 {
391         FIXME("(%p,%p,%p,0x%08lx,%p) stub!\n",
392         SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
393         return 0;
394 }
395
396 /*
397  *      ports
398  */
399
400 /******************************************************************************
401  *  NtCreatePort                [NTDLL.@]
402  *  ZwCreatePort                [NTDLL.@]
403  */
404 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
405                              DWORD MaxConnectInfoLength,DWORD MaxDataLength,DWORD unknown)
406 {
407   FIXME("(%p,%p,0x%08lx,0x%08lx,0x%08lx),stub!\n",PortHandle,ObjectAttributes,
408         MaxConnectInfoLength,MaxDataLength,unknown);
409   return 0;
410 }
411
412 /******************************************************************************
413  *  NtConnectPort               [NTDLL.@]
414  *  ZwConnectPort               [NTDLL.@]
415  */
416 NTSTATUS WINAPI NtConnectPort(PHANDLE PortHandle,PUNICODE_STRING PortName,PVOID Unknown1,
417                               PLPCSECTIONINFO sectionInfo,PLPCSECTIONMAPINFO mapInfo,PVOID Unknown2,
418                               PVOID ConnectInfo,PDWORD pConnectInfoLength)
419 {
420   FIXME("(%p,%s,%p,%p,%p,%p,%p,%p (%ld)),stub!\n",PortHandle,debugstr_w(PortName->Buffer),Unknown1,
421         sectionInfo,mapInfo,Unknown2,ConnectInfo,pConnectInfoLength,pConnectInfoLength?*pConnectInfoLength:-1);
422   if(ConnectInfo && pConnectInfoLength)
423     TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
424   return 0;
425 }
426
427 /******************************************************************************
428  *  NtListenPort                [NTDLL.@]
429  *  ZwListenPort                [NTDLL.@]
430  */
431 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPCMESSAGE pLpcMessage)
432 {
433   FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
434   return 0;
435 }
436
437 /******************************************************************************
438  *  NtAcceptConnectPort [NTDLL.@]
439  *  ZwAcceptConnectPort [NTDLL.@]
440  */
441 NTSTATUS WINAPI NtAcceptConnectPort(PHANDLE PortHandle,DWORD Unknown,PLPCMESSAGE pLpcMessage,
442                                     DWORD acceptIt,DWORD Unknown2,PLPCSECTIONMAPINFO mapInfo)
443 {
444   FIXME("(%p,0x%08lx,%p,0x%08lx,0x%08lx,%p),stub!\n",PortHandle,Unknown,pLpcMessage,acceptIt,Unknown2,mapInfo);
445   return 0;
446 }
447
448 /******************************************************************************
449  *  NtCompleteConnectPort       [NTDLL.@]
450  *  ZwCompleteConnectPort       [NTDLL.@]
451  */
452 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
453 {
454   FIXME("(%p),stub!\n",PortHandle);
455   return 0;
456 }
457
458 /******************************************************************************
459  *  NtRegisterThreadTerminatePort       [NTDLL.@]
460  *  ZwRegisterThreadTerminatePort       [NTDLL.@]
461  */
462 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
463 {
464   FIXME("(%p),stub!\n",PortHandle);
465   return 0;
466 }
467
468 /******************************************************************************
469  *  NtRequestWaitReplyPort              [NTDLL.@]
470  *  ZwRequestWaitReplyPort              [NTDLL.@]
471  */
472 NTSTATUS WINAPI NtRequestWaitReplyPort(HANDLE PortHandle,PLPCMESSAGE pLpcMessageIn,PLPCMESSAGE pLpcMessageOut)
473 {
474   FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
475   if(pLpcMessageIn)
476   {
477     TRACE("Message to send:\n");
478     TRACE("\tActualMessageLength = %d\n",pLpcMessageIn->ActualMessageLength);
479     TRACE("\tTotalMessageLength  = %d\n",pLpcMessageIn->TotalMessageLength);
480     TRACE("\tMessageType         = %ld\n",pLpcMessageIn->MessageType);
481     TRACE("\tClientProcessId     = %ld\n",pLpcMessageIn->ClientProcessId);
482     TRACE("\tClientThreadId      = %ld\n",pLpcMessageIn->ClientThreadId);
483     TRACE("\tMessageId           = %ld\n",pLpcMessageIn->MessageId);
484     TRACE("\tSharedSectionSize   = %ld\n",pLpcMessageIn->SharedSectionSize);
485     TRACE("\tMessageData         = %s\n",debugstr_an(pLpcMessageIn->MessageData,pLpcMessageIn->ActualMessageLength));
486   }
487   return 0;
488 }
489
490 /******************************************************************************
491  *  NtReplyWaitReceivePort      [NTDLL.@]
492  *  ZwReplyWaitReceivePort      [NTDLL.@]
493  */
494 NTSTATUS WINAPI NtReplyWaitReceivePort(HANDLE PortHandle,PDWORD Unknown,PLPCMESSAGE pLpcMessageOut,PLPCMESSAGE pLpcMessageIn)
495 {
496   FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,Unknown,pLpcMessageOut,pLpcMessageIn);
497   return 0;
498 }
499
500 /*
501  *      Misc
502  */
503
504  /******************************************************************************
505  *  NtSetIntervalProfile        [NTDLL.@]
506  *  ZwSetIntervalProfile        [NTDLL.@]
507  */
508 NTSTATUS WINAPI NtSetIntervalProfile(DWORD x1,DWORD x2) {
509         FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
510         return 0;
511 }
512
513 /******************************************************************************
514  *  NtQueryPerformanceCounter   [NTDLL.@]
515  */
516 NTSTATUS WINAPI NtQueryPerformanceCounter(
517         IN PLARGE_INTEGER Counter,
518         IN PLARGE_INTEGER Frequency)
519 {
520         FIXME("(%p, 0%p) stub\n",
521         Counter, Frequency);
522         return 0;
523 }
524
525 /******************************************************************************
526  *  NtCreateMailslotFile        [NTDLL.@]
527  *  ZwCreateMailslotFile        [NTDLL.@]
528  */
529 NTSTATUS WINAPI NtCreateMailslotFile(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8)
530 {
531         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);
532         return 0;
533 }
534
535 /******************************************************************************
536  * NtQuerySystemInformation [NTDLL.@]
537  * ZwQuerySystemInformation [NTDLL.@]
538  *
539  * ARGUMENTS:
540  *  SystemInformationClass      Index to a certain information structure
541  *      SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
542  *      SystemCacheInformation          SYSTEM_CACHE_INFORMATION
543  *      SystemConfigurationInformation  CONFIGURATION_INFORMATION
544  *      observed (class/len):
545  *              0x0/0x2c
546  *              0x12/0x18
547  *              0x2/0x138
548  *              0x8/0x600
549  *              0x25/0xc
550  *  SystemInformation   caller supplies storage for the information structure
551  *  Length              size of the structure
552  *  ResultLength        Data written
553  */
554 NTSTATUS WINAPI NtQuerySystemInformation(
555         IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
556         OUT PVOID SystemInformation,
557         IN ULONG Length,
558         OUT PULONG ResultLength)
559 {
560     switch(SystemInformationClass)
561     {
562     case 0x25:
563         /* Something to do with the size of the registry             *
564          * Since we don't have a size limitation, fake it            *
565          * This is almost certainly wrong.                           *
566          * This sets each of the three words in the struct to 32 MB, *
567          * which is enough to make the IE 5 installer happy.         */
568         FIXME("(0x%08x,%p,0x%08lx,%p) faking max registry size of 32 MB\n",
569               SystemInformationClass,SystemInformation,Length,ResultLength);
570         *(DWORD *)SystemInformation = 0x2000000;
571         *(((DWORD *)SystemInformation)+1) = 0x200000;
572         *(((DWORD *)SystemInformation)+2) = 0x200000;
573         break;
574
575     default:
576         FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
577               SystemInformationClass,SystemInformation,Length,ResultLength);
578         ZeroMemory (SystemInformation, Length);
579     }
580
581     return STATUS_SUCCESS;
582 }
583
584
585 /******************************************************************************
586  *  NtCreatePagingFile          [NTDLL.@]
587  *  ZwCreatePagingFile          [NTDLL.@]
588  */
589 NTSTATUS WINAPI NtCreatePagingFile(
590         IN PUNICODE_STRING PageFileName,
591         IN ULONG MiniumSize,
592         IN ULONG MaxiumSize,
593         OUT PULONG ActualSize)
594 {
595         FIXME("(%p(%s),0x%08lx,0x%08lx,%p),stub!\n",
596         PageFileName->Buffer, debugstr_w(PageFileName->Buffer),MiniumSize,MaxiumSize,ActualSize);
597         return 0;
598 }
599
600 /******************************************************************************
601  *  NtDisplayString                             [NTDLL.@]
602  *
603  * writes a string to the nt-textmode screen eg. during startup
604  */
605 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
606 {
607     STRING stringA;
608     NTSTATUS ret;
609
610     if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
611     {
612         MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
613         RtlFreeAnsiString( &stringA );
614     }
615     return ret;
616 }
617
618 /******************************************************************************
619  *  NtPowerInformation                          [NTDLL.@]
620  *
621  */
622 NTSTATUS WINAPI NtPowerInformation(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5)
623 {
624         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4,x5);
625         return 0;
626 }
627
628 /******************************************************************************
629  *  NtAllocateLocallyUniqueId (NTDLL.@)
630  *
631  * FIXME: the server should do that
632  */
633 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
634 {
635     static LUID luid;
636
637     FIXME("%p (0x%08lx%08lx)\n", Luid, luid.HighPart, luid.LowPart);
638
639     luid.LowPart++;
640     if (luid.LowPart==0)
641         luid.HighPart++;
642     Luid->HighPart = luid.HighPart;
643     Luid->LowPart = luid.LowPart;
644
645     return STATUS_SUCCESS;
646 }
647
648 /******************************************************************************
649  *        VerSetConditionMask   (NTDLL.@)
650  */
651 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
652                                       BYTE dwConditionMask)
653 {
654     if(dwTypeBitMask == 0)
655         return dwlConditionMask;
656     dwConditionMask &= 0x07;
657     if(dwConditionMask == 0)
658         return dwlConditionMask;
659
660     if(dwTypeBitMask & VER_PRODUCT_TYPE)
661         dwlConditionMask |= dwConditionMask << 7*3;
662     else if (dwTypeBitMask & VER_SUITENAME)
663         dwlConditionMask |= dwConditionMask << 6*3;
664     else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
665         dwlConditionMask |= dwConditionMask << 5*3;
666     else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
667         dwlConditionMask |= dwConditionMask << 4*3;
668     else if (dwTypeBitMask & VER_PLATFORMID)
669         dwlConditionMask |= dwConditionMask << 3*3;
670     else if (dwTypeBitMask & VER_BUILDNUMBER)
671         dwlConditionMask |= dwConditionMask << 2*3;
672     else if (dwTypeBitMask & VER_MAJORVERSION)
673         dwlConditionMask |= dwConditionMask << 1*3;
674     else if (dwTypeBitMask & VER_MINORVERSION)
675         dwlConditionMask |= dwConditionMask << 0*3;
676     return dwlConditionMask;
677 }