请看下面的更新
我一直在尝试修复 Ruby 库跨 UAC 上下文与另一个程序通信的能力,并且需要创建一个与当前用户具有相同安全属性的共享文件映射。我正在使用 Ruby/dl 并试图让它在 Ruby 1.9.3 上工作是导致我的问题的原因。
在 advapi31 中调用OpenProcessToken函数会导致分段错误。您将在下面找到一个最小示例,它导致我的机器出现分段错误。我收到的错误文本在这里,这里也是错误文本打印到命令行后出现的错误框的屏幕截图:
require 'dl'
require 'dl/import'
require 'dl/types'
module Win
extend DL::Importer
dlload 'kernel32', 'advapi32'
include DL::Win32Types
# args: none
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
extern 'HANDLE GetCurrentProcess()'
# args: hProcessHandle, dwDesiredAccess, (out) phNewTokenHandle
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
extern 'BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE)'
# args: hObject
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
extern 'BOOL CloseHandle(HANDLE)'
# args: none
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx
extern 'DWORD GetLastError()'
def self.open_process_token
token_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
raise_error_if_zero(OpenProcessToken(Win.GetCurrentProcess, 0x8, token_handle.ref))
raise_error_if_zero(CloseHandle(token_handle))
end
def self.raise_error_if_zero(result)
if result == 0
raise "Windows error: #{Win.GetLastError}"
end
end
end
Win.open_process_token
更新
将 Ruby 更新到 1.9.3p545(使用 RubyInstaller)允许我运行上面提供的示例,但我仍然遇到问题。我在这里创建了一个包含文件的要点,这些文件在使用 1.9.3p545 运行时会产生分段错误(尽管这次没有解释器变得无响应并产生上述对话框。)我已经在我的机器以及另一台安装相同版本 Ruby 的机器,结果相同。由于我之前没有提到它,我正在运行 Windows 7 Pro 64 位,我测试它的另一台计算机也是如此。
我注意到一些可能暗示更深层次的问题的事情,不一定与 OpenProcessToken 相关。以下任何一项都可以单独防止段错误:
- 将 runner.rb 中的第 3 行复制到 mwe.rb 的底部并直接运行 mwe.rb。
- 注释掉 mwe.rb 的第 5 行或注释掉一些较大的 errors.rb 子集(例如注释掉第 37 到 99 行不会导致段错误)。
- 注释掉 runner.rb 的第 3 行,实际上只需要其他文件并退出。
- 从 Pageant::Win 中注释掉以下组合不会导致段错误:
- 来电
extern
- 来电
struct
- 常数
- 类方法
- 来电
在最后一种情况下,不需要注释掉特定类别的所有项目。例如,如果我注释掉TOKEN_USER
和SECURITY_ATTRIBUTES
. 我还可以通过注释掉TOKEN_USER
和extern
关联的语句来防止段错误IsValidSecurityDescriptor
。我尝试了其他几种导致相同行为的组合。
任何帮助,将不胜感激。