mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00

Remove the commented-out IsValidPath() in that file, and remove as well the temporary prototypes in regutil.c . svn path=/branches/setup_improvements/; revision=75249
268 lines
6.9 KiB
C
268 lines
6.9 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS text-mode setup
|
|
* FILE: base/setup/usetup/filesup.c
|
|
* PURPOSE: File support functions
|
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "usetup.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
static BOOLEAN HasCurrentCabinet = FALSE;
|
|
static WCHAR CurrentCabinetName[MAX_PATH];
|
|
static CAB_SEARCH Search;
|
|
|
|
static
|
|
NTSTATUS
|
|
SetupCreateSingleDirectory(
|
|
PWCHAR DirectoryName)
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
UNICODE_STRING PathName;
|
|
HANDLE DirectoryHandle;
|
|
NTSTATUS Status;
|
|
|
|
if (!RtlCreateUnicodeString(&PathName, DirectoryName))
|
|
return STATUS_NO_MEMORY;
|
|
|
|
if (PathName.Length > sizeof(WCHAR) &&
|
|
PathName.Buffer[PathName.Length / sizeof(WCHAR) - 2] == L'\\' &&
|
|
PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == L'.')
|
|
{
|
|
PathName.Length -= sizeof(WCHAR);
|
|
PathName.Buffer[PathName.Length / sizeof(WCHAR)] = 0;
|
|
}
|
|
|
|
if (PathName.Length > sizeof(WCHAR) &&
|
|
PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == L'\\')
|
|
{
|
|
PathName.Length -= sizeof(WCHAR);
|
|
PathName.Buffer[PathName.Length / sizeof(WCHAR)] = 0;
|
|
}
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&PathName,
|
|
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtCreateFile(&DirectoryHandle,
|
|
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_DIRECTORY,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_OPEN_IF,
|
|
FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE,
|
|
NULL,
|
|
0);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
NtClose(DirectoryHandle);
|
|
}
|
|
|
|
RtlFreeUnicodeString(&PathName);
|
|
|
|
return Status;
|
|
}
|
|
|
|
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(NULL, PathBuffer))
|
|
{
|
|
DPRINT("Create: %S\n", PathBuffer);
|
|
Status = SetupCreateSingleDirectory(PathBuffer);
|
|
if (!NT_SUCCESS(Status))
|
|
goto done;
|
|
}
|
|
|
|
*Ptr = L'\\';
|
|
}
|
|
|
|
Ptr++;
|
|
}
|
|
|
|
if (!DoesPathExist(NULL, 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
|
|
SetupExtractFile(
|
|
PWCHAR CabinetFileName,
|
|
PWCHAR SourceFileName,
|
|
PWCHAR DestinationPathName)
|
|
{
|
|
ULONG CabStatus;
|
|
|
|
DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
|
|
CabinetFileName, SourceFileName, DestinationPathName);
|
|
|
|
if (HasCurrentCabinet)
|
|
{
|
|
DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName);
|
|
}
|
|
|
|
if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0))
|
|
{
|
|
DPRINT("Using same cabinet as last time\n");
|
|
|
|
/* Use our last location because the files should be sequential */
|
|
CabStatus = CabinetFindNextFileSequential(SourceFileName, &Search);
|
|
if (CabStatus != CAB_STATUS_SUCCESS)
|
|
{
|
|
DPRINT("Sequential miss on file: %S\n", SourceFileName);
|
|
|
|
/* Looks like we got unlucky */
|
|
CabStatus = CabinetFindFirst(SourceFileName, &Search);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPRINT("Using new cabinet\n");
|
|
|
|
if (HasCurrentCabinet)
|
|
{
|
|
CabinetCleanup();
|
|
}
|
|
|
|
wcscpy(CurrentCabinetName, CabinetFileName);
|
|
|
|
CabinetInitialize();
|
|
CabinetSetEventHandlers(NULL, NULL, NULL);
|
|
CabinetSetCabinetName(CabinetFileName);
|
|
|
|
CabStatus = CabinetOpen();
|
|
if (CabStatus == CAB_STATUS_SUCCESS)
|
|
{
|
|
DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
|
|
HasCurrentCabinet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DPRINT("Cannot open cabinet (%d)\n", CabStatus);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
/* We have to start at the beginning here */
|
|
CabStatus = CabinetFindFirst(SourceFileName, &Search);
|
|
}
|
|
|
|
if (CabStatus != CAB_STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("Unable to find '%S' in cabinet '%S'\n", SourceFileName, CabinetGetCabinetName());
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
CabinetSetDestinationPath(DestinationPathName);
|
|
CabStatus = CabinetExtractFile(&Search);
|
|
if (CabStatus != CAB_STATUS_SUCCESS)
|
|
{
|
|
DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
BOOLEAN
|
|
IsValidPath(
|
|
IN PCWSTR InstallDir)
|
|
{
|
|
UINT i, Length;
|
|
|
|
Length = wcslen(InstallDir);
|
|
|
|
// TODO: Add check for 8.3 too.
|
|
|
|
/* Path must be at least 2 characters long */
|
|
// if (Length < 2)
|
|
// return FALSE;
|
|
|
|
/* Path must start with a backslash */
|
|
// if (InstallDir[0] != L'\\')
|
|
// return FALSE;
|
|
|
|
/* Path must not end with a backslash */
|
|
if (InstallDir[Length - 1] == L'\\')
|
|
return FALSE;
|
|
|
|
/* Path must not contain whitespace characters */
|
|
for (i = 0; i < Length; i++)
|
|
{
|
|
if (iswspace(InstallDir[i]))
|
|
return FALSE;
|
|
}
|
|
|
|
/* Path component must not end with a dot */
|
|
for (i = 0; i < Length; i++)
|
|
{
|
|
if (InstallDir[i] == L'\\' && i > 0)
|
|
{
|
|
if (InstallDir[i - 1] == L'.')
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (InstallDir[Length - 1] == L'.')
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|