ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

delete.c
Go to the documentation of this file.
00001 /* $Id: delete.c 56650 2012-05-23 16:51:22Z ion $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            lib/kernel32/file/delete.c
00006  * PURPOSE:         Deleting files
00007  * PROGRAMMER:      Ariadne (ariadne@xs4all.nl)
00008  * UPDATE HISTORY:
00009  *                  Created 01/11/98
00010  */
00011 
00012 /* INCLUDES ****************************************************************/
00013 
00014 #include <k32.h>
00015 #define NDEBUG
00016 #include <reactos/debug.h>
00017 
00018 /* FUNCTIONS ****************************************************************/
00019 
00020 /*
00021  * @implemented
00022  */
00023 BOOL
00024 WINAPI
00025 DeleteFileA(IN LPCSTR lpFileName)
00026 {
00027     PUNICODE_STRING FileName;
00028 
00029     /* Convert the string to unicode, and call the wide function */
00030     FileName = Basep8BitStringToStaticUnicodeString(lpFileName);
00031     if (FileName) return DeleteFileW(FileName->Buffer);
00032     return FALSE;
00033 }
00034 
00035 /*
00036  * @implemented
00037  */
00038 BOOL
00039 WINAPI
00040 DeleteFileW(IN LPCWSTR lpFileName)
00041 {
00042     FILE_DISPOSITION_INFORMATION FileDispInfo;
00043     OBJECT_ATTRIBUTES ObjectAttributes;
00044     IO_STATUS_BLOCK IoStatusBlock;
00045     UNICODE_STRING NtPathU;
00046     HANDLE FileHandle;
00047     NTSTATUS Status;
00048     RTL_RELATIVE_NAME_U RelativeName;
00049     PWCHAR PathBuffer;
00050     FILE_ATTRIBUTE_TAG_INFORMATION FileTagInformation;
00051 
00052     /* Convert to NT path and get the relative name too */
00053     if (!RtlDosPathNameToNtPathName_U(lpFileName,
00054                                       &NtPathU,
00055                                       NULL,
00056                                       &RelativeName))
00057     {
00058         /* Bail out if the path name makes no sense */
00059         SetLastError(ERROR_PATH_NOT_FOUND);
00060         return FALSE;
00061     }
00062 
00063     /* Save the path buffer in case we free it later */
00064     PathBuffer = NtPathU.Buffer;
00065 
00066     /* If we have a relative name... */
00067     if (RelativeName.RelativeName.Length)
00068     {
00069         /* Do a relative open with only the relative path set */
00070         NtPathU = RelativeName.RelativeName;
00071     }
00072     else
00073     {
00074         /* Do a full path open with no containing directory */
00075         RelativeName.ContainingDirectory = NULL;
00076     }
00077 
00078     /* Now open the directory name that was passed in */
00079     InitializeObjectAttributes(&ObjectAttributes,
00080                                &NtPathU,
00081                                OBJ_CASE_INSENSITIVE,
00082                                RelativeName.ContainingDirectory,
00083                                NULL);
00084     Status = NtOpenFile(&FileHandle,
00085                         DELETE | FILE_READ_ATTRIBUTES,
00086                         &ObjectAttributes,
00087                         &IoStatusBlock,
00088                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00089                         FILE_NON_DIRECTORY_FILE |
00090                         FILE_OPEN_FOR_BACKUP_INTENT |
00091                         FILE_OPEN_REPARSE_POINT);
00092     if (NT_SUCCESS(Status))
00093     {
00094         /* Check if there's a reparse point associated with this file handle */
00095         Status = NtQueryInformationFile(FileHandle,
00096                                         &IoStatusBlock,
00097                                         &FileTagInformation,
00098                                         sizeof(FileTagInformation),
00099                                         FileAttributeTagInformation);
00100         if ((NT_SUCCESS(Status)) &&
00101             (FileTagInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
00102             (FileTagInformation.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT))
00103         {
00104             /* There is, so now try to open it with reparse behavior */
00105             NtClose(FileHandle);
00106             Status = NtOpenFile(&FileHandle,
00107                                 DELETE,
00108                                 &ObjectAttributes,
00109                                 &IoStatusBlock,
00110                                 FILE_SHARE_DELETE |
00111                                 FILE_SHARE_READ |
00112                                 FILE_SHARE_WRITE,
00113                                 FILE_NON_DIRECTORY_FILE |
00114                                 FILE_OPEN_FOR_BACKUP_INTENT);
00115             if (!NT_SUCCESS(Status))
00116             {
00117                 /* We failed -- maybe whoever is handling this tag isn't there */
00118                 if (Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED)
00119                 {
00120                     /* Try to open it for delete, without reparse behavior */
00121                     Status = NtOpenFile(&FileHandle,
00122                                         DELETE,
00123                                         &ObjectAttributes,
00124                                         &IoStatusBlock,
00125                                         FILE_SHARE_READ |
00126                                         FILE_SHARE_WRITE |
00127                                         FILE_SHARE_DELETE,
00128                                         FILE_NON_DIRECTORY_FILE |
00129                                         FILE_OPEN_FOR_BACKUP_INTENT |
00130                                         FILE_OPEN_REPARSE_POINT);
00131                 }
00132 
00133                 if (!NT_SUCCESS(Status))
00134                 {
00135                      RtlReleaseRelativeName(&RelativeName);
00136                      RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00137                      BaseSetLastNTError(Status);
00138                      return FALSE;
00139                 }
00140             }
00141         }
00142         else if (!(NT_SUCCESS(Status)) &&
00143                  (Status != STATUS_NOT_IMPLEMENTED) &&
00144                  (Status != STATUS_INVALID_PARAMETER))
00145         {
00146             /* We had some critical error querying the attributes, bail out */
00147             RtlReleaseRelativeName(&RelativeName);
00148             RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00149             NtClose(FileHandle);
00150             BaseSetLastNTError(Status);
00151             return FALSE;
00152         }
00153     }
00154     else
00155     {
00156         /* It's possible that FILE_OPEN_REPARSE_POINT was not understood */
00157         if (Status == STATUS_INVALID_PARAMETER)
00158         {
00159             /* Try opening the file normally, with reparse behavior */
00160             Status = NtOpenFile(&FileHandle,
00161                                 DELETE,
00162                                 &ObjectAttributes,
00163                                 &IoStatusBlock,
00164                                 FILE_SHARE_DELETE |
00165                                 FILE_SHARE_READ |
00166                                 FILE_SHARE_WRITE,
00167                                 FILE_NON_DIRECTORY_FILE |
00168                                 FILE_OPEN_FOR_BACKUP_INTENT);
00169             if (!NT_SUCCESS(Status))
00170             {
00171                 /* This failed too, fail */
00172                 RtlReleaseRelativeName(&RelativeName);
00173                 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00174                 BaseSetLastNTError(Status);
00175                 return FALSE;
00176             }
00177         }
00178         else
00179         {
00180             /* Maybe we didn't have READ_ATTRIBUTE rights? */
00181             if (Status != STATUS_ACCESS_DENIED)
00182             {
00183                 /* Nope, it was something else, let's fail */
00184                 RtlReleaseRelativeName(&RelativeName);
00185                 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00186                 BaseSetLastNTError(Status);
00187                 return FALSE;
00188             }
00189 
00190             /* Let's try again, without querying attributes */
00191             Status = NtOpenFile(&FileHandle,
00192                                 DELETE,
00193                                 &ObjectAttributes,
00194                                 &IoStatusBlock,
00195                                 FILE_SHARE_DELETE |
00196                                 FILE_SHARE_READ |
00197                                 FILE_SHARE_WRITE,
00198                                 FILE_NON_DIRECTORY_FILE |
00199                                 FILE_OPEN_FOR_BACKUP_INTENT |
00200                                 FILE_OPEN_REPARSE_POINT);
00201             if (!NT_SUCCESS(Status))
00202             {
00203                 /* This failed too, so bail out */
00204                 RtlReleaseRelativeName(&RelativeName);
00205                 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00206                 BaseSetLastNTError(Status);
00207                 return FALSE;
00208             }
00209         }
00210     }
00211 
00212     /* Ready to delete the file, so cleanup temporary data */
00213     RtlReleaseRelativeName(&RelativeName);
00214     RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
00215 
00216     /* Ask for the file to be deleted */
00217     FileDispInfo.DeleteFile = TRUE;
00218     Status = NtSetInformationFile(FileHandle,
00219                                   &IoStatusBlock,
00220                                   &FileDispInfo,
00221                                   sizeof(FILE_DISPOSITION_INFORMATION),
00222                                   FileDispositionInformation);
00223     NtClose(FileHandle);
00224     if (!NT_SUCCESS(Status))
00225     {
00226         /* Deletion failed, tell the caller */
00227         BaseSetLastNTError(Status);
00228         return FALSE;
00229     }
00230 
00231     /* Tell the caller deletion worked */
00232     return TRUE;
00233 }
00234 
00235 /* EOF */

Generated on Sun May 27 2012 04:16:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.