ThirdParty/Send2Trash/send2trash/plat_win.py

changeset 5994
cf0b37d2a28d
parent 3644
a2c88b9b1d16
child 6228
9c3fbf39ec9b
--- a/ThirdParty/Send2Trash/send2trash/plat_win.py	Sat Nov 25 13:49:54 2017 +0100
+++ b/ThirdParty/Send2Trash/send2trash/plat_win.py	Thu Nov 30 17:00:18 2017 +0100
@@ -1,12 +1,13 @@
-# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
+# Copyright 2017 Virgil Dupras
 
-# This software is licensed under the "BSD" License as described in the "LICENSE" file, 
-# which should be included with this package. The terms are also available at 
+# This software is licensed under the "BSD" License as described in the "LICENSE" file,
+# which should be included with this package. The terms are also available at
 # http://www.hardcoded.net/licenses/bsd_license
 
 from __future__ import unicode_literals
 
-from ctypes import windll, Structure, byref, c_uint
+from ctypes import (windll, Structure, byref, c_uint,
+                    create_unicode_buffer, sizeof, addressof)
 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL
 import os.path as op
 
@@ -46,7 +47,19 @@
     fileop = SHFILEOPSTRUCTW()
     fileop.hwnd = 0
     fileop.wFunc = FO_DELETE
-    fileop.pFrom = LPCWSTR(path + '\0')
+    # FIX: https://github.com/hsoft/send2trash/issues/17
+    # Starting in python 3.6.3 it is no longer possible to use:
+    # LPCWSTR(path + '\0') directly as embedded null characters are no longer
+    # allowed in strings
+    # Workaround 
+    #  - create buffer of c_wchar[] (LPCWSTR is based on this type)
+    #  - buffer is two c_wchar characters longer (double null terminator)
+    #  - cast the address of the buffer to a LPCWSTR
+    # NOTE: based on how python allocates memory for these types they should
+    # always be zero, if this is ever not true we can go back to explicitly
+    # setting the last two characters to null using buffer[index] = '\0'.
+    buffer = create_unicode_buffer(path, len(path)+2)
+    fileop.pFrom = LPCWSTR(addressof(buffer))
     fileop.pTo = None
     fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT
     fileop.fAnyOperationsAborted = 0
@@ -54,6 +67,4 @@
     fileop.lpszProgressTitle = None
     result = SHFileOperationW(byref(fileop))
     if result:
-        msg = "Couldn't perform operation. Error code: %d" % result
-        raise OSError(msg)
-
+        raise WindowsError(None, None, path, result)

eric ide

mercurial