[USETUP]
authorEric Kohl <eric.kohl@reactos.org>
Tue, 15 Jul 2014 21:34:12 +0000 (21:34 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 15 Jul 2014 21:34:12 +0000 (21:34 +0000)
Reimplement SetupCreateDirectory in such a way, that a full directory path will be created, if needed. This enables us to install ReactOS in a sub-directory like for example '\OS\Test\Alpha\ReactOS'.

svn path=/trunk/; revision=63715

reactos/base/setup/usetup/filesup.c

index eaabc3d..2fe323a 100644 (file)
@@ -37,8 +37,9 @@ static BOOLEAN HasCurrentCabinet = FALSE;
 static WCHAR CurrentCabinetName[MAX_PATH];
 static CAB_SEARCH Search;
 
+static
 NTSTATUS
-SetupCreateDirectory(
+SetupCreateSingleDirectory(
     PWCHAR DirectoryName)
 {
     OBJECT_ATTRIBUTES ObjectAttributes;
@@ -92,6 +93,111 @@ SetupCreateDirectory(
 }
 
 
+static
+BOOLEAN
+DoesPathExist(
+    PWSTR PathName)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    UNICODE_STRING Name;
+    HANDLE FileHandle;
+    NTSTATUS Status;
+
+    RtlInitUnicodeString(&Name,
+                         PathName);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&FileHandle,
+                        GENERIC_READ | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        0,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    if (!NT_SUCCESS(Status))
+    {
+        return FALSE;
+    }
+
+    NtClose(FileHandle);
+
+    return TRUE;
+}
+
+
+NTSTATUS
+SetupCreateDirectory(
+    PWCHAR PathName)
+{
+    PWCHAR PathBuffer = NULL;
+    PWCHAR Ptr, EndPtr;
+    ULONG BackslashCount;
+    ULONG Size;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    Size = (wcslen(PathName) + 1) * sizeof(WCHAR);
+    PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Size);
+    if (PathBuffer == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    wcscpy(PathBuffer, PathName);
+    EndPtr = PathBuffer + wcslen(PathName);
+
+    Ptr = PathBuffer;
+
+    /* Skip the '\Device\HarddiskX\PartitionY\ part */
+    BackslashCount = 0;
+    while (Ptr < EndPtr && BackslashCount < 4)
+    {
+        if (*Ptr == L'\\')
+            BackslashCount++;
+
+        Ptr++;
+    }
+
+    while (Ptr < EndPtr)
+    {
+        if (*Ptr == L'\\')
+        {
+            *Ptr = 0;
+
+            DPRINT("PathBuffer: %S\n", PathBuffer);
+            if (!DoesPathExist(PathBuffer))
+            {
+                DPRINT("Create: %S\n", PathBuffer);
+                Status = SetupCreateSingleDirectory(PathBuffer);
+                if (!NT_SUCCESS(Status))
+                    goto done;
+            }
+
+            *Ptr = L'\\';
+        }
+
+        Ptr++;
+    }
+
+    if (!DoesPathExist(PathBuffer))
+    {
+        DPRINT("Create: %S\n", PathBuffer);
+        Status = SetupCreateSingleDirectory(PathBuffer);
+        if (!NT_SUCCESS(Status))
+            goto done;
+    }
+
+done:
+    DPRINT("Done.\n");
+    if (PathBuffer != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
+
+    return Status;
+}
+
+
 NTSTATUS
 SetupCopyFile(
     PWCHAR SourceFileName,