-/*\r
- * PROJECT: Recycle bin management\r
- * LICENSE: GPL v2 - See COPYING in the top level directory\r
- * FILE: lib/recyclebin/openclose.c\r
- * PURPOSE: Public interface\r
- * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org)\r
- */\r
-\r
-#include "recyclebin_private.h"\r
-\r
-typedef struct _ENUMERATE_RECYCLE_BIN_CONTEXT\r
-{\r
- PRECYCLE_BIN bin;\r
- PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback;\r
- PVOID Context;\r
-} ENUMERATE_RECYCLE_BIN_CONTEXT, *PENUMERATE_RECYCLE_BIN_CONTEXT;\r
-\r
-BOOL WINAPI\r
-CloseRecycleBinHandle(\r
- IN HANDLE hDeletedFile)\r
-{\r
- BOOL ret = FALSE;\r
-\r
- if (!IntCheckDeletedFileHandle(hDeletedFile))\r
- SetLastError(ERROR_INVALID_HANDLE);\r
- else\r
- {\r
- PDELETED_FILE_HANDLE file = (PDELETED_FILE_HANDLE)hDeletedFile;\r
- ret = DereferenceHandle(&file->refCount);\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-DeleteFileToRecycleBinA(\r
- IN LPCSTR FileName)\r
-{\r
- int len;\r
- LPWSTR FileNameW = NULL;\r
- BOOL ret = FALSE;\r
-\r
- /* Check parameters */\r
- if (FileName == NULL)\r
- {\r
- SetLastError(ERROR_INVALID_PARAMETER);\r
- goto cleanup;\r
- }\r
-\r
- len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0);\r
- if (len == 0)\r
- goto cleanup;\r
- FileNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));\r
- if (!FileNameW)\r
- {\r
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
- goto cleanup;\r
- }\r
- if (MultiByteToWideChar(CP_ACP, 0, FileName, -1, FileNameW, len) == 0)\r
- goto cleanup;\r
-\r
- ret = DeleteFileToRecycleBinW(FileNameW);\r
-\r
-cleanup:\r
- HeapFree(GetProcessHeap(), 0, FileNameW);\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-DeleteFileToRecycleBinW(\r
- IN LPCWSTR FileName)\r
-{\r
- LPWSTR FullFileName = NULL;\r
- DWORD dwBufferLength = 0;\r
- LPWSTR lpFilePart;\r
- DWORD len;\r
- PRECYCLE_BIN bin = NULL;\r
- BOOL ret = FALSE;\r
-\r
- /* Check parameters */\r
- if (FileName == NULL)\r
- {\r
- SetLastError(ERROR_INVALID_PARAMETER);\r
- goto cleanup;\r
- }\r
-\r
- /* Get full file name */\r
- while (TRUE)\r
- {\r
- len = GetFullPathNameW(FileName, dwBufferLength, FullFileName, &lpFilePart);\r
- if (len == 0)\r
- goto cleanup;\r
- else if (len < dwBufferLength)\r
- break;\r
- HeapFree(GetProcessHeap(), 0, FullFileName);\r
- dwBufferLength = len;\r
- FullFileName = HeapAlloc(GetProcessHeap(), 0, dwBufferLength * sizeof(WCHAR));\r
- if (!FullFileName)\r
- {\r
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
- goto cleanup;\r
- }\r
- }\r
-\r
- if (!lpFilePart || dwBufferLength < 2 || FullFileName[1] != ':')\r
- {\r
- /* Only a directory name, or not a local file */\r
- SetLastError(ERROR_INVALID_NAME);\r
- }\r
-\r
- /* Open recycle bin */\r
- bin = IntReferenceRecycleBin(FullFileName[0]);\r
- if (!bin)\r
- goto cleanup;\r
-\r
- if (bin->Callbacks.DeleteFile)\r
- ret = bin->Callbacks.DeleteFile(bin, FullFileName, lpFilePart);\r
- else\r
- SetLastError(ERROR_NOT_SUPPORTED);\r
-\r
-cleanup:\r
- HeapFree(GetProcessHeap(), 0, FullFileName);\r
- if (bin)\r
- DereferenceHandle(&bin->refCount);\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-EmptyRecycleBinA(\r
- IN CHAR driveLetter)\r
-{\r
- return EmptyRecycleBinW((WCHAR)driveLetter);\r
-}\r
-\r
-BOOL WINAPI\r
-EmptyRecycleBinW(\r
- IN WCHAR driveLetter)\r
-{\r
- PRECYCLE_BIN bin = NULL;\r
- BOOL ret = FALSE;\r
-\r
- /* Open recycle bin */\r
- bin = IntReferenceRecycleBin(driveLetter);\r
- if (!bin)\r
- goto cleanup;\r
-\r
- if (bin->Callbacks.EmptyRecycleBin)\r
- ret = bin->Callbacks.EmptyRecycleBin(&bin);\r
- else\r
- SetLastError(ERROR_NOT_SUPPORTED);\r
-\r
-cleanup:\r
- if (bin)\r
- DereferenceHandle(&bin->refCount);\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-EnumerateRecycleBinA(\r
- IN CHAR driveLetter,\r
- IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,\r
- IN PVOID Context OPTIONAL)\r
-{\r
- return EnumerateRecycleBinW((WCHAR)driveLetter, pFnCallback, Context);\r
-}\r
-\r
-static BOOL\r
-IntCloseDeletedFileHandle(\r
- IN PREFCOUNT_DATA pData)\r
-{\r
- PDELETED_FILE_HANDLE file;\r
-\r
- file = CONTAINING_RECORD(pData, DELETED_FILE_HANDLE, refCount);\r
- if (!DereferenceHandle(&file->bin->refCount))\r
- return FALSE;\r
-\r
- file->magic = 0;\r
- HeapFree(GetProcessHeap(), 0, file);\r
- return TRUE;\r
-}\r
-\r
-static BOOL\r
-IntEnumerateRecycleBinCallback(\r
- IN PVOID Context,\r
- IN HANDLE hDeletedFile)\r
-{\r
- PENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext = (PENUMERATE_RECYCLE_BIN_CONTEXT)Context;\r
- PDELETED_FILE_HANDLE DeletedFileHandle = NULL;\r
- BOOL ret = FALSE;\r
-\r
- DeletedFileHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(DELETED_FILE_HANDLE));\r
- if (!DeletedFileHandle)\r
- {\r
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
- goto cleanup;\r
- }\r
-\r
- ReferenceHandle(&CallbackContext->bin->refCount);\r
- InitializeHandle(&DeletedFileHandle->refCount, IntCloseDeletedFileHandle);\r
- DeletedFileHandle->magic = DELETEDFILE_MAGIC;\r
- DeletedFileHandle->bin = CallbackContext->bin;\r
- DeletedFileHandle->hDeletedFile = hDeletedFile;\r
-\r
- ret = CallbackContext->pFnCallback(CallbackContext->Context, DeletedFileHandle);\r
-\r
-cleanup:\r
- if (!ret)\r
- {\r
- if (DeletedFileHandle)\r
- DereferenceHandle(&DeletedFileHandle->refCount);\r
- }\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-EnumerateRecycleBinW(\r
- IN WCHAR driveLetter,\r
- IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,\r
- IN PVOID Context OPTIONAL)\r
-{\r
- PRECYCLE_BIN bin = NULL;\r
- BOOL ret = FALSE;\r
-\r
- /* Check parameters */\r
- if (pFnCallback == NULL)\r
- {\r
- SetLastError(ERROR_INVALID_PARAMETER);\r
- goto cleanup;\r
- }\r
-\r
- /* Open recycle bin */\r
- bin = IntReferenceRecycleBin(driveLetter);\r
- if (!bin)\r
- goto cleanup;\r
-\r
- if (bin->Callbacks.EnumerateFiles)\r
- {\r
- ENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext;\r
-\r
- CallbackContext.bin = bin;\r
- CallbackContext.pFnCallback = pFnCallback;\r
- CallbackContext.Context = Context;\r
-\r
- ret = bin->Callbacks.EnumerateFiles(bin, IntEnumerateRecycleBinCallback, &CallbackContext);\r
- }\r
- else\r
- SetLastError(ERROR_NOT_SUPPORTED);\r
-\r
-cleanup:\r
- if (bin)\r
- DereferenceHandle(&bin->refCount);\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-GetDeletedFileDetailsA(\r
- IN HANDLE hDeletedFile,\r
- IN DWORD BufferSize,\r
- IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL,\r
- OUT LPDWORD RequiredSize OPTIONAL)\r
-{\r
- PDELETED_FILE_DETAILS_W FileDetailsW = NULL;\r
- DWORD BufferSizeW = 0;\r
- BOOL ret = FALSE;\r
-\r
- if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName))\r
- {\r
- BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName)\r
- + (BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) * sizeof(WCHAR);\r
- }\r
- if (FileDetails && BufferSizeW)\r
- {\r
- FileDetailsW = HeapAlloc(GetProcessHeap(), 0, BufferSizeW);\r
- if (!FileDetailsW)\r
- {\r
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
- goto cleanup;\r
- }\r
- }\r
-\r
- ret = GetDeletedFileDetailsW(hDeletedFile, BufferSizeW, FileDetailsW, RequiredSize);\r
- if (!ret)\r
- goto cleanup;\r
-\r
- if (FileDetails)\r
- {\r
- memcpy(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName));\r
- if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL))\r
- goto cleanup;\r
- }\r
- ret = TRUE;\r
-\r
-cleanup:\r
- HeapFree(GetProcessHeap(), 0, FileDetailsW);\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-GetDeletedFileDetailsW(\r
- IN HANDLE hDeletedFile,\r
- IN DWORD BufferSize,\r
- IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL,\r
- OUT LPDWORD RequiredSize OPTIONAL)\r
-{\r
- BOOL ret = FALSE;\r
-\r
- if (!IntCheckDeletedFileHandle(hDeletedFile))\r
- SetLastError(ERROR_INVALID_HANDLE);\r
- else\r
- {\r
- PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile;\r
- if (DeletedFile->bin->Callbacks.GetDetails)\r
- ret = DeletedFile->bin->Callbacks.GetDetails(DeletedFile->bin, DeletedFile->hDeletedFile, BufferSize, FileDetails, RequiredSize);\r
- else\r
- SetLastError(ERROR_NOT_SUPPORTED);\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-BOOL WINAPI\r
-RestoreFile(\r
- IN HANDLE hDeletedFile)\r
-{\r
- BOOL ret = FALSE;\r
-\r
- if (!IntCheckDeletedFileHandle(hDeletedFile))\r
- SetLastError(ERROR_INVALID_HANDLE);\r
- else\r
- {\r
- PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile;\r
- if (DeletedFile->bin->Callbacks.RestoreFile)\r
- ret = DeletedFile->bin->Callbacks.RestoreFile(DeletedFile->bin, DeletedFile->hDeletedFile);\r
- else\r
- SetLastError(ERROR_NOT_SUPPORTED);\r
- }\r
-\r
- return ret;\r
-}\r
+/*
+ * PROJECT: Recycle bin management
+ * LICENSE: GPL v2 - See COPYING in the top level directory
+ * FILE: lib/recyclebin/openclose.c
+ * PURPOSE: Public interface
+ * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#include "recyclebin_private.h"
+
+typedef struct _ENUMERATE_RECYCLE_BIN_CONTEXT
+{
+ PRECYCLE_BIN bin;
+ PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback;
+ PVOID Context;
+} ENUMERATE_RECYCLE_BIN_CONTEXT, *PENUMERATE_RECYCLE_BIN_CONTEXT;
+
+BOOL WINAPI
+CloseRecycleBinHandle(
+ IN HANDLE hDeletedFile)
+{
+ BOOL ret = FALSE;
+
+ if (!IntCheckDeletedFileHandle(hDeletedFile))
+ SetLastError(ERROR_INVALID_HANDLE);
+ else
+ {
+ PDELETED_FILE_HANDLE file = (PDELETED_FILE_HANDLE)hDeletedFile;
+ ret = DereferenceHandle(&file->refCount);
+ }
+
+ return ret;
+}
+
+BOOL WINAPI
+DeleteFileToRecycleBinA(
+ IN LPCSTR FileName)
+{
+ int len;
+ LPWSTR FileNameW = NULL;
+ BOOL ret = FALSE;
+
+ /* 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)
+{
+ LPWSTR FullFileName = NULL;
+ DWORD dwBufferLength = 0;
+ LPWSTR lpFilePart;
+ DWORD len;
+ PRECYCLE_BIN bin = NULL;
+ BOOL ret = FALSE;
+
+ /* Check parameters */
+ if (FileName == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto cleanup;
+ }
+
+ /* Get full file name */
+ while (TRUE)
+ {
+ len = GetFullPathNameW(FileName, dwBufferLength, FullFileName, &lpFilePart);
+ if (len == 0)
+ goto cleanup;
+ else if (len < dwBufferLength)
+ break;
+ HeapFree(GetProcessHeap(), 0, FullFileName);
+ dwBufferLength = len;
+ FullFileName = HeapAlloc(GetProcessHeap(), 0, dwBufferLength * sizeof(WCHAR));
+ if (!FullFileName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ }
+
+ if (!lpFilePart || dwBufferLength < 2 || FullFileName[1] != ':')
+ {
+ /* Only a directory name, or not a local file */
+ SetLastError(ERROR_INVALID_NAME);
+ }
+
+ /* Open recycle bin */
+ bin = IntReferenceRecycleBin(FullFileName[0]);
+ if (!bin)
+ goto cleanup;
+
+ if (bin->Callbacks.DeleteFile)
+ ret = bin->Callbacks.DeleteFile(bin, FullFileName, lpFilePart);
+ else
+ SetLastError(ERROR_NOT_SUPPORTED);
+
+cleanup:
+ HeapFree(GetProcessHeap(), 0, FullFileName);
+ if (bin)
+ DereferenceHandle(&bin->refCount);
+ return ret;
+}
+
+BOOL WINAPI
+EmptyRecycleBinA(
+ IN CHAR driveLetter)
+{
+ return EmptyRecycleBinW((WCHAR)driveLetter);
+}
+
+BOOL WINAPI
+EmptyRecycleBinW(
+ IN WCHAR driveLetter)
+{
+ PRECYCLE_BIN bin = NULL;
+ BOOL ret = FALSE;
+
+ /* Open recycle bin */
+ bin = IntReferenceRecycleBin(driveLetter);
+ if (!bin)
+ goto cleanup;
+
+ if (bin->Callbacks.EmptyRecycleBin)
+ ret = bin->Callbacks.EmptyRecycleBin(&bin);
+ else
+ SetLastError(ERROR_NOT_SUPPORTED);
+
+cleanup:
+ if (bin)
+ DereferenceHandle(&bin->refCount);
+ return ret;
+}
+
+BOOL WINAPI
+EnumerateRecycleBinA(
+ IN CHAR driveLetter,
+ IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
+ IN PVOID Context OPTIONAL)
+{
+ return EnumerateRecycleBinW((WCHAR)driveLetter, pFnCallback, Context);
+}
+
+static BOOL
+IntCloseDeletedFileHandle(
+ IN PREFCOUNT_DATA pData)
+{
+ PDELETED_FILE_HANDLE file;
+
+ file = CONTAINING_RECORD(pData, DELETED_FILE_HANDLE, refCount);
+ if (!DereferenceHandle(&file->bin->refCount))
+ return FALSE;
+
+ file->magic = 0;
+ HeapFree(GetProcessHeap(), 0, file);
+ return TRUE;
+}
+
+static BOOL
+IntEnumerateRecycleBinCallback(
+ IN PVOID Context,
+ IN HANDLE hDeletedFile)
+{
+ PENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext = (PENUMERATE_RECYCLE_BIN_CONTEXT)Context;
+ PDELETED_FILE_HANDLE DeletedFileHandle = NULL;
+ BOOL ret = FALSE;
+
+ DeletedFileHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(DELETED_FILE_HANDLE));
+ if (!DeletedFileHandle)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+
+ ReferenceHandle(&CallbackContext->bin->refCount);
+ InitializeHandle(&DeletedFileHandle->refCount, IntCloseDeletedFileHandle);
+ DeletedFileHandle->magic = DELETEDFILE_MAGIC;
+ DeletedFileHandle->bin = CallbackContext->bin;
+ DeletedFileHandle->hDeletedFile = hDeletedFile;
+
+ ret = CallbackContext->pFnCallback(CallbackContext->Context, DeletedFileHandle);
+
+cleanup:
+ if (!ret)
+ {
+ if (DeletedFileHandle)
+ DereferenceHandle(&DeletedFileHandle->refCount);
+ }
+ return ret;
+}
+
+BOOL WINAPI
+EnumerateRecycleBinW(
+ IN WCHAR driveLetter,
+ IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
+ IN PVOID Context OPTIONAL)
+{
+ PRECYCLE_BIN bin = NULL;
+ BOOL ret = FALSE;
+
+ /* Check parameters */
+ if (pFnCallback == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto cleanup;
+ }
+
+ /* Open recycle bin */
+ bin = IntReferenceRecycleBin(driveLetter);
+ if (!bin)
+ goto cleanup;
+
+ if (bin->Callbacks.EnumerateFiles)
+ {
+ ENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext;
+
+ CallbackContext.bin = bin;
+ CallbackContext.pFnCallback = pFnCallback;
+ CallbackContext.Context = Context;
+
+ ret = bin->Callbacks.EnumerateFiles(bin, IntEnumerateRecycleBinCallback, &CallbackContext);
+ }
+ else
+ SetLastError(ERROR_NOT_SUPPORTED);
+
+cleanup:
+ if (bin)
+ DereferenceHandle(&bin->refCount);
+ return ret;
+}
+
+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;
+
+ 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)
+ {
+ memcpy(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)
+{
+ BOOL ret = FALSE;
+
+ if (!IntCheckDeletedFileHandle(hDeletedFile))
+ SetLastError(ERROR_INVALID_HANDLE);
+ else
+ {
+ PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile;
+ if (DeletedFile->bin->Callbacks.GetDetails)
+ ret = DeletedFile->bin->Callbacks.GetDetails(DeletedFile->bin, DeletedFile->hDeletedFile, BufferSize, FileDetails, RequiredSize);
+ else
+ SetLastError(ERROR_NOT_SUPPORTED);
+ }
+
+ return ret;
+}
+
+BOOL WINAPI
+RestoreFile(
+ IN HANDLE hDeletedFile)
+{
+ BOOL ret = FALSE;
+
+ if (!IntCheckDeletedFileHandle(hDeletedFile))
+ SetLastError(ERROR_INVALID_HANDLE);
+ else
+ {
+ PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile;
+ if (DeletedFile->bin->Callbacks.RestoreFile)
+ ret = DeletedFile->bin->Callbacks.RestoreFile(DeletedFile->bin, DeletedFile->hDeletedFile);
+ else
+ SetLastError(ERROR_NOT_SUPPORTED);
+ }
+
+ return ret;
+}