I need to convert an interface defined in Delpi to C++. I made small demo project that contains all of the stuff shown below.
First is the Delphi function that the person claims to be working on this thread:
function CanFileBeDeletedToRecycleBin(const AFileName: UnicodeString): Boolean;
var
RecycleBinManager: IRecycleBinManager;
begin
OleCheck(CoCreateInstance(CLSID_RecycleBinManager, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IRecycleBinManager, RecycleBinManager));
try
Result := RecycleBinManager.WillRecycle(PWideChar(AFileName)) = S_OK;
finally
RecycleBinManager := nil;
end;
end;
The rest of the Delphi interface definitions are here.
So I came up with the following C++ code that unfortunately crashes. (Again, let me repeat that the person who wrote Delphi version claims that it works fine for him.)
HRESULT hr;
CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
// {4A04656D-52AA-49DE-8A09-CB178760E748}
const CLSID CLSID_RecycleBinManager = {0x4A04656D, 0x52AA, 0x49DE, {0x8A, 0x09, 0xCB, 0x17, 0x87, 0x60, 0xE7, 0x48}};
// {5869092D-8AF9-4A6C-AE84-1F03BE2246CC}
const IID IID_IRecycleBinManager = {0x5869092D, 0x8AF9, 0x4A6C, {0xAE, 0x84, 0x1F, 0x03, 0xBE, 0x22, 0x46, 0xCC}};
IRecycleBinManager* pIRBM = NULL;
hr = CoCreateInstance(CLSID_RecycleBinManager, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
IID_IRecycleBinManager, (void**) &pIRBM);
// hr = SHCoCreateInstance(NULL, &CLSID_RecycleBinManager, NULL, IID_IRecycleBinManager, (void **)&pIRBM);
if (SUCCEEDED(hr))
{
//I get a crash on the next line:
//Unhandled exception at 0x76175ed2: 0xC0000005: Access violation writing location 0xa84d252b.
hr = pIRBM->WillRecycle(L"C:\\test del");
pIRBM->Release();
}
I tried my best to convert that interface from Delphi (here) to C++. Here's what I got (after @RemyLebeau's suggestions, which unfortunately still didn't work for me.)
#pragma pack(push,1)
struct DELETEDITEM
{
DWORD dwFileSizeLow;
DWORD dwFileSizeHigh;
#pragma pack(push,8)
FILETIME ftDeletionTime;
#pragma pack(pop)
WCHAR szOriginalPath[MAX_PATH];
WCHAR szDisplacedPath[MAX_PATH];
};
#pragma pack(pop)
enum RECYCLEBIN_TYPE : unsigned char
{
RBTYPE_VOLUME,
RBTYPE_KNOWNFOLDER
};
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("6E325F88-D12F-49E5-895B-8EC98630C021")
IEnumRecycleItems : public IUnknown
{
public:
//virtual HRESULT __stdcall Next(unsigned celt, /* out */ tagDELETEDITEM &rgelt, unsigned &pceltFetched) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Next(
__RPC__in ULONG celt,
__RPC__deref_out DELETEDITEM* rgelt,
__RPC__deref_out ULONG* pceltFetched
) = 0;
//virtual HRESULT __stdcall Skip(unsigned celt) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Skip(
__RPC__in ULONG celt
) = 0;
//virtual HRESULT __stdcall Reset(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Reset(
void
) = 0;
//virtual HRESULT __stdcall Clone(/* out */ _di_IEnumRecycleItems &ppenum) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Clone(
__RPC__deref_out IEnumRecycleItems** ppenum
) = 0;
};
MIDL_INTERFACE("0125E62F-8349-443A-854B-A55FB84CFA35")
IRecycle : public IUnknown
{
public:
//virtual HRESULT __stdcall Compact(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Compact(void) = 0;
//virtual HRESULT __stdcall GetFileData(const System::WideChar * pszPath, /* out */ tagDELETEDITEM &lpData) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetFileData(
__RPC__in const WCHAR* pszPath,
__RPC__deref_out DELETEDITEM* lpData
) = 0;
//virtual HRESULT __stdcall GetItemCount(/* out */ __int64 &lpCount) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetItemCount(
__RPC__deref_out __int64* lpCount
) = 0;
//virtual HRESULT __stdcall GetUsedSpace(/* out */ __int64 &lpUsedSpace) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetUsedSpace(
__RPC__deref_out __int64* lpUsedSpace
) = 0;
//virtual HRESULT __stdcall IsEmpty(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsEmpty(
void
) = 0;
//virtual HRESULT __stdcall PurgeAll(_di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeAll(
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall PurgeItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall SuspendUpdating(BOOL fSuspend) = 0 ;
virtual HRESULT STDMETHODCALLTYPE SuspendUpdating(
__RPC__in BOOL fSuspend
) = 0;
//virtual HRESULT __stdcall RecycleItem(const System::WideChar * lpstrItem, const unsigned dwAttrs, const __int64 iFileSize, /* out */ _di_IShellItem &psi) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RecycleItem(
__RPC__in const WCHAR* lpstrItem,
__RPC__in const DWORD dwAttrs,
__RPC__in const __int64 iFileSize,
__RPC__deref_out IShellItem** psi
) = 0;
//virtual HRESULT __stdcall RestoreItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RestoreItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall IsRecycled(const System::WideChar * pszPath, PBOOL lpRecycled) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsRecycled(
__RPC__in const WCHAR* pszPath,
__RPC__out PBOOL lpRecycled
) = 0;
//virtual HRESULT __stdcall EnumItems(unsigned dwFlags, /* out */ _di_IEnumRecycleItems &EnumRecycleItems) = 0 ;
virtual HRESULT STDMETHODCALLTYPE EnumItems(
__RPC__in DWORD dwFlags,
__RPC__deref_out IEnumRecycleItems** enm
) = 0;
//virtual HRESULT __stdcall WillRecycle(const System::WideChar * pszPath) = 0 ;
virtual HRESULT STDMETHODCALLTYPE WillRecycle(
__RPC__in const WCHAR* pszPath
) = 0;
};
MIDL_INTERFACE("F964AD97-96F4-48AB-B444-E8588BC7C7B3")
IRecycleBin : public IUnknown
{
public:
//virtual HRESULT __stdcall Compact(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Compact(void) = 0;
//virtual HRESULT __stdcall GetFileData(const System::WideChar * pszPath, /* out */ tagDELETEDITEM &lpData) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetFileData(
__RPC__in const WCHAR* pszPath,
__RPC__deref_out DELETEDITEM* lpData
) = 0;
//virtual HRESULT __stdcall GetItemCount(/* out */ __int64 &lpCount) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetItemCount(
__RPC__deref_out __int64* lpCount
) = 0;
//virtual HRESULT __stdcall GetUsedSpace(/* out */ __int64 &lpUsedSpace) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetUsedSpace(
__RPC__deref_out __int64* lpUsedSpace
) = 0;
//virtual HRESULT __stdcall IsEmpty(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsEmpty(
void
) = 0;
//virtual HRESULT __stdcall PurgeAll(_di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeAll(
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall PurgeItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall SuspendUpdating(BOOL fSuspend) = 0 ;
virtual HRESULT STDMETHODCALLTYPE SuspendUpdating(
__RPC__in BOOL fSuspend
) = 0;
//virtual HRESULT __stdcall RecycleItem(const System::WideChar * lpstrItem, const unsigned dwAttrs, const __int64 iFileSize, /* out */ _di_IShellItem &psi) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RecycleItem(
__RPC__in const WCHAR* lpstrItem,
__RPC__in const DWORD dwAttrs,
__RPC__in const __int64 iFileSize,
__RPC__deref_out IShellItem** psi
) = 0;
//virtual HRESULT __stdcall RestoreItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RestoreItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall IsRecycled(const System::WideChar * pszPath, PBOOL lpRecycled) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsRecycled(
__RPC__in const WCHAR* pszPath,
__RPC__out PBOOL lpRecycled
) = 0;
//virtual HRESULT __stdcall EnumItems(unsigned dwFlags, /* out */ _di_IEnumRecycleItems &EnumRecycleItems) = 0 ;
virtual HRESULT STDMETHODCALLTYPE EnumItems(
__RPC__in DWORD dwFlags,
__RPC__deref_out IEnumRecycleItems** enm
) = 0;
//virtual HRESULT __stdcall WillRecycle(const System::WideChar * pszPath) = 0 ;
virtual HRESULT STDMETHODCALLTYPE WillRecycle(
__RPC__in const WCHAR* pszPath
) = 0;
//virtual HRESULT __stdcall Initialize(const tagRECYCLEBIN_TYPE rbType, const System::WideChar * pszID) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Initialize(
__RPC__in const RECYCLEBIN_TYPE rbType,
__RPC__in const WCHAR* pszID
) = 0;
//virtual HRESULT __stdcall GetTypeID(/* out */ tagRECYCLEBIN_TYPE &rbType, System::WideChar * &pszID) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetTypeID(
__RPC__deref_out RECYCLEBIN_TYPE* rbType,
__RPC__in const WCHAR* pszID
) = 0;
//virtual HRESULT __stdcall GetIDList(/* out */ Winapi::Shlobj::PItemIDList &ppidl) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetIDList(
__RPC__deref_out LPITEMIDLIST *ppidl
) = 0;
//virtual HRESULT __stdcall GetLocation(System::WideChar * pszPathBuffer, unsigned cchMax) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetLocation(
__RPC__in WCHAR* pszPathBuffer,
__RPC__in UINT cchMax
) = 0;
//virtual HRESULT __stdcall GetMaxCapacityRange(/* out */ __int64 &lpMin, /* out */ __int64 &lpMax) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetMaxCapacityRange(
__RPC__deref_out __int64* lpMin,
__RPC__deref_out __int64* lpMax
) = 0;
//virtual HRESULT __stdcall GetMaxCapacity(/* out */ __int64 &lpCapacity) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetMaxCapacity(
__RPC__deref_out __int64* lpCapacity
) = 0;
//virtual HRESULT __stdcall SetMaxCapacity(const __int64 lpCapacity) = 0 ;
virtual HRESULT STDMETHODCALLTYPE SetMaxCapacity(
__RPC__in const __int64 lpCapacity
) = 0;
//virtual HRESULT __stdcall GetPurgeOnDelete(/* out */ BOOL &fNukeOnDelete) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetPurgeOnDelete(
__RPC__deref_out BOOL* fNukeOnDelete
) = 0;
//virtual HRESULT __stdcall SetPurgeOnDelete(const BOOL fNukeOnDelete) = 0 ;
virtual HRESULT STDMETHODCALLTYPE SetPurgeOnDelete(
__RPC__in const BOOL fNukeOnDelete
) = 0;
};
MIDL_INTERFACE("5869092D-8AF9-4A6C-AE84-1F03BE2246CC")
IRecycleBinManager : public IUnknown
{
public:
//virtual HRESULT __stdcall Compact(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Compact(void) = 0;
//virtual HRESULT __stdcall GetFileData(const System::WideChar * pszPath, /* out */ tagDELETEDITEM &lpData) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetFileData(
__RPC__in const WCHAR* pszPath,
__RPC__deref_out DELETEDITEM* pDeletedItem
) = 0;
//virtual HRESULT __stdcall GetItemCount(/* out */ __int64 &lpCount) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetItemCount(
__RPC__deref_out __int64* lpCount
) = 0;
//virtual HRESULT __stdcall GetUsedSpace(/* out */ __int64 &lpUsedSpace) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetUsedSpace(
__RPC__deref_out __int64* lpUsedSpace
) = 0;
//virtual HRESULT __stdcall IsEmpty(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsEmpty(
void
) = 0;
//virtual HRESULT __stdcall PurgeAll(_di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeAll(
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall PurgeItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE PurgeItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall SuspendUpdating(BOOL fSuspend) = 0 ;
virtual HRESULT STDMETHODCALLTYPE SuspendUpdating(
__RPC__in BOOL fSuspend
) = 0;
//virtual HRESULT __stdcall RecycleItem(const System::WideChar * lpstrItem, const unsigned dwAttrs, const __int64 iFileSize, /* out */ _di_IShellItem &psi) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RecycleItem(
__RPC__in const WCHAR* lpstrItem,
__RPC__in const DWORD dwAttrs,
__RPC__in const __int64 iFileSize,
__RPC__deref_out IShellItem** psi
) = 0;
//virtual HRESULT __stdcall RestoreItems(const System::WideChar * lpstrItems, _di_IFileOperation pfo) = 0 ;
virtual HRESULT STDMETHODCALLTYPE RestoreItems(
__RPC__in const WCHAR* lpstrItems,
__RPC__in IFileOperation* pfo
) = 0;
//virtual HRESULT __stdcall IsRecycled(const System::WideChar * pszPath, PBOOL lpRecycled) = 0 ;
virtual HRESULT STDMETHODCALLTYPE IsRecycled(
__RPC__in const WCHAR* pszPath,
__RPC__out PBOOL lpRecycled
) = 0;
//virtual HRESULT __stdcall EnumItems(unsigned dwFlags, /* out */ _di_IEnumRecycleItems &EnumRecycleItems) = 0 ;
virtual HRESULT STDMETHODCALLTYPE EnumItems(
__RPC__in DWORD dwFlags,
__RPC__deref_out IEnumRecycleItems** enm
) = 0;
//virtual HRESULT __stdcall WillRecycle(const System::WideChar * pszPath) = 0 ;
virtual HRESULT STDMETHODCALLTYPE WillRecycle(
__RPC__in const WCHAR* pszPath
) = 0;
//virtual HRESULT __stdcall DelayCompaction(const BOOL fDelay) = 0 ;
virtual HRESULT STDMETHODCALLTYPE DelayCompaction(
__RPC__in const BOOL fDelay
) = 0;
//virtual HRESULT __stdcall GetRecycleBinCount(/* out */ int &iCount) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetRecycleBinCount(
__RPC__deref_out int* iCount
) = 0;
//virtual HRESULT __stdcall GetRecycleBinAt(const int index, const GUID &iid, /* out */ void *ppv) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetRecycleBinAt(
__RPC__in const int index,
const GUID *iid,
__RPC__deref_out void **ppv
) = 0;
//virtual HRESULT __stdcall GetRecycleBin(const System::WideChar * pszPath, const GUID &iid, /* out */ void *ppv) = 0 ;
virtual HRESULT STDMETHODCALLTYPE GetRecycleBin(
__RPC__in const WCHAR* pszRootPath,
const GUID *iid,
__RPC__deref_out void **ppv
) = 0;
//virtual HRESULT __stdcall Refresh(void) = 0 ;
virtual HRESULT STDMETHODCALLTYPE Refresh(
void
) = 0;
};
#endif
Can someone take a look. What am I missing there?