1 # Copyright 2013 Hardcoded Software (http://www.hardcoded.net) |
1 # Copyright 2017 Virgil Dupras |
2 |
2 |
3 # This software is licensed under the "BSD" License as described in the "LICENSE" file, |
3 # This software is licensed under the "BSD" License as described in the "LICENSE" file, |
4 # which should be included with this package. The terms are also available at |
4 # which should be included with this package. The terms are also available at |
5 # http://www.hardcoded.net/licenses/bsd_license |
5 # http://www.hardcoded.net/licenses/bsd_license |
6 |
6 |
7 from __future__ import unicode_literals |
7 from __future__ import unicode_literals |
8 |
8 |
9 from ctypes import windll, Structure, byref, c_uint |
9 from ctypes import (windll, Structure, byref, c_uint, |
|
10 create_unicode_buffer, sizeof, addressof) |
10 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL |
11 from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL |
11 import os.path as op |
12 import os.path as op |
12 |
13 |
13 from .compat import text_type |
14 from .compat import text_type |
14 |
15 |
44 if not op.isabs(path): |
45 if not op.isabs(path): |
45 path = op.abspath(path) |
46 path = op.abspath(path) |
46 fileop = SHFILEOPSTRUCTW() |
47 fileop = SHFILEOPSTRUCTW() |
47 fileop.hwnd = 0 |
48 fileop.hwnd = 0 |
48 fileop.wFunc = FO_DELETE |
49 fileop.wFunc = FO_DELETE |
49 fileop.pFrom = LPCWSTR(path + '\0') |
50 # FIX: https://github.com/hsoft/send2trash/issues/17 |
|
51 # Starting in python 3.6.3 it is no longer possible to use: |
|
52 # LPCWSTR(path + '\0') directly as embedded null characters are no longer |
|
53 # allowed in strings |
|
54 # Workaround |
|
55 # - create buffer of c_wchar[] (LPCWSTR is based on this type) |
|
56 # - buffer is two c_wchar characters longer (double null terminator) |
|
57 # - cast the address of the buffer to a LPCWSTR |
|
58 # NOTE: based on how python allocates memory for these types they should |
|
59 # always be zero, if this is ever not true we can go back to explicitly |
|
60 # setting the last two characters to null using buffer[index] = '\0'. |
|
61 buffer = create_unicode_buffer(path, len(path)+2) |
|
62 fileop.pFrom = LPCWSTR(addressof(buffer)) |
50 fileop.pTo = None |
63 fileop.pTo = None |
51 fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT |
64 fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT |
52 fileop.fAnyOperationsAborted = 0 |
65 fileop.fAnyOperationsAborted = 0 |
53 fileop.hNameMappings = 0 |
66 fileop.hNameMappings = 0 |
54 fileop.lpszProgressTitle = None |
67 fileop.lpszProgressTitle = None |
55 result = SHFileOperationW(byref(fileop)) |
68 result = SHFileOperationW(byref(fileop)) |
56 if result: |
69 if result: |
57 msg = "Couldn't perform operation. Error code: %d" % result |
70 raise WindowsError(None, None, path, result) |
58 raise OSError(msg) |
|
59 |
|