2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/delete.c
5 * PURPOSE: Deleting files
6 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
11 /* INCLUDES ****************************************************************/
15 #include <reactos/debug.h>
17 /* FUNCTIONS ****************************************************************/
24 DeleteFileA(IN LPCSTR lpFileName
)
26 PUNICODE_STRING FileName
;
28 /* Convert the string to unicode, and call the wide function */
29 FileName
= Basep8BitStringToStaticUnicodeString(lpFileName
);
30 if (FileName
) return DeleteFileW(FileName
->Buffer
);
39 DeleteFileW(IN LPCWSTR lpFileName
)
41 FILE_DISPOSITION_INFORMATION FileDispInfo
;
42 OBJECT_ATTRIBUTES ObjectAttributes
;
43 IO_STATUS_BLOCK IoStatusBlock
;
44 UNICODE_STRING NtPathU
;
47 RTL_RELATIVE_NAME_U RelativeName
;
49 FILE_ATTRIBUTE_TAG_INFORMATION FileTagInformation
;
51 /* Convert to NT path and get the relative name too */
52 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
57 /* Bail out if the path name makes no sense */
58 SetLastError(ERROR_PATH_NOT_FOUND
);
62 /* Save the path buffer in case we free it later */
63 PathBuffer
= NtPathU
.Buffer
;
65 /* If we have a relative name... */
66 if (RelativeName
.RelativeName
.Length
)
68 /* Do a relative open with only the relative path set */
69 NtPathU
= RelativeName
.RelativeName
;
73 /* Do a full path open with no containing directory */
74 RelativeName
.ContainingDirectory
= NULL
;
77 /* Now open the directory name that was passed in */
78 InitializeObjectAttributes(&ObjectAttributes
,
81 RelativeName
.ContainingDirectory
,
83 Status
= NtOpenFile(&FileHandle
,
84 DELETE
| FILE_READ_ATTRIBUTES
,
87 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
88 FILE_NON_DIRECTORY_FILE
|
89 FILE_OPEN_FOR_BACKUP_INTENT
|
90 FILE_OPEN_REPARSE_POINT
);
91 if (NT_SUCCESS(Status
))
93 /* Check if there's a reparse point associated with this file handle */
94 Status
= NtQueryInformationFile(FileHandle
,
97 sizeof(FileTagInformation
),
98 FileAttributeTagInformation
);
99 if ((NT_SUCCESS(Status
)) &&
100 (FileTagInformation
.FileAttributes
& FILE_ATTRIBUTE_REPARSE_POINT
) &&
101 (FileTagInformation
.ReparseTag
!= IO_REPARSE_TAG_MOUNT_POINT
))
103 /* There is, so now try to open it with reparse behavior */
105 Status
= NtOpenFile(&FileHandle
,
112 FILE_NON_DIRECTORY_FILE
|
113 FILE_OPEN_FOR_BACKUP_INTENT
);
114 if (!NT_SUCCESS(Status
))
116 /* We failed -- maybe whoever is handling this tag isn't there */
117 if (Status
== STATUS_IO_REPARSE_TAG_NOT_HANDLED
)
119 /* Try to open it for delete, without reparse behavior */
120 Status
= NtOpenFile(&FileHandle
,
127 FILE_NON_DIRECTORY_FILE
|
128 FILE_OPEN_FOR_BACKUP_INTENT
|
129 FILE_OPEN_REPARSE_POINT
);
132 if (!NT_SUCCESS(Status
))
134 RtlReleaseRelativeName(&RelativeName
);
135 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
136 BaseSetLastNTError(Status
);
141 else if (!(NT_SUCCESS(Status
)) &&
142 (Status
!= STATUS_NOT_IMPLEMENTED
) &&
143 (Status
!= STATUS_INVALID_PARAMETER
))
145 /* We had some critical error querying the attributes, bail out */
146 RtlReleaseRelativeName(&RelativeName
);
147 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
149 BaseSetLastNTError(Status
);
155 /* It's possible that FILE_OPEN_REPARSE_POINT was not understood */
156 if (Status
== STATUS_INVALID_PARAMETER
)
158 /* Try opening the file normally, with reparse behavior */
159 Status
= NtOpenFile(&FileHandle
,
166 FILE_NON_DIRECTORY_FILE
|
167 FILE_OPEN_FOR_BACKUP_INTENT
);
168 if (!NT_SUCCESS(Status
))
170 /* This failed too, fail */
171 RtlReleaseRelativeName(&RelativeName
);
172 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
173 BaseSetLastNTError(Status
);
179 /* Maybe we didn't have READ_ATTRIBUTE rights? */
180 if (Status
!= STATUS_ACCESS_DENIED
)
182 /* Nope, it was something else, let's fail */
183 RtlReleaseRelativeName(&RelativeName
);
184 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
185 BaseSetLastNTError(Status
);
189 /* Let's try again, without querying attributes */
190 Status
= NtOpenFile(&FileHandle
,
197 FILE_NON_DIRECTORY_FILE
|
198 FILE_OPEN_FOR_BACKUP_INTENT
|
199 FILE_OPEN_REPARSE_POINT
);
200 if (!NT_SUCCESS(Status
))
202 /* This failed too, so bail out */
203 RtlReleaseRelativeName(&RelativeName
);
204 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
205 BaseSetLastNTError(Status
);
211 /* Ready to delete the file, so cleanup temporary data */
212 RtlReleaseRelativeName(&RelativeName
);
213 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer
);
215 /* Ask for the file to be deleted */
216 FileDispInfo
.DeleteFile
= TRUE
;
217 Status
= NtSetInformationFile(FileHandle
,
220 sizeof(FILE_DISPOSITION_INFORMATION
),
221 FileDispositionInformation
);
223 if (!NT_SUCCESS(Status
))
225 /* Deletion failed, tell the caller */
226 BaseSetLastNTError(Status
);
230 /* Tell the caller deletion worked */