Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用ctypes实现NtCreateNamedPipeFile_Python_Winapi_Ctypes_Named Pipes - Fatal编程技术网

在Python中使用ctypes实现NtCreateNamedPipeFile

在Python中使用ctypes实现NtCreateNamedPipeFile,python,winapi,ctypes,named-pipes,Python,Winapi,Ctypes,Named Pipes,我正试图用ctypes从NTAPI实现NtCreateNamedPipeFile未记录的函数,但我无法让它工作(我对ctypes几乎没有经验) 首先,如果我提供了函数定义中的所有参数,我会得到一个错误“ValueError:调用的过程可能包含太多的参数(超过4个字节)” 如果删除NamedPipeFileHandle参数(假设句柄可能是此函数返回的句柄),则会得到“OSError:[WinError 87]参数不正确” 我试图在我的实现中调整类型和参数,但无论我做什么,我都会得到相同的WinEr

我正试图用ctypes从NTAPI实现NtCreateNamedPipeFile未记录的函数,但我无法让它工作(我对ctypes几乎没有经验)

首先,如果我提供了函数定义中的所有参数,我会得到一个错误“ValueError:调用的过程可能包含太多的参数(超过4个字节)”

如果删除NamedPipeFileHandle参数(假设句柄可能是此函数返回的句柄),则会得到“OSError:[WinError 87]参数不正确”

我试图在我的实现中调整类型和参数,但无论我做什么,我都会得到相同的WinError87。 它不是很具有描述性,所以很难理解我在这里做错了什么(可能是很多事情)

以下是定义:

ULONG_PTR = ctypes.wintypes.WPARAM
FILE_READ_DATA = 0x00000001
FILE_WRITE_DATA = 0x00000002
SYNCHRONIZE = 0x00100000
FILE_READ_ATTRIBUTES = 0x80
FILE_CREATE = 0x00000002

def NtError(status):
    err = ntdll.RtlNtStatusToDosError(status)
    return ctypes.WinError(err)


class IO_STATUS_BLOCK(ctypes.Structure):
    class _STATUS(ctypes.Union):
        _fields_ = (('Status',  LONG),
                    ('Pointer', LPVOID))
    _anonymous_ = '_Status',
    _fields_ = (('_Status', _STATUS),
                ('Information', ULONG_PTR))


class UNICODE_STRING(ctypes.Structure):
    _fields_ = (('Length', USHORT),
                ('MaximumLength', USHORT),
                ('Buffer', LPWSTR))

class OBJECT_ATTRIBUTES(ctypes.Structure):
    _fields_ = (
        ('Length', ULONG),
        ('RootDirectory', HANDLE),
        ('ObjectName', UNICODE_STRING),
        ('Attributes', ULONG),
    )

ntdll = ctypes.WinDLL('ntdll')

def _decl(name, ret=None, args=()):
    fn = getattr(ntdll, name)
    fn.restype = ret
    fn.argtypes = args
    return fn

NtCreateNamedPipeFile = _decl('NtCreateNamedPipeFile', LONG,
                              (
                                   POINTER(HANDLE),
                                   DWORD,
                                   POINTER(OBJECT_ATTRIBUTES),
                                   POINTER(IO_STATUS_BLOCK),
                                   ULONG,
                                   ULONG,
                                   ULONG,
                                   BOOL,
                                   BOOL,
                                   BOOL,
                                   ULONG,
                                   ULONG,
                                   ULONG,
                                   LARGE_INTEGER))
电话本身:

handle = HANDLE()
iosb = IO_STATUS_BLOCK()

us_pipe_name = UNICODE_STRING()
us_pipe_name.Buffer = '\\??\\pipe\\' + name
us_pipe_name.Length = len(us_pipe_name.Buffer)
us_pipe_name.MaximumLength = len(us_pipe_name.Buffer)

obj_attrs = OBJECT_ATTRIBUTES()
obj_attrs.ObjectName = us_pipe_name

status = NtCreateNamedPipeFile(
    # ctypes.byref(handle),  # NamedPipeFileHandle
    FILE_READ_DATA | SYNCHRONIZE,  # DesiredAccess
    ctypes.byref(obj_attrs),  # ObjectAttributes
    ctypes.byref(iosb),  # IoStatusBlock
    0,  # ShareAccess
    FILE_CREATE,  # CreateDisposition
    0,  # CreateOptions
    0,  # WriteModeMessage
    0,  # ReadModeMessage
    1,  # NonBlocking
    1,  # MaxInstances
    1024,  # InBufferSize
    1024,  # OutBufferSize
    0,  # DefaultTimeout
)

if status != 0:
    exception = NtError(status)
    raise exception

我在这里做错了什么?

NtCreateNamedPipeFile
return
NTSTATUS
code,而不是win32错误。它永远不会回来<代码>“\\?\\pipe\\”-路径前缀无效。必须是
'\\??\\pipe\\\\'
或更好的
'\\GLOBAL???\\pipe\\\'
或更好的
'\\Device\\NamedPipe\\\\'
。也使用非阻塞模式不是好主意。如果需要异步io-使用它而不是非阻塞同步模式-只需不使用CreateOptions中的
FILE\u SYNCHRONOUS\u io\u NONALERT
FILE\u SYNCHRONOUS\u io\u ALERT
(您现在可以这样做)。`OBJECT_属性`有更多字段。这里有一些问题。您对UNICODE\u字符串的处理是错误的<代码>长度和
最大长度
应以字节为单位,而不是以字符为单位。您在
OBJECT\u属性中缺少两个字段--
SecurityDescriptor
SecurityQualityOfService
,并且您没有将
Length
字段初始化为
ctypes.sizeof(self)
。对于此系统调用,
ShareAccess
具有特殊含义。读写共享是双工的;读共享是出站的;写入共享是入站的;IIRC 0共享是无效参数。通常,如果不是第一个实例,则处置应为
文件\u打开\u(3)。您只允许使用一个实例,因此请确保这是第一个实例,并且
文件\u CREATE
处置是可以的。一般来说,使用通用权限更可靠。请求对入站进行
GENERIC\u READ
访问,对出站进行
GENERIC\u WRITE
访问,对双工同时进行。如果您使用的是同步I/O(例如,
FILE\u synchronous\u IO\u NONALERT
),请同时请求
SYNCHRONIZE
访问(它属于通用权限,但I/O管理器不够聪明,无法检查此项)。如果您尚未请求
GENERIC\u READ
access,则还需要请求
FILE\u READ\u ATTRIBUTES
,以便能够通过
NtQueryInformationFile
FilePipeLocalInformation
查询管道状态。