gpt4 book ai didi

c# - SECURITY_ATTRIBUTES 何时更改,为什么更改?

转载 作者:行者123 更新时间:2023-12-04 18:07:22 24 4
gpt4 key购买 nike

我有一些代码使用 P/Invoke 来启动进程并捕获标准输出。 (我们为什么使用 P/Invoke 而不是 System.Diagnostics.Process 来做这件事的故事很长很复杂;可以说它是一项要求就足够了。)它已经在高负载下在生产中工作了将近一年,并且进行了测试一直通过。

今天早上虽然我跑了测试,但他们失败了。我不能确定我最后一次在今天早上(2014 年 5 月 15 日)之前运行测试是什么时候,但我相信是 2014 年 4 月 24 日。测试通过了,但今天早上失败了。我收到了“PInvokeStackImbalance”错误消息,所以我做了一些研究,最终实现了 extern 使用的结构之一的签名。方法(在本例中为 CreatePipe)不正确。我改变了它,测试又开始通过了。

我很高兴找到了修复程序,但我担心部署。 为什么结构体的签名会发生变化? 我没有升级我的操作系统或任何东西 - 我在 4/24 上运行 Windows 7 x64,我现在仍在运行它。 (部署环境是 Windows Server 2012。)从那以后我安装(和卸载)了一些应用程序,但它们一直是轻量级的 3rd 方工具,而不是 Microsoft 或系统组件。我认为 Windows 更新修补程序负责,但我不知道是哪个。

需要明确的是,在我自己的代码中,我所做的只是更改:

    [StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public UInt32 nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}

对此:
    [StructLayout(LayoutKind.Sequential)]
internal class SECURITY_ATTRIBUTES
{
public int nLength = 12;
public IntPtr lpSecurityDescriptor = IntPtr.Zero;
public bool bInheritHandle;
}

当我部署到生产环境时,我需要确保我为让代码在我的机器上运行所做的更改不会破坏应用程序。有谁知道如何确定需要更改的内容以及如何确定生产环境是否需要更改?

编辑:

这是为标准输出打开管道的代码:
    private PipeInfo CreatePipe()
{
PipeInfo pipeInfo = new PipeInfo();

SafeFileHandle safeFileHandle = null;
try
{
Native.SECURITY_ATTRIBUTES pipeAttributes = new Native.SECURITY_ATTRIBUTES();
pipeAttributes.bInheritHandle = true;
if (!Native.CreatePipe(out safeFileHandle, out pipeInfo.ChildHandle, pipeAttributes, 0) || safeFileHandle.IsInvalid || pipeInfo.ChildHandle.IsInvalid)
{
throw new Win32Exception();
}

if (!Native.DuplicateHandle(new HandleRef(this, Native.GetCurrentProcess()), safeFileHandle, new HandleRef(this, Native.GetCurrentProcess()), out pipeInfo.ParentHandle, 0, false, 2))
{
throw new Win32Exception();
}
}
finally
{
if (safeFileHandle != null && !safeFileHandle.IsInvalid)
{
safeFileHandle.Close();
}
}

return pipeInfo;
}

我不能完全相信这段代码,我很大程度上从 .NET Reference Source 中取消了它。

只是要明确时间表:
  • 2013 年 5 月 - 写 CreatePipe带有 SECURITY_ATTRIBUTES 的第一个版本的代码
  • 2013 年 6 月 - 部署;代码自
  • 以来一直运行成功
  • 2014 年 4 月 - 没有进行任何更改,代码开始抛出堆栈不平衡错误
  • 2014 年 5 月 - 我更改为 SECURITY_ATTRIBUTES 的第二个版本并且错误消失
  • 最佳答案

    我们在 x64 上遇到了这个问题,这篇文章是我们搜索的最高结果。我们对 nLength 使用了魔法 12,就像我们从 C# 源程序中获得的解决方案一样:https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs

        [StructLayout(LayoutKind.Sequential)]
    internal class SECURITY_ATTRIBUTES {
    #if !SILVERLIGHT
    // We don't support ACL's on Silverlight nor on CoreSystem builds in our API's.
    // But, we need P/Invokes to occasionally take these as parameters. We can pass null.
    public int nLength = 12;
    public SafeLocalMemHandle lpSecurityDescriptor = new SafeLocalMemHandle(IntPtr.Zero, false);
    public bool bInheritHandle = false;
    #endif // !SILVERLIGHT
    }
    事实证明 CreatePipe 需要一个指针,来自 docs :

    lpPipeAttributes

    A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpPipeAttributes is NULL, the handle cannot be inherited.


    stackoverflow post 中详细介绍了解决方案.它适用于 x86 和 x64。我们的代码基于堆栈溢出帖子和进程源(使用 DWORD = System.UInt32; 在顶部)。
    internal static class NativeMethods
    {

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe,
    IntPtr lpPipeAttributes, int nSize);

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, SafeHandle hSourceHandle,
    IntPtr hTargetProcess, out SafeFileHandle targetHandle, int dwDesiredAccess,
    bool bInheritHandle, int dwOptions);

    [StructLayout(LayoutKind.Sequential)]
    public struct PIPE_SECURITY_ATTRIBUTES
    {
    public DWORD nLength;
    public IntPtr lpSecurityDescriptor;
    [MarshalAs(UnmanagedType.Bool)]
    public bool bInheritHandle;
    }

    public static void CreatePipe(out SafeFileHandle parentHandle, out SafeFileHandle childHandle, bool parentInputs)
    {
    PIPE_SECURITY_ATTRIBUTES lpPipeAttributes = new PIPE_SECURITY_ATTRIBUTES();
    lpPipeAttributes.nLength = (DWORD)Marshal.SizeOf(lpPipeAttributes);
    lpPipeAttributes.bInheritHandle = true;
    lpPipeAttributes.lpSecurityDescriptor = IntPtr.Zero;
    IntPtr attr = Marshal.AllocHGlobal(Marshal.SizeOf(lpPipeAttributes));
    Marshal.StructureToPtr(lpPipeAttributes, attr, true);
    SafeFileHandle hWritePipe = null;
    try
    {
    if (parentInputs)
    CreatePipeWithSecurityAttributes(out childHandle, out hWritePipe, attr, 0);
    else
    CreatePipeWithSecurityAttributes(out hWritePipe, out childHandle, attr, 0);
    if (!DuplicateHandle(GetCurrentProcess(), hWritePipe, GetCurrentProcess(), out parentHandle, 0, false, 2))
    throw new Exception();
    }
    finally
    {
    if ((hWritePipe != null) && !hWritePipe.IsInvalid)
    {
    hWritePipe.Close();
    }
    }
    }

    public static void CreatePipeWithSecurityAttributes(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe,
    IntPtr lpPipeAttributes, int nSize)
    {
    hReadPipe = null;
    if ((!CreatePipe(out hReadPipe, out hWritePipe, lpPipeAttributes, nSize) || hReadPipe.IsInvalid) || hWritePipe.IsInvalid)
    throw new Exception();
    }
    }

    关于c# - SECURITY_ATTRIBUTES 何时更改,为什么更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23687015/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com