[ros-diffs] [ion] 56650: [KERNEL32]: Reimplement DeleteFileA and W to handle the new ansi-Unicode functions, as well as to handle the same cases that Pierre implemented in the directory functions (dealing with...

ion at svn.reactos.org ion at svn.reactos.org
Wed May 23 16:51:23 UTC 2012


Author: ion
Date: Wed May 23 16:51:22 2012
New Revision: 56650

URL: http://svn.reactos.org/svn/reactos?rev=56650&view=rev
Log:
[KERNEL32]: Reimplement DeleteFileA and W to handle the new ansi-Unicode functions, as well as to handle the same cases that Pierre implemented in the directory functions (dealing with reparse points and tags).

Modified:
    trunk/reactos/dll/win32/kernel32/client/file/delete.c

Modified: trunk/reactos/dll/win32/kernel32/client/file/delete.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/file/delete.c?rev=56650&r1=56649&r2=56650&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/delete.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/delete.c [iso-8859-1] Wed May 23 16:51:22 2012
@@ -14,7 +14,6 @@
 #include <k32.h>
 #define NDEBUG
 #include <reactos/debug.h>
-DEBUG_CHANNEL(kernel32file);
 
 /* FUNCTIONS ****************************************************************/
 
@@ -23,101 +22,214 @@
  */
 BOOL
 WINAPI
-DeleteFileA (
-	LPCSTR	lpFileName
-	)
+DeleteFileA(IN LPCSTR lpFileName)
 {
-	PWCHAR FileNameW;
-
-   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
-      return FALSE;
-
-	return DeleteFileW (FileNameW);
+    PUNICODE_STRING FileName;
+
+    /* Convert the string to unicode, and call the wide function */
+    FileName = Basep8BitStringToStaticUnicodeString(lpFileName);
+    if (FileName) return DeleteFileW(FileName->Buffer);
+    return FALSE;
 }
-
 
 /*
  * @implemented
  */
 BOOL
 WINAPI
-DeleteFileW (
-	LPCWSTR	lpFileName
-	)
+DeleteFileW(IN LPCWSTR lpFileName)
 {
-	FILE_DISPOSITION_INFORMATION FileDispInfo;
-	OBJECT_ATTRIBUTES ObjectAttributes;
-	IO_STATUS_BLOCK IoStatusBlock;
-	UNICODE_STRING NtPathU;
-	HANDLE FileHandle;
-	NTSTATUS Status;
-
-	TRACE("DeleteFileW (lpFileName %S)\n",lpFileName);
-
-	if (!RtlDosPathNameToNtPathName_U (lpFileName,
-	                                   &NtPathU,
-	                                   NULL,
-	                                   NULL))
-   {
-      SetLastError(ERROR_PATH_NOT_FOUND);
-		return FALSE;
-   }
-
-	TRACE("NtPathU \'%wZ\'\n", &NtPathU);
-
-        InitializeObjectAttributes(&ObjectAttributes,
-                                   &NtPathU,
-                                   OBJ_CASE_INSENSITIVE,
-                                   NULL,
-                                   NULL);
-
-	Status = NtCreateFile (&FileHandle,
-	                       DELETE,
-	                       &ObjectAttributes,
-	                       &IoStatusBlock,
-	                       NULL,
-	                       FILE_ATTRIBUTE_NORMAL,
-	                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-	                       FILE_OPEN,
-                               FILE_NON_DIRECTORY_FILE,
-	                       NULL,
-	                       0);
-
-	RtlFreeHeap(RtlGetProcessHeap(),
-                    0,
-                    NtPathU.Buffer);
-
-	if (!NT_SUCCESS(Status))
-	{
-		WARN("Status 0x%08x\n", Status);
-		BaseSetLastNTError (Status);
-		return FALSE;
-	}
-
-	FileDispInfo.DeleteFile = TRUE;
-
-	Status = NtSetInformationFile (FileHandle,
-	                               &IoStatusBlock,
-	                               &FileDispInfo,
-	                               sizeof(FILE_DISPOSITION_INFORMATION),
-	                               FileDispositionInformation);
-	if (!NT_SUCCESS(Status))
-	{
-		WARN("Status 0x%08x\n", Status);
-		NtClose (FileHandle);
-		BaseSetLastNTError (Status);
-		return FALSE;
-	}
-
-	Status = NtClose (FileHandle);
-	if (!NT_SUCCESS (Status))
-	{
-		WARN("Status 0x%08x\n", Status);
-		BaseSetLastNTError (Status);
-		return FALSE;
-	}
-
-	return TRUE;
+    FILE_DISPOSITION_INFORMATION FileDispInfo;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    UNICODE_STRING NtPathU;
+    HANDLE FileHandle;
+    NTSTATUS Status;
+    RTL_RELATIVE_NAME_U RelativeName;
+    PWCHAR PathBuffer;
+    FILE_ATTRIBUTE_TAG_INFORMATION FileTagInformation;
+
+    /* Convert to NT path and get the relative name too */
+    if (!RtlDosPathNameToNtPathName_U(lpFileName,
+                                      &NtPathU,
+                                      NULL,
+                                      &RelativeName))
+    {
+        /* Bail out if the path name makes no sense */
+        SetLastError(ERROR_PATH_NOT_FOUND);
+        return FALSE;
+    }
+
+    /* Save the path buffer in case we free it later */
+    PathBuffer = NtPathU.Buffer;
+
+    /* If we have a relative name... */
+    if (RelativeName.RelativeName.Length)
+    {
+        /* Do a relative open with only the relative path set */
+        NtPathU = RelativeName.RelativeName;
+    }
+    else
+    {
+        /* Do a full path open with no containing directory */
+        RelativeName.ContainingDirectory = NULL;
+    }
+
+    /* Now open the directory name that was passed in */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtPathU,
+                               OBJ_CASE_INSENSITIVE,
+                               RelativeName.ContainingDirectory,
+                               NULL);
+    Status = NtOpenFile(&FileHandle,
+                        DELETE | FILE_READ_ATTRIBUTES,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_NON_DIRECTORY_FILE |
+                        FILE_OPEN_FOR_BACKUP_INTENT |
+                        FILE_OPEN_REPARSE_POINT);
+    if (NT_SUCCESS(Status))
+    {
+        /* Check if there's a reparse point associated with this file handle */
+        Status = NtQueryInformationFile(FileHandle,
+                                        &IoStatusBlock,
+                                        &FileTagInformation,
+                                        sizeof(FileTagInformation),
+                                        FileAttributeTagInformation);
+        if ((NT_SUCCESS(Status)) &&
+            (FileTagInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+            (FileTagInformation.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT))
+        {
+            /* There is, so now try to open it with reparse behavior */
+            NtClose(FileHandle);
+            Status = NtOpenFile(&FileHandle,
+                                DELETE,
+                                &ObjectAttributes,
+                                &IoStatusBlock,
+                                FILE_SHARE_DELETE |
+                                FILE_SHARE_READ |
+                                FILE_SHARE_WRITE,
+                                FILE_NON_DIRECTORY_FILE |
+                                FILE_OPEN_FOR_BACKUP_INTENT);
+            if (!NT_SUCCESS(Status))
+            {
+                /* We failed -- maybe whoever is handling this tag isn't there */
+                if (Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED)
+                {
+                    /* Try to open it for delete, without reparse behavior */
+                    Status = NtOpenFile(&FileHandle,
+                                        DELETE,
+                                        &ObjectAttributes,
+                                        &IoStatusBlock,
+                                        FILE_SHARE_READ |
+                                        FILE_SHARE_WRITE |
+                                        FILE_SHARE_DELETE,
+                                        FILE_NON_DIRECTORY_FILE |
+                                        FILE_OPEN_FOR_BACKUP_INTENT |
+                                        FILE_OPEN_REPARSE_POINT);
+                }
+
+                if (!NT_SUCCESS(Status))
+                {
+                     RtlReleaseRelativeName(&RelativeName);
+                     RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+                     BaseSetLastNTError(Status);
+                     return FALSE;
+                }
+            }
+        }
+        else if (!(NT_SUCCESS(Status)) &&
+                 (Status != STATUS_NOT_IMPLEMENTED) &&
+                 (Status != STATUS_INVALID_PARAMETER))
+        {
+            /* We had some critical error querying the attributes, bail out */
+            RtlReleaseRelativeName(&RelativeName);
+            RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+            NtClose(FileHandle);
+            BaseSetLastNTError(Status);
+            return FALSE;
+        }
+    }
+    else
+    {
+        /* It's possible that FILE_OPEN_REPARSE_POINT was not understood */
+        if (Status == STATUS_INVALID_PARAMETER)
+        {
+            /* Try opening the file normally, with reparse behavior */
+            Status = NtOpenFile(&FileHandle,
+                                DELETE,
+                                &ObjectAttributes,
+                                &IoStatusBlock,
+                                FILE_SHARE_DELETE |
+                                FILE_SHARE_READ |
+                                FILE_SHARE_WRITE,
+                                FILE_NON_DIRECTORY_FILE |
+                                FILE_OPEN_FOR_BACKUP_INTENT);
+            if (!NT_SUCCESS(Status))
+            {
+                /* This failed too, fail */
+                RtlReleaseRelativeName(&RelativeName);
+                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+                BaseSetLastNTError(Status);
+                return FALSE;
+            }
+        }
+        else
+        {
+            /* Maybe we didn't have READ_ATTRIBUTE rights? */
+            if (Status != STATUS_ACCESS_DENIED)
+            {
+                /* Nope, it was something else, let's fail */
+                RtlReleaseRelativeName(&RelativeName);
+                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+                BaseSetLastNTError(Status);
+                return FALSE;
+            }
+
+            /* Let's try again, without querying attributes */
+            Status = NtOpenFile(&FileHandle,
+                                DELETE,
+                                &ObjectAttributes,
+                                &IoStatusBlock,
+                                FILE_SHARE_DELETE |
+                                FILE_SHARE_READ |
+                                FILE_SHARE_WRITE,
+                                FILE_NON_DIRECTORY_FILE |
+                                FILE_OPEN_FOR_BACKUP_INTENT |
+                                FILE_OPEN_REPARSE_POINT);
+            if (!NT_SUCCESS(Status))
+            {
+                /* This failed too, so bail out */
+                RtlReleaseRelativeName(&RelativeName);
+                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+                BaseSetLastNTError(Status);
+                return FALSE;
+            }
+        }
+    }
+
+    /* Ready to delete the file, so cleanup temporary data */
+    RtlReleaseRelativeName(&RelativeName);
+    RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+
+    /* Ask for the file to be deleted */
+    FileDispInfo.DeleteFile = TRUE;
+    Status = NtSetInformationFile(FileHandle,
+                                  &IoStatusBlock,
+                                  &FileDispInfo,
+                                  sizeof(FILE_DISPOSITION_INFORMATION),
+                                  FileDispositionInformation);
+    NtClose(FileHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Deletion failed, tell the caller */
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Tell the caller deletion worked */
+    return TRUE;
 }
 
 /* EOF */




More information about the Ros-diffs mailing list