标签: deviceiocontrol

在.NET中,如何在NTFS中创建连接,而不是Symlink?

我正在尝试创建一个NTFS Junction.从cmd行我可以使用sysinternals中junction.exe工具执行此操作.结点的DIR cmd输出如下所示:

 Volume in drive C has no label.
 Volume Serial Number is C8BC-2EBD

 Directory of c:\users\cheeso\Documents

03/22/2009  09:45 PM    <JUNCTION>     My Music [\??\c:\users\cheeso\Music]
05/11/2007  05:42 PM    <DIR>          My Received Files
03/22/2009  09:46 PM    <JUNCTION>     my videos [\??\c:\users\cheeso\Videos]
Run Code Online (Sandbox Code Playgroud)

我在某地读过Junctions是Symbolic Links的子集.

所以我尝试使用CreateSymbolicLink创建一个Junction.当我这样做时,我实际上得到了一个符号链接,而不是一个连接点.

09/09/2009  11:50 AM    <SYMLINKD>     newLink [.\]
Run Code Online (Sandbox Code Playgroud)

还有CreateHardLink.那里的文档说交汇点(又名"重新分析点")是硬链接的子集.但我似乎无法接受这项工作.它完成但没有创建硬链接或联结.

我正在使用.NET/C#,导入如下所示:

    [Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)]
    public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);

    [Interop.DllImport("kernel32.dll", EntryPoint="CreateHardLinkW", CharSet=Interop.CharSet.Unicode)]
    public static extern bool CreateHardLink(string lpFileName, …
Run Code Online (Sandbox Code Playgroud)

.net pinvoke winapi ntfs deviceiocontrol

15
推荐指数
1
解决办法
8130
查看次数

HDD序列号在Windows XP,Vista和7中每2字节翻转一次,但在Windows 8中则不翻

我需要获取HDD序列号,以将其用作许可软件的密钥.我在这个url中使用了diskid32代码:http://www.winsim.com/diskid32/diskid32.html 它使用了DeviceIoControl Win32 API和IO控制代码IOCTL_STORAGE_QUERY_PROPERTY.

有效.但是,当我仔细检查硬盘本身上印刷的实际序列号时,我发现该号码的每2个字节都被翻转了.

一个简单的解决方案可能是简单地将字节翻转回来.它适用于Windows XP,Vista和7,但在Windows 8中不需要翻转!

我想知道在Windows XP,Vista和7中翻转字节的确切原因,以及为什么不在Windows 8中翻转.下一个Windows怎么

部分代码略有变化:

  int drive = 0;
  HANDLE hPhysicalDriveIOCTL = 0;
  char driveName [256];
  sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
  //  Windows NT, Windows 2000, Windows XP - admin rights not required
  hPhysicalDriveIOCTL = CreateFile (driveName, 0,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                           OPEN_EXISTING, 0, NULL);
  if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
  {
     _STORAGE_PROPERTY_QUERY query;
     DWORD cbBytesReturned = 0; …
Run Code Online (Sandbox Code Playgroud)

ioctl windows-8 deviceiocontrol

14
推荐指数
1
解决办法
2937
查看次数

Pinvoke DeviceIoControl参数

我正在使用C#项目DeviceIoControl.我已经为我的签名咨询了相关的Pinvoke.net页面:

[DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
    SafeFileHandle hDevice,
    EIOControlCode IoControlCode,

    [MarshalAs(UnmanagedType.AsAny)]
    [In] object InBuffer,
    uint nInBufferSize,

    [MarshalAs(UnmanagedType.AsAny)]
    [Out] object OutBuffer,
    uint nOutBufferSize,

    out uint pBytesReturned,
    [In] IntPtr Overlapped
    );
Run Code Online (Sandbox Code Playgroud)

我从来没有见过object和前,但MSDN文档听起来前途:[MarshalAs(UnmanagedType.AsAny)]

一种动态类型,它在运行时确定对象的类型,并将对象编组为该类型.该成员仅对平台调用方法有效.

我的问题是:使用此签名的"最佳"和/或"正确"方式是什么?

例如,IOCTL_STORAGE_QUERY_PROPERTY期望InBuffer是一个STORAGE_PROPERTY_QUERY结构.看起来我应该能够定义该结构,创建一个new实例,并将其传递给我的Pinvoke签名:

var query = new STORAGE_PROPERTY_QUERY { PropertyId = 0, QueryType = 0 };
DeviceIoControl(..., query, Marshal.SizeOf(query), ...);
Run Code Online (Sandbox Code Playgroud)

但是,我刚刚System.ExecutionEngineException做了这个,所以我改为:

int …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke deviceiocontrol

12
推荐指数
1
解决办法
7533
查看次数

无法将 C# 字符串从用户空间传递到内核模式 C 并使用它来查找特定的 LDR_DATA_TABLE_ENTRY

我在比较从用户模式类型 LPWSTR 传递到 LDR 表条目类型 UNICODE_STRING 的字符串时遇到困难

内核 C:

struct {
    int pid;
    int user_pid;
    int size;
    int protection_mode;
    int allocation_type;
    void* address;
    void* write_buffer;
    LPWSTR module_name;
}
userland_operation;
Run Code Online (Sandbox Code Playgroud)

这个结构体通过 deviceiocontrol 传递给内核。对应的用户空间结构如下:

public struct MemOperation
{
    public int Pid;
    public int UserPid;
    public int Size;
    public int protection_mode;
    public int allocation_type;
    public IntPtr Addr;
    public IntPtr WriteBuffer;
    [MarshalAs(UnmanagedType.LPWStr)] public String ModuleName;
}
Run Code Online (Sandbox Code Playgroud)

字符串在哪里 ModuleName被编组为 LPWStr。

ModuleName是进程中加载​​模块的所需搜索词。现在,事情变得棘手了。我可以通过访问的字符串_LDR_DATA_TABLE_ENTRYUNICODE_STRING. 我想将此 UNICODE_STRING 与我的 LPWSTR 进行比较。

我尝试了以下方法,但没有奏效:

{
    UNICODE_STRING …
Run Code Online (Sandbox Code Playgroud)

c c# deviceiocontrol windows-kernel

10
推荐指数
1
解决办法
119
查看次数

C#WriteFile()停止在USB驱动器上的扇区242写入

我编写了下面的代码,将0xFF写入USB存储设备上的所有字节.由于某种原因,WriteFile()调用在扇区242开始出错.我在两个独立的USB存储设备上完成了这个操作,然后在十六进制编辑器中检查设备.扇区242似乎是FAT16格式化设备上文件分配表的开始,以及NTFS设备上引导区域的开始.我确信它在这些确切的位置错误并不是巧合,但是我不知道如何改变这种行为.我在WriteFile失败时收到的HRESULT是-2147024891,即E_ACCESSDENIED.有谁知道可能导致问题的原因是什么?

注意:如果您要在本地系统上运行此代码,请非常小心,因为我已经硬编码了USB设备的物理设备ID.请务必使用您尝试写入的设备更新deviceId变量.你不想破坏你的硬盘.

    public enum EMoveMethod : uint
    {
        Begin = 0,
        Current = 1,
        End = 2
    }

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint SetFilePointer([In] SafeFileHandle hFile, [In] long lDistanceToMove, [Out] out int lpDistanceToMoveHigh, [In] EMoveMethod dwMoveMethod);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

    [DllImport("kernel32", SetLastError = true)]
    internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes, int numBytesToRead, out …
Run Code Online (Sandbox Code Playgroud)

c# file-io deviceiocontrol

8
推荐指数
1
解决办法
5292
查看次数

如何正确检索电池序列号?

在Delphi 7中,我正在开发一个库,该库实现了一个对象,该对象封装了有关连接到系统的电池的信息.除了检索电池的序列号外,它运行良好.

我用于此次调用的代码如下:

function TBattery.GetSerialNumber(hbat: THandle): boolean;
var
  bqi:          TBatteryQueryInformation;
  Serial:       PWideChar;
  SerialSize,
  dwOut:        DWORD;
begin
  Result := False;

  if hbat <> INVALID_HANDLE_VALUE then
  begin
    ZeroMemory(@bqi, SizeOf(bqi));
    dwOut := 0;

    bqi.BatteryTag := FBatteryTag;
    bqi.InformationLevel := BatterySerialNumber;

    SerialSize := 2048;
    GetMem(Serial, SerialSize);
    try
      ZeroMemory(Serial, SerialSize);

      Result := DeviceIoControl(hbat, IOCTL_BATTERY_QUERY_INFORMATION, @bqi,
                                SizeOf(bqi), Serial, SerialSize, @dwOut, nil);

      if Result then
        FSerialNumber := Serial;
    finally
      FreeMem(Serial, SerialSize);
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

不幸的是,DeviceIoControl()总是返回False,如果我GetLastError()之后检查然后它返回错误87,"参数不正确."

这没有多大意义,因为如果我简单地将InformationLevelfrom 更改为BatterySerialNumberto BatteryUniqueID …

delphi winapi deviceiocontrol

7
推荐指数
1
解决办法
2144
查看次数

物理磁盘大小不正确(IoCtlDiskGetDriveGeometry)

我使用下面的代码来获取物理磁盘大小,但返回的大小不正确.我用其他工具检查了尺寸.

以下代码报告

总磁盘空间:8.249.955.840字节

它应该是

总磁盘空间:8.254.390.272字节

如何检索实际/正确的物理磁盘大小?在USB驱动器和普通硬盘上测试.代码很长,这里将它分开来显示.

结构:

[StructLayout(LayoutKind.Sequential)]
internal struct DiskGeometry {
    public long Cylinders;
    public int MediaType;
    public int TracksPerCylinder;
    public int SectorsPerTrack;
    public int BytesPerSector;
}
Run Code Online (Sandbox Code Playgroud)

原生方法:

internal static class NativeMethods {
    [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern SafeFileHandle CreateFile(
        string fileName,
        uint fileAccess,
        uint fileShare,
        IntPtr securityAttributes,
        uint creationDisposition,
        uint flags,
        IntPtr template
        );

    [DllImport("Kernel32.dll", SetLastError=false, CharSet=CharSet.Auto)]
    public static extern int DeviceIoControl(
        SafeFileHandle device,
        uint controlCode,
        IntPtr inBuffer,
        uint inBufferSize,
        IntPtr outBuffer, …
Run Code Online (Sandbox Code Playgroud)

c# size ioctl disk deviceiocontrol

6
推荐指数
1
解决办法
3789
查看次数

如何异步调用DeviceIOControl代码?

我试图通过使用MSDN上描述的OVERLAPPED结构异步调用DeviceIO函数.我使用FSCTL_ENUM_USN_DATA控制代码枚举NTFS驱动器的MFT,但我不能异步运行它.文件句柄是使用FILE_FLAG_OVERLAPPED创建的,但是我是否使用FILE_FLAG_OVERLAPPED的重叠结构没有区别.该功能不会立即返回.在这两种情况下似乎都是同步的.下面的示例显示了C:\驱动器上前100.000个MFT条目的枚举.由于我不太熟悉重叠结构的使用,我可能做错了.我的问题:如何异步执行DeviceIoControl(hDevice,FSCTL_ENUM_USN_DATA,...)?谢谢你的帮助.

#include "stdafx.h"
#include <Windows.h>

typedef struct {
  DWORDLONG  nextusn;
  USN_RECORD FirstUsnRecord;
  BYTE Buffer[500];
}TDeviceIoControlOutputBuffer, *PTDeviceIoControlOutputBuffer;

int _tmain(int argc, _TCHAR* argv[])
{
    MFT_ENUM_DATA lInputMftData;
    lInputMftData.StartFileReferenceNumber = 0;
    lInputMftData.MinMajorVersion = 2;
    lInputMftData.MaxMajorVersion = 3;
    lInputMftData.LowUsn = 0;
    lInputMftData.HighUsn = 0;

    TDeviceIoControlOutputBuffer lOutputMftData;
    DWORD lOutBytesReturned = 0;
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    OVERLAPPED  lOverlapped = { 0 };
    lOverlapped.hEvent = hEvent;
    LPCWSTR path = L"\\\\.\\C:";
    HANDLE hDevice = CreateFile(path, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if …
Run Code Online (Sandbox Code Playgroud)

asynchronous ioctl overlap overlapped-io deviceiocontrol

6
推荐指数
1
解决办法
2081
查看次数

获取文件夹ID C#

我试图在他们的生命周期中跟踪文件和文件夹(他们可能被移动或重命名).我已经完成了搜索,发现FileSystemWatcher可能是最流行的跟踪文件和文件夹的方式,但是,这对我来说不起作用,因为应用程序可能会也可能不会一直运行.我选择尝试通过ID跟踪文件夹.

我找到了一种方法来跟踪来自此堆栈帖子的答案的ID中的文件.我可以在此答案中基于方法B成功获取文件ID .

在搜索时我发现这个堆栈帖子说明他使用FSCTL_GET_OBJECT_ID找到了他的解决方案.我花了很多时间试图弄清楚如何使用这个功能,但我无法绕过它.我基本上没有从C#中调用本机Windows函数的经验.

任何人都可以为我推动正确的方向吗?我觉得我必须遗漏一些明显的东西.

有没有理由C#无法访问文件/文件夹ID?跟踪文件/文件夹是不常见的?

编辑,添加代码:

        static uint returnVal;

    //Working example to get File ID
    public static string GetFileId(string path)
    {
        WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();

        FileInfo fi = new FileInfo(path);
        FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        WinAPI.GetFileInformationByHandle(fs.Handle, out objectFileInfo);

        fs.Close();

        ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + (ulong)objectFileInfo.FileIndexLow;

        return fileIndex.ToString();
    }

    public static string GetFolderId(string path)
    {
        //Get a handle on the given folder
        IntPtr cFile = WinAPI.CreateFile( …
Run Code Online (Sandbox Code Playgroud)

c# windows winapi deviceiocontrol

5
推荐指数
1
解决办法
3441
查看次数

在 Windows 10 上浏览 NTFS 更改日志

我正在尝试阅读 NTFS 更改日志,但我注意到我能找到的所有示例代码在 Windows 10 上都失败了,即使它在 Windows 7 上也能运行。

例如,Microsoft 自己的示例Walking a Buffer of Change Journal Records可在 Windows 7 上运行,但是当我在 Windows 10 上运行相同的代码时,当我使用 FSCTL_READ_USN_JOURNAL 调用 DeviceIoControl 时,我收到错误 87(参数不正确)(请注意,前面的调用到 DeviceIoControl 与 FSCTL_QUERY_USN_JOURNAL 成功完成并返回有效数据。)。

我什至将 EXE 编译并在 Windows 7 上运行并将其复制到 Windows 10 机器,但它仍然失败,所以我相信 Windows 10 可能对参数验证或类似的东西更严格?

我以管理员身份运行代码,所以这不是问题。

我找不到对此问题的任何其他引用,但是如果我采用其他人的示例代码并尝试在 Windows 10 上运行它,我会遇到同样的问题。

编辑:

代码本身:

#include <Windows.h>
#include <WinIoCtl.h>
#include <stdio.h>

#define BUF_LEN 4096

void main()
{
   HANDLE hVol;
   CHAR Buffer[BUF_LEN];

   USN_JOURNAL_DATA JournalData;
   READ_USN_JOURNAL_DATA ReadData = {0, 0xFFFFFFFF, FALSE, 0, 0};
   PUSN_RECORD …
Run Code Online (Sandbox Code Playgroud)

winapi ntfs visual-c++ deviceiocontrol

5
推荐指数
1
解决办法
1646
查看次数