set most of trunk svn property eol-style:native
[reactos.git] / reactos / lib / recyclebin / recyclebin.c
index 955495e..51bf5e1 100644 (file)
-/*\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;
+}