mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 07:36:05 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
417
lib/recyclebin/recyclebin.c
Normal file
417
lib/recyclebin/recyclebin.c
Normal file
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* PROJECT: Recycle bin management
|
||||
* LICENSE: GPL v2 - See COPYING in the top level directory
|
||||
* FILE: lib/recyclebin/recyclebin.c
|
||||
* PURPOSE: Public interface
|
||||
* PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#include "recyclebin_private.h"
|
||||
#include <stdio.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(recyclebin);
|
||||
|
||||
BOOL WINAPI
|
||||
CloseRecycleBinHandle(
|
||||
IN HANDLE hDeletedFile)
|
||||
{
|
||||
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n", hDeletedFile);
|
||||
|
||||
hr = IRecycleBinFile_Release(rbf);
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
DeleteFileToRecycleBinA(
|
||||
IN LPCSTR FileName)
|
||||
{
|
||||
int len;
|
||||
LPWSTR FileNameW = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(FileName));
|
||||
|
||||
/* Check parameters */
|
||||
if (FileName == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto cleanup;
|
||||
FileNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!FileNameW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
if (MultiByteToWideChar(CP_ACP, 0, FileName, -1, FileNameW, len) == 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = DeleteFileToRecycleBinW(FileNameW);
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, FileNameW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
DeleteFileToRecycleBinW(
|
||||
IN LPCWSTR FileName)
|
||||
{
|
||||
IRecycleBin *prb;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s)\n", debugstr_w(FileName));
|
||||
|
||||
hr = GetDefaultRecycleBin(NULL, &prb);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
|
||||
hr = IRecycleBin_DeleteFile(prb, FileName);
|
||||
IRecycleBin_Release(prb);
|
||||
|
||||
cleanup:
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
DeleteFileHandleToRecycleBin(
|
||||
IN HANDLE hDeletedFile)
|
||||
{
|
||||
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n", hDeletedFile);
|
||||
|
||||
hr = IRecycleBinFile_Delete(rbf);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
EmptyRecycleBinA(
|
||||
IN LPCSTR pszRoot OPTIONAL)
|
||||
{
|
||||
int len;
|
||||
LPWSTR szRootW = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(pszRoot));
|
||||
|
||||
if (pszRoot)
|
||||
{
|
||||
len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto cleanup;
|
||||
szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!szRootW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = EmptyRecycleBinW(szRootW);
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, szRootW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
EmptyRecycleBinW(
|
||||
IN LPCWSTR pszRoot OPTIONAL)
|
||||
{
|
||||
IRecycleBin *prb;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s)\n", debugstr_w(pszRoot));
|
||||
|
||||
hr = GetDefaultRecycleBin(pszRoot, &prb);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
|
||||
hr = IRecycleBin_EmptyRecycleBin(prb);
|
||||
IRecycleBin_Release(prb);
|
||||
|
||||
cleanup:
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
EnumerateRecycleBinA(
|
||||
IN LPCSTR pszRoot OPTIONAL,
|
||||
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
|
||||
IN PVOID Context OPTIONAL)
|
||||
{
|
||||
int len;
|
||||
LPWSTR szRootW = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot), pFnCallback, Context);
|
||||
|
||||
if (pszRoot)
|
||||
{
|
||||
len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto cleanup;
|
||||
szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!szRootW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = EnumerateRecycleBinW(szRootW, pFnCallback, Context);
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, szRootW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
EnumerateRecycleBinW(
|
||||
IN LPCWSTR pszRoot OPTIONAL,
|
||||
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
|
||||
IN PVOID Context OPTIONAL)
|
||||
{
|
||||
IRecycleBin *prb = NULL;
|
||||
IRecycleBinEnumList *prbel = NULL;
|
||||
IRecycleBinFile *prbf;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot), pFnCallback, Context);
|
||||
|
||||
hr = GetDefaultRecycleBin(NULL, &prb);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
|
||||
hr = IRecycleBin_EnumObjects(prb, &prbel);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
while (TRUE)
|
||||
{
|
||||
hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL);
|
||||
if (hr == S_FALSE)
|
||||
{
|
||||
hr = S_OK;
|
||||
goto cleanup;
|
||||
}
|
||||
else if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
if (!pFnCallback(Context, (HANDLE)prbf))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (prb)
|
||||
IRecycleBin_Release(prb);
|
||||
if (prbel)
|
||||
IRecycleBinEnumList_Release(prbel);
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
GetDeletedFileDetailsA(
|
||||
IN HANDLE hDeletedFile,
|
||||
IN DWORD BufferSize,
|
||||
IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL,
|
||||
OUT LPDWORD RequiredSize OPTIONAL)
|
||||
{
|
||||
PDELETED_FILE_DETAILS_W FileDetailsW = NULL;
|
||||
DWORD BufferSizeW = 0;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
|
||||
|
||||
if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName))
|
||||
{
|
||||
BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName)
|
||||
+ (BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) * sizeof(WCHAR);
|
||||
}
|
||||
if (FileDetails && BufferSizeW)
|
||||
{
|
||||
FileDetailsW = HeapAlloc(GetProcessHeap(), 0, BufferSizeW);
|
||||
if (!FileDetailsW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = GetDeletedFileDetailsW(hDeletedFile, BufferSizeW, FileDetailsW, RequiredSize);
|
||||
if (!ret)
|
||||
goto cleanup;
|
||||
|
||||
if (FileDetails)
|
||||
{
|
||||
CopyMemory(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName));
|
||||
if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL))
|
||||
goto cleanup;
|
||||
}
|
||||
ret = TRUE;
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, FileDetailsW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
GetDeletedFileDetailsW(
|
||||
IN HANDLE hDeletedFile,
|
||||
IN DWORD BufferSize,
|
||||
IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL,
|
||||
OUT LPDWORD RequiredSize OPTIONAL)
|
||||
{
|
||||
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
|
||||
HRESULT hr;
|
||||
SIZE_T NameSize, Needed;
|
||||
|
||||
TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
|
||||
|
||||
hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + NameSize;
|
||||
if (RequiredSize)
|
||||
*RequiredSize = (DWORD)Needed;
|
||||
if (Needed > BufferSize)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
goto cleanup;
|
||||
}
|
||||
hr = IRecycleBinFile_GetFileName(rbf, NameSize, FileDetails->FileName, NULL);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
hr = IRecycleBinFile_GetLastModificationTime(rbf, &FileDetails->LastModification);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
hr = IRecycleBinFile_GetDeletionTime(rbf, &FileDetails->DeletionTime);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
hr = IRecycleBinFile_GetFileSize(rbf, &FileDetails->FileSize);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
hr = IRecycleBinFile_GetPhysicalFileSize(rbf, &FileDetails->PhysicalFileSize);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
hr = IRecycleBinFile_GetAttributes(rbf, &FileDetails->Attributes);
|
||||
if (!SUCCEEDED(hr))
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
GetRecycleBinDetails(
|
||||
IN LPCWSTR pszVolume OPTIONAL,
|
||||
OUT ULARGE_INTEGER *pulTotalItems,
|
||||
OUT ULARGE_INTEGER *pulTotalSize)
|
||||
{
|
||||
pulTotalItems->QuadPart = 0;
|
||||
pulTotalSize->QuadPart = 0;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
RestoreFile(
|
||||
IN HANDLE hDeletedFile)
|
||||
{
|
||||
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n", hDeletedFile);
|
||||
|
||||
hr = IRecycleBinFile_Restore(rbf);
|
||||
if (SUCCEEDED(hr))
|
||||
return TRUE;
|
||||
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||
SetLastError(HRESULT_CODE(hr));
|
||||
else
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
GetDefaultRecycleBin(
|
||||
IN LPCWSTR pszVolume OPTIONAL,
|
||||
OUT IRecycleBin **pprb)
|
||||
{
|
||||
IUnknown *pUnk;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_w(pszVolume), pprb);
|
||||
|
||||
if (!pprb)
|
||||
return E_POINTER;
|
||||
|
||||
if (!pszVolume)
|
||||
hr = RecycleBinGeneric_Constructor(&pUnk);
|
||||
else
|
||||
{
|
||||
/* FIXME: do a better validation! */
|
||||
if (wcslen(pszVolume) != 3 || pszVolume[1] != ':' || pszVolume[2] != '\\')
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
|
||||
|
||||
/* For now, only support this type of recycle bins... */
|
||||
hr = RecycleBin5_Constructor(pszVolume, &pUnk);
|
||||
}
|
||||
if (!SUCCEEDED(hr))
|
||||
return hr;
|
||||
hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBin, (void **)pprb);
|
||||
IUnknown_Release(pUnk);
|
||||
return hr;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue