diff --git a/src/calibre/utils/windows/winutil.c b/src/calibre/utils/windows/winutil.c index 3a3ae11bdb..6315ab51cb 100644 --- a/src/calibre/utils/windows/winutil.c +++ b/src/calibre/utils/windows/winutil.c @@ -446,19 +446,19 @@ be a unicode string. Returns unicode strings." "move_file()\n\nRename the specified file." }, - {"add_to_recent_docs", (PyCFunction)add_to_recent_docs, METH_VARARGS, + {"add_to_recent_docs", (PyCFunction)winutil_add_to_recent_docs, METH_VARARGS, "add_to_recent_docs()\n\nAdd a path to the recent documents list" }, - {"file_association", (PyCFunction)file_association, METH_VARARGS, + {"file_association", (PyCFunction)winutil_file_association, METH_VARARGS, "file_association()\n\nGet the executable associated with the given file extension" }, - {"friendly_name", (PyCFunction)friendly_name, METH_VARARGS, + {"friendly_name", (PyCFunction)winutil_friendly_name, METH_VARARGS, "friendly_name()\n\nGet the friendly name for the specified prog_id/exe" }, - {"notify_associations_changed", (PyCFunction)notify_associations_changed, METH_VARARGS, + {"notify_associations_changed", (PyCFunction)winutil_notify_associations_changed, METH_VARARGS, "notify_associations_changed()\n\nNotify the OS that file associations have changed" }, diff --git a/src/calibre/utils/windows/winutilpp.cpp b/src/calibre/utils/windows/winutilpp.cpp index e81fa3d531..1ba43e84e9 100644 --- a/src/calibre/utils/windows/winutilpp.cpp +++ b/src/calibre/utils/windows/winutilpp.cpp @@ -14,21 +14,6 @@ #include // for CComPtr #include -static inline int -py_to_wchar(PyObject *obj, wchar_t **output) { - if (!PyUnicode_Check(obj)) { - if (obj == Py_None) { *output = NULL; return 1; } - PyErr_SetString(PyExc_TypeError, "unicode object expected"); - return 0; - } -#if PY_MAJOR_VERSION < 3 - *output = PyUnicode_AS_UNICODE(obj); -#else - *output = PyUnicode_AsWideCharString(obj, NULL); -#endif - return 1; -} - class wchar_raii { private: wchar_t **handle; @@ -38,7 +23,7 @@ class wchar_raii { wchar_raii & operator=( const wchar_raii & ) ; public: - wchar_raii(wchar_t **buf) : handle(*buf) {} + wchar_raii() : handle(NULL) {} ~wchar_raii() { #if PY_MAJOR_VERSION >= 3 @@ -48,15 +33,30 @@ class wchar_raii { } wchar_t *ptr() { return *handle; } + void set_ptr(wchar_t **val) { handle = val; } }; +static inline int +py_to_wchar(PyObject *obj, wchar_raii *output) { + if (!PyUnicode_Check(obj)) { + if (obj == Py_None) { return 1; } + PyErr_SetString(PyExc_TypeError, "unicode object expected"); + return 0; + } +#if PY_MAJOR_VERSION < 3 + output->set_ptr(&PyUnicode_AS_UNICODE(obj)); +#else + output->set_ptr(&PyUnicode_AsWideCharString(obj, NULL)); +#endif + return 1; +} + extern "C" { PyObject * winutil_add_to_recent_docs(PyObject *self, PyObject *args) { - wchar_t *path_, *app_id_; - if (!PyArg_ParseTuple(args, "O&O&", py_to_wchar, &path_, py_to_wchar, &app_id_)) return NULL; - wchar_raii path(path_), app_id(app_id_); + wchar_raii path, app_id; + if (!PyArg_ParseTuple(args, "O&O&", py_to_wchar, &path, py_to_wchar, &app_id)) return NULL; if (app_id.ptr()) { CComPtr item; HRESULT hr = SHCreateItemFromParsingName(path.ptr(), NULL, IID_PPV_ARGS(&item)); @@ -75,10 +75,10 @@ winutil_add_to_recent_docs(PyObject *self, PyObject *args) { PyObject * winutil_file_association(PyObject *self, PyObject *args) { - wchar_t *ext_, buf[2048]; + wchar_t buf[2048]; + wchar_raii ext; DWORD sz = sizeof(buf); - if (!PyArg_ParseTuple(args, "O&", py_to_wchar, &ext_)) return NULL; - wchar_raii ext(ext_); + if (!PyArg_ParseTuple(args, "O&", py_to_wchar, &ext)) return NULL; HRESULT hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, ext.ptr(), NULL, buf, &sz); if (!SUCCEEDED(hr) || sz < 1) Py_RETURN_NONE; return Py_BuildValue("u", buf); @@ -86,10 +86,10 @@ winutil_file_association(PyObject *self, PyObject *args) { PyObject * winutil_friendly_name(PyObject *self, PyObject *args) { - wchar_t *exe_, *prog_id_, buf[2048], *p; + wchar_t buf[2048], *p; + wchar_raii exe, prog_id; DWORD sz = sizeof(buf); - if (!PyArg_ParseTuple(args, "O&O&", py_to_wchar, &prog_id_, py_to_wchar, &exe_)) return NULL; - wchar_raii exe(exe_), prog_id(prog_id_); + if (!PyArg_ParseTuple(args, "O&O&", py_to_wchar, &prog_id, py_to_wchar, &exe)) return NULL; ASSOCF flags = ASSOCF_REMAPRUNDLL; if (exe.ptr()) { p = exe.ptr();