📄 python.pm
字号:
} else { $self->pidl("result = $conv;"); } $signature .= "result"; } if (substr($signature, -2) eq ", ") { $signature = substr($signature, 0, -2); } if ($result_size > 1) { $signature .= ")"; } $self->pidl("return result;"); $self->deindent; $self->pidl("}"); $self->pidl(""); return ($outfnname, $signature);}sub PythonFunctionPackIn($$$){ my ($self, $fn, $fnname) = @_; my $metadata_args = find_metadata_args($fn); my $infnname = "pack_$fnname\_args_in"; $self->pidl("static bool $infnname(PyObject *args, PyObject *kwargs, struct $fn->{NAME} *r)"); $self->pidl("{"); $self->indent; my $args_format = ""; my $args_string = ""; my $args_names = ""; my $signature = ""; foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/,@{$e->{DIRECTION}})); next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, @{$e->{DIRECTION}})); $self->pidl("PyObject *py_$e->{NAME};"); $args_format .= "O"; $args_string .= ", &py_$e->{NAME}"; $args_names .= "\"$e->{NAME}\", "; $signature .= "$e->{NAME}, "; } if (substr($signature, -2) eq ", ") { $signature = substr($signature, 0, -2); } $self->pidl("const char *kwnames[] = {"); $self->indent; $self->pidl($args_names . "NULL"); $self->deindent; $self->pidl("};"); $self->pidl(""); $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"$args_format:$fn->{NAME}\", discard_const_p(char *, kwnames)$args_string)) {"); $self->indent; $self->pidl("return false;"); $self->deindent; $self->pidl("}"); $self->pidl(""); my $env = GenerateFunctionInEnv($fn, "r->"); my $fail = "return false;"; foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/,@{$e->{DIRECTION}})); if ($metadata_args->{in}->{$e->{NAME}}) { my $py_var = "py_".$metadata_args->{in}->{$e->{NAME}}; $self->pidl("PY_CHECK_TYPE(PyList, $py_var, $fail);"); my $val = "PyList_Size($py_var)"; if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") { $self->pidl("r->in.$e->{NAME} = talloc_ptrtype(r, r->in.$e->{NAME});"); $self->pidl("*r->in.$e->{NAME} = $val;"); } else { $self->pidl("r->in.$e->{NAME} = $val;"); } } else { $self->ConvertObjectFromPython($env, "r", $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail); } } $self->pidl("return true;"); $self->deindent; $self->pidl("}"); $self->pidl(""); return ($infnname, $signature);}sub PythonFunction($$$){ my ($self, $fn, $iface, $prettyname) = @_; my $fnname = "py_$fn->{NAME}"; my $docstring = $self->DocString($fn, $fn->{NAME}); my ($insignature, $outsignature); my ($infn, $outfn); if (has_property($fn, "todo")) { unless ($docstring) { $docstring = "NULL"; } $infn = "NULL"; $outfn = "NULL"; } else { ($infn, $insignature) = $self->PythonFunctionPackIn($fn, $fnname); ($outfn, $outsignature) = $self->PythonFunctionUnpackOut($fn, $fnname); my $signature = "S.$prettyname($insignature) -> $outsignature"; if ($docstring) { $docstring = "\"$signature\\n\\n\"$docstring"; } else { $docstring = "\"$signature\""; } } return ($infn, $outfn, $docstring);}sub handle_werror($$$$){ my ($self, $var, $retval, $mem_ctx) = @_; $self->pidl("if (!W_ERROR_IS_OK($var)) {"); $self->indent; $self->pidl("PyErr_SetWERROR($var);"); $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx); $self->pidl("return $retval;"); $self->deindent; $self->pidl("}"); $self->pidl("");}sub handle_ntstatus($$$$){ my ($self, $var, $retval, $mem_ctx) = @_; $self->pidl("if (NT_STATUS_IS_ERR($var)) {"); $self->indent; $self->pidl("PyErr_SetNTSTATUS($var);"); $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx); $self->pidl("return $retval;"); $self->deindent; $self->pidl("}"); $self->pidl("");}sub PythonType($$$$){ my ($self, $modulename, $d, $interface, $basename) = @_; my $actual_ctype = $d; if ($actual_ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $actual_ctype->{DATA}; } if ($actual_ctype->{TYPE} eq "STRUCT") { my $typeobject; my $fn_name = $d->{NAME}; $fn_name =~ s/^$interface->{NAME}_//; $fn_name =~ s/^$basename\_//; if ($d->{TYPE} eq "STRUCT") { $typeobject = $self->PythonStruct($modulename, $fn_name, $d->{NAME}, mapTypeName($d), $d); } else { $typeobject = $self->PythonStruct($modulename, $fn_name, $d->{NAME}, mapTypeName($d), $d->{DATA}); } $self->register_module_typeobject($fn_name, $typeobject); } if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") { $self->EnumAndBitmapConsts($d->{NAME}, $d); } if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) { $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA}); } if ($actual_ctype->{TYPE} eq "UNION" and defined($actual_ctype->{ELEMENTS})) { $self->pidl("PyObject *py_import_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, " .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; $self->FromUnionToPythonFunction("mem_ctx", $actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in)"); $self->pidl("{"); $self->indent; $self->FromPythonToUnionFunction($actual_ctype, mapTypeName($d), "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); }}sub DocString($$$){ my ($self, $d, $name) = @_; if (has_property($d, "helpstring")) { my $docstring = uc("py_doc_$name"); $self->pidl("#define $docstring ".has_property($d, "helpstring")); return $docstring; } return undef;}sub Interface($$$){ my($self,$interface,$basename) = @_; $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n"); $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n"); $self->pidl_hdr("\n"); $self->Const($_) foreach (@{$interface->{CONSTS}}); foreach my $d (@{$interface->{TYPES}}) { next if has_property($d, "nopython"); $self->PythonType($basename, $d, $interface, $basename); } if (defined $interface->{PROPERTIES}->{uuid}) { $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $interface->{NAME}_InterfaceType;\n"); $self->pidl(""); my @fns = (); foreach my $d (@{$interface->{FUNCTIONS}}) { next if not defined($d->{OPNUM}); next if has_property($d, "nopython"); my $prettyname = $d->{NAME}; $prettyname =~ s/^$interface->{NAME}_//; $prettyname =~ s/^$basename\_//; my ($infn, $outfn, $fndocstring) = $self->PythonFunction($d, $interface->{NAME}, $prettyname); push (@fns, [$infn, $outfn, "dcerpc_$d->{NAME}", $prettyname, $fndocstring, $d->{OPNUM}]); } $self->pidl("const struct PyNdrRpcMethodDef py_ndr_$interface->{NAME}\_methods[] = {"); $self->pidl_hdr("extern const struct PyNdrRpcMethodDef py_ndr_$interface->{NAME}\_methods[];"); $self->indent; foreach my $d (@fns) { my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d; $self->pidl("{ \"$prettyname\", $docstring, (dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },"); } $self->pidl("{ NULL }"); $self->deindent; $self->pidl("};"); $self->pidl(""); $self->pidl("static PyObject *interface_$interface->{NAME}_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)"); $self->pidl("{"); $self->indent; $self->pidl("dcerpc_InterfaceObject *ret;"); $self->pidl("const char *binding_string;"); $self->pidl("struct cli_credentials *credentials;"); $self->pidl("struct loadparm_context *lp_ctx = NULL;"); $self->pidl("PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;"); $self->pidl("TALLOC_CTX *mem_ctx = NULL;"); $self->pidl("struct event_context *event_ctx;"); $self->pidl("NTSTATUS status;"); $self->pidl(""); $self->pidl("const char *kwnames[] = {"); $self->indent; $self->pidl("\"binding\", \"lp_ctx\", \"credentials\", \"basis_connection\", NULL"); $self->deindent; $self->pidl("};"); $self->pidl("extern struct loadparm_context *lp_from_py_object(PyObject *py_obj);"); $self->pidl("extern struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj);"); $self->pidl(""); $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s|OOO:$interface->{NAME}\", discard_const_p(char *, kwnames), &binding_string, &py_lp_ctx, &py_credentials, &py_basis)) {"); $self->indent; $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("lp_ctx = lp_from_py_object(py_lp_ctx);"); $self->pidl("if (lp_ctx == NULL) {"); $self->indent; $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected loadparm context\");"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("credentials = cli_credentials_from_py_object(py_credentials);"); $self->pidl("if (credentials == NULL) {"); $self->indent; $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected credentials\");"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl("ret = PyObject_New(dcerpc_InterfaceObject, &$interface->{NAME}_InterfaceType);"); $self->pidl(""); $self->pidl("event_ctx = event_context_init(mem_ctx);"); $self->pidl(""); $self->pidl("if (py_basis != Py_None) {"); $self->indent; $self->pidl("struct dcerpc_pipe *base_pipe;"); $self->pidl(""); $self->pidl("if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {"); $self->indent; $self->pidl("PyErr_SetString(PyExc_ValueError, \"basis_connection must be a DCE/RPC connection\");"); $self->pidl("talloc_free(mem_ctx);"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); $self->pidl("base_pipe = ((dcerpc_InterfaceObject *)py_basis)->pipe;"); $self->pidl(""); $self->pidl("status = dcerpc_secondary_context(base_pipe, &ret->pipe, &ndr_table_$interface->{NAME});"); $self->deindent; $self->pidl("} else {"); $self->indent; $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, "); $self->pidl(" &ndr_table_$interface->{NAME}, credentials, event_ctx, lp_ctx);"); $self->deindent; $self->pidl("}"); $self->handle_ntstatus("status", "NULL", "mem_ctx"); $self->pidl("ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;"); $self->pidl("return (PyObject *)ret;"); $self->deindent; $self->pidl("}"); $self->pidl(""); my $signature = "\"$interface->{NAME}(binding, lp_ctx=None, credentials=None) -> connection\\n\"\"\\n\"\"binding should be a DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\\n\"\"lp_ctx should be a path to a smb.conf file or a param.LoadParm object\\n\"\"credentials should be a credentials.Credentials object.\\n\\n\""; my $docstring = $self->DocString($interface, $interface->{NAME}); if ($docstring) { $docstring = "$signature$docstring"; } else { $docstring = $signature; } $self->pidl("PyTypeObject $interface->{NAME}_InterfaceType = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$basename.$interface->{NAME}\","); $self->pidl(".tp_basicsize = sizeof(dcerpc_InterfaceObject),"); $self->pidl(".tp_base = &dcerpc_InterfaceType,"); $self->pidl(".tp_doc = $docstring,"); $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,"); $self->pidl(".tp_new = interface_$interface->{NAME}_new,"); $self->deindent; $self->pidl("};"); $self->pidl(""); $self->register_module_typeobject($interface->{NAME}, "&$interface->{NAME}_InterfaceType"); $self->register_module_readycode(["if (!PyInterface_AddNdrRpcMethods(&$interface->{NAME}_InterfaceType, py_ndr_$interface->{NAME}\_methods))", "\treturn;", ""]); } $self->pidl_hdr("\n"); $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n");}sub register_module_method($$$$$){ my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_; push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc])}sub register_module_typeobject($$$){ my ($self, $name, $py_name) = @_; $self->register_module_object($name, "(PyObject *)$py_name"); $self->check_ready_type($py_name);}sub check_ready_type($$){ my ($self, $py_name) = @_; push (@{$self->{ready_types}}, $py_name) unless (grep(/^$py_name$/,@{$self->{ready_types}}));}sub register_module_readycode($$){ my ($self, $code) = @_; push (@{$self->{readycode}}, @$code);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -