mirror of
https://github.com/reactos/reactos.git
synced 2024-07-07 21:25:05 +00:00
* Added ini file suport (Thanks to Royce Mitchell!)
* Improved the partition list. * Use information from txtsetup.sif to create directories. * Added basic error handling. svn path=/trunk/; revision=3753
This commit is contained in:
parent
d4293289b3
commit
58cbfb764a
|
@ -366,6 +366,57 @@ WriteConsoleOutputCharacters(LPCSTR lpCharacter,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
WriteConsoleOutputCharactersW(LPCWSTR lpCharacter,
|
||||
ULONG nLength,
|
||||
COORD dwWriteCoord)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PCHAR Buffer;
|
||||
COORD *pCoord;
|
||||
PCHAR pText;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
|
||||
Buffer = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
nLength + sizeof(COORD));
|
||||
pCoord = (COORD *)Buffer;
|
||||
pText = (PCHAR)(pCoord + 1);
|
||||
|
||||
*pCoord = dwWriteCoord;
|
||||
|
||||
/* FIXME: use real unicode->oem conversion */
|
||||
for (i = 0; i < nLength; i++)
|
||||
pText[i] = (CHAR)lpCharacter[i];
|
||||
pText[i] = 0;
|
||||
|
||||
Status = NtDeviceIoControlFile(StdOutput,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
||||
NULL,
|
||||
0,
|
||||
Buffer,
|
||||
nLength + sizeof(COORD));
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
NtWaitForSingleObject(StdOutput,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
|
||||
ULONG nLength,
|
||||
|
@ -892,7 +943,7 @@ SetTextXY(SHORT x, SHORT y, PCHAR Text)
|
|||
|
||||
|
||||
VOID
|
||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text)
|
||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text)
|
||||
{
|
||||
COORD coPos;
|
||||
ULONG Length;
|
||||
|
@ -901,16 +952,20 @@ SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text)
|
|||
coPos.X = x;
|
||||
coPos.Y = y;
|
||||
|
||||
Length = strlen(Text);
|
||||
Length = wcslen(Text);
|
||||
if (Length > len - 1)
|
||||
{
|
||||
Length = len - 1;
|
||||
}
|
||||
|
||||
FillConsoleOutputAttribute(0x70,
|
||||
len,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
WriteConsoleOutputCharacters(Text,
|
||||
Length,
|
||||
coPos);
|
||||
WriteConsoleOutputCharactersW(Text,
|
||||
Length,
|
||||
coPos);
|
||||
|
||||
coPos.X += Length;
|
||||
FillConsoleOutputCharacter('_',
|
||||
|
|
|
@ -108,7 +108,7 @@ VOID
|
|||
SetTextXY(SHORT x, SHORT y, PCHAR Text);
|
||||
|
||||
VOID
|
||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text);
|
||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text);
|
||||
|
||||
VOID
|
||||
SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: drivesup.h,v 1.2 2002/11/02 23:17:06 ekohl Exp $
|
||||
/* $Id: drivesup.h,v 1.3 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/drivesup.h
|
||||
|
@ -38,4 +38,4 @@ GetDriveLetter(ULONG DriveNumber,
|
|||
|
||||
#endif /* __DRIVESUP_H__ */
|
||||
|
||||
/* EOF */
|
||||
/* EOF */
|
||||
|
|
79
reactos/subsys/system/usetup/filesup.c
Normal file
79
reactos/subsys/system/usetup/filesup.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: filesup.c,v 1.1 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/filesup.c
|
||||
* PURPOSE: File support functions
|
||||
* PROGRAMMER: Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ntdll/rtl.h>
|
||||
|
||||
#include "usetup.h"
|
||||
#include "filesup.h"
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CreateDirectory(PWCHAR DirectoryName)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
UNICODE_STRING PathName;
|
||||
HANDLE DirectoryHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlCreateUnicodeString(&PathName,
|
||||
DirectoryName);
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = &PathName;
|
||||
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
Status = NtCreateFile(&DirectoryHandle,
|
||||
DIRECTORY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_DIRECTORY,
|
||||
0,
|
||||
FILE_CREATE,
|
||||
FILE_DIRECTORY_FILE,
|
||||
NULL,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
NtClose(DirectoryHandle);
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&PathName);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* EOF */
|
36
reactos/subsys/system/usetup/filesup.h
Normal file
36
reactos/subsys/system/usetup/filesup.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: filesup.h,v 1.1 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/filesup.h
|
||||
* PURPOSE: File support functions
|
||||
* PROGRAMMER: Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef __FILESUP_H__
|
||||
#define __FILESUP_H__
|
||||
|
||||
NTSTATUS
|
||||
CreateDirectory(PWCHAR DirectoryName);
|
||||
|
||||
|
||||
#endif /* __FILESUP_H__ */
|
||||
|
||||
/* EOF */
|
841
reactos/subsys/system/usetup/inicache.c
Normal file
841
reactos/subsys/system/usetup/inicache.c
Normal file
|
@ -0,0 +1,841 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: inicache.c,v 1.1 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/inicache.c
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory
|
||||
* PROGRAMMER: Royce Mitchell III
|
||||
* Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include "usetup.h"
|
||||
#include "inicache.h"
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS ********************************************************/
|
||||
|
||||
static PINICACHEKEY
|
||||
IniCacheFreeKey(PINICACHEKEY Key)
|
||||
{
|
||||
PINICACHEKEY Next;
|
||||
|
||||
if (Key == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Next = Key->Next;
|
||||
if (Key->Name != NULL)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key->Name);
|
||||
Key->Name = NULL;
|
||||
}
|
||||
|
||||
if (Key->Value != NULL)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key->Value);
|
||||
Key->Value = NULL;
|
||||
}
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key);
|
||||
|
||||
return(Next);
|
||||
}
|
||||
|
||||
|
||||
static PINICACHESECTION
|
||||
IniCacheFreeSection(PINICACHESECTION Section)
|
||||
{
|
||||
PINICACHESECTION Next;
|
||||
|
||||
if (Section == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Next = Section->Next;
|
||||
while (Section->FirstKey != NULL)
|
||||
{
|
||||
Section->FirstKey = IniCacheFreeKey(Section->FirstKey);
|
||||
}
|
||||
Section->LastKey = NULL;
|
||||
|
||||
if (Section->Name != NULL)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Section->Name);
|
||||
Section->Name = NULL;
|
||||
}
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Section);
|
||||
|
||||
return(Next);
|
||||
}
|
||||
|
||||
|
||||
static PINICACHEKEY
|
||||
IniCacheFindKey(PINICACHESECTION Section,
|
||||
PWCHAR Name,
|
||||
ULONG NameLength)
|
||||
{
|
||||
PINICACHEKEY Key;
|
||||
|
||||
Key = Section->FirstKey;
|
||||
while (Key != NULL)
|
||||
{
|
||||
if (NameLength == wcslen(Key->Name))
|
||||
{
|
||||
if (_wcsnicmp(Key->Name, Name, NameLength) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
Key = Key->Next;
|
||||
}
|
||||
|
||||
return(Key);
|
||||
}
|
||||
|
||||
|
||||
static PINICACHEKEY
|
||||
IniCacheAddKey(PINICACHESECTION Section,
|
||||
PCHAR Name,
|
||||
ULONG NameLength,
|
||||
PCHAR Value,
|
||||
ULONG ValueLength)
|
||||
{
|
||||
PINICACHEKEY Key;
|
||||
ULONG i;
|
||||
|
||||
Key = NULL;
|
||||
|
||||
if (Section == NULL ||
|
||||
Name == NULL ||
|
||||
NameLength == 0 ||
|
||||
Value == NULL ||
|
||||
ValueLength == 0)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
sizeof(INICACHEKEY));
|
||||
if (Key == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
RtlZeroMemory(Key,
|
||||
sizeof(INICACHEKEY));
|
||||
|
||||
|
||||
Key->Name = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
(NameLength + 1) * sizeof(WCHAR));
|
||||
if (Key->Name == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Copy value name */
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
Key->Name[i] = (WCHAR)Name[i];
|
||||
}
|
||||
Key->Name[NameLength] = 0;
|
||||
|
||||
|
||||
Key->Value = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
(ValueLength + 1) * sizeof(WCHAR));
|
||||
if (Key->Value == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key->Name);
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Key);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Copy value data */
|
||||
for (i = 0; i < ValueLength; i++)
|
||||
{
|
||||
Key->Value[i] = (WCHAR)Value[i];
|
||||
}
|
||||
Key->Value[ValueLength] = 0;
|
||||
|
||||
|
||||
if (Section->FirstKey == NULL)
|
||||
{
|
||||
Section->FirstKey = Key;
|
||||
Section->LastKey = Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
Section->LastKey->Next = Key;
|
||||
Key->Prev = Section->LastKey;
|
||||
Section->LastKey = Key;
|
||||
}
|
||||
|
||||
return(Key);
|
||||
}
|
||||
|
||||
|
||||
static PINICACHESECTION
|
||||
IniCacheFindSection(PINICACHE Cache,
|
||||
PWCHAR Name,
|
||||
ULONG NameLength)
|
||||
{
|
||||
PINICACHESECTION Section = NULL;
|
||||
|
||||
if (Cache == NULL || Name == NULL || NameLength == 0)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Section = Cache->FirstSection;
|
||||
|
||||
/* iterate through list of sections */
|
||||
while (Section != NULL)
|
||||
{
|
||||
if (NameLength == wcslen(Section->Name))
|
||||
{
|
||||
/* are the contents the same too? */
|
||||
if (_wcsnicmp(Section->Name, Name, NameLength) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* get the next section*/
|
||||
Section = Section->Next;
|
||||
}
|
||||
|
||||
return(Section);
|
||||
}
|
||||
|
||||
|
||||
static PINICACHESECTION
|
||||
IniCacheAddSection(PINICACHE Cache,
|
||||
PCHAR Name,
|
||||
ULONG NameLength)
|
||||
{
|
||||
PINICACHESECTION Section = NULL;
|
||||
ULONG i;
|
||||
|
||||
if (Cache == NULL || Name == NULL || NameLength == 0)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Section = (PINICACHESECTION)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
sizeof(INICACHESECTION));
|
||||
if (Section == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
RtlZeroMemory(Section,
|
||||
sizeof(INICACHESECTION));
|
||||
|
||||
/* Allocate and initialize section name */
|
||||
Section->Name = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
(NameLength + 1) * sizeof(WCHAR));
|
||||
if (Section->Name == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Section);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Copy section name */
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
Section->Name[i] = (WCHAR)Name[i];
|
||||
}
|
||||
Section->Name[NameLength] = 0;
|
||||
|
||||
/* Append section */
|
||||
if (Cache->FirstSection == NULL)
|
||||
{
|
||||
Cache->FirstSection = Section;
|
||||
Cache->LastSection = Section;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache->LastSection->Next = Section;
|
||||
Section->Prev = Cache->LastSection;
|
||||
Cache->LastSection = Section;
|
||||
}
|
||||
|
||||
return(Section);
|
||||
}
|
||||
|
||||
|
||||
static PCHAR
|
||||
IniCacheSkipWhitespace(PCHAR Ptr)
|
||||
{
|
||||
while (*Ptr != 0 && isspace(*Ptr))
|
||||
Ptr++;
|
||||
|
||||
return((*Ptr == 0) ? NULL : Ptr);
|
||||
}
|
||||
|
||||
|
||||
static PCHAR
|
||||
IniCacheSkipToNextSection(PCHAR Ptr)
|
||||
{
|
||||
while (*Ptr != 0 && *Ptr != '[')
|
||||
{
|
||||
while (*Ptr != 0 && *Ptr != L'\n')
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
return((*Ptr == 0) ? NULL : Ptr);
|
||||
}
|
||||
|
||||
|
||||
static PCHAR
|
||||
IniCacheGetSectionName(PCHAR Ptr,
|
||||
PCHAR *NamePtr,
|
||||
PULONG NameSize)
|
||||
{
|
||||
ULONG Size = 0;
|
||||
CHAR Name[256];
|
||||
|
||||
*NamePtr = NULL;
|
||||
*NameSize = 0;
|
||||
|
||||
/* skip whitespace */
|
||||
while (*Ptr != 0 && isspace(*Ptr))
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
*NamePtr = Ptr;
|
||||
|
||||
while (*Ptr != 0 && *Ptr != ']')
|
||||
{
|
||||
Size++;
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
Ptr++;
|
||||
|
||||
while (*Ptr != 0 && *Ptr != L'\n')
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
Ptr++;
|
||||
|
||||
*NameSize = Size;
|
||||
|
||||
strncpy(Name, *NamePtr, Size);
|
||||
Name[Size] = 0;
|
||||
|
||||
DPRINT("SectionName: '%s'\n", Name);
|
||||
|
||||
return(Ptr);
|
||||
}
|
||||
|
||||
|
||||
static PCHAR
|
||||
IniCacheGetKeyName(PCHAR Ptr,
|
||||
PCHAR *NamePtr,
|
||||
PULONG NameSize)
|
||||
{
|
||||
ULONG Size = 0;
|
||||
|
||||
*NamePtr = NULL;
|
||||
*NameSize = 0;
|
||||
|
||||
/* skip whitespace */
|
||||
while (*Ptr != 0 && isspace(*Ptr))
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
*NamePtr = Ptr;
|
||||
|
||||
while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '=')
|
||||
{
|
||||
Size++;
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
*NameSize = Size;
|
||||
|
||||
return(Ptr);
|
||||
}
|
||||
|
||||
|
||||
static PCHAR
|
||||
IniCacheGetKeyValue(PCHAR Ptr,
|
||||
PCHAR *DataPtr,
|
||||
PULONG DataSize)
|
||||
{
|
||||
ULONG Size = 0;
|
||||
|
||||
*DataPtr = NULL;
|
||||
*DataSize = 0;
|
||||
|
||||
/* skip whitespace */
|
||||
while (*Ptr != 0 && isspace(*Ptr))
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
/* check and skip '=' */
|
||||
if (*Ptr != '=')
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
Ptr++;
|
||||
|
||||
/* skip whitespace */
|
||||
while (*Ptr != 0 && isspace(*Ptr))
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
/* check for quoted data */
|
||||
if (*Ptr == '\"')
|
||||
{
|
||||
Ptr++;
|
||||
*DataPtr = Ptr;
|
||||
|
||||
while (*Ptr != 0 && *Ptr != '\"')
|
||||
{
|
||||
Ptr++;
|
||||
Size++;
|
||||
}
|
||||
Ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*DataPtr = Ptr;
|
||||
|
||||
while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '\n')
|
||||
{
|
||||
Ptr++;
|
||||
Size++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip to next line */
|
||||
while (*Ptr != 0 && *Ptr != '\n')
|
||||
{
|
||||
Ptr++;
|
||||
}
|
||||
Ptr++;
|
||||
|
||||
*DataSize = Size;
|
||||
|
||||
return(Ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* PUBLIC FUNCTIONS *********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
IniCacheLoad(PINICACHE *Cache,
|
||||
PUNICODE_STRING FileName)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
FILE_STANDARD_INFORMATION FileInfo;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle;
|
||||
NTSTATUS Status;
|
||||
PCHAR FileBuffer;
|
||||
ULONG FileLength;
|
||||
PCHAR Ptr;
|
||||
LARGE_INTEGER FileOffset;
|
||||
|
||||
ULONG i;
|
||||
PINICACHESECTION Section;
|
||||
PINICACHEKEY Key;
|
||||
|
||||
PCHAR SectionName;
|
||||
ULONG SectionNameSize;
|
||||
|
||||
PCHAR KeyName;
|
||||
ULONG KeyNameSize;
|
||||
|
||||
PCHAR KeyValue;
|
||||
ULONG KeyValueSize;
|
||||
|
||||
*Cache = NULL;
|
||||
|
||||
/* Open ini file */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
FileName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
GENERIC_READ | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_READ,
|
||||
FILE_NON_DIRECTORY_FILE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("NtOpenFile() successful\n");
|
||||
|
||||
/* Query file size */
|
||||
Status = NtQueryInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileInfo,
|
||||
sizeof(FILE_STANDARD_INFORMATION),
|
||||
FileStandardInformation);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("NtQueryInformationFile() returns STATUS_PENDING\n");
|
||||
|
||||
}
|
||||
else if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
FileLength = FileInfo.EndOfFile.u.LowPart;
|
||||
|
||||
DPRINT("File size: %lu\n", FileLength);
|
||||
|
||||
/* Allocate file buffer */
|
||||
FileBuffer = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
FileLength + 1);
|
||||
if (FileBuffer == NULL)
|
||||
{
|
||||
DPRINT1("RtlAllocateHeap() failed\n");
|
||||
NtClose(FileHandle);
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Read file */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
FileBuffer,
|
||||
FileLength,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("NtReadFile() returns STATUS_PENDING\n");
|
||||
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
/* Append string terminator */
|
||||
FileBuffer[FileLength] = 0;
|
||||
|
||||
NtClose(FileHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtReadFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
FileBuffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
/* Allocate inicache header */
|
||||
*Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
sizeof(INICACHE));
|
||||
if (*Cache == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Initialize inicache header */
|
||||
RtlZeroMemory(*Cache,
|
||||
sizeof(INICACHE));
|
||||
|
||||
/* Parse ini file */
|
||||
Section = NULL;
|
||||
Ptr = FileBuffer;
|
||||
while (Ptr != NULL && *Ptr != 0)
|
||||
{
|
||||
Ptr = IniCacheSkipWhitespace(Ptr);
|
||||
if (Ptr == NULL)
|
||||
continue;
|
||||
|
||||
if (*Ptr == '[')
|
||||
{
|
||||
Section = NULL;
|
||||
Ptr++;
|
||||
|
||||
Ptr = IniCacheGetSectionName(Ptr,
|
||||
&SectionName,
|
||||
&SectionNameSize);
|
||||
|
||||
Section = IniCacheAddSection(*Cache,
|
||||
SectionName,
|
||||
SectionNameSize);
|
||||
if (Section == NULL)
|
||||
{
|
||||
DPRINT("IniCacheAddSection() failed\n");
|
||||
Ptr = IniCacheSkipToNextSection(Ptr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Section == NULL)
|
||||
{
|
||||
Ptr = IniCacheSkipToNextSection(Ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
Ptr = IniCacheGetKeyName(Ptr,
|
||||
&KeyName,
|
||||
&KeyNameSize);
|
||||
|
||||
Ptr = IniCacheGetKeyValue(Ptr,
|
||||
&KeyValue,
|
||||
&KeyValueSize);
|
||||
|
||||
Key = IniCacheAddKey(Section,
|
||||
KeyName,
|
||||
KeyNameSize,
|
||||
KeyValue,
|
||||
KeyValueSize);
|
||||
if (Key == NULL)
|
||||
{
|
||||
DPRINT("IniCacheAddKey() failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free file buffer */
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
FileBuffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
IniCacheDestroy(PINICACHE Cache)
|
||||
{
|
||||
if (Cache == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (Cache->FirstSection != NULL)
|
||||
{
|
||||
Cache->FirstSection = IniCacheFreeSection(Cache->FirstSection);
|
||||
}
|
||||
Cache->LastSection = NULL;
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Cache);
|
||||
}
|
||||
|
||||
|
||||
PINICACHESECTION
|
||||
IniCacheGetSection(PINICACHE Cache,
|
||||
PWCHAR Name)
|
||||
{
|
||||
PINICACHESECTION Section = NULL;
|
||||
|
||||
if (Cache == NULL || Name == NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* iterate through list of sections */
|
||||
Section = Cache->FirstSection;
|
||||
while (Section != NULL)
|
||||
{
|
||||
DPRINT("Comparing '%S' and '%S'\n", Section->Name, Name);
|
||||
|
||||
/* Are the section names the same? */
|
||||
if (_wcsicmp(Section->Name, Name) == 0)
|
||||
return(Section);
|
||||
|
||||
/* Get the next section */
|
||||
Section = Section->Next;
|
||||
}
|
||||
|
||||
DPRINT("Section not found\n");
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IniCacheGetKey(PINICACHESECTION Section,
|
||||
PWCHAR KeyName,
|
||||
PWCHAR *KeyValue)
|
||||
{
|
||||
PINICACHEKEY Key;
|
||||
|
||||
if (Section == NULL || KeyName == NULL || KeyValue == NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
*KeyValue = NULL;
|
||||
|
||||
Key = IniCacheFindKey(Section, KeyName, wcslen(KeyName));
|
||||
if (Key == NULL)
|
||||
{
|
||||
return(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
*KeyValue = Key->Value;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
PINICACHEITERATOR
|
||||
IniCacheFindFirstValue(PINICACHESECTION Section,
|
||||
PWCHAR *KeyName,
|
||||
PWCHAR *KeyValue)
|
||||
{
|
||||
PINICACHEITERATOR Iterator;
|
||||
PINICACHEKEY Key;
|
||||
|
||||
if (Section == NULL || KeyName == NULL || KeyValue == NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Key = Section->FirstKey;
|
||||
if (Key == NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
*KeyName = Key->Name;
|
||||
*KeyValue = Key->Value;
|
||||
|
||||
Iterator = (PINICACHEITERATOR)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
sizeof(INICACHEITERATOR));
|
||||
if (Iterator == NULL)
|
||||
{
|
||||
DPRINT("RtlAllocateHeap() failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Iterator->Section = Section;
|
||||
Iterator->Key = Key;
|
||||
|
||||
return(Iterator);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IniCacheFindNextValue(PINICACHEITERATOR Iterator,
|
||||
PWCHAR *KeyName,
|
||||
PWCHAR *KeyValue)
|
||||
{
|
||||
PINICACHEKEY Key;
|
||||
|
||||
if (Iterator == NULL || KeyName == NULL || KeyValue == NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
Key = Iterator->Key->Next;
|
||||
if (Key == NULL)
|
||||
{
|
||||
DPRINT("No more entries\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
*KeyName = Key->Name;
|
||||
*KeyValue = Key->Value;
|
||||
|
||||
Iterator->Key = Key;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
IniCacheFindClose(PINICACHEITERATOR Iterator)
|
||||
{
|
||||
if (Iterator == NULL)
|
||||
return;
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Iterator);
|
||||
}
|
||||
|
||||
/* EOF */
|
104
reactos/subsys/system/usetup/inicache.h
Normal file
104
reactos/subsys/system/usetup/inicache.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/inicache.h
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory
|
||||
* PROGRAMMER: Royce Mitchell III
|
||||
* Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef __INICACHE_H__
|
||||
#define __INICACHE_H__
|
||||
|
||||
|
||||
typedef struct _INICACHEKEY
|
||||
{
|
||||
PWCHAR Name;
|
||||
PWCHAR Value;
|
||||
|
||||
struct _INICACHEKEY *Next;
|
||||
struct _INICACHEKEY *Prev;
|
||||
} INICACHEKEY, *PINICACHEKEY;
|
||||
|
||||
|
||||
typedef struct _INICACHESECTION
|
||||
{
|
||||
PWCHAR Name;
|
||||
|
||||
PINICACHEKEY FirstKey;
|
||||
PINICACHEKEY LastKey;
|
||||
|
||||
struct _INICACHESECTION *Next;
|
||||
struct _INICACHESECTION *Prev;
|
||||
} INICACHESECTION, *PINICACHESECTION;
|
||||
|
||||
|
||||
typedef struct _INICACHE
|
||||
{
|
||||
PINICACHESECTION FirstSection;
|
||||
PINICACHESECTION LastSection;
|
||||
} INICACHE, *PINICACHE;
|
||||
|
||||
|
||||
typedef struct _PINICACHEITERATOR
|
||||
{
|
||||
PINICACHESECTION Section;
|
||||
PINICACHEKEY Key;
|
||||
} INICACHEITERATOR, *PINICACHEITERATOR;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
IniCacheLoad(PINICACHE *Cache,
|
||||
PUNICODE_STRING FileName);
|
||||
|
||||
VOID
|
||||
IniCacheDestroy(PINICACHE Cache);
|
||||
|
||||
PINICACHESECTION
|
||||
IniCacheGetSection(PINICACHE Cache,
|
||||
PWCHAR Name);
|
||||
|
||||
NTSTATUS
|
||||
IniCacheGetKey(PINICACHESECTION Section,
|
||||
PWCHAR KeyName,
|
||||
PWCHAR *KeyValue);
|
||||
|
||||
|
||||
|
||||
PINICACHEITERATOR
|
||||
IniCacheFindFirstValue(PINICACHESECTION Section,
|
||||
PWCHAR *KeyName,
|
||||
PWCHAR *KeyValue);
|
||||
|
||||
BOOLEAN
|
||||
IniCacheFindNextValue(PINICACHEITERATOR Iterator,
|
||||
PWCHAR *KeyName,
|
||||
PWCHAR *KeyValue);
|
||||
|
||||
VOID
|
||||
IniCacheFindClose(PINICACHEITERATOR Iterator);
|
||||
|
||||
|
||||
#endif /* __INICACHE_H__ */
|
||||
|
||||
/* EOF */
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.3 2002/10/29 18:40:02 ekohl Exp $
|
||||
# $Id: makefile,v 1.4 2002/11/13 18:25:18 ekohl Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
|
@ -12,7 +12,7 @@ TARGET_INSTALLDIR = system32
|
|||
|
||||
TARGET_CFLAGS = -D__NTAPP__
|
||||
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o console.o drivesup.o partlist.o
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o console.o drivesup.o filesup.o inicache.o partlist.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: partlist.c,v 1.3 2002/11/02 23:17:06 ekohl Exp $
|
||||
/* $Id: partlist.c,v 1.4 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/partlist.c
|
||||
|
@ -39,6 +39,88 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static VOID
|
||||
AddPartitionList(ULONG DiskNumber,
|
||||
PDISKENTRY DiskEntry,
|
||||
DRIVE_LAYOUT_INFORMATION *LayoutBuffer)
|
||||
{
|
||||
PPARTENTRY PartEntry;
|
||||
ULONG i;
|
||||
ULONG EntryCount;
|
||||
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* Determine required number of partiton entries.
|
||||
* This must include entries for unused disk space.
|
||||
*/
|
||||
|
||||
/* Check for unpartitioned disk */
|
||||
if (LayoutBuffer->PartitionCount == 0)
|
||||
{
|
||||
EntryCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < LayoutBuffer->PartitionCount; i++)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
EntryCount = LayoutBuffer->PartitionCount;
|
||||
}
|
||||
|
||||
|
||||
DiskEntry->PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
EntryCount * sizeof(PARTENTRY));
|
||||
DiskEntry->PartCount = EntryCount;
|
||||
|
||||
RtlZeroMemory(DiskEntry->PartArray,
|
||||
EntryCount * sizeof(PARTENTRY));
|
||||
|
||||
if (LayoutBuffer->PartitionCount == 0)
|
||||
{
|
||||
/* Initialize an 'Unpartitioned space' entry */
|
||||
PartEntry = &DiskEntry->PartArray[0];
|
||||
|
||||
PartEntry->Unpartitioned = TRUE;
|
||||
PartEntry->PartSize = 0; /* ?? */
|
||||
|
||||
PartEntry->Used = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < LayoutBuffer->PartitionCount; i++)
|
||||
{
|
||||
PartEntry = &DiskEntry->PartArray[i];
|
||||
|
||||
if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) &&
|
||||
(!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)))
|
||||
{
|
||||
PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
|
||||
PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber,
|
||||
PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
|
||||
|
||||
PartEntry->DriveLetter = GetDriveLetter(DiskNumber,
|
||||
LayoutBuffer->PartitionEntry[i].PartitionNumber);
|
||||
|
||||
PartEntry->Unpartitioned = FALSE;
|
||||
|
||||
PartEntry->Used = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PartEntry->Used = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PPARTLIST
|
||||
CreatePartitionList(SHORT Left,
|
||||
SHORT Top,
|
||||
|
@ -49,16 +131,15 @@ CreatePartitionList(SHORT Left,
|
|||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
SYSTEM_DEVICE_INFORMATION Sdi;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
ULONG ReturnSize;
|
||||
NTSTATUS Status;
|
||||
ULONG DiskCount;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
ULONG DiskNumber;
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
UNICODE_STRING Name;
|
||||
HANDLE FileHandle;
|
||||
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
|
||||
SCSI_ADDRESS ScsiAddress;
|
||||
ULONG i;
|
||||
|
||||
List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST));
|
||||
if (List == NULL)
|
||||
|
@ -96,11 +177,11 @@ CreatePartitionList(SHORT Left,
|
|||
Sdi.NumberOfDisks * sizeof(DISKENTRY));
|
||||
List->DiskCount = Sdi.NumberOfDisks;
|
||||
|
||||
for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++)
|
||||
for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
|
||||
{
|
||||
swprintf(Buffer,
|
||||
L"\\Device\\Harddisk%d\\Partition0",
|
||||
DiskCount);
|
||||
DiskNumber);
|
||||
RtlInitUnicodeString(&Name,
|
||||
Buffer);
|
||||
|
||||
|
@ -144,17 +225,17 @@ CreatePartitionList(SHORT Left,
|
|||
sizeof(SCSI_ADDRESS));
|
||||
|
||||
|
||||
List->DiskArray[DiskCount].DiskSize =
|
||||
List->DiskArray[DiskNumber].DiskSize =
|
||||
DiskGeometry.Cylinders.QuadPart *
|
||||
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
||||
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
||||
(ULONGLONG)DiskGeometry.BytesPerSector;
|
||||
List->DiskArray[DiskCount].DiskNumber = DiskCount;
|
||||
List->DiskArray[DiskCount].Port = ScsiAddress.PortNumber;
|
||||
List->DiskArray[DiskCount].Bus = ScsiAddress.PathId;
|
||||
List->DiskArray[DiskCount].Id = ScsiAddress.TargetId;
|
||||
List->DiskArray[DiskNumber].DiskNumber = DiskNumber;
|
||||
List->DiskArray[DiskNumber].Port = ScsiAddress.PortNumber;
|
||||
List->DiskArray[DiskNumber].Bus = ScsiAddress.PathId;
|
||||
List->DiskArray[DiskNumber].Id = ScsiAddress.TargetId;
|
||||
|
||||
List->DiskArray[DiskCount].FixedDisk = TRUE;
|
||||
List->DiskArray[DiskNumber].FixedDisk = TRUE;
|
||||
|
||||
|
||||
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
|
||||
|
@ -171,31 +252,9 @@ CreatePartitionList(SHORT Left,
|
|||
8192);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
List->DiskArray[DiskCount].PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
LayoutBuffer->PartitionCount * sizeof(PARTENTRY));
|
||||
List->DiskArray[DiskCount].PartCount = LayoutBuffer->PartitionCount;
|
||||
|
||||
for (i = 0; i < LayoutBuffer->PartitionCount; i++)
|
||||
{
|
||||
if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) &&
|
||||
!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType))
|
||||
{
|
||||
List->DiskArray[DiskCount].PartArray[i].PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
|
||||
List->DiskArray[DiskCount].PartArray[i].PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber,
|
||||
List->DiskArray[DiskCount].PartArray[i].PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
|
||||
|
||||
List->DiskArray[DiskCount].PartArray[i].DriveLetter = GetDriveLetter(DiskCount,
|
||||
LayoutBuffer->PartitionEntry[i].PartitionNumber);
|
||||
|
||||
List->DiskArray[DiskCount].PartArray[i].Used = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
List->DiskArray[DiskCount].PartArray[i].Used = FALSE;
|
||||
}
|
||||
}
|
||||
AddPartitionList(DiskNumber,
|
||||
&List->DiskArray[DiskNumber],
|
||||
LayoutBuffer);
|
||||
}
|
||||
|
||||
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
|
||||
|
@ -203,9 +262,9 @@ CreatePartitionList(SHORT Left,
|
|||
else
|
||||
{
|
||||
/* mark removable disk entry */
|
||||
List->DiskArray[DiskCount].FixedDisk = FALSE;
|
||||
List->DiskArray[DiskCount].PartCount = 0;
|
||||
List->DiskArray[DiskCount].PartArray = NULL;
|
||||
List->DiskArray[DiskNumber].FixedDisk = FALSE;
|
||||
List->DiskArray[DiskNumber].PartCount = 0;
|
||||
List->DiskArray[DiskNumber].PartArray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,9 +380,8 @@ PrintPartitionData(PPARTLIST List,
|
|||
|
||||
ULONGLONG PartSize;
|
||||
PCHAR Unit;
|
||||
PCHAR PartType;
|
||||
UCHAR Attribute;
|
||||
|
||||
PCHAR PartType;
|
||||
|
||||
Width = List->Right - List->Left - 1;
|
||||
Height = List->Bottom - List->Top - 1;
|
||||
|
@ -336,33 +394,38 @@ PrintPartitionData(PPARTLIST List,
|
|||
|
||||
PartEntry = &List->DiskArray[DiskIndex].PartArray[PartIndex];
|
||||
|
||||
if ((PartEntry->PartType == PARTITION_FAT_12) ||
|
||||
(PartEntry->PartType == PARTITION_FAT_16) ||
|
||||
(PartEntry->PartType == PARTITION_HUGE) ||
|
||||
(PartEntry->PartType == PARTITION_XINT13))
|
||||
/* Determine partition type */
|
||||
PartType = NULL;
|
||||
if (PartEntry->Unpartitioned == FALSE)
|
||||
{
|
||||
PartType = "FAT";
|
||||
}
|
||||
else if ((PartEntry->PartType == PARTITION_FAT32) ||
|
||||
(PartEntry->PartType == PARTITION_FAT32_XINT13))
|
||||
{
|
||||
PartType = "FAT32";
|
||||
}
|
||||
else if (PartEntry->PartType == PARTITION_IFS)
|
||||
{
|
||||
PartType = "NTFS"; /* FIXME: Not quite correct! */
|
||||
}
|
||||
else
|
||||
{
|
||||
PartType = "Unknown";
|
||||
if ((PartEntry->PartType == PARTITION_FAT_12) ||
|
||||
(PartEntry->PartType == PARTITION_FAT_16) ||
|
||||
(PartEntry->PartType == PARTITION_HUGE) ||
|
||||
(PartEntry->PartType == PARTITION_XINT13))
|
||||
{
|
||||
PartType = "FAT";
|
||||
}
|
||||
else if ((PartEntry->PartType == PARTITION_FAT32) ||
|
||||
(PartEntry->PartType == PARTITION_FAT32_XINT13))
|
||||
{
|
||||
PartType = "FAT32";
|
||||
}
|
||||
else if (PartEntry->PartType == PARTITION_IFS)
|
||||
{
|
||||
PartType = "NTFS"; /* FIXME: Not quite correct! */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */
|
||||
{
|
||||
PartSize = (PartEntry->PartSize + (1 << 29)) >> 30;
|
||||
Unit = "GB";
|
||||
}
|
||||
else if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
|
||||
else
|
||||
#endif
|
||||
if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
|
||||
{
|
||||
PartSize = (PartEntry->PartSize + (1 << 19)) >> 20;
|
||||
Unit = "MB";
|
||||
|
@ -370,29 +433,58 @@ PrintPartitionData(PPARTLIST List,
|
|||
else
|
||||
{
|
||||
PartSize = (PartEntry->PartSize + (1 << 9)) >> 10;
|
||||
Unit = "kB";
|
||||
Unit = "KB";
|
||||
}
|
||||
|
||||
if (PartEntry->DriveLetter != (CHAR)0)
|
||||
|
||||
if (PartEntry->Unpartitioned == TRUE)
|
||||
{
|
||||
sprintf(LineBuffer,
|
||||
"%c: %d: nr: %d type: %x (%s) %I64u %s",
|
||||
" Unpartitioned space %I64u %s",
|
||||
PartSize,
|
||||
Unit);
|
||||
}
|
||||
else if (PartEntry->DriveLetter != (CHAR)0)
|
||||
{
|
||||
if (PartType == NULL)
|
||||
{
|
||||
sprintf(LineBuffer,
|
||||
"%c: Type %-3lu %I64u %s",
|
||||
PartEntry->DriveLetter,
|
||||
PartEntry->PartType,
|
||||
PartSize,
|
||||
Unit);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(LineBuffer,
|
||||
"%c: %s %I64u %s",
|
||||
PartEntry->DriveLetter,
|
||||
PartType,
|
||||
PartSize,
|
||||
Unit);
|
||||
}
|
||||
|
||||
#if 0
|
||||
sprintf(LineBuffer,
|
||||
"%c: %s (%d: nr: %d type: %x) %I64u %s",
|
||||
PartEntry->DriveLetter,
|
||||
PartType,
|
||||
PartIndex,
|
||||
PartEntry->PartNumber,
|
||||
PartEntry->PartType,
|
||||
PartType,
|
||||
PartSize,
|
||||
Unit);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(LineBuffer,
|
||||
" %d: nr: %d type: %x (%s) %I64u %s",
|
||||
"-- %s (%d: nr: %d type: %x) %I64u %s",
|
||||
PartEntry->FileSystemName,
|
||||
PartIndex,
|
||||
PartEntry->PartNumber,
|
||||
PartEntry->PartType,
|
||||
PartType,
|
||||
PartSize,
|
||||
Unit);
|
||||
}
|
||||
|
@ -435,7 +527,6 @@ PrintDiskData(PPARTLIST List,
|
|||
ULONGLONG DiskSize;
|
||||
PCHAR Unit;
|
||||
SHORT PartIndex;
|
||||
BOOL PartPrinted;
|
||||
|
||||
DiskEntry = &List->DiskArray[DiskIndex];
|
||||
|
||||
|
@ -448,24 +539,23 @@ PrintDiskData(PPARTLIST List,
|
|||
coPos.X = List->Left + 1;
|
||||
coPos.Y = List->Top + 1 + List->Line;
|
||||
|
||||
#if 0
|
||||
if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
|
||||
{
|
||||
DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
|
||||
Unit = "GB";
|
||||
}
|
||||
else if (DiskEntry->DiskSize >= 0xA00000ULL) /* 10 MB */
|
||||
else
|
||||
#endif
|
||||
{
|
||||
DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
|
||||
if (DiskSize == 0)
|
||||
DiskSize = 1;
|
||||
Unit = "MB";
|
||||
}
|
||||
else
|
||||
{
|
||||
DiskSize = (DiskEntry->DiskSize + (1 << 9)) >> 10;
|
||||
Unit = "kB";
|
||||
}
|
||||
|
||||
sprintf(LineBuffer,
|
||||
"%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
|
||||
"%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
|
||||
DiskSize,
|
||||
Unit,
|
||||
DiskEntry->DiskNumber,
|
||||
|
@ -494,25 +584,19 @@ PrintDiskData(PPARTLIST List,
|
|||
PrintEmptyLine(List);
|
||||
|
||||
|
||||
PartPrinted = FALSE;
|
||||
|
||||
/* Print partition lines*/
|
||||
for (PartIndex = 0; PartIndex < List->DiskArray[DiskIndex].PartCount; PartIndex++)
|
||||
for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++)
|
||||
{
|
||||
if (List->DiskArray[DiskIndex].PartArray[PartIndex].Used == TRUE)
|
||||
if (DiskEntry->PartArray[PartIndex].Used == TRUE)
|
||||
{
|
||||
PrintPartitionData(List,
|
||||
DiskIndex,
|
||||
PartIndex);
|
||||
PartPrinted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print separator line */
|
||||
if (PartPrinted == TRUE)
|
||||
{
|
||||
PrintEmptyLine(List);
|
||||
}
|
||||
PrintEmptyLine(List);
|
||||
}
|
||||
|
||||
|
||||
|
@ -582,7 +666,7 @@ DrawPartitionList(PPARTLIST List)
|
|||
coPos,
|
||||
&Written);
|
||||
|
||||
/* draw upper right corner */
|
||||
/* draw lower right corner */
|
||||
coPos.X = List->Right;
|
||||
coPos.Y = List->Bottom;
|
||||
FillConsoleOutputCharacter(0xD9, // '+',
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: partlist.h,v 1.3 2002/11/02 23:17:06 ekohl Exp $
|
||||
/* $Id: partlist.h,v 1.4 2002/11/13 18:25:18 ekohl Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: subsys/system/usetup/partlist.h
|
||||
|
@ -50,6 +50,11 @@ typedef struct _PARTENTRY
|
|||
ULONG PartType;
|
||||
|
||||
CHAR DriveLetter;
|
||||
CHAR VolumeLabel[17];
|
||||
CHAR FileSystemName[9];
|
||||
|
||||
BOOL Unpartitioned;
|
||||
|
||||
BOOL Used;
|
||||
} PARTENTRY, *PPARTENTRY;
|
||||
|
||||
|
|
|
@ -27,9 +27,13 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <ntdll/rtl.h>
|
||||
|
||||
#include <ntos/minmax.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
#include "usetup.h"
|
||||
#include "console.h"
|
||||
#include "partlist.h"
|
||||
#include "inicache.h"
|
||||
|
||||
|
||||
|
||||
|
@ -56,14 +60,16 @@
|
|||
|
||||
HANDLE ProcessHeap;
|
||||
|
||||
BOOL PartDataValid = FALSE;
|
||||
BOOLEAN PartDataValid;
|
||||
PARTDATA PartData;
|
||||
|
||||
CHAR InstallDir[51];
|
||||
WCHAR InstallDir[51];
|
||||
|
||||
UNICODE_STRING SourcePath;
|
||||
UNICODE_STRING SourceRootPath;
|
||||
|
||||
PINICACHE IniCache;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
@ -88,6 +94,216 @@ PrintString(char* fmt,...)
|
|||
}
|
||||
|
||||
|
||||
static VOID
|
||||
PopupError(PCHAR Text,
|
||||
PCHAR Status)
|
||||
{
|
||||
SHORT xScreen;
|
||||
SHORT yScreen;
|
||||
SHORT yTop;
|
||||
SHORT xLeft;
|
||||
COORD coPos;
|
||||
ULONG Written;
|
||||
ULONG Length;
|
||||
ULONG MaxLength;
|
||||
ULONG Lines;
|
||||
PCHAR p;
|
||||
PCHAR pnext;
|
||||
BOOLEAN LastLine;
|
||||
SHORT Width;
|
||||
SHORT Height;
|
||||
|
||||
|
||||
/* Count text lines and longest line */
|
||||
MaxLength = 0;
|
||||
Lines = 0;
|
||||
pnext = Text;
|
||||
while (TRUE)
|
||||
{
|
||||
p = strchr(pnext, '\n');
|
||||
if (p == NULL)
|
||||
{
|
||||
Length = strlen(pnext);
|
||||
LastLine = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = (ULONG)(p - pnext);
|
||||
LastLine = FALSE;
|
||||
}
|
||||
|
||||
Lines++;
|
||||
if (Length > MaxLength)
|
||||
MaxLength = Length;
|
||||
|
||||
if (LastLine == TRUE)
|
||||
break;
|
||||
|
||||
pnext = p + 1;
|
||||
}
|
||||
|
||||
/* Check length of status line */
|
||||
if (Status != NULL)
|
||||
{
|
||||
Length = strlen(Status);
|
||||
if (Length > MaxLength)
|
||||
MaxLength = Length;
|
||||
}
|
||||
|
||||
GetScreenSize(&xScreen, &yScreen);
|
||||
|
||||
Width = MaxLength + 4;
|
||||
Height = Lines + 2;
|
||||
if (Status != NULL)
|
||||
Height += 2;
|
||||
|
||||
yTop = (yScreen - Height) / 2;
|
||||
xLeft = (xScreen - Width) / 2;
|
||||
|
||||
|
||||
/* Set screen attributes */
|
||||
coPos.X = xLeft;
|
||||
for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
|
||||
{
|
||||
FillConsoleOutputAttribute(0x74,
|
||||
Width,
|
||||
coPos,
|
||||
&Written);
|
||||
}
|
||||
|
||||
/* draw upper left corner */
|
||||
coPos.X = xLeft;
|
||||
coPos.Y = yTop;
|
||||
FillConsoleOutputCharacter(0xDA, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* draw upper edge */
|
||||
coPos.X = xLeft + 1;
|
||||
coPos.Y = yTop;
|
||||
FillConsoleOutputCharacter(0xC4, // '-',
|
||||
Width - 2,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* draw upper right corner */
|
||||
coPos.X = xLeft + Width - 1;
|
||||
coPos.Y = yTop;
|
||||
FillConsoleOutputCharacter(0xBF, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* Draw right edge, inner space and left edge */
|
||||
for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
|
||||
{
|
||||
coPos.X = xLeft;
|
||||
FillConsoleOutputCharacter(0xB3, // '|',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + 1;
|
||||
FillConsoleOutputCharacter(' ',
|
||||
Width - 2,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + Width - 1;
|
||||
FillConsoleOutputCharacter(0xB3, // '|',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
}
|
||||
|
||||
/* draw lower left corner */
|
||||
coPos.X = xLeft;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
FillConsoleOutputCharacter(0xC0, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* draw lower edge */
|
||||
coPos.X = xLeft + 1;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
FillConsoleOutputCharacter(0xC4, // '-',
|
||||
Width - 2,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* draw lower right corner */
|
||||
coPos.X = xLeft + Width - 1;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
FillConsoleOutputCharacter(0xD9, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
/* Print message text */
|
||||
coPos.Y = yTop + 1;
|
||||
pnext = Text;
|
||||
while (TRUE)
|
||||
{
|
||||
p = strchr(pnext, '\n');
|
||||
if (p == NULL)
|
||||
{
|
||||
Length = strlen(pnext);
|
||||
LastLine = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = (ULONG)(p - pnext);
|
||||
LastLine = FALSE;
|
||||
}
|
||||
|
||||
if (Length != 0)
|
||||
{
|
||||
coPos.X = xLeft + 2;
|
||||
WriteConsoleOutputCharacters(pnext,
|
||||
Length,
|
||||
coPos);
|
||||
}
|
||||
|
||||
if (LastLine == TRUE)
|
||||
break;
|
||||
|
||||
coPos.Y++;
|
||||
pnext = p + 1;
|
||||
}
|
||||
|
||||
/* Print separator line and status text */
|
||||
if (Status != NULL)
|
||||
{
|
||||
coPos.Y = yTop + Height - 3;
|
||||
coPos.X = xLeft;
|
||||
FillConsoleOutputCharacter(0xC3, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + 1;
|
||||
FillConsoleOutputCharacter(0xC4, // '-',
|
||||
Width - 2,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + Width - 1;
|
||||
FillConsoleOutputCharacter(0xB4, // '+',
|
||||
1,
|
||||
coPos,
|
||||
&Written);
|
||||
|
||||
coPos.Y++;
|
||||
coPos.X = xLeft + 2;
|
||||
WriteConsoleOutputCharacters(Status,
|
||||
min(strlen(Status), Width - 4),
|
||||
coPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Confirm quit setup
|
||||
* RETURNS
|
||||
|
@ -97,65 +313,15 @@ PrintString(char* fmt,...)
|
|||
static BOOL
|
||||
ConfirmQuit(PINPUT_RECORD Ir)
|
||||
{
|
||||
SHORT xScreen;
|
||||
SHORT yScreen;
|
||||
SHORT yTop;
|
||||
SHORT xLeft;
|
||||
BOOL Result = FALSE;
|
||||
PUSHORT pAttributes = NULL;
|
||||
PUCHAR pCharacters = NULL;
|
||||
COORD Pos;
|
||||
|
||||
GetScreenSize(&xScreen, &yScreen);
|
||||
yTop = (yScreen - 10) / 2;
|
||||
xLeft = (xScreen - 52) / 2;
|
||||
|
||||
/* Save screen */
|
||||
#if 0
|
||||
Pos.X = 0;
|
||||
Pos.Y = 0;
|
||||
pAttributes = (PUSHORT)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
xScreen * yScreen * sizeof(USHORT));
|
||||
CHECKPOINT1;
|
||||
DPRINT1("pAttributes %p\n", pAttributes);
|
||||
ReadConsoleOutputAttributes(pAttributes,
|
||||
xScreen * yScreen,
|
||||
Pos,
|
||||
NULL);
|
||||
CHECKPOINT1;
|
||||
pCharacters = (PUCHAR)RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
xScreen * yScreen * sizeof(UCHAR));
|
||||
CHECKPOINT1;
|
||||
ReadConsoleOutputCharacters(pCharacters,
|
||||
xScreen * yScreen,
|
||||
Pos,
|
||||
NULL);
|
||||
CHECKPOINT1;
|
||||
#endif
|
||||
|
||||
/* Draw popup window */
|
||||
SetTextXY(xLeft, yTop,
|
||||
"+----------------------------------------------------+");
|
||||
SetTextXY(xLeft, yTop + 1,
|
||||
"| ReactOS 0.0.20 is not completely installed on your |");
|
||||
SetTextXY(xLeft, yTop + 2,
|
||||
"| computer. If you quit Setup now, you will need to |");
|
||||
SetTextXY(xLeft, yTop + 3,
|
||||
"| run Setup again to install ReactOS. |");
|
||||
SetTextXY(xLeft, yTop + 4,
|
||||
"| |");
|
||||
SetTextXY(xLeft, yTop + 5,
|
||||
"| * Press ENTER to continue Setup. |");
|
||||
SetTextXY(xLeft, yTop + 6,
|
||||
"| * Press F3 to quit Setup. |");
|
||||
SetTextXY(xLeft, yTop + 7,
|
||||
"+----------------------------------------------------+");
|
||||
SetTextXY(xLeft, yTop + 8,
|
||||
"| F3= Quit ENTER = Continue |");
|
||||
SetTextXY(xLeft, yTop + 9,
|
||||
"+----------------------------------------------------+");
|
||||
PopupError("ReactOS is not completely installed on your\n"
|
||||
"computer. If you quit Setup now, you will need to\n"
|
||||
"run Setup again to install ReactOS.\n"
|
||||
"\n"
|
||||
" * Press ENTER to continue Setup.\n"
|
||||
" * Press F3 to quit Setup.",
|
||||
"F3= Quit ENTER = Continue");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
|
@ -174,34 +340,11 @@ CHECKPOINT1;
|
|||
}
|
||||
}
|
||||
|
||||
/* Restore screen */
|
||||
#if 0
|
||||
CHECKPOINT1;
|
||||
WriteConsoleOutputAttributes(pAttributes,
|
||||
xScreen * yScreen,
|
||||
Pos,
|
||||
NULL);
|
||||
CHECKPOINT1;
|
||||
|
||||
WriteConsoleOutputCharacters(pCharacters,
|
||||
xScreen * yScreen,
|
||||
Pos);
|
||||
CHECKPOINT1;
|
||||
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
pAttributes);
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
pCharacters);
|
||||
#endif
|
||||
|
||||
return(Result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Start page
|
||||
* RETURNS
|
||||
|
@ -211,6 +354,12 @@ static ULONG
|
|||
StartPage(PINPUT_RECORD Ir)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
WCHAR FileNameBuffer[MAX_PATH];
|
||||
UNICODE_STRING FileName;
|
||||
|
||||
PINICACHESECTION Section;
|
||||
PWCHAR Value;
|
||||
|
||||
|
||||
SetStatusText(" Please wait...");
|
||||
|
||||
|
@ -226,12 +375,91 @@ StartPage(PINPUT_RECORD Ir)
|
|||
PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Open and load txtsetup.sif here. A pointer (or handle) to the
|
||||
* ini data should be stored in a global variable.
|
||||
* The full path to txtsetup.sif is created by appending '\txtsetup.sif'
|
||||
* to the unicode string SourceRootPath.
|
||||
*/
|
||||
|
||||
/* Load txtsetup.sif from install media. */
|
||||
wcscpy(FileNameBuffer, SourceRootPath.Buffer);
|
||||
wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
|
||||
RtlInitUnicodeString(&FileName,
|
||||
FileNameBuffer);
|
||||
|
||||
IniCache = NULL;
|
||||
Status = IniCacheLoad(&IniCache,
|
||||
&FileName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Open 'Version' section */
|
||||
Section = IniCacheGetSection(IniCache,
|
||||
L"Version");
|
||||
if (Section == NULL)
|
||||
{
|
||||
PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get pointer 'Signature' key */
|
||||
Status = IniCacheGetKey(Section,
|
||||
L"Signature",
|
||||
&Value);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check 'Signature' string */
|
||||
if (_wcsicmp(Value, L"$ReactOS$") != 0)
|
||||
{
|
||||
PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
PopupError("This is a test error.", "ENTER = Reboot computer");
|
||||
|
||||
SetStatusText(" ENTER = Continue");
|
||||
|
||||
|
@ -246,6 +474,9 @@ StartPage(PINPUT_RECORD Ir)
|
|||
}
|
||||
|
||||
return(START_PAGE);
|
||||
#endif
|
||||
|
||||
return(INTRO_PAGE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -607,8 +838,8 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
|||
SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
|
||||
SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
|
||||
|
||||
strcpy(InstallDir, "\\reactos");
|
||||
Length = strlen(InstallDir);
|
||||
wcscpy(InstallDir, L"\\reactos");
|
||||
Length = wcslen(InstallDir);
|
||||
|
||||
SetInputTextXY(8, 11, 51, InstallDir);
|
||||
|
||||
|
@ -632,6 +863,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
|||
}
|
||||
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
|
||||
return(PREPARE_COPY_PAGE);
|
||||
}
|
||||
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
|
||||
|
@ -647,7 +879,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
|||
{
|
||||
if (Length < 50)
|
||||
{
|
||||
InstallDir[Length] = Ir->Event.KeyEvent.uChar.AsciiChar;
|
||||
InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
|
||||
Length++;
|
||||
InstallDir[Length] = 0;
|
||||
SetInputTextXY(8, 11, 51, InstallDir);
|
||||
|
@ -662,24 +894,14 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
|||
static ULONG
|
||||
PrepareCopyPage(PINPUT_RECORD Ir)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
CHAR PathBuffer[MAX_PATH];
|
||||
UNICODE_STRING PathName;
|
||||
HANDLE DirectoryHandle;
|
||||
NTSTATUS Status;
|
||||
PCHAR End;
|
||||
WCHAR PathBuffer[MAX_PATH];
|
||||
PINICACHESECTION Section;
|
||||
PINICACHEITERATOR Iterator;
|
||||
PWCHAR KeyName;
|
||||
PWCHAR KeyValue;
|
||||
ULONG Length;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
PCHAR Dirs[]= {
|
||||
"System32",
|
||||
"System32\\Config",
|
||||
"System32\\Drivers",
|
||||
"Inf",
|
||||
"Help",
|
||||
"Fonts",
|
||||
NULL};
|
||||
|
||||
SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
|
||||
|
||||
|
@ -701,111 +923,133 @@ PrepareCopyPage(PINPUT_RECORD Ir)
|
|||
SetHighlightedTextXY(50, 12, "Done");
|
||||
|
||||
|
||||
|
||||
|
||||
/* create directories */
|
||||
SetInvertedTextXY(8, 14, "Create directories");
|
||||
|
||||
|
||||
/* Open 'Directories' section */
|
||||
Section = IniCacheGetSection(IniCache,
|
||||
L"Directories");
|
||||
if (Section == NULL)
|
||||
{
|
||||
PopupError("Setup failed to find the 'Directories' section\n"
|
||||
"in TXTSETUP.SIF.\n",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Enumerate the ini section 'Directories' and create all "relative" directories
|
||||
* FIXME:
|
||||
* Install directories like '\reactos\test' are not handled yet.
|
||||
*/
|
||||
|
||||
/* Build full install directory name */
|
||||
swprintf(PathBuffer,
|
||||
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
PartData.DiskNumber,
|
||||
PartData.PartNumber);
|
||||
if (InstallDir[0] != L'\\')
|
||||
wcscat(PathBuffer, L"\\");
|
||||
wcscat(PathBuffer, InstallDir);
|
||||
|
||||
/* create the systemroot directory */
|
||||
sprintf(PathBuffer,
|
||||
"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
PartData.DiskNumber,
|
||||
PartData.PartNumber);
|
||||
if (InstallDir[0] != '\\')
|
||||
strcat(PathBuffer, "\\");
|
||||
strcat(PathBuffer, InstallDir);
|
||||
|
||||
/* remove trailing backslash */
|
||||
Length = strlen(PathBuffer);
|
||||
/* Remove trailing backslash */
|
||||
Length = wcslen(PathBuffer);
|
||||
if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
|
||||
PathBuffer[Length - 1] = 0;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&PathName,
|
||||
PathBuffer);
|
||||
/* Create the install directory */
|
||||
Status = CreateDirectory(PathBuffer);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
|
||||
{
|
||||
DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = &PathName;
|
||||
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
PopupError("Setup could not create the install directory.",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
Status = NtCreateFile(&DirectoryHandle,
|
||||
DIRECTORY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_DIRECTORY,
|
||||
0,
|
||||
FILE_CREATE,
|
||||
FILE_DIRECTORY_FILE,
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
while(TRUE)
|
||||
{
|
||||
PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status);
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
|
||||
/* Enumerate the directory values and create the subdirectories */
|
||||
Iterator = IniCacheFindFirstValue(Section,
|
||||
&KeyName,
|
||||
&KeyValue);
|
||||
if (Iterator != NULL)
|
||||
{
|
||||
do
|
||||
{
|
||||
PrintTextXY(6, 25, "Created directory.");
|
||||
NtClose (DirectoryHandle);
|
||||
if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
|
||||
{
|
||||
DPRINT("Absolute Path: '%S'\n", KeyValue);
|
||||
|
||||
swprintf(PathBuffer,
|
||||
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
PartData.DiskNumber,
|
||||
PartData.PartNumber);
|
||||
wcscat(PathBuffer, KeyValue);
|
||||
|
||||
DPRINT("FullPath: '%S'\n", PathBuffer);
|
||||
}
|
||||
else if (KeyValue[0] != L'\\')
|
||||
{
|
||||
DPRINT("RelativePath: '%S'\n", KeyValue);
|
||||
swprintf(PathBuffer,
|
||||
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
PartData.DiskNumber,
|
||||
PartData.PartNumber);
|
||||
|
||||
if (InstallDir[0] != L'\\')
|
||||
wcscat(PathBuffer, L"\\");
|
||||
wcscat(PathBuffer, InstallDir);
|
||||
wcscat(PathBuffer, L"\\");
|
||||
wcscat(PathBuffer, KeyValue);
|
||||
|
||||
DPRINT("FullPath: '%S'\n", PathBuffer);
|
||||
|
||||
Status = CreateDirectory(PathBuffer);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
|
||||
{
|
||||
DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
|
||||
|
||||
PopupError("Setup could not create install directories.",
|
||||
"ENTER = Reboot computer");
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
ConInKey(Ir);
|
||||
|
||||
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||
{
|
||||
IniCacheFindClose(Iterator);
|
||||
return(QUIT_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (IniCacheFindNextValue(Iterator, &KeyName, &KeyValue));
|
||||
|
||||
|
||||
RtlFreeUnicodeString(&PathName);
|
||||
|
||||
|
||||
/* create the subdirectories */
|
||||
|
||||
/* append backslash and init end pointer */
|
||||
strcat(PathBuffer, "\\");
|
||||
Length = strlen(PathBuffer);
|
||||
End = &PathBuffer[Length];
|
||||
|
||||
for (i = 0; Dirs[i] != NULL; i++)
|
||||
{
|
||||
strcpy(End, Dirs[i]);
|
||||
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&PathName,
|
||||
PathBuffer);
|
||||
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = &PathName;
|
||||
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
Status = NtCreateFile(&DirectoryHandle,
|
||||
DIRECTORY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_DIRECTORY,
|
||||
0,
|
||||
FILE_CREATE,
|
||||
FILE_DIRECTORY_FILE,
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintTextXY(6, 25, "Created directory.");
|
||||
NtClose (DirectoryHandle);
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&PathName);
|
||||
}
|
||||
IniCacheFindClose(Iterator);
|
||||
}
|
||||
|
||||
|
||||
SetTextXY(8, 14, "Create directories");
|
||||
|
@ -1066,12 +1310,14 @@ NtProcessStartup(PPEB Peb)
|
|||
0,0,0,0,0);
|
||||
}
|
||||
|
||||
PartDataValid = FALSE;
|
||||
|
||||
Page = START_PAGE;
|
||||
while (Page != REBOOT_PAGE)
|
||||
{
|
||||
ClearScreen();
|
||||
|
||||
SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup ");
|
||||
SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
|
||||
|
||||
switch (Page)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue