public static IDENTIFY_DEVICE_DATA?IdentifyDefice(string deviceName) { ATA_PASS_THROUGH_EX aptx = new ATA_PASS_THROUGH_EX(); ATADeviceQuiry adqry = new ATADeviceQuiry(); IDENTIFY_DEVICE_DATA idd = new IDENTIFY_DEVICE_DATA(); adqry.reqDataBuf = new byte[512]; adqry.header.Length = (ushort)Marshal.SizeOf(aptx); adqry.header.AtaFlags = ATA_FLAGS_DATA_IN; adqry.header.DataTransferLength = (ushort)adqry.reqDataBuf.Length; //512 adqry.header.DataBufferOffset = Marshal.OffsetOf(typeof(ATADeviceQuiry), "reqDataBuf"); adqry.header.TimeOutValue = 1; adqry.header.PreviousTaskFile = new IDEREGS(); adqry.header.CurrentTaskFile = new IDEREGS(); adqry.header.CurrentTaskFile.bCommandReg = WIN_IDENTIFYDEVICE; uint IOCTL_ATA_PASS_THROUGH = CTL_CODE( IOCTL_SCSI_BASE, 0x040b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); SafeFileHandle driveHandle = Kernel32Methods.CreateFileW( lpFileName: deviceName, dwDesiredAccess: Kernel32Methods.GENERIC_READ | Kernel32Methods.GENERIC_WRITE, // Administrative privilege is required dwShareMode: Kernel32Methods.FILE_SHARE_READ | Kernel32Methods.FILE_SHARE_WRITE, lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: Kernel32Methods.OPEN_EXISTING, dwFlagsAndAttributes: Kernel32Methods.FILE_ATTRIBUTE_NORMAL, hTemplateFile: IntPtr.Zero); if (driveHandle == null || driveHandle.IsInvalid) { #if DEBUG string message = GetErrorMessage(Marshal.GetLastWin32Error()); Console.WriteLine($"CreateFile (IdentifyDevice) with disk {deviceName} failed. Error: " + message); #endif driveHandle?.Close(); return(null); } uint returnBytesCount; bool result = Kernel32Methods.DeviceIoControl( hDevice: driveHandle, dwIoControlCode: IOCTL_ATA_PASS_THROUGH, lpInBuffer: ref adqry, nInBufferSize: (uint)Marshal.SizeOf(adqry), lpOutBuffer: ref adqry, nOutBufferSize: (uint)Marshal.SizeOf(adqry), lpBytesReturned: out returnBytesCount, lpOverlapped: IntPtr.Zero); driveHandle.Close(); if (result == false) { #if DEBUG string message = GetErrorMessage(Marshal.GetLastWin32Error()); Console.WriteLine($"DeviceIoControl (IdentifyDevice) with disk {deviceName} failed. Error: " + message); #endif return(null); } // Raw memory copy of reqDataBuf byte array to IDENTIFY_DEVICE struct IntPtr tempPtr = Marshal.AllocHGlobal(Marshal.SizeOf(idd)); Marshal.Copy(adqry.reqDataBuf, 0, tempPtr, adqry.reqDataBuf.Length); idd = (IDENTIFY_DEVICE_DATA)Marshal.PtrToStructure(tempPtr, idd.GetType()); Marshal.FreeHGlobal(tempPtr); return(idd); }
public static bool SetAPM(string driveName, byte apmVal) { ATA_PASS_THROUGH_EX aptx = new ATA_PASS_THROUGH_EX(); ATADeviceQuiry adq = new ATADeviceQuiry(); adq.reqDataBuf = new byte[512]; aptx.Length = (ushort)Marshal.SizeOf(aptx);; aptx.AtaFlags = ATA_FLAGS_DATA_IN; aptx.DataTransferLength = (ushort)adq.reqDataBuf.Length; //512; aptx.TimeOutValue = 1; aptx.DataBufferOffset = Marshal.OffsetOf(typeof(ATADeviceQuiry), "reqDataBuf"); aptx.PreviousTaskFile = new IDEREGS(); aptx.CurrentTaskFile = new IDEREGS(); aptx.CurrentTaskFile.bCommandReg = SET_FEATURES; switch (apmVal) { case 0: { throw new ArgumentException("APM value cannot be 0"); } // Disable APM case DISABLE_APM_VALUE: { aptx.CurrentTaskFile.bFeaturesReg = SETFEATURES_DIS_APM; break; } // Set APM to value default: { aptx.CurrentTaskFile.bFeaturesReg = SETFEATURES_EN_APM; aptx.CurrentTaskFile.bSectorCountReg = apmVal; break; } } adq.header = aptx; uint IOCTL_ATA_PASS_THROUGH = CTL_CODE( IOCTL_SCSI_BASE, 0x040b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); SafeFileHandle driveHandle = Kernel32Methods.CreateFileW( lpFileName: driveName, dwDesiredAccess: Kernel32Methods.GENERIC_READ | Kernel32Methods.GENERIC_WRITE, // Administrative privilege is required dwShareMode: Kernel32Methods.FILE_SHARE_READ | Kernel32Methods.FILE_SHARE_WRITE, lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: Kernel32Methods.OPEN_EXISTING, dwFlagsAndAttributes: Kernel32Methods.FILE_ATTRIBUTE_NORMAL, hTemplateFile: IntPtr.Zero); if (driveHandle == null || driveHandle.IsInvalid) { #if DEBUG string message = GetErrorMessage(Marshal.GetLastWin32Error()); Console.WriteLine($"CreateFile (APMControl) with disk {driveName} failed. Error: " + message); #endif driveHandle?.Close(); return(false); } uint returnBytesCount; bool result = Kernel32Methods.DeviceIoControl( hDevice: driveHandle, dwIoControlCode: IOCTL_ATA_PASS_THROUGH, lpInBuffer: ref adq, nInBufferSize: (uint)Marshal.SizeOf(adq), lpOutBuffer: ref adq, nOutBufferSize: (uint)Marshal.SizeOf(adq), lpBytesReturned: out returnBytesCount, lpOverlapped: IntPtr.Zero); driveHandle.Close(); if (result == false) { #if DEBUG string message = GetErrorMessage(Marshal.GetLastWin32Error()); Console.WriteLine($"DeviceIoControl (APMControl) with disk {driveName} failed. Error: " + message); #endif return(false); } return(result); }