C#/Native:使用 SCSI PassThrough 读取 HDD 串行

2023-12-08

我编写了三种利用本机的不同方法CreateFile and DeviceIoControl调用以检索 HDD 序列号(而不是型号)。第一个使用S.M.A.R.T.,第二个使用Storage Query第三个使用SCSI PassThrough。我的大部分代码都是基于的内容这个线程(有一些修复和改进)。

这是我使用得到的结果diskid32 实用程序:

Trying to read the drive IDs using physical access with admin rights

Drive Model Number________________: [ST975XXXXX]
Drive Serial Number_______________: [            6WS2XXXX]

Trying to read the drive IDs using physical access with zero rights

Product Id = [ST975XXXXX]
Serial Number = [6WS2XXXX]

Trying to read the drive IDs using Smart

Drive Model Number________________: [ST975XXXXX]
Drive Serial Number_______________: [            6WS2XXXX]

现在,这是使用我的方法的结果:

S.M.A.R.T. = 6WS2XXXX
Storage Query = 6WS2XXXX
SCSI PassThrough = ST975XXXXX

嗯……休斯顿,我们这里有问题。通过前两种方法,我得到了正确的序列号。最后一个我得到的型号非常糟糕。现在,这是我的代码:

--- METHOD ---

internal static String GetHardDiskSerialSCSIPassthrough(SafeFileHandle deviceHandle)
{
    IntPtr bufferPointer = IntPtr.Zero;
    String serial = String.Empty;
    UInt32 bytesReturned;

    SCSIPassthroughBuffered bspt = new SCSIPassthroughBuffered();
    bspt.SPT.Length = (UInt16)Marshal.SizeOf(bspt.SPT);
    bspt.SPT.CommandDescriptorBlockLength = 16;
    bspt.SPT.DataIn = 0x1;
    bspt.SPT.DataTransferLength = 64;
    bspt.SPT.DataBufferOffset = new IntPtr(Marshal.SizeOf(bspt) - 64);
    bspt.SPT.TimeOutValue = 60;
    bspt.SPT.CommandDescriptorBlock = new Byte[] { 0x12, 0x1, 0x80, 0x0, 64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

    Int32 bufferSize = Marshal.SizeOf(bspt);

    try
    {
        bufferPointer = Marshal.AllocHGlobal(bufferSize);

        Marshal.StructureToPtr(bspt, bufferPointer, true);

        if (DeviceIoControl(deviceHandle, 0x4D004, bufferPointer, (UInt32)bufferSize, bufferPointer, (UInt32)bufferSize, out bytesReturned, IntPtr.Zero) && (bytesReturned > 0))
        {
            SCSIPassthroughBuffered result = (SCSIPassthroughBuffered)Marshal.PtrToStructure(bufferPointer, typeof(SCSIPassthroughBuffered));
            serial = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length).Replace("\0", String.Empty).Trim();
        }
    }
    finally
    {
        Marshal.FreeHGlobal(bufferPointer);
    }

    return serial;
}

--- STRUCTURES ---

[StructLayout(LayoutKind.Sequential)]
private struct SCSIPassthrough
{
    public UInt16 Length;
    public Byte SCSIStatus;
    public Byte PathID;
    public Byte TargetID;
    public Byte LogicalUnitNumber;
    public Byte CommandDescriptorBlockLength;
    public Byte SenseInfoLength;
    public Byte DataIn;
    public UInt32 DataTransferLength;
    public UInt32 TimeOutValue;
    public IntPtr DataBufferOffset;
    public UInt32 SenseInfoOffset;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public Byte[] CommandDescriptorBlock;
}

[StructLayout(LayoutKind.Sequential)]
private struct SCSIPassthroughBuffered
{
    public SCSIPassthrough SPT;
    public UInt32 Filler;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
    public Byte[] Buffer;
}

我究竟做错了什么?也许使用了错误的 CDB?


您的代码实际上对我来说运行正常,即它返回与引用线程中描述的其他方法相同的数据。我必须做的唯一改变是:

serial = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length)
                       .Replace("\0", String.Empty)
                       .Trim();

To:

serial = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length)
                       .Substring(IntPtr.Size)
                       .Replace("\0", String.Empty)
                       .Trim();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#/Native:使用 SCSI PassThrough 读取 HDD 串行 的相关文章

  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • VB.NET 中的静态方法实现

    我很困惑Static在 VB NET 中的实现 在 C 中 我们可以创建静态类和静态方法来为我们的应用程序编写实用方法 现在 VB NET 让我们创建Module代替静态类 如果我们在模块中创建一个方法 默认情况下它会变成静态的 但在我的应
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 新添加的元素 $.each 和 events

    我已经阅读了很多帖子 each并新增了元素 事件附件 StackOverflow 上当前有关此主题的许多问题似乎对我不起作用 on 通常推荐 因为它允许我们附加新元素并且仍然维护单个事件侦听器 处理程序 在我当前的代码中 1 input t
  • 检测可穿戴设备何时与 Android 手机连接/断开连接

    Pebble 手表有一个 Intent 当 Pebble 连接 断开连接时会全局发送 这允许手机应用程序知道手表是否已连接 我已进行搜索 但无法找到有关 Android Wear 类似功能的信息 如何知道可穿戴设备是否已连接到手机 是否可以
  • 生成 Linkedin 访问令牌

    我一直在尝试使用简单的 REST 客户端以及 Mozilla 的 REST 插件 我正进入 状态 HTTP 1 1 401 未经授权 响应 正文中的 error unauthorized client error description 客
  • .NET,每分钟都有事件(每分钟)。计时器是最好的选择吗?

    我想使用 C 在 Windows 窗体应用程序中每分钟 按时钟 做一些事情 我只是想知道最好的方法是什么 我可以使用计时器并将其间隔设置为 60000 但要让它按分钟运行 我必须精确地按分钟启用它 这不太可行 我可以使用计时器并将其间隔设置
  • java.lang.SecurityException:权限拒绝:实现内容提供程序时打开提供程序

    我有问题 我尝试在我的消费者应用程序中实现内容提供程序 这是我来自应用程序 A 提供商 的 Android 清单
  • 以相反顺序打印 bash 参数

    我必须编写一个脚本 它将接受所有参数并反向打印它们 我已经提出了解决方案 但发现它非常糟糕 你有更聪明的主意吗 bin sh gt tekst txt for i in do echo i cat tekst txt gt temp mv
  • spring 3.0 MVC 似乎忽略 messages.properties

    Spring 3 0 MVC 首先 我没有找到任何有关 messages properties 的文档泉源我在各种论坛上发现了有关覆盖错误消息的所有内容 如果有人能参考 messages properties 的记录位置 那就太棒了 也许
  • MVC 3 和 DRY 自定义验证

    除非我遗漏了一些东西 这很有可能 否则在我看来 自定义验证总是违反 DRY 的 在我见过的所有示例中 即使使用 MVC 3 引入的全新非侵入式客户端验证 我们也必须为服务器端验证创建 NET 代码 并为客户端验证创建 jQuery 或 Ja
  • 我应该使用 HTML5 和 CSS3 吗?

    我是一个想要了解最新网络技术的人 但也很感激很多人仍然使用 IE6 7 8 如果一半内容在大多数浏览器上都无法显示 这是浪费代码 时间吗 这只是使用不同样式表的情况 还是只使用一个样式表 如果浏览器不支持文本阴影 那就搞砸了 他们可以看到它
  • 左填充猪中的一根绳子

    我想用 0 s 填充字符串数据类型字段 有什么办法可以做到这一点吗 我需要有固定长度 40 值 提前致谢 千里眼 零的数量需要根据剩余字符串的长度动态生成 所以我认为这在本地猪中是不可能的 这在 UDF 中是很有可能的 输入 txt 111
  • 在 Angular 2 中使用 Typescript 选择输入中的文本

    我正在尝试准确地执行中所描述的操作这个帖子 但是在 Angular2 中 基本上都是使用javascript函数 setSelectionRange start end 在用户单击触发器后的输入中 我找不到任何方法来使用 Typescrip
  • 如何将图片绘制到闭合曲线区域

    你好 我想在 onDraw Canvas canvas 中将图像的一部分绘制到闭合曲线上 我已经使用以下代码绘制了一条闭合曲线 油漆 setColor 颜色 红色 油漆 setAlpha 80 canvas drawPath turnpag
  • C++ #include 未找到

    当我在 Visual Studio Express 中编译 C 程序时 它说找不到atlbase h 我是否缺少一些 SDK 或者其他东西 视觉工作室 2017 When running the Visual Studio Installe
  • 基于表单的网站身份验证的权威指南[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 这个问题的答案是社区努力 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 版主注 这个问题不太适合我们的问答格式话题性规则目前适用于 Stack Overflow 对于内容
  • 如何访问FlipView内DataTemplate内的xaml控件

    我想访问 C 代码中的 图像 元素 我知道我无法直接访问它 因为它位于数据模板中 我已经尝试过视觉树 但仍然无法在代码中获取 图像 控制元素
  • 如何在 VS 负载测试之前设置 JWT 令牌

    我正在尝试运行 Visual Studio 负载测试 但在运行之前 我必须调用登录 webAPI 来生成 JWT 令牌 然后在所有 webAPI Web 测试中使用此令牌 我只需要调用一次登录即可生成令牌 我的所有其他 webAPI 调用中
  • 如何在.NET中不使用乘法运算符来实现乘法[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我想在 NET中实现两个整数的乘法而不使用乘法运算符 public uint Multi
  • 写入我的临时文件的权限被拒绝

    我正在尝试使用 Python 在 Windows 操作系统上创建并写入临时文件 我已经使用了Python模块tempfile创建一个临时文件 但是当我去写入临时文件时出现错误Permission Denied 我不允许写入临时文件吗 难道我
  • android.database.sqlite.SQLiteException:靠近“Group”:语法错误(代码1):

    Error Caused by android database sqlite SQLiteException near Group syntax error code 1 while compiling create table Grou
  • C#/Native:使用 SCSI PassThrough 读取 HDD 串行

    我编写了三种利用本机的不同方法CreateFile and DeviceIoControl调用以检索 HDD 序列号 而不是型号 第一个使用S M A R T 第二个使用Storage Query第三个使用SCSI PassThrough