Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendelete.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
1.7.6.1
|