Files
2025-03-13 16:17:53 +01:00

106 lines
2.9 KiB
C++

#ifndef __PY_IDA_DISKIO__
#define __PY_IDA_DISKIO__
//<code(py_diskio)>
//-------------------------------------------------------------------------
struct bytearray_linput_data_t
{
linput_t *li;
qstring *bytes;
};
DECLARE_TYPE_AS_MOVABLE(bytearray_linput_data_t);
typedef qvector<bytearray_linput_data_t> bytearray_linput_data_vec_t;
static bytearray_linput_data_vec_t bytearray_linput_data_vec;
//</code(py_diskio)>
//<inline(py_diskio)>
//--------------------------------------------------------------------------
PyObject *py_enumerate_files(PyObject *path, PyObject *fname, PyObject *callback)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
struct ida_local file_enumerator_adapter_t : public file_enumerator_t
{
PyObject *callback;
file_enumerator_adapter_t(PyObject *c) : callback(c) {}
int visit_file(const char *file) override
{
// No need to 'PYW_GIL_GET' here, as this is called synchronously
// and from the same thread as the one that executes
// 'py_enumerate_files'.
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_file(PyUnicode_FromString(file));
newref_t py_ret(
PyObject_CallFunctionObjArgs(
callback,
py_file.o,
nullptr));
return !py_ret || !PyNumber_Check(py_ret.o)
? 1 /* stop enum on failure */
: PyInt_AsLong(py_ret.o);
}
};
ida_local file_enumerator_adapter_t adapter(callback);
do
{
if ( !PyUnicode_Check(path) || !PyUnicode_Check(fname) || !PyCallable_Check(callback) )
break;
qstring _path;
qstring _fname;
if ( !PyUnicode_as_qstring(&_path, path) || !PyUnicode_as_qstring(&_fname, fname) )
break;
char answer[QMAXPATH];
answer[0] = '\0';
int r = enumerate_files(
answer, sizeof(answer),
_path.c_str(),
_fname.c_str(),
adapter);
return Py_BuildValue("(is)", r, answer);
} while ( false );
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
linput_t *py_create_bytearray_linput(const qstring &s)
{
qstring *bytes = new qstring(s);
linput_t *li = create_bytearray_linput((const uchar *) bytes->c_str(), bytes->length());
if ( li != nullptr )
{
bytearray_linput_data_t &ld = bytearray_linput_data_vec.push_back();
ld.bytes = bytes;
ld.li = li;
}
else
{
delete bytes;
}
return li;
}
//-------------------------------------------------------------------------
void py_close_linput(linput_t *li)
{
bytearray_linput_data_vec_t::iterator it = bytearray_linput_data_vec.begin();
bytearray_linput_data_vec_t::iterator end = bytearray_linput_data_vec.end();
for ( ; it != end; ++it )
{
if ( it->li == li )
{
delete it->bytes;
bytearray_linput_data_vec.erase(it);
break;
}
}
close_linput(li);
}
//</inline(py_diskio)>
#endif