kernel32: Partial CompareStringEx implementation.
[wine] / dlls / kernel32 / cpu.c
1 /*
2  * What processor?
3  *
4  * Copyright 1995,1997 Morten Welinder
5  * Copyright 1997-1998 Marcus Meissner
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #ifdef HAVE_SYS_TIME_H
29 # include <sys/time.h>
30 #endif
31
32
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "ntstatus.h"
36 #define WIN32_NO_STATUS
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winnt.h"
40 #include "winternl.h"
41 #include "psapi.h"
42 #include "wine/unicode.h"
43 #include "wine/debug.h"
44 #include "ddk/wdm.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(reg);
47
48 #define SHARED_DATA     ((KSHARED_USER_DATA*)0x7ffe0000)
49
50 /****************************************************************************
51  *              QueryPerformanceCounter (KERNEL32.@)
52  *
53  * Get the current value of the performance counter.
54  * 
55  * PARAMS
56  *  counter [O] Destination for the current counter reading
57  *
58  * RETURNS
59  *  Success: TRUE. counter contains the current reading
60  *  Failure: FALSE.
61  *
62  * SEE ALSO
63  *  See QueryPerformanceFrequency.
64  */
65 BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter)
66 {
67     NtQueryPerformanceCounter( counter, NULL );
68     return TRUE;
69 }
70
71
72 /****************************************************************************
73  *              QueryPerformanceFrequency (KERNEL32.@)
74  *
75  * Get the resolution of the performance counter.
76  *
77  * PARAMS
78  *  frequency [O] Destination for the counter resolution
79  *
80  * RETURNS
81  *  Success. TRUE. Frequency contains the resolution of the counter.
82  *  Failure: FALSE.
83  *
84  * SEE ALSO
85  *  See QueryPerformanceCounter.
86  */
87 BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency)
88 {
89     LARGE_INTEGER counter;
90     NtQueryPerformanceCounter( &counter, frequency );
91     return TRUE;
92 }
93
94
95 /***********************************************************************
96  *                      GetSystemInfo                   [KERNEL32.@]
97  *
98  * Get information about the system.
99  *
100  * RETURNS
101  *  Nothing.
102  *
103  * NOTES
104  * On the first call it creates cached values, so it doesn't have to determine
105  * them repeatedly. On Linux, the "/proc/cpuinfo" special file is used.
106  *
107  * It also creates a cached flag array for IsProcessorFeaturePresent().
108  */
109 VOID WINAPI GetSystemInfo(
110         LPSYSTEM_INFO si        /* [out] Destination for system information, may not be NULL */)
111 {
112     NTSTATUS                 nts;
113     SYSTEM_BASIC_INFORMATION sbi;
114     SYSTEM_CPU_INFORMATION   sci;
115
116     TRACE("si=0x%p\n", si);
117
118     if ((nts = NtQuerySystemInformation( SystemBasicInformation, &sbi, sizeof(sbi), NULL )) != STATUS_SUCCESS ||
119         (nts = NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL )) != STATUS_SUCCESS)
120     {
121         SetLastError(RtlNtStatusToDosError(nts));
122         return;
123     }
124
125     si->u.s.wProcessorArchitecture  = sci.Architecture;
126     si->u.s.wReserved               = 0;
127     si->dwPageSize                  = sbi.PageSize;
128     si->lpMinimumApplicationAddress = sbi.LowestUserAddress;
129     si->lpMaximumApplicationAddress = sbi.HighestUserAddress;
130     si->dwActiveProcessorMask       = sbi.ActiveProcessorsAffinityMask;
131     si->dwNumberOfProcessors        = sbi.NumberOfProcessors;
132
133     switch (sci.Architecture)
134     {
135     case PROCESSOR_ARCHITECTURE_INTEL:
136         switch (sci.Level)
137         {
138         case 3:  si->dwProcessorType = PROCESSOR_INTEL_386;     break;
139         case 4:  si->dwProcessorType = PROCESSOR_INTEL_486;     break;
140         case 5:
141         case 6:  si->dwProcessorType = PROCESSOR_INTEL_PENTIUM; break;
142         default: si->dwProcessorType = PROCESSOR_INTEL_PENTIUM; break;
143         }
144         break;
145     case PROCESSOR_ARCHITECTURE_PPC:
146         switch (sci.Level)
147         {
148         case 1:  si->dwProcessorType = PROCESSOR_PPC_601;       break;
149         case 3:
150         case 6:  si->dwProcessorType = PROCESSOR_PPC_603;       break;
151         case 4:  si->dwProcessorType = PROCESSOR_PPC_604;       break;
152         case 9:  si->dwProcessorType = PROCESSOR_PPC_604;       break;
153         case 20: si->dwProcessorType = PROCESSOR_PPC_620;       break;
154         default: si->dwProcessorType = 0;
155         }
156         break;
157     case PROCESSOR_ARCHITECTURE_AMD64:
158         si->dwProcessorType = PROCESSOR_AMD_X8664;
159         break;
160     case PROCESSOR_ARCHITECTURE_ARM:
161         switch (sci.Level)
162         {
163         case 4:  si->dwProcessorType = PROCESSOR_ARM_7TDMI;     break;
164         default: si->dwProcessorType = PROCESSOR_ARM920;
165         }
166         break;
167     default:
168         FIXME("Unknown processor architecture %x\n", sci.Architecture);
169         si->dwProcessorType = 0;
170     }
171     si->dwAllocationGranularity     = sbi.AllocationGranularity;
172     si->wProcessorLevel             = sci.Level;
173     si->wProcessorRevision          = sci.Revision;
174 }
175
176
177 /***********************************************************************
178  *                      GetNativeSystemInfo             [KERNEL32.@]
179  */
180 VOID WINAPI GetNativeSystemInfo(
181     LPSYSTEM_INFO si    /* [out] Destination for system information, may not be NULL */)
182 {
183     BOOL is_wow64;
184
185     GetSystemInfo(si); 
186
187     IsWow64Process(GetCurrentProcess(), &is_wow64);
188     if (is_wow64)
189     {
190         if (si->u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
191         {
192             si->u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
193             si->dwProcessorType = PROCESSOR_AMD_X8664;
194         }
195         else
196         {
197             FIXME("Add the proper information for %d in wow64 mode\n",
198                   si->u.s.wProcessorArchitecture);
199         }
200     }
201 }
202
203 /***********************************************************************
204  *                      IsProcessorFeaturePresent       [KERNEL32.@]
205  *
206  * Determine if the cpu supports a given feature.
207  * 
208  * RETURNS
209  *  TRUE, If the processor supports feature,
210  *  FALSE otherwise.
211  */
212 BOOL WINAPI IsProcessorFeaturePresent (
213         DWORD feature   /* [in] Feature number, (PF_ constants from "winnt.h") */) 
214 {
215   if (feature < 64)
216     return SHARED_DATA->ProcessorFeatures[feature];
217   else
218     return FALSE;
219 }
220
221 /***********************************************************************
222  *           K32GetPerformanceInfo (KERNEL32.@)
223  */
224 BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
225 {
226     NTSTATUS status;
227
228     TRACE( "(%p, %d)\n", info, size );
229
230     status = NtQuerySystemInformation( SystemPerformanceInformation, info, size, NULL );
231
232     if (status)
233     {
234         SetLastError( RtlNtStatusToDosError( status ) );
235         return FALSE;
236     }
237     return TRUE;
238 }