/[Sims3RigEditor]/trunk/ViewDDS/Processor.cs
ViewVC logotype

Contents of /trunk/ViewDDS/Processor.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 39 - (show annotations) (download)
Thu Aug 5 21:38:32 2010 UTC (9 years, 11 months ago) by william
File size: 13442 byte(s)
update Paint.NET DDS plugin, again...

1 /////////////////////////////////////////////////////////////////////////////////
2 // Paint.NET //
3 // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
4 // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
5 // See src/Resources/Files/License.txt for full licensing and attribution //
6 // details. //
7 // . //
8 /////////////////////////////////////////////////////////////////////////////////
9
10 using Microsoft.Win32;
11 using System;
12 using System.ComponentModel;
13 using System.Runtime.InteropServices;
14
15 namespace PaintDotNet.SystemLayer
16 {
17 /// <summary>
18 /// Provides static methods and properties related to the CPU.
19 /// </summary>
20 public static class Processor
21 {
22 private static int logicalCpuCount;
23 private static string cpuName;
24
25 static Processor()
26 {
27 logicalCpuCount = ConcreteLogicalCpuCount;
28 }
29
30 private static ProcessorArchitecture Convert(ushort wProcessorArchitecture)
31 {
32 ProcessorArchitecture platform;
33
34 switch (wProcessorArchitecture)
35 {
36 case NativeConstants.PROCESSOR_ARCHITECTURE_AMD64:
37 platform = ProcessorArchitecture.X64;
38 break;
39
40 case NativeConstants.PROCESSOR_ARCHITECTURE_INTEL:
41 platform = ProcessorArchitecture.X86;
42 break;
43
44 default:
45 case NativeConstants.PROCESSOR_ARCHITECTURE_UNKNOWN:
46 platform = ProcessorArchitecture.Unknown;
47 break;
48 }
49
50 return platform;
51 }
52
53 /// <summary>
54 /// Returns the processor architecture that the current process is using.
55 /// </summary>
56 /// <remarks>
57 /// Note that if the current process is 32-bit, but the OS is 64-bit, this
58 /// property will still return X86 and not X64.
59 /// </remarks>
60 public static ProcessorArchitecture Architecture
61 {
62 get
63 {
64 NativeStructs.SYSTEM_INFO sysInfo = new NativeStructs.SYSTEM_INFO();
65 NativeMethods.GetSystemInfo(ref sysInfo);
66 ProcessorArchitecture architecture = Convert(sysInfo.wProcessorArchitecture);
67 return architecture;
68 }
69 }
70
71 /// <summary>
72 /// Returns the processor architecture of the installed operating system.
73 /// </summary>
74 /// <remarks>
75 /// Note that this may differ from the Architecture property if, for instance,
76 /// this is a 32-bit process on a 64-bit OS.
77 /// </remarks>
78 public static ProcessorArchitecture NativeArchitecture
79 {
80 get
81 {
82 NativeStructs.SYSTEM_INFO sysInfo = new NativeStructs.SYSTEM_INFO();
83 NativeMethods.GetNativeSystemInfo(ref sysInfo);
84 ProcessorArchitecture architecture = Convert(sysInfo.wProcessorArchitecture);
85 return architecture;
86 }
87 }
88
89 private static string GetCpuName()
90 {
91 Guid processorClassGuid = new Guid("{50127DC3-0F36-415E-A6CC-4CB3BE910B65}");
92 IntPtr hDiSet = IntPtr.Zero;
93 string cpuName = null;
94
95 try
96 {
97 hDiSet = NativeMethods.SetupDiGetClassDevsW(ref processorClassGuid, null, IntPtr.Zero, NativeConstants.DIGCF_PRESENT);
98
99 if (hDiSet == NativeConstants.INVALID_HANDLE_VALUE)
100 {
101 NativeMethods.ThrowOnWin32Error("SetupDiGetClassDevsW returned INVALID_HANDLE_VALUE");
102 }
103
104 bool bResult = false;
105 uint memberIndex = 0;
106
107 while (true)
108 {
109 NativeStructs.SP_DEVINFO_DATA spDevinfoData = new NativeStructs.SP_DEVINFO_DATA();
110 spDevinfoData.cbSize = (uint)Marshal.SizeOf(typeof(NativeStructs.SP_DEVINFO_DATA));
111
112 bResult = NativeMethods.SetupDiEnumDeviceInfo(hDiSet, memberIndex, ref spDevinfoData);
113
114 if (!bResult)
115 {
116 int error = Marshal.GetLastWin32Error();
117
118 if (error == NativeConstants.ERROR_NO_MORE_ITEMS)
119 {
120 break;
121 }
122 else
123 {
124 throw new Win32Exception("SetupDiEnumDeviceInfo returned false, GetLastError() = " + error.ToString());
125 }
126 }
127
128 uint lengthReq = 0;
129 bResult = NativeMethods.SetupDiGetDeviceInstanceIdW(hDiSet, ref spDevinfoData, IntPtr.Zero, 0, out lengthReq);
130
131 if (bResult)
132 {
133 NativeMethods.ThrowOnWin32Error("SetupDiGetDeviceInstanceIdW(1) returned true");
134 }
135
136 if (lengthReq == 0)
137 {
138 NativeMethods.ThrowOnWin32Error("SetupDiGetDeviceInstanceIdW(1) returned false, but also 0 for lengthReq");
139 }
140
141 IntPtr str = IntPtr.Zero;
142 string regPath = null;
143
144 try
145 {
146 // Note: We cannot use Memory.Allocate() here because this property is
147 // usually retrieved during app shutdown, during which the heap may not
148 // be available.
149 str = Marshal.AllocHGlobal(checked((int)(sizeof(char) * (1 + lengthReq))));
150 bResult = NativeMethods.SetupDiGetDeviceInstanceIdW(hDiSet, ref spDevinfoData, str, lengthReq, out lengthReq);
151
152 if (!bResult)
153 {
154 NativeMethods.ThrowOnWin32Error("SetupDiGetDeviceInstanceIdW(2) returned false");
155 }
156
157 regPath = Marshal.PtrToStringUni(str);
158 }
159
160 finally
161 {
162 if (str != IntPtr.Zero)
163 {
164 Marshal.FreeHGlobal(str);
165 str = IntPtr.Zero;
166 }
167 }
168
169 string keyName = @"SYSTEM\CurrentControlSet\Enum\" + regPath;
170 using (RegistryKey procKey = Registry.LocalMachine.OpenSubKey(keyName, false))
171 {
172 const string friendlyName = "FriendlyName";
173
174 if (procKey != null)
175 {
176 object valueObj = procKey.GetValue(friendlyName);
177 string value = valueObj as string;
178
179 if (value != null)
180 {
181 cpuName = value;
182 }
183 }
184 }
185
186 if (cpuName != null)
187 {
188 break;
189 }
190
191 ++memberIndex;
192 }
193 }
194
195 finally
196 {
197 if (hDiSet != IntPtr.Zero)
198 {
199 NativeMethods.SetupDiDestroyDeviceInfoList(hDiSet);
200 hDiSet = IntPtr.Zero;
201 }
202 }
203
204 return cpuName;
205 }
206
207 /// <summary>
208 /// Returns the name of the CPU that is installed. If more than 1 CPU is installed,
209 /// then the name of the first one is retrieved.
210 /// </summary>
211 /// <remarks>
212 /// This is the name that shows up in Windows Device Manager in the "Processors" node.
213 /// Note to implementors: This is only ever used for diagnostics (e.g., crash log).
214 /// </remarks>
215 public static string CpuName
216 {
217 get
218 {
219 if (cpuName == null)
220 {
221 cpuName = GetCpuName();
222 }
223
224 return cpuName;
225 }
226 }
227
228 /// <summary>
229 /// Gets the number of logical or "virtual" processors installed in the computer.
230 /// </summary>
231 /// <remarks>
232 /// This value may not return the actual number of processors installed in the system.
233 /// It may be set to another number for testing and benchmarking purposes. It is
234 /// recommended that you use this property instead of ConcreteLogicalCpuCount for the
235 /// purposes of optimizing thread usage.
236 /// The maximum value for this property is 32 when running as a 32-bit process, or
237 /// 64 for a 64-bit process. Note that this implies the maximum is 32 for a 32-bit process
238 /// even when running on a 64-bit system.
239 /// </remarks>
240 public static int LogicalCpuCount
241 {
242 get
243 {
244 return logicalCpuCount;
245 }
246
247 set
248 {
249 if (value < 1 || value > (IntPtr.Size * 8))
250 {
251 throw new ArgumentOutOfRangeException("value", value, "must be in the range [0, " + (IntPtr.Size * 8).ToString() + "]");
252 }
253
254 logicalCpuCount = value;
255 }
256 }
257
258 /// <summary>
259 /// Gets the number of logical or "virtual" processors installed in the computer.
260 /// </summary>
261 /// <remarks>
262 /// This property will always return the actual number of logical processors installed
263 /// in the system. Note that processors such as Intel Xeons and Pentium 4's with
264 /// HyperThreading will result in values that are twice the number of physical processor
265 /// packages that have been installed (i.e. 2 Xeons w/ HT => ConcreteLogicalCpuCount = 4).
266 /// </remarks>
267 public static int ConcreteLogicalCpuCount
268 {
269 get
270 {
271 return Environment.ProcessorCount;
272 }
273 }
274
275 /// <summary>
276 /// Gets the approximate speed of the processor, in megahurtz.
277 /// </summary>
278 /// <remarks>
279 /// No accuracy is guaranteed, and precision is dependent on the operating system.
280 /// If there is an error determining the CPU speed, then 0 will be returned.
281 /// </remarks>
282 public static int ApproximateSpeedMhz
283 {
284 get
285 {
286 const string keyName = @"HARDWARE\DESCRIPTION\System\CentralProcessor\0";
287 const string valueName = @"~MHz";
288 int mhz = 0;
289
290 try
291 {
292 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, false))
293 {
294 if (key != null)
295 {
296 object value = key.GetValue(valueName);
297 mhz = (int)value;
298 }
299 }
300 }
301
302 catch (Exception)
303 {
304 mhz = 0;
305 }
306
307 return mhz;
308 }
309 }
310
311 private static ProcessorFeature features = (ProcessorFeature)0;
312
313 public static ProcessorFeature Features
314 {
315 get
316 {
317 if (features == (ProcessorFeature)0)
318 {
319 ProcessorFeature newFeatures = (ProcessorFeature)0;
320
321 // DEP
322 if (SafeNativeMethods.IsProcessorFeaturePresent(NativeConstants.PF_NX_ENABLED))
323 {
324 newFeatures |= ProcessorFeature.DEP;
325 }
326
327 // SSE
328 if (SafeNativeMethods.IsProcessorFeaturePresent(NativeConstants.PF_XMMI_INSTRUCTIONS_AVAILABLE))
329 {
330 newFeatures |= ProcessorFeature.SSE;
331 }
332
333 // SSE2
334 if (SafeNativeMethods.IsProcessorFeaturePresent(NativeConstants.PF_XMMI64_INSTRUCTIONS_AVAILABLE))
335 {
336 newFeatures |= ProcessorFeature.SSE2;
337 }
338
339 // SSE3
340 if (SafeNativeMethods.IsProcessorFeaturePresent(NativeConstants.PF_SSE3_INSTRUCTIONS_AVAILABLE))
341 {
342 newFeatures |= ProcessorFeature.SSE3;
343 }
344
345 features = newFeatures;
346 }
347
348 return features;
349 }
350 }
351
352 public static bool IsFeaturePresent(ProcessorFeature feature)
353 {
354 return ((Features & feature) == feature);
355 }
356 }
357 }

  ViewVC Help
Powered by ViewVC 1.1.22