/Ghostbuster/Buster.cs

# · C# · 665 lines · 437 code · 103 blank · 125 comment · 25 complexity · f81f81b6f59ca2f883b7d0daaac5180c MD5 · raw file

  1. #region License
  2. /*
  3. Copyright (c) 2009, G.W. van der Vegt
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without modification, are permitted provided
  6. that the following conditions are met:
  7. * Redistributions of source code must retain the above copyright notice, this list of conditions and the
  8. following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
  10. the following disclaimer in the documentation and/or other materials provided with the distribution.
  11. * Neither the name of G.W. van der Vegt nor the names of its contributors may be
  12. used to endorse or promote products derived from this software without specific prior written
  13. permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  15. EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  16. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  17. THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  18. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  21. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  22. THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #endregion License
  25. namespace Ghostbuster
  26. {
  27. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Collections.Specialized;
  31. using System.IO;
  32. using System.Text;
  33. using System.Windows.Forms;
  34. using GhostBuster;
  35. using Swiss;
  36. using HDEVINFO = System.IntPtr;
  37. using System.Runtime.InteropServices;
  38. using System.ComponentModel;
  39. using System.Diagnostics;
  40. using System.Security.Principal;
  41. #region Enumerations
  42. /// <summary>
  43. /// Needed to retrieve the Friendly Name.
  44. ///
  45. /// See http://stackoverflow.com/questions/304986/how-do-i-get-the-friendly-name-of-a-com-port-in-windows
  46. /// </summary>
  47. public enum SPDRP
  48. {
  49. DEVICEDESC = 0x00000000,
  50. HARDWAREID = 0x00000001,
  51. COMPATIBLEIDS = 0x00000002,
  52. NTDEVICEPATHS = 0x00000003,
  53. SERVICE = 0x00000004,
  54. CONFIGURATION = 0x00000005,
  55. CONFIGURATIONVECTOR = 0x00000006,
  56. CLASS = 0x00000007,
  57. CLASSGUID = 0x00000008,
  58. DRIVER = 0x00000009,
  59. CONFIGFLAGS = 0x0000000A,
  60. MFG = 0x0000000B,
  61. FRIENDLYNAME = 0x0000000C,
  62. LOCATION_INFORMATION = 0x0000000D,
  63. PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E,
  64. CAPABILITIES = 0x0000000F,
  65. UI_NUMBER = 0x00000010,
  66. UPPERFILTERS = 0x00000011,
  67. LOWERFILTERS = 0x00000012,
  68. MAXIMUM_PROPERTY = 0x00000013,
  69. }
  70. #endregion Enumerations
  71. public class Buster : IDisposable
  72. {
  73. #region Fields
  74. public static readonly String S_TITLE = "GhostBuster";
  75. /// <summary>
  76. /// Section Name in IniFile
  77. /// </summary>
  78. public const String ClassKey = "Class.RemoveIfGosted";
  79. /// <summary>
  80. /// Section Name in IniFile
  81. /// </summary>
  82. public const String DeviceKey = "Descr.RemoveIfGosted";
  83. /// <summary>
  84. /// Section Name in IniFile
  85. /// </summary>
  86. public const String WildcardKey = "Wildcards";
  87. /// <summary>
  88. /// A Handle.
  89. /// </summary>
  90. internal static HDEVINFO DevInfoSet;
  91. /// <summary>
  92. /// The Classes to remove.
  93. /// </summary>
  94. public static StringCollection Classes = new StringCollection();
  95. /// <summary>
  96. /// The Devices to remove.
  97. /// </summary>
  98. public static StringCollection Devices = new StringCollection();
  99. /// <summary>
  100. /// The Devices.
  101. ///// </summary>
  102. public static List<HwEntry> HwEntries = new List<HwEntry>();
  103. /// <summary>
  104. /// IniFileName (Should Automatically use %AppData% when neccesary)!
  105. /// </summary>
  106. public static String IniFileName = String.Empty;
  107. /// <summary>
  108. /// The Wildcards to remove.
  109. /// </summary>
  110. public static List<Wildcard> Wildcards = new List<Wildcard>();
  111. #endregion Fields
  112. #region Constructors
  113. /// <summary>
  114. /// Constructor.
  115. ///
  116. /// Defaults to AppIni.
  117. /// </summary>
  118. public Buster()
  119. : this(IniFile.AppIni)
  120. {
  121. //Nothing
  122. }
  123. /// <summary>
  124. /// Constructor.
  125. ///
  126. /// Loads static data from am Ini File.
  127. /// </summary>
  128. /// <param name="IniFileName"></param>
  129. public Buster(String IniFileName)
  130. {
  131. //! Take this one from %appdata% or the CommandLine.
  132. Buster.IniFileName = IniFileName;
  133. LoadDevicesAndClasses(new IniFile(IniFileName));
  134. LoadWildcards(new IniFile(IniFileName));
  135. }
  136. #endregion Constructors
  137. #region Methods
  138. public static void AddClassKey(String Class)
  139. {
  140. using (IniFile ini = new IniFile(Buster.IniFileName))
  141. {
  142. ini.WriteString(Buster.ClassKey,
  143. String.Format("item_{0}", ini.ReadInteger(Buster.ClassKey, "Count", 0)),
  144. Class);
  145. ini.WriteInteger(Buster.ClassKey,
  146. "Count",
  147. ini.ReadInteger(Buster.ClassKey, "Count", 0) + 1);
  148. ini.UpdateFile();
  149. }
  150. LoadDevicesAndClasses(new IniFile(IniFileName));
  151. }
  152. public static void AddDeviceKey(String Device)
  153. {
  154. using (IniFile ini = new IniFile(Buster.IniFileName))
  155. {
  156. ini.WriteString(Buster.DeviceKey,
  157. String.Format("item_{0}", ini.ReadInteger(Buster.DeviceKey, "Count", 0)),
  158. Device);
  159. ini.WriteInteger(Buster.DeviceKey,
  160. "Count",
  161. ini.ReadInteger(Buster.DeviceKey, "Count", 0) + 1);
  162. ini.UpdateFile();
  163. }
  164. LoadDevicesAndClasses(new IniFile(IniFileName));
  165. }
  166. /// <summary>
  167. /// Enumerate all devices and optionally uninstall ghosted ones.
  168. /// </summary>
  169. public static void Enumerate()
  170. {
  171. SetupDi.SP_DEVINFO_DATA aDeviceInfoData = new SetupDi.SP_DEVINFO_DATA();
  172. HwEntries.Clear();
  173. try
  174. {
  175. //Cache all HKLM Services Key Names and DisplayNames
  176. SetupDi.EnumServices();
  177. DevInfoSet = SetupDi.SetupDiGetClassDevs(ref SetupDi.NullGuid, 0, IntPtr.Zero, (uint)SetupDi.DIGCF.DIGCF_ALLCLASSES);
  178. if (DevInfoSet != (IntPtr)SetupDi.INVALID_HANDLE_VALUE)
  179. {
  180. aDeviceInfoData.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(aDeviceInfoData);
  181. Int32 i = 0;
  182. using (IniFile ini = new IniFile(IniFileName))
  183. {
  184. while (SetupDi.SetupDiEnumDeviceInfo(DevInfoSet, i, ref aDeviceInfoData))
  185. {
  186. SetupDi.DeviceInfo aDeviceInfo = new SetupDi.DeviceInfo();
  187. //DeviceClass is used for grouping items...
  188. SetupDi.GetClassDescriptionFromGuid(ref aDeviceInfo, aDeviceInfoData.ClassGuid);
  189. //veg: Gives Exceptions, remove and return error name...
  190. try
  191. {
  192. //TODO: Retrieving DeviceName fails.
  193. SetupDi.GetDeviceDescription(ref aDeviceInfo, DevInfoSet, aDeviceInfoData);
  194. SetupDi.GetDeviceName(ref aDeviceInfo, DevInfoSet, aDeviceInfoData);
  195. SetupDi.GetDeviceStatus(ref aDeviceInfo, DevInfoSet, ref aDeviceInfoData);
  196. uint PropertyRegDataType;
  197. uint nBytes = 512;
  198. StringBuilder sb = new StringBuilder();
  199. sb.Length = (int)nBytes;
  200. uint RequiredSize = 0;
  201. SetupDi.SetupDiGetDeviceRegistryProperty(DevInfoSet, ref aDeviceInfoData,
  202. (uint)SPDRP.FRIENDLYNAME, out PropertyRegDataType,
  203. sb, nBytes, out RequiredSize);
  204. HwEntries.Add(new HwEntry(DevInfoSet, aDeviceInfo, aDeviceInfoData, sb.ToString()));
  205. }
  206. finally
  207. {
  208. //Nothing
  209. }
  210. i++;
  211. }
  212. }
  213. }
  214. }
  215. finally
  216. {
  217. //Nothing
  218. }
  219. }
  220. public static void LoadDevicesAndClasses(IniFile ini)
  221. {
  222. Devices = ini.ReadSectionValues(DeviceKey);
  223. Classes = ini.ReadSectionValues(ClassKey);
  224. }
  225. public static void RemoveClassKey(String Class)
  226. {
  227. using (IniFile ini = new IniFile(IniFileName))
  228. {
  229. foreach (DictionaryEntry de in ini.ReadSection(ClassKey))
  230. {
  231. if (de.Value.ToString() == Class)
  232. {
  233. ini.DeleteKey(ClassKey, de.Key.ToString());
  234. }
  235. }
  236. ini.UpdateFile();
  237. }
  238. LoadDevicesAndClasses(new IniFile(IniFileName));
  239. }
  240. public static void RemoveDeviceKey(String Device)
  241. {
  242. using (IniFile ini = new IniFile(Buster.IniFileName))
  243. {
  244. foreach (DictionaryEntry de in ini.ReadSection(Buster.DeviceKey))
  245. {
  246. if (de.Value.ToString() == Device)
  247. {
  248. ini.DeleteKey(Buster.DeviceKey, de.Key.ToString());
  249. }
  250. }
  251. ini.UpdateFile();
  252. }
  253. LoadDevicesAndClasses(new IniFile(IniFileName));
  254. }
  255. internal static void AddWildCard(String wildcard)
  256. {
  257. Wildcards.Add(new Wildcard(wildcard));
  258. SaveWildcards(new IniFile(IniFileName));
  259. }
  260. internal static void RemoveWildCard(String pattern)
  261. {
  262. for (Int32 i = Wildcards.Count - 1; i >= 0; i--)
  263. {
  264. if (Wildcards[i].Pattern.Equals(pattern))
  265. {
  266. Wildcards.RemoveAt(i);
  267. }
  268. }
  269. SaveWildcards(new IniFile(IniFileName));
  270. }
  271. private static void LoadWildcards(IniFile ini)
  272. {
  273. StringDictionary sd = ini.ReadSection(WildcardKey);
  274. sd.Remove("Count");
  275. Wildcards.Clear();
  276. foreach (String key in sd.Keys)
  277. {
  278. Wildcards.Add(new Wildcard(ini.ReadString(WildcardKey, key, "xyyz")));
  279. }
  280. }
  281. private static void SaveWildcards(IniFile ini)
  282. {
  283. ini.EraseSection(WildcardKey);
  284. ini.WriteInteger(WildcardKey, "Count", Wildcards.Count);
  285. foreach (Wildcard w in Wildcards)
  286. {
  287. ini.WriteString(WildcardKey,
  288. "item_" + Wildcards.IndexOf(w).ToString(), w.Pattern);
  289. }
  290. ini.UpdateFile();
  291. }
  292. public static bool IsAdmin()
  293. {
  294. WindowsIdentity user = WindowsIdentity.GetCurrent();
  295. WindowsPrincipal principal = new WindowsPrincipal(user);
  296. return principal.IsInRole(WindowsBuiltInRole.Administrator);
  297. }
  298. #endregion Methods
  299. #region IDisposable Members
  300. public void Dispose()
  301. {
  302. Devices.Clear();
  303. Classes.Clear();
  304. Wildcards.Clear();
  305. HwEntries.Clear();
  306. }
  307. public static void WriteToEventLog(string message, EventLogEntryType elet)
  308. {
  309. string cs = S_TITLE;
  310. Debug.WriteLine(message);
  311. EventLog log = new EventLog();
  312. if (Buster.IsAdmin())
  313. {
  314. if (!EventLog.SourceExists(cs))
  315. {
  316. EventLog.CreateEventSource(cs, cs);
  317. }
  318. if (EventLog.SourceExists(cs))
  319. {
  320. log.Source = cs;
  321. log.EnableRaisingEvents = true;
  322. log.WriteEntry(message, elet);
  323. }
  324. }
  325. }
  326. #endregion
  327. }
  328. /// <summary>
  329. /// Needed to retrieve the Friendly Name.
  330. /// </summary>
  331. public class GUID_DEVCLASS
  332. {
  333. #region Fields
  334. public static readonly Guid ADAPTER = new Guid("{0x4d36e964, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  335. public static readonly Guid APMSUPPORT = new Guid("{0xd45b1c18, 0xc8fa, 0x11d1, {0x9f, 0x77, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30}}");
  336. public static readonly Guid AVC = new Guid("{0xc06ff265, 0xae09, 0x48f0, {0x81, 0x2c, 0x16, 0x75, 0x3d, 0x7c, 0xba, 0x83}}");
  337. public static readonly Guid BATTERY = new Guid("{0x72631e54, 0x78a4, 0x11d0, {0xbc, 0xf7, 0x00, 0xaa, 0x00, 0xb7, 0xb3, 0x2a}}");
  338. public static readonly Guid BIOMETRIC = new Guid("{0x53d29ef7, 0x377c, 0x4d14, {0x86, 0x4b, 0xeb, 0x3a, 0x85, 0x76, 0x93, 0x59}}");
  339. public static readonly Guid BLUETOOTH = new Guid("{0xe0cbf06c, 0xcd8b, 0x4647, {0xbb, 0x8a, 0x26, 0x3b, 0x43, 0xf0, 0xf9, 0x74}}");
  340. public static readonly Guid CDROM = new Guid("{0x4d36e965, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  341. public static readonly Guid COMPUTER = new Guid("{0x4d36e966, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  342. public static readonly Guid DECODER = new Guid("{0x6bdd1fc2, 0x810f, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  343. public static readonly Guid DISKDRIVE = new Guid("{0x4d36e967, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  344. public static readonly Guid DISPLAY = new Guid("{0x4d36e968, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  345. public static readonly Guid DOT4 = new Guid("{0x48721b56, 0x6795, 0x11d2, {0xb1, 0xa8, 0x00, 0x80, 0xc7, 0x2e, 0x74, 0xa2}}");
  346. public static readonly Guid DOT4PRINT = new Guid("{0x49ce6ac8, 0x6f86, 0x11d2, {0xb1, 0xe5, 0x00, 0x80, 0xc7, 0x2e, 0x74, 0xa2}}");
  347. public static readonly Guid ENUM1394 = new Guid("{0xc459df55, 0xdb08, 0x11d1, {0xb0, 0x09, 0x00, 0xa0, 0xc9, 0x08, 0x1f, 0xf6}}");
  348. public static readonly Guid FDC = new Guid("{0x4d36e969, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  349. public static readonly Guid FLOPPYDISK = new Guid("{0x4d36e980, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  350. public static readonly Guid FSFILTER_ACTIVITYMONITOR = new Guid("{0xb86dff51, 0xa31e, 0x4bac, {0xb3, 0xcf, 0xe8, 0xcf, 0xe7, 0x5c, 0x9f, 0xc2}}");
  351. public static readonly Guid FSFILTER_ANTIVIRUS = new Guid("{0xb1d1a169, 0xc54f, 0x4379, {0x81, 0xdb, 0xbe, 0xe7, 0xd8, 0x8d, 0x74, 0x54}}");
  352. public static readonly Guid FSFILTER_CFSMETADATASERVER = new Guid("{0xcdcf0939, 0xb75b, 0x4630, {0xbf, 0x76, 0x80, 0xf7, 0xba, 0x65, 0x58, 0x84}}");
  353. public static readonly Guid FSFILTER_COMPRESSION = new Guid("{0xf3586baf, 0xb5aa, 0x49b5, {0x8d, 0x6c, 0x05, 0x69, 0x28, 0x4c, 0x63, 0x9f}}");
  354. public static readonly Guid FSFILTER_CONTENTSCREENER = new Guid("{0x3e3f0674, 0xc83c, 0x4558, {0xbb, 0x26, 0x98, 0x20, 0xe1, 0xeb, 0xa5, 0xc5}}");
  355. public static readonly Guid FSFILTER_CONTINUOUSBACKUP = new Guid("{0x71aa14f8, 0x6fad, 0x4622, {0xad, 0x77, 0x92, 0xbb, 0x9d, 0x7e, 0x69, 0x47}}");
  356. public static readonly Guid FSFILTER_COPYPROTECTION = new Guid("{0x89786ff1, 0x9c12, 0x402f, {0x9c, 0x9e, 0x17, 0x75, 0x3c, 0x7f, 0x43, 0x75}}");
  357. public static readonly Guid FSFILTER_ENCRYPTION = new Guid("{0xa0a701c0, 0xa511, 0x42ff, {0xaa, 0x6c, 0x06, 0xdc, 0x03, 0x95, 0x57, 0x6f}}");
  358. public static readonly Guid FSFILTER_HSM = new Guid("{0xd546500a, 0x2aeb, 0x45f6, {0x94, 0x82, 0xf4, 0xb1, 0x79, 0x9c, 0x31, 0x77}}");
  359. public static readonly Guid FSFILTER_INFRASTRUCTURE = new Guid("{0xe55fa6f9, 0x128c, 0x4d04, {0xab, 0xab, 0x63, 0x0c, 0x74, 0xb1, 0x45, 0x3a}}");
  360. public static readonly Guid FSFILTER_OPENFILEBACKUP = new Guid("{0xf8ecafa6, 0x66d1, 0x41a5, {0x89, 0x9b, 0x66, 0x58, 0x5d, 0x72, 0x16, 0xb7}}");
  361. public static readonly Guid FSFILTER_PHYSICALQUOTAMANAGEMENT = new Guid("{0x6a0a8e78, 0xbba6, 0x4fc4, {0xa7, 0x09, 0x1e, 0x33, 0xcd, 0x09, 0xd6, 0x7e}}");
  362. public static readonly Guid FSFILTER_QUOTAMANAGEMENT = new Guid("{0x8503c911, 0xa6c7, 0x4919, {0x8f, 0x79, 0x50, 0x28, 0xf5, 0x86, 0x6b, 0x0c}}");
  363. public static readonly Guid FSFILTER_REPLICATION = new Guid("{0x48d3ebc4, 0x4cf8, 0x48ff, {0xb8, 0x69, 0x9c, 0x68, 0xad, 0x42, 0xeb, 0x9f}}");
  364. public static readonly Guid FSFILTER_SECURITYENHANCER = new Guid("{0xd02bc3da, 0x0c8e, 0x4945, {0x9b, 0xd5, 0xf1, 0x88, 0x3c, 0x22, 0x6c, 0x8c}}");
  365. public static readonly Guid FSFILTER_SYSTEM = new Guid("{0x5d1b9aaa, 0x01e2, 0x46af, {0x84, 0x9f, 0x27, 0x2b, 0x3f, 0x32, 0x4c, 0x46}}");
  366. public static readonly Guid FSFILTER_SYSTEMRECOVERY = new Guid("{0x2db15374, 0x706e, 0x4131, {0xa0, 0xc7, 0xd7, 0xc7, 0x8e, 0xb0, 0x28, 0x9a}}");
  367. public static readonly Guid FSFILTER_UNDELETE = new Guid("{0xfe8f1572, 0xc67a, 0x48c0, {0xbb, 0xac, 0x0b, 0x5c, 0x6d, 0x66, 0xca, 0xfb}}");
  368. public static readonly Guid GPS = new Guid("{0x6bdd1fc3, 0x810f, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  369. public static readonly Guid HDC = new Guid("{0x4d36e96a, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  370. public static readonly Guid HIDCLASS = new Guid("{0x745a17a0, 0x74d3, 0x11d0, {0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda}}");
  371. public static readonly Guid IMAGE = new Guid("{0x6bdd1fc6, 0x810f, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  372. public static readonly Guid INFINIBAND = new Guid("{0x30ef7132, 0xd858, 0x4a0c, {0xac, 0x24, 0xb9, 0x02, 0x8a, 0x5c, 0xca, 0x3f}}");
  373. public static readonly Guid INFRARED = new Guid("{0x6bdd1fc5, 0x810f, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  374. public static readonly Guid KEYBOARD = new Guid("{0x4d36e96b, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  375. public static readonly Guid LEGACYDRIVER = new Guid("{0x8ecc055d, 0x047f, 0x11d1, {0xa5, 0x37, 0x00, 0x00, 0xf8, 0x75, 0x3e, 0xd1}}");
  376. public static readonly Guid MEDIA = new Guid("{0x4d36e96c, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  377. public static readonly Guid MEDIUM_CHANGER = new Guid("{0xce5939ae, 0xebde, 0x11d0, {0xb1, 0x81, 0x00, 0x00, 0xf8, 0x75, 0x3e, 0xc4}}");
  378. public static readonly Guid MODEM = new Guid("{0x4d36e96d, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  379. public static readonly Guid MONITOR = new Guid("{0x4d36e96e, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  380. public static readonly Guid MOUSE = new Guid("{0x4d36e96f, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  381. public static readonly Guid MTD = new Guid("{0x4d36e970, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  382. public static readonly Guid MULTIFUNCTION = new Guid("{0x4d36e971, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  383. public static readonly Guid MULTIPORTSERIAL = new Guid("{0x50906cb8, 0xba12, 0x11d1, {0xbf, 0x5d, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30}}");
  384. public static readonly Guid NET = new Guid("{0x4d36e972, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  385. public static readonly Guid NETCLIENT = new Guid("{0x4d36e973, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  386. public static readonly Guid NETSERVICE = new Guid("{0x4d36e974, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  387. public static readonly Guid NETTRANS = new Guid("{0x4d36e975, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  388. public static readonly Guid NODRIVER = new Guid("{0x4d36e976, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  389. public static readonly Guid PCMCIA = new Guid("{0x4d36e977, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  390. public static readonly Guid PNPPRINTERS = new Guid("{0x4658ee7e, 0xf050, 0x11d1, {0xb6, 0xbd, 0x00, 0xc0, 0x4f, 0xa3, 0x72, 0xa7}}");
  391. public static readonly Guid PORTS = new Guid("{0x4d36e978, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  392. public static readonly Guid PRINTER = new Guid("{0x4d36e979, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  393. public static readonly Guid PRINTERUPGRADE = new Guid("{0x4d36e97a, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  394. public static readonly Guid PROCESSOR = new Guid("{0x50127dc3, 0x0f36, 0x415e, {0xa6, 0xcc, 0x4c, 0xb3, 0xbe, 0x91, 0x0B, 0x65}}");
  395. public static readonly Guid SBP2 = new Guid("{0xd48179be, 0xec20, 0x11d1, {0xb6, 0xb8, 0x00, 0xc0, 0x4f, 0xa3, 0x72, 0xa7}}");
  396. public static readonly Guid SCSIADAPTER = new Guid("{0x4d36e97b, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  397. public static readonly Guid SECURITYACCELERATOR = new Guid("{0x268c95a1, 0xedfe, 0x11d3, {0x95, 0xc3, 0x00, 0x10, 0xdc, 0x40, 0x50, 0xa5}}");
  398. public static readonly Guid SMARTCARDREADER = new Guid("{0x50dd5230, 0xba8a, 0x11d1, {0xbf, 0x5d, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30}}");
  399. public static readonly Guid SOUND = new Guid("{0x4d36e97c, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  400. public static readonly Guid SYSTEM = new Guid("{0x4d36e97d, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  401. public static readonly Guid TAPEDRIVE = new Guid("{0x6d807884, 0x7d21, 0x11cf, {0x80, 0x1c, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  402. public static readonly Guid UNKNOWN = new Guid("{0x4d36e97e, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}");
  403. public static readonly Guid USB = new Guid("{0x36fc9e60, 0xc465, 0x11cf, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}");
  404. public static readonly Guid VOLUME = new Guid("{0x71a27cdd, 0x812a, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  405. public static readonly Guid VOLUMESNAPSHOT = new Guid("{0x533c5b84, 0xec70, 0x11d2, {0x95, 0x05, 0x00, 0xc0, 0x4f, 0x79, 0xde, 0xaf}}");
  406. public static readonly Guid WCEUSBS = new Guid("{0x25dbce51, 0x6c8f, 0x4a72, {0x8a, 0x6d, 0xb5, 0x4c, 0x2b, 0x4f, 0xc8, 0x35}}");
  407. //http://stackoverflow.com/questions/304986/how-do-i-get-the-friendly-name-of-a-com-port-in-windows
  408. public static readonly Guid _1394 = new Guid("{0x6bdd1fc1, 0x810f, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}");
  409. public static readonly Guid _1394DEBUG = new Guid("{0x66f250d6, 0x7801, 0x4a64, {0xb1, 0x39, 0xee, 0xa8, 0x0a, 0x45, 0x0b, 0x24}}");
  410. public static readonly Guid _61883 = new Guid("{0x7ebefbc0, 0x3200, 0x11d2, {0xb4, 0xc2, 0x00, 0xa0, 0xc9, 0x69, 0x7d, 0x07}}");
  411. #endregion Fields
  412. }
  413. /// <summary>
  414. /// A Hardware Entry.
  415. /// </summary>
  416. public class HwEntry
  417. {
  418. #region Fields
  419. /// <summary>
  420. /// Needed for Removal
  421. /// </summary>
  422. private SetupDi.SP_DEVINFO_DATA aDeviceInfoData;
  423. /// <summary>
  424. /// Needed for Removal
  425. /// </summary>
  426. private HDEVINFO aDeviceInfoSet;
  427. #endregion Fields
  428. #region Constructors
  429. /// <summary>
  430. /// Creates a HwEntty to add to the list of devices considered for removal.
  431. /// </summary>
  432. /// <param name="aDeviceInfoSet">Needed for Removal</param>
  433. /// <param name="aDeviceInfo">Needed for Name and Status</param>
  434. /// <param name="aDeviceInfoData">Needed for Removal</param>
  435. /// <param name="FriendlyName">The Friendly name if any</param>
  436. public HwEntry(HDEVINFO aDeviceInfoSet, SetupDi.DeviceInfo aDeviceInfo, SetupDi.SP_DEVINFO_DATA aDeviceInfoData, String FriendlyName)
  437. {
  438. this.aDeviceInfoSet = aDeviceInfoSet;
  439. this.Description = aDeviceInfo.description;
  440. this.DeviceClass = aDeviceInfo.deviceclass;
  441. this.aDeviceInfoData = aDeviceInfoData;
  442. if (aDeviceInfo.disabled)
  443. {
  444. this.DeviceStatus = "Disabled";
  445. }
  446. else if (aDeviceInfo.service)
  447. {
  448. //! Make Sure Services are NEVER flagged as Ghosted by checking them first.
  449. this.DeviceStatus = "Service";
  450. }
  451. else if (aDeviceInfo.ghosted)
  452. {
  453. this.DeviceStatus = "Ghosted";
  454. }
  455. else
  456. {
  457. this.DeviceStatus = "Ok";
  458. }
  459. this.FriendlyName = FriendlyName;
  460. }
  461. #endregion Constructors
  462. #region Properties
  463. /// <summary>
  464. /// The Device Desecription.
  465. /// </summary>
  466. public String Description
  467. {
  468. get;
  469. internal set;
  470. }
  471. /// <summary>
  472. /// The Device Class.
  473. /// </summary>
  474. public String DeviceClass
  475. {
  476. get;
  477. private set;
  478. }
  479. /// <summary>
  480. /// The Device Status.
  481. /// </summary>
  482. public String DeviceStatus
  483. {
  484. get;
  485. private set;
  486. }
  487. /// <summary>
  488. /// The Friendly name if any
  489. /// </summary>
  490. public String FriendlyName
  491. {
  492. get;
  493. internal set;
  494. }
  495. /// <summary>
  496. /// Ghosted.
  497. /// </summary>
  498. public Boolean Ghosted
  499. {
  500. get
  501. {
  502. return DeviceStatus.Equals("Ghosted");
  503. }
  504. }
  505. #endregion Properties
  506. #region Methods
  507. /// <summary>
  508. /// Removes a Device.
  509. /// </summary>
  510. /// <returns>true if successfull</returns>
  511. private Boolean RemoveDevice()
  512. {
  513. Boolean Result = SetupDi.SetupDiRemoveDevice(Buster.DevInfoSet, ref aDeviceInfoData);
  514. Int32 lasterror = Marshal.GetLastWin32Error();
  515. String msg = String.Empty;
  516. if (Result)
  517. {
  518. msg = String.Format("Device '{0}' removed successfully", Description);
  519. Buster.WriteToEventLog(msg, EventLogEntryType.Information);
  520. }
  521. else
  522. {
  523. msg = String.Format("Device removal of '{0}' failed", Description);
  524. msg += "\r\n" + String.Format("; {0}", new Win32Exception(lasterror).Message);
  525. Buster.WriteToEventLog(msg, EventLogEntryType.Warning);
  526. }
  527. return Result;
  528. }
  529. /// <summary>
  530. /// Remove a Ghosted Device if Filtered.
  531. /// </summary>
  532. /// <returns>true if successfull</returns>
  533. public Boolean RemoveDevice_IF_Ghosted_AND_Marked()
  534. {
  535. if (Ghosted)
  536. {
  537. if (Buster.Devices.Contains(Description.Trim()) && RemoveDevice())
  538. {
  539. return true;
  540. }
  541. if (Buster.Classes.Contains(DeviceClass.Trim()) && RemoveDevice())
  542. {
  543. return true;
  544. }
  545. foreach (Wildcard w in Buster.Wildcards)
  546. {
  547. if (w.IsMatch(Description.Trim()) && RemoveDevice())
  548. {
  549. return true;
  550. }
  551. }
  552. }
  553. return false;
  554. }
  555. #endregion Methods
  556. }
  557. }