mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
311 lines
8.1 KiB
C++
311 lines
8.1 KiB
C++
#ifndef __PY_IDAAPI_LOADER_INPUT__
|
|
#define __PY_IDAAPI_LOADER_INPUT__
|
|
|
|
//--------------------------------------------------------------------------
|
|
//<inline(py_idaapi_loader_input)>
|
|
class loader_input_t
|
|
{
|
|
private:
|
|
linput_t *li;
|
|
int own;
|
|
qstring fn;
|
|
enum
|
|
{
|
|
OWN_NONE = 0, // li not created yet
|
|
OWN_CREATE = 1, // Owns li because we created it
|
|
OWN_FROM_LI = 2, // No ownership we borrowed the li from another class
|
|
OWN_FROM_FP = 3, // We got an li instance from an fp instance, we have to unmake_linput() on Close
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
void _from_capsule(PyObject *pycapsule)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
this->set_linput((linput_t *)PyCapsule_GetPointer(pycapsule, VALID_CAPSULE_NAME));
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void assign(const loader_input_t &rhs)
|
|
{
|
|
fn = rhs.fn;
|
|
li = rhs.li;
|
|
own = OWN_FROM_LI;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
loader_input_t(const loader_input_t &rhs)
|
|
{
|
|
assign(rhs);
|
|
}
|
|
public:
|
|
// Special attribute that tells the pyvar_to_idcvar how to convert this
|
|
// class from and to IDC. The value of this variable must be set to two
|
|
int __idc_cvt_id__;
|
|
//--------------------------------------------------------------------------
|
|
loader_input_t(PyObject *pycapsule = nullptr): li(nullptr), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
if ( pycapsule != nullptr && PyCapsule_IsValid(pycapsule, VALID_CAPSULE_NAME) )
|
|
_from_capsule(pycapsule);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void close()
|
|
{
|
|
if ( li == nullptr )
|
|
return;
|
|
|
|
PYW_GIL_GET;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
if ( own == OWN_CREATE )
|
|
close_linput(li);
|
|
else if ( own == OWN_FROM_FP )
|
|
unmake_linput(li);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
li = nullptr;
|
|
own = OWN_NONE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
~loader_input_t()
|
|
{
|
|
close();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
bool open(const char *filename, bool remote)
|
|
{
|
|
close();
|
|
PYW_GIL_GET;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
li = open_linput(filename, remote);
|
|
if ( li != nullptr )
|
|
{
|
|
// Save file name
|
|
fn = filename;
|
|
own = OWN_CREATE;
|
|
}
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return li != nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void set_linput(linput_t *linput)
|
|
{
|
|
close();
|
|
own = OWN_FROM_LI;
|
|
li = linput;
|
|
fn.sprnt("<linput_t * %p>", linput);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static loader_input_t *from_linput(linput_t *linput)
|
|
{
|
|
loader_input_t *l = new loader_input_t();
|
|
l->set_linput(linput);
|
|
return l;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// This method can be used to pass a linput_t* from C code
|
|
static loader_input_t *from_capsule(PyObject *pycapsule)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
if ( !PyCapsule_IsValid(pycapsule, VALID_CAPSULE_NAME) )
|
|
return nullptr;
|
|
loader_input_t *l = new loader_input_t();
|
|
l->_from_capsule(pycapsule);
|
|
return l;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static loader_input_t *from_fp(FILE *fp)
|
|
{
|
|
PYW_GIL_GET;
|
|
loader_input_t *l = nullptr;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
linput_t *fp_li = make_linput(fp);
|
|
if ( fp_li != nullptr )
|
|
{
|
|
l = new loader_input_t();
|
|
l->own = OWN_FROM_FP;
|
|
l->fn.sprnt("<FILE * %p>", fp);
|
|
l->li = fp_li;
|
|
}
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return l;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
linput_t *get_linput()
|
|
{
|
|
return li;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
bool open_memory(ea_t start, int64 size)
|
|
{
|
|
PYW_GIL_GET;
|
|
linput_t *l;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
l = create_memory_linput(start, asize_t(size));
|
|
if ( l != nullptr )
|
|
{
|
|
close();
|
|
li = l;
|
|
fn = "<memory>";
|
|
own = OWN_CREATE;
|
|
}
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return l != nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int64 seek(int64 offset, int whence)
|
|
{
|
|
int64 r;
|
|
PYW_GIL_GET;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
r = qlseek(li, offset, whence);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return r;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int64 tell()
|
|
{
|
|
int64 r;
|
|
PYW_GIL_GET;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
r = qltell(li);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return r;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *getz(size_t size, int64 fpos)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
do
|
|
{
|
|
char *buf = (char *) malloc(size + 5);
|
|
if ( buf == nullptr )
|
|
break;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
qlgetz(li, fpos, buf, size);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
PyObject *ret = PyUnicode_FromString(buf);
|
|
free(buf);
|
|
return ret;
|
|
} while ( false );
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *gets(int64 len)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
bytevec_t buf;
|
|
buf.resize(len);
|
|
bool ok;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
ok = qlgets((char *) buf.begin(), buf.size(), li) != nullptr;
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
if ( !ok )
|
|
Py_RETURN_NONE;
|
|
return PyUnicode_FromString((const char *) buf.begin());
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *read(int64 size)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
ssize_t ssize(size);
|
|
bytevec_t buf;
|
|
if ( ssize < 0 )
|
|
ssize = qlsize(li) - qltell(li);
|
|
buf.resize(ssize);
|
|
ssize_t nread;
|
|
nread = qlread(li, (char *) buf.begin(), buf.size());
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
if ( nread <= 0 )
|
|
{
|
|
buf.clear();
|
|
nread = 0;
|
|
}
|
|
return PyBytes_FromStringAndSize((const char *) buf.begin(), nread);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
bool opened()
|
|
{
|
|
return li != nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *readbytes(size_t size, bool big_endian)
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
do
|
|
{
|
|
char *buf = (char *) malloc(size + 5);
|
|
if ( buf == nullptr )
|
|
break;
|
|
int r;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
r = lreadbytes(li, buf, size, big_endian);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
if ( r == -1 )
|
|
r = 0;
|
|
PyObject *ret = PyUnicode_FromStringAndSize(buf, r);
|
|
free(buf);
|
|
return ret;
|
|
} while ( false );
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int file2base(int64 pos, ea_t ea1, ea_t ea2, int patchable)
|
|
{
|
|
int rc;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
rc = ::file2base(li, pos, ea1, ea2, patchable);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return rc;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int64 size()
|
|
{
|
|
int64 rc;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
rc = qlsize(li);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
return rc;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *filename()
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
return PyUnicode_FromString(fn.c_str());
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
PyObject *get_byte()
|
|
{
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
int ch;
|
|
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
|
ch = qlgetc(li);
|
|
SWIG_PYTHON_THREAD_END_ALLOW;
|
|
if ( ch == EOF )
|
|
Py_RETURN_NONE;
|
|
return Py_BuildValue("i", ch);
|
|
}
|
|
};
|
|
//</inline(py_idaapi_loader_input)>
|
|
|
|
#endif // __PY_IDAAPI_LOADER_INPUT__
|