ERLEDIGT
NEIN
NEIN
ANTWORTEN
2
2
ZUGRIFFE
559
559
EMPFEHLEN
-
Hallo,
ich will die S.M.A.R.T. Daten der Festplatten auslesen. Dazu habe ich eine VB.NET Klasse gefunden Hier!.
Diese habe ich nun nach C# übersetzt und ab geändert so wie es halt nötig war. Mein problem, beim aufruf der DLL-Funktion DeviceIoControl() wird das Programm einfach beendet. Der Output im VisualStudio:
Ich hänge mal meine von VB nach C# übersetzte Smart-Klasse dran. Aber wie gesagt manche Sachen musste ich ändern.The program '[3352] SmartView.vshost.exe: Managed (v2.0.50727)' has exited with code -1073740791 (0xc0000409).
Code csharp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Management; using System.Linq; using System.Text; using System.Collections; using System.Windows.Forms; namespace SmartView { #region ReadSmartResult Enum public enum ReadSmartResult { DRIVE_DOES_NOT_EXIST = 0, ACCESS_DENIED = 1, NO_SMART_AVAILABLE = 2, SUCCEEDED = 3 } #endregion #region Attributes Enum public enum Attributes { // Invalid attribute identifier SMART_ATTRIB_Invalid = 0, // Frequency of errors while reading raw data SMART_ATTRIB_RAW_READ_ERROR_RATE = 1, // Average efficiency of a hard disk SMART_ATTRIB_THROUGHPUT_PERFORMANCE = 2, // needed to spin up SMART_ATTRIB_SPIN_UP_TIME = 3, // Number of spindle start/stop cycles SMART_ATTRIB_START_STOP_COUNT = 4, // Quantity of remapped sectors SMART_ATTRIB_REALLOCATION_SECTOR_COUNT = 5, // Reserve of channel while reading SMART_ATTRIB_Read_Channel_Margin = 6, // Frequency of errors while positioning SMART_ATTRIB_SEEK_ERROR_RATE = 7, // Average efficiency of operations while positioning SMART_ATTRIB_Seek_TimerPerformance = 8, // Number of hours elapsed in the power-on state SMART_ATTRIB_POWER_ON_HOURS_COUNT = 9, // Number of retry attempts to spin up SMART_ATTRIB_SPIN_RETRY_COUNT = 10, // count Number of attempts to calibrate the device SMART_ATTRIB_RECALIBRATION_RETRIES = 11, // Number of power-on events SMART_ATTRIB_DEVICE_POWER_CYCLE_COUNT = 12, // Frequency of ‘program’ errors while reading from a disk SMART_ATTRIB_SOFT_READ_ERROR_RATE = 13, // Fequency of mistakes as a result of impact loads SMART_ATTRIB_AIRFLOW_TEMPERATURE = 190, // Fequency of mistakes as a result of impact loads SMART_ATTRIB_G_Sense_Error_Rate = 191, // Number of power-off or emergency retract cycles SMART_ATTRIB_Power_Off_Retract_Count = 192, // Number of cycles into landing zone position SMART_ATTRIB_LOAD_UNLOAD_CYCLE_COUNT = 193, // Temperature of a hard disk assembly SMART_ATTRIB_HDA_TEMPERATURE = 194, // Number of ECC on-the-fly errors SMART_ATTRIB_Hardware_ECC_Recovered = 195, // Number of remapping operations SMART_ATTRIB_REALLOCATION_COUNT = 196, // Number of unstable sectors (waiting for remapping) SMART_ATTRIB_CURRENT_PENDING_SECTOR_COUNT = 197, // Number of uncorrected errors SMART_ATTRIB_UNCORRECTABLE_SECTOR_COUNT = 198, // Number of CRC errors during UDMA mode SMART_ATTRIB_ULTRA_DMA_CRC_ERROR_COUNT = 199, // Number of errors while writing to disk (or) multi-zone // error rate (or) flying height SMART_ATTRIB_WRITE_ERROR_RATE = 200, // Number of off-track errors SMART_ATTRIB_Soft_Read_Error_Count = 201, // Number of Data Address Mark (DAM) errors (or) vendor-specific SMART_ATTRIB_Data_Address_Mark_Errors = 202, // Number of ECC errors SMART_ATTRIB_Run_Out_Cancel = 203, // Number of errors corrected by software ECC SMART_ATTRIB_Soft_ECC_Correction = 204, // Number of thermal asperity errors SMART_ATTRIB_Thermal_Asperity_Rate = 205, // Height of heads above the disk surface SMART_ATTRIB_Flying_Height = 206, // Amount of high current used to spin up the drive SMART_ATTRIB_Spin_High_Current = 207, // Number of buzz routines to spin up the drive SMART_ATTRIB_Spin_Buzz = 208, // Drive’s seek performance during offline operations SMART_ATTRIB_Offline_Seek_Performance = 209, // Shift of disk is possible as a result of strong shock loading // in the store, as a result of falling (or) temperature SMART_ATTRIB_Disk_Shift = 220, // Number of errors as a result of impact loads as detected // by a shock sensor SMART_ATTRIB_G_SENSE_ERROR_Count = 221, // Number of hours in general operational state SMART_ATTRIB_Loaded_Hours = 222, // Loading on drive caused by numerous recurrences of operations, // like reading, recording, positioning of heads, etc. SMART_ATTRIB_Load_Unload_Retry_Count = 223, // Load on drive caused by friction in mechanical parts of the store SMART_ATTRIB_Load_Friction = 224, // Total number of load cycles SMART_ATTRIB_Load_Unload_Cycle_Count1 = 225, // General time for loading in a drive SMART_ATTRIB_Load_In_Time = 226, // Quantity efforts of the rotating moment of a drive SMART_ATTRIB_Torque_Amplification_Count = 227, // Number of power-off retract events. SMART_ATTRIB_POWER_OFF_RETRACT_COUNT1 = 228, // Amplitude of heads trembling (GMR-head) in running mode SMART_ATTRIB_GMR_Head_Amplitude = 230, // Temperature of a drive SMART_ATTRIB_Drive_Temperature = 231, // Time while head is positioning SMART_ATTRIB_Head_Flying_Hours = 240, // Number of errors while reading from a disk SMART_ATTRIB_Read_Error_Retry_Rate = 250 } #endregion public class Smart { public string[] Drives; public string[] Names; public STORAGE_PREDICT_FAILURE SmartData; #region Konstanten private const int IOCTL_STORAGE_PREDICT_FAILURE = 0x2D1100; // uint könnte probleme geben private const uint STATUS_INVALID_DEVICE_REQUEST = 0xC0000010; private const short FILE_SHARE_NONE = 0; private const short OPEN_EXISTING = 3; private const short INVALID_HANDLE_VALUE = -1; private const uint GENERIC_READ = 0x80000000; // fehler beim casten? private const int GENERIC_WRITE = 0x40000000; private const int FILE_SHARE_READ = 1; private const int FILE_SHARE_WRITE = 2; #endregion #region DLL Deklaration [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] private static extern int DeviceIoControl(IntPtr hDevice, int dwioControlCode, IntPtr lpInBuffer, int nInBufferSize, out STORAGE_PREDICT_FAILURE lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped); #endregion #region Funktionen // Festplatten (und auch USB-Laufwerke) per WMI ermitteln public int GetPhysicalDrives() { ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); Hashtable ht = new Hashtable(); int i = 0; ManagementObjectCollection moc = searcher.Get(); Drives = new string[moc.Count]; Names = new string[moc.Count]; try { foreach (ManagementObject wmi_HD in moc) { ht.Add(wmi_HD.Properties["deviceid"].Value, wmi_HD.Properties["caption"].Value); // Hier kommt die Exception Drives[i] = wmi_HD.Properties["deviceid"].Value.ToString(); Names[i] = wmi_HD.Properties["caption"].Value.ToString(); i++; } return i; } catch (Exception ex) { return 0; } finally { ht = null; } } // Smart-Werte für angegebenes Laufwerk lesen // stehen danach in SmartData zur Verfügung public ReadSmartResult ReadSmart(string Drive) { IntPtr Device; bool Result; int ReturnedBytes = 0; this.SmartData = new STORAGE_PREDICT_FAILURE(); IntPtr zeroPtr = new IntPtr(0); // Laufwerk öffnen Device = CreateFile(Drive, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (Device.ToInt32() == INVALID_HANDLE_VALUE) { if (Marshal.GetLastWin32Error() == 2) { //Zugriff verweigert, wahrscheinlich fehlen Adminrechte return ReadSmartResult.ACCESS_DENIED; } else { // das angegebene Laufwerk existiert nicht return ReadSmartResult.DRIVE_DOES_NOT_EXIST; } } // S.M.A.R.T. auslesen Result = Convert.ToBoolean(DeviceIoControl(Device, IOCTL_STORAGE_PREDICT_FAILURE, IntPtr.Zero, 0, out SmartData, Marshal.SizeOf(SmartData), ref ReturnedBytes, IntPtr.Zero)); CloseHandle(Device); if (Result) { // erfolgreich return ReadSmartResult.SUCCEEDED; } else { // es konnten keine S.M.A.R.T. Eigenschaften gelesen werden return ReadSmartResult.NO_SMART_AVAILABLE; } } // Attributsnamen (falls vohanden) ausgeben public string GetAttribute(Attributes Index) { string outString; outString = Index.ToString(); // Wenn outString noch numerisch ist, dann ist kein // Beschreibungstext in der Definition angegeben, // Ersatztext wird ausgegeben if (IsNumeric(outString)) outString = "<Herstellerspezifisch>"; return outString; } // Smart-Wert auswerten, 12Byte beginnend ab Offset // Offset = X * 12 + 2 public void GetSmartValue(int Offset, ref int Attribut, ref long Value, ref long Worst, ref long Data) { // Der S.M.A.R.T.-Wert setzt sich aus 12Byte zusammen // 1. Byte - Attributesnamen Attribut = SmartData.VendorSpecific[Offset]; // 2./3. Byte - Herstellerspezifisch // interessant ist hier das 1. Bit, falls der Wert dieses // Smartwertes unter dem Grenzwert liegt, gibt dieses bit an, // ob die Festplatte innerhalb der nächsten 24h ausfallen wird! // 4. Byte - Wert Value = SmartData.VendorSpecific[Offset + 3]; // 5.-12. Byte - RAW-Value (herstellerspezifisch) Worst = SmartData.VendorSpecific[Offset + 4]; string str = ""; for (int i = 11; i <= 5; i--) { str += Convert.ToString((SmartData.VendorSpecific[Offset + i]), 16); } Data = Convert.ToInt64(str, 16); } #endregion // Werte aus SmartData in Listview eintragen public void AddSmartToListView(ListView lv, int Index) { int Attribut = 0; long Value = 0, Worst = 0, Data = 0; for (int i = 0; i <= 29; i++) { GetSmartValue(i * 12 + 2, ref Attribut, ref Value, ref Worst, ref Data); // 0 ist kein gültiger Wert, d.h. dieser Speicherblock enthält // kein Attribut if (!Attribut.Equals(Attributes.SMART_ATTRIB_Invalid)) { // ins Listview eintragen ListViewItem lvi = new ListViewItem(); //Attributes at = new Attributes(); //string att = Enum.GetName(typeof(Attributes), Attribut); Attributes at = (Attributes)Enum.Parse(typeof(Attributes), Convert.ToString(Attribut)); //string attributeName = Enum.GetName(typeof(Attributes), Convert.ToString(1)); //Attributes attr = (Attributes) Enum.Parse(typeof(Attributes), attributeName); lvi.Text = Attribut + " - " + GetAttribute(at); lvi.SubItems.Add(Value.ToString()); lvi.SubItems.Add(Worst.ToString()); lvi.SubItems.Add(Data.ToString()); for (int j = 0; j <= lv.Groups.Count - 1; i++) { if (lv.Groups[j].Name == "LW" + Index) lvi.Group = lv.Groups[j]; } lv.Items.Add(lvi); } } } #region Hilfsklasse zur Zwischenspeicherung [StructLayout(LayoutKind.Sequential)] public class STORAGE_PREDICT_FAILURE { public int PredictFailure; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] VendorSpecific; public STORAGE_PREDICT_FAILURE() { VendorSpecific = new byte[511]; } } #endregion #region IsNumeric Methode // IsNumeric Function static bool IsNumeric(object Expression) { // Variable to collect the Return value of the TryParse method. bool isNum; // Define variable to collect out parameter of the TryParse method. If the conversion fails, the out parameter is zero. double retNum; // The TryParse method converts a string in a specified style and culture-specific format to its double-precision floating point number equivalent. // The TryParse method does not generate an exception if the conversion fails. If the conversion passes, True is returned. If it does not, False is returned. isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum); return isNum; } #endregion } }
Und hier noch mein Aufruf der Klasse:
Code csharp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
private void button1_Click(object sender, EventArgs e) { Smart smart = new Smart(); listView1.Items.Clear(); listView1.Groups.Clear(); // Laufwerke ermitteln int j = smart.GetPhysicalDrives() - 1; // S.M.A.R.T. Eigenschaften auslesen und ins Listview eintragen for(int i = 0; i <= j; i++) { switch(smart.ReadSmart(smart.Drives[i])) { case ReadSmartResult.SUCCEEDED: // S.M.A.R.T.-Werte wurden ausgelesen und werden // ins Listview eingetragen listView1.Groups.Add("LW" + i, smart.Names[i] + " (" + smart.Drives[i] + ")"); smart.AddSmartToListView(listView1, i); break; case ReadSmartResult.NO_SMART_AVAILABLE: // S.M.A.R.T. ist für dieses Laufwerk nicht verfügbar listView1.Groups.Add("LW" + i, smart.Names[i] + " (" + smart.Drives[i] + ")"); ListViewItem lvi = new ListViewItem(); lvi.Text = "S.M.A.R.T. not available"; lvi.Group = listView1.Groups[i]; listView1.Items.Add(lvi); break; case ReadSmartResult.ACCESS_DENIED: // Zugriff uafs Laufwerk verweigert, wahrscheinlich fehlen // Adminrechte (v.a. unter Vista) listView1.Groups.Add("LW" + i, smart.Names[i] + " (" + smart.Drives[i] + ")"); ListViewItem lvi2 = new ListViewItem(); lvi2.Text = "Zugriff verweigert, Administratorrechte benötigt!"; lvi2.Group = listView1.Groups[i]; listView1.Items.Add(lvi2); break; case ReadSmartResult.DRIVE_DOES_NOT_EXIST: // Das angegebene Laufwerk existiert nicht // nichts ausgeben break; } } }
Hoffentlich kann mir jemand helfen!
-
Was musstest du denn ändern?
Ich würde mal probieren ein bisschen mit den DLLImport-Attributen herumzuspielen, vielleicht CharSet auf Ansi setzen.
Oder es passt irgendwas nicht mit der Übergabe by value/by reference. Ist aber nur geraten.
-
Hallo,
nachdem ich erst zunächst gelöst habe indem ich die VB Datei einfach benutz habe muss ich es nun aber nach C# portieren.
Ich weiß jedoch wo der Fehler ist aber nicht warum.
Dieser VB.NET Code klappt:
Code vb:1 2 3 4 5 6 7 8 9
<DllImport("kernel32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Auto)> _ Friend Function DeviceIoControl(ByVal hDevice As IntPtr, ByVal dwioControlCode As Integer, ByVal lpInBuffer As IntPtr, ByVal nInBufferSize As Integer, <Out()> ByVal lpOutBuffer As StoragePredictFailure, ByVal nOutBufferSize As Integer, ByRef lpBytesReturned As Integer, ByVal lpOverlapped As IntPtr) As Boolean
Übersetz nach C# mit dem dazugehörigen Aufruf geht es nicht.
Code c#:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] private static extern bool DeviceIoControl(IntPtr hDevice, int dwioControlCode, IntPtr lpInBuffer, int nInBufferSize, out STORAGE_PREDICT_FAILURE lpOutBuffer, int nOutBufferSize, out int lpBytesReturned, IntPtr lpOverlapped); // ... // Aufruf bool Result = DeviceIoControl(Device, IOCTL_STORAGE_PREDICT_FAILURE, IntPtr.Zero, 0, out SmartData, Marshal.SizeOf(SmartData), out ReturnedBytes, IntPtr.Zero);
Ich kann mir das nicht erklären, das Programm wird einfach beendet, das heißt ich kann auch nicht den letzten Win32Error abrufen.
Das einzigste was ich sagen kann ist ...has exited with code -1073740791 (0xc0000409)., aber dazu findet man nichts im Internet.
Ähnliche Themen
-
[WDK] DeviceIoControl plötzlich fehlerhaft
Von Cromon im Forum C/C++Antworten: 0Letzter Beitrag: 11.12.10, 01:53 -
XML in C übersetzen
Von Tikonteroga im Forum XML TechnologienAntworten: 21Letzter Beitrag: 24.04.07, 10:05 -
Übersetzen
Von deforation im Forum Cinema 4DAntworten: 3Letzter Beitrag: 23.06.06, 19:47 -
Exe Datei patchen/übersetzen
Von Ak-Alex im Forum Coders TalkAntworten: 3Letzter Beitrag: 03.10.03, 21:10 -
DeviceIoControl
Von Chefprog im Forum Sonstige SprachenAntworten: 1Letzter Beitrag: 19.10.01, 15:10





Zitieren
Login




