-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
recycle-bin.c
100 lines (80 loc) · 2.03 KB
/
recycle-bin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define _WIN32_IE _WIN32_IE_IE70
#include "progress.h"
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <versionhelpers.h>
#include <initguid.h>
#include <shlobj.h>
#define CHECK(result) if (FAILED(result)) {\
return result;\
}
#define CHECK_OBJ(obj, result) if (FAILED(result)) {\
obj->lpVtbl->Release(obj);\
return result;\
}
int wmain(int argc, wchar_t **argv) {
if (argc == 2) {
if (wcscmp(argv[1], L"--version") == 0) {
puts("2.0.0");
return 0;
}
if (wcscmp(argv[1], L"--help") == 0) {
puts("\n Move files and folders to the recycle bin\n\n Usage: recycle-bin <path> [...]\n\n Created by Sindre Sorhus");
return 0;
}
} else if (argc == 1) {
puts("Specify at least one path");
return 1;
}
int count = argc - 1;
wchar_t **files = argv + 1;
CHECK(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
IFileOperation *op;
CHECK(CoCreateInstance(
&CLSID_FileOperation,
NULL,
CLSCTX_ALL,
&IID_IFileOperation,
(void**)&op
));
if (IsWindows8OrGreater()) {
CHECK_OBJ(op, op->lpVtbl->SetOperationFlags(
op,
FOFX_ADDUNDORECORD |
FOFX_RECYCLEONDELETE |
FOF_NOERRORUI |
FOF_NOCONFIRMATION |
FOF_SILENT |
FOFX_EARLYFAILURE
));
} else {
CHECK_OBJ(op, op->lpVtbl->SetOperationFlags(
op,
FOF_NO_UI |
FOF_ALLOWUNDO |
FOF_NOERRORUI |
FOF_SILENT |
FOFX_EARLYFAILURE
));
}
PCIDLIST_ABSOLUTE list[count];
for (int i = 0; i < count; i++) {
int len = GetFullPathName(files[i], 0, NULL, NULL);
if (len == 0) {
op->lpVtbl->Release(op);
return 1;
}
wchar_t *buf = malloc((len + 1) * sizeof(wchar_t));
GetFullPathName(files[i], len, buf, NULL);
list[i] = ILCreateFromPath(buf);
free(buf);
}
IShellItemArray *items;
DWORD cookie;
CHECK_OBJ(op, SHCreateShellItemArrayFromIDLists(count, list, &items));
CHECK_OBJ(op, op->lpVtbl->Advise(op, &progressSink, &cookie));
CHECK_OBJ(op, op->lpVtbl->DeleteItems(op, (IUnknown*)items));
CHECK_OBJ(op, op->lpVtbl->PerformOperations(op));
return op->lpVtbl->Release(op);
}