请参阅下面的更新
我一直在尝试解决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)使我可以运行上面提供的示例,但是仍然存在问题。我在此处创建了一个包含以下文件的Gist ,这些文件在以1.9.3p545运行时会产生分段错误(尽管这次没有解释器变得没有响应并不会产生上述对话框)。机器以及另一台安装了相同版本Ruby且结果相同的机器。由于我之前没有提到它,因此我正在运行64位Windows 7 Pro,对于在其上测试过的另一台计算机也是如此。
我注意到一些可能暗示着更深层问题的事情,不一定与OpenProcessToken有关。以下任一情况都可以单独防止出现段错误:
extern
struct
在最后一种情况下,不必注释掉特定类别的所有项目。例如,如果我注释掉TOKEN_USER
和,则可以避免出现段错误SECURITY_ATTRIBUTES
。我也可以通过注释掉TOKEN_USER
与extern
关联的语句来防止段错误IsValidSecurityDescriptor
。我尝试了其他几种导致相同行为的组合。
任何帮助,将不胜感激。
此错误不是由于ruby,而是由于您的代码。
您在open_process_token方法中对DL :: CPtr类型的变量使用了不合适的方法ref。
方法open_process_token
def self.open_process_token
token_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
OpenProcessToken(Win.GetCurrentProcess, 0x8, token_handle.ref)
end
应该
def self.open_process_token
ptoken_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
OpenProcessToken(Win.GetCurrentProcess, 0x8, ptoken_handle)
token_handle = ptoken_handle.ptr.to_i
end
(感谢Heesob Park的本次发行。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句