Abe*_*bel 5 .net c# pinvoke interop marshalling
我需要某个任务来枚举系统中的所有句柄.到目前为止,我发现的最好的方法是使用underdocumented NtQuerySystemInformationwith SystemHandleInformationclass参数.
到现在为止还挺好.但是,在64位Windows上以32位模式运行它,所需的结构如下:
// 32-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public uint ProcessID;
public byte ObjectTypeNumber;
public byte Flags;
public ushort Handle;
public uint Object_Pointer;
public UInt32 GrantedAccess;
}
Run Code Online (Sandbox Code Playgroud)
而对于64位Windows(x64,我没有测试Itanium,我希望没有什么不同......),结构如下:
// 64-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public int Reserved; // unknown, no documentation found
public uint ProcessID;
public byte ObjectTypeNumber;
public byte Flags;
public ushort Handle;
public long Object_Pointer;
public UInt32 GrantedAccess;
}
Run Code Online (Sandbox Code Playgroud)
现在,我应该改变Object_Pointer成IntPtr.我希望我能做同样的事情ProcessId,有一个参考说这实际上是一个HANDLE实际上是64位的值.但是,Reserved总是为零,所以我不能IntPtr以相同的方式合并它.
这可能不是发生这种情况的唯一情况.我正在寻找处理这些差异的最佳实践方法:
#if WIN32除非我想维护单独的二进制文件,否则使用常量like (在IntPtr的引用源内部使用)将不起作用.if IntPtr.Size ==4在代码中使用.这适用于外部函数,但不适用于类型.GetType但我不确定它在哪里引导(可能有助于编组?).这些都不是理想的,但到目前为止,唯一万无一失的方法似乎就是用if IsWin64()声明给我的系统加油.我希望听到比我更好的方法.
鉴于 IntPtr 的大小不同,为什么不尝试以下操作:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public IntPtr ProcessID; // mask with 0xffffffff
public byte ObjectTypeNumber;
public byte Flags;
public ushort Handle;
public IntPtr Object_Pointer; // again good for 32/64bit
public UInt32 GrantedAccess;
}
Run Code Online (Sandbox Code Playgroud)
这应该适用于未更改的 32 位和 64 位。
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |