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