Windows MTP driver: Set modified and created times when putting files/folders on device. Also read modified time correctly.

This commit is contained in:
Kovid Goyal 2021-04-20 13:48:50 +05:30
parent 1455f4dda1
commit 7f4685544c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 30 additions and 13 deletions

View File

@ -560,7 +560,7 @@ class MTP_DEVICE(BASE):
# }}} # }}}
if __name__ == '__main__': def main():
dev = MTP_DEVICE(None) dev = MTP_DEVICE(None)
dev.startup() dev.startup()
try: try:
@ -577,3 +577,7 @@ if __name__ == '__main__':
print('Prefix for main mem:', dev.prefix_for_location(None)) print('Prefix for main mem:', dev.prefix_for_location(None))
finally: finally:
dev.shutdown() dev.shutdown()
if __name__ == '__main__':
main()

View File

@ -9,7 +9,7 @@
#include <new> #include <new>
#define ADDPROP(x) hr = properties->Add(x); if (FAILED(hr)) { hresult_set_exc("Failed to add property to filesystem properties collection", hr); properties->Release(); return NULL; } #define ADDPROP(x) hr = properties->Add(x); if (FAILED(hr)) { hresult_set_exc("Failed to add property " #x " to filesystem properties collection", hr); properties->Release(); return NULL; }
namespace wpd { namespace wpd {
@ -34,6 +34,7 @@ static IPortableDeviceKeyCollection* create_filesystem_properties_collection() {
ADDPROP(WPD_OBJECT_ISHIDDEN); ADDPROP(WPD_OBJECT_ISHIDDEN);
ADDPROP(WPD_OBJECT_CAN_DELETE); ADDPROP(WPD_OBJECT_CAN_DELETE);
ADDPROP(WPD_OBJECT_SIZE); ADDPROP(WPD_OBJECT_SIZE);
ADDPROP(WPD_OBJECT_DATE_CREATED);
ADDPROP(WPD_OBJECT_DATE_MODIFIED); ADDPROP(WPD_OBJECT_DATE_MODIFIED);
return properties; return properties;
@ -82,16 +83,14 @@ static void set_size_property(PyObject *dict, REFPROPERTYKEY key, const char *py
} }
} }
static void set_date_property(PyObject *dict, REFPROPERTYKEY key, const char *pykey, IPortableDeviceValues *properties) { static void
FLOAT val = 0; set_date_property(PyObject *dict, REFPROPERTYKEY key, const char *pykey, IPortableDeviceValues *properties) {
PROPVARIANT ts = {0};
if (SUCCEEDED(properties->GetValue(key, &ts))) {
SYSTEMTIME st; SYSTEMTIME st;
unsigned int microseconds; if (ts.vt == VT_DATE && VariantTimeToSystemTime(ts.date, &st)) {
PyObject *t; const unsigned int microseconds = 1000 * st.wMilliseconds;
PyObject *t = Py_BuildValue("H H H H H H I", (unsigned short)st.wYear,
if (SUCCEEDED(properties->GetFloatValue(key, &val))) {
if (VariantTimeToSystemTime(val, &st)) {
microseconds = 1000 * st.wMilliseconds;
t = Py_BuildValue("H H H H H H I", (unsigned short)st.wYear,
(unsigned short)st.wMonth, (unsigned short)st.wDay, (unsigned short)st.wMonth, (unsigned short)st.wDay,
(unsigned short)st.wHour, (unsigned short)st.wMinute, (unsigned short)st.wHour, (unsigned short)st.wMinute,
(unsigned short)st.wSecond, microseconds); (unsigned short)st.wSecond, microseconds);
@ -123,7 +122,7 @@ static void set_properties(PyObject *obj, IPortableDeviceValues *values) {
set_size_property(obj, WPD_OBJECT_SIZE, "size", values); set_size_property(obj, WPD_OBJECT_SIZE, "size", values);
set_date_property(obj, WPD_OBJECT_DATE_MODIFIED, "modified", values); set_date_property(obj, WPD_OBJECT_DATE_MODIFIED, "modified", values);
set_date_property(obj, WPD_OBJECT_DATE_CREATED, "created", values);
} }
// }}} // }}}
@ -398,6 +397,15 @@ static IPortableDeviceValues* create_object_properties(const wchar_t *parent_id,
IPortableDeviceValues *values = NULL; IPortableDeviceValues *values = NULL;
HRESULT hr; HRESULT hr;
BOOL ok = FALSE; BOOL ok = FALSE;
PROPVARIANT timestamp = {0};
SYSTEMTIME systemtime;
GetLocalTime(&systemtime);
timestamp.vt = VT_DATE;
if (!SystemTimeToVariantTime(&systemtime, &timestamp.date)) {
LONG err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
hresult_set_exc("Failed to convert system time to variant time", hr); goto end;
}
hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&values)); CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&values));
@ -418,6 +426,11 @@ static IPortableDeviceValues* create_object_properties(const wchar_t *parent_id,
hr = values->SetGuidValue(WPD_OBJECT_CONTENT_TYPE, content_type); hr = values->SetGuidValue(WPD_OBJECT_CONTENT_TYPE, content_type);
if (FAILED(hr)) { hresult_set_exc("Failed to set content_type value", hr); goto end; } if (FAILED(hr)) { hresult_set_exc("Failed to set content_type value", hr); goto end; }
hr = values->SetValue(WPD_OBJECT_DATE_CREATED, &timestamp);
if (FAILED(hr)) { hresult_set_exc("Failed to set created timestamp", hr); goto end; }
hr = values->SetValue(WPD_OBJECT_DATE_MODIFIED, &timestamp);
if (FAILED(hr)) { hresult_set_exc("Failed to set modified timestamp", hr); goto end; }
if (!IsEqualGUID(WPD_CONTENT_TYPE_FOLDER, content_type)) { if (!IsEqualGUID(WPD_CONTENT_TYPE_FOLDER, content_type)) {
hr = values->SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, size); hr = values->SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, size);
if (FAILED(hr)) { hresult_set_exc("Failed to set size value", hr); goto end; } if (FAILED(hr)) { hresult_set_exc("Failed to set size value", hr); goto end; }