mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Speedup windows_get_fileid
Also make it more robust by avoiding registry/time lookups. Fixes #1898110 [Cannot load Calibre 64 bit](https://bugs.launchpad.net/calibre/+bug/1898110)
This commit is contained in:
parent
b94819be9e
commit
b180fea7d6
@ -9,6 +9,7 @@ import os
|
||||
import shutil
|
||||
import time
|
||||
from math import ceil
|
||||
from contextlib import suppress
|
||||
|
||||
from calibre import force_unicode, isbytestring, prints, sanitize_file_name
|
||||
from calibre.constants import (
|
||||
@ -218,9 +219,10 @@ def case_preserving_open_file(path, mode='wb', mkdir_mode=0o777):
|
||||
return ans, fpath
|
||||
|
||||
|
||||
def windows_get_fileid(path):
|
||||
''' The fileid uniquely identifies actual file contents (it is the same for
|
||||
all hardlinks to a file). Similar to inode number on linux. '''
|
||||
def old_windows_get_fileid(path):
|
||||
# we dont use this anymore as the win32 implementation reads the windows
|
||||
# registry to convert file times which is slow and breaks on systems with
|
||||
# registry issues.
|
||||
import win32file
|
||||
from pywintypes import error
|
||||
if isbytestring(path):
|
||||
@ -237,6 +239,20 @@ def windows_get_fileid(path):
|
||||
return data[4], data[8], data[9]
|
||||
|
||||
|
||||
def windows_get_fileid(path):
|
||||
''' The fileid uniquely identifies actual file contents (it is the same for
|
||||
all hardlinks to a file). Similar to inode number on linux. '''
|
||||
try:
|
||||
get_file_id = plugins['winutil'][0].get_file_id
|
||||
except AttributeError:
|
||||
# running from source without updating binary
|
||||
return old_windows_get_fileid(path)
|
||||
if isbytestring(path):
|
||||
path = path.decode(filesystem_encoding)
|
||||
with suppress(OSError):
|
||||
return get_file_id(path)
|
||||
|
||||
|
||||
def samefile_windows(src, dst):
|
||||
samestring = (os.path.normcase(os.path.abspath(src)) ==
|
||||
os.path.normcase(os.path.abspath(dst)))
|
||||
|
@ -380,6 +380,7 @@ extern PyObject *winutil_friendly_name(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_notify_associations_changed(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_move_to_trash(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_manage_shortcut(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_get_file_id(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef winutil_methods[] = {
|
||||
{"special_folder_path", winutil_folder_path, METH_VARARGS,
|
||||
@ -471,6 +472,10 @@ be a unicode string. Returns unicode strings."
|
||||
"manage_shortcut()\n\nManage a shortcut"
|
||||
},
|
||||
|
||||
{"get_file_id", (PyCFunction)winutil_get_file_id, METH_VARARGS,
|
||||
"get_file_id(path)\n\nGet the windows file id (volume_num, file_index_high, file_index_low)"
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -114,6 +114,23 @@ py_to_wchar(PyObject *obj, wchar_raii *output) {
|
||||
|
||||
extern "C" {
|
||||
|
||||
PyObject*
|
||||
winutil_get_file_id(PyObject *self, PyObject *args) {
|
||||
wchar_raii path;
|
||||
if (!PyArg_ParseTuple(args, "O&", py_to_wchar, &path)) return NULL;
|
||||
if (path.ptr()) {
|
||||
HANDLE h = CreateFileW(path.ptr(), 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, PyTuple_GET_ITEM(args, 0));
|
||||
BY_HANDLE_FILE_INFORMATION info = {0};
|
||||
BOOL ok = GetFileInformationByHandle(h, &info);
|
||||
CloseHandle(h);
|
||||
if (!ok) return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, PyTuple_GET_ITEM(args, 0));
|
||||
unsigned long volnum = info.dwVolumeSerialNumber, index_high = info.nFileIndexHigh, index_low = info.nFileIndexLow;
|
||||
return Py_BuildValue("kkk", volnum, index_high, index_low);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
winutil_add_to_recent_docs(PyObject *self, PyObject *args) {
|
||||
wchar_raii path, app_id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user