2 * PROJECT: Recycle bin management
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/recyclebin/recyclebin_generic.c
5 * PURPOSE: Deals with a system-wide recycle bin
6 * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
9 #include "recyclebin_private.h"
11 struct RecycleBinGeneric
14 IRecycleBin recycleBinImpl
;
17 static HRESULT STDMETHODCALLTYPE
18 RecycleBinGeneric_RecycleBin_QueryInterface(
23 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
25 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
30 if (IsEqualIID(riid
, &IID_IUnknown
))
31 *ppvObject
= &s
->recycleBinImpl
;
32 else if (IsEqualIID(riid
, &IID_IRecycleBin
))
33 *ppvObject
= &s
->recycleBinImpl
;
40 IUnknown_AddRef(This
);
44 static ULONG STDMETHODCALLTYPE
45 RecycleBinGeneric_RecycleBin_AddRef(
48 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
49 ULONG refCount
= InterlockedIncrement((PLONG
)&s
->ref
);
50 TRACE("(%p)\n", This
);
55 RecycleBinGeneric_Destructor(
56 struct RecycleBinGeneric
*s
)
63 static ULONG STDMETHODCALLTYPE
64 RecycleBinGeneric_RecycleBin_Release(
67 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
70 TRACE("(%p)\n", This
);
72 refCount
= InterlockedDecrement((PLONG
)&s
->ref
);
75 RecycleBinGeneric_Destructor(s
);
80 static HRESULT STDMETHODCALLTYPE
81 RecycleBinGeneric_RecycleBin_DeleteFile(
83 IN LPCWSTR szFileName
)
86 LPWSTR szFullName
= NULL
;
87 DWORD dwBufferLength
= 0;
89 WCHAR szVolume
[MAX_PATH
];
92 TRACE("(%p, %s)\n", This
, debugstr_w(szFileName
));
94 /* Get full file name */
97 len
= GetFullPathNameW(szFileName
, dwBufferLength
, szFullName
, NULL
);
101 CoTaskMemFree(szFullName
);
102 return HRESULT_FROM_WIN32(GetLastError());
104 else if (len
< dwBufferLength
)
107 CoTaskMemFree(szFullName
);
108 dwBufferLength
= len
;
109 szFullName
= CoTaskMemAlloc(dwBufferLength
* sizeof(WCHAR
));
111 return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY
);
114 /* Get associated volume path */
116 if (!GetVolumePathNameW(szFullName
, szVolume
, MAX_PATH
))
118 CoTaskMemFree(szFullName
);
119 return HRESULT_FROM_WIN32(GetLastError());
122 swprintf(szVolume
, L
"%c:\\", szFullName
[0]);
125 /* Skip namespace (if any) */
126 if (szVolume
[0] == '\\'
127 && szVolume
[1] == '\\'
128 && (szVolume
[2] == '.' || szVolume
[2] == '?')
129 && szVolume
[3] == '\\')
131 MoveMemory(szVolume
, &szVolume
[4], (MAX_PATH
- 4) * sizeof(WCHAR
));
134 hr
= GetDefaultRecycleBin(szVolume
, &prb
);
137 CoTaskMemFree(szFullName
);
141 hr
= IRecycleBin_DeleteFile(prb
, szFullName
);
142 CoTaskMemFree(szFullName
);
143 IRecycleBin_Release(prb
);
147 static HRESULT STDMETHODCALLTYPE
148 RecycleBinGeneric_RecycleBin_EmptyRecycleBin(
149 IN IRecycleBin
*This
)
151 WCHAR szVolumeName
[MAX_PATH
];
152 DWORD dwLogicalDrives
, i
;
156 TRACE("(%p)\n", This
);
158 dwLogicalDrives
= GetLogicalDrives();
159 if (dwLogicalDrives
== 0)
160 return HRESULT_FROM_WIN32(GetLastError());
162 for (i
= 0; i
< 26; i
++)
164 if (!(dwLogicalDrives
& (1 << i
)))
166 swprintf(szVolumeName
, L
"%c:\\", 'A' + i
);
167 if (GetDriveTypeW(szVolumeName
) != DRIVE_FIXED
)
170 hr
= GetDefaultRecycleBin(szVolumeName
, &prb
);
174 hr
= IRecycleBin_EmptyRecycleBin(prb
);
175 IRecycleBin_Release(prb
);
181 static HRESULT STDMETHODCALLTYPE
182 RecycleBinGeneric_RecycleBin_EnumObjects(
183 IN IRecycleBin
*This
,
184 OUT IRecycleBinEnumList
**ppEnumList
)
186 TRACE("(%p, %p)\n", This
, ppEnumList
);
187 return RecycleBinGenericEnum_Constructor(ppEnumList
);
190 CONST_VTBL
struct IRecycleBinVtbl RecycleBinGenericVtbl
=
192 RecycleBinGeneric_RecycleBin_QueryInterface
,
193 RecycleBinGeneric_RecycleBin_AddRef
,
194 RecycleBinGeneric_RecycleBin_Release
,
195 RecycleBinGeneric_RecycleBin_DeleteFile
,
196 RecycleBinGeneric_RecycleBin_EmptyRecycleBin
,
197 RecycleBinGeneric_RecycleBin_EnumObjects
,
200 HRESULT
RecycleBinGeneric_Constructor(OUT IUnknown
**ppUnknown
)
202 /* This RecycleBin implementation was introduced to be able to manage all
203 * drives at once, and instanciate the 'real' implementations when needed */
204 struct RecycleBinGeneric
*s
;
206 s
= CoTaskMemAlloc(sizeof(struct RecycleBinGeneric
));
208 return E_OUTOFMEMORY
;
210 s
->recycleBinImpl
.lpVtbl
= &RecycleBinGenericVtbl
;
212 *ppUnknown
= (IUnknown
*)&s
->recycleBinImpl
;