mirror of
https://github.com/reactos/reactos.git
synced 2024-08-28 06:08:23 +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
|
NTSTATUS
|
||||||
WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
|
WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
|
||||||
ULONG nLength,
|
ULONG nLength,
|
||||||
|
@ -892,7 +943,7 @@ SetTextXY(SHORT x, SHORT y, PCHAR Text)
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text)
|
SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text)
|
||||||
{
|
{
|
||||||
COORD coPos;
|
COORD coPos;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -901,14 +952,18 @@ SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text)
|
||||||
coPos.X = x;
|
coPos.X = x;
|
||||||
coPos.Y = y;
|
coPos.Y = y;
|
||||||
|
|
||||||
Length = strlen(Text);
|
Length = wcslen(Text);
|
||||||
|
if (Length > len - 1)
|
||||||
|
{
|
||||||
|
Length = len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
FillConsoleOutputAttribute(0x70,
|
FillConsoleOutputAttribute(0x70,
|
||||||
len,
|
len,
|
||||||
coPos,
|
coPos,
|
||||||
&Written);
|
&Written);
|
||||||
|
|
||||||
WriteConsoleOutputCharacters(Text,
|
WriteConsoleOutputCharactersW(Text,
|
||||||
Length,
|
Length,
|
||||||
coPos);
|
coPos);
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ VOID
|
||||||
SetTextXY(SHORT x, SHORT y, PCHAR Text);
|
SetTextXY(SHORT x, SHORT y, PCHAR Text);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text);
|
SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text);
|
SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS text-mode setup
|
* PROJECT: ReactOS text-mode setup
|
||||||
* FILE: subsys/system/usetup/drivesup.h
|
* FILE: subsys/system/usetup/drivesup.h
|
||||||
|
|
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 = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ TARGET_INSTALLDIR = system32
|
||||||
|
|
||||||
TARGET_CFLAGS = -D__NTAPP__
|
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
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS text-mode setup
|
* PROJECT: ReactOS text-mode setup
|
||||||
* FILE: subsys/system/usetup/partlist.c
|
* FILE: subsys/system/usetup/partlist.c
|
||||||
|
@ -39,6 +39,88 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
PPARTLIST
|
||||||
CreatePartitionList(SHORT Left,
|
CreatePartitionList(SHORT Left,
|
||||||
SHORT Top,
|
SHORT Top,
|
||||||
|
@ -49,16 +131,15 @@ CreatePartitionList(SHORT Left,
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
SYSTEM_DEVICE_INFORMATION Sdi;
|
SYSTEM_DEVICE_INFORMATION Sdi;
|
||||||
DISK_GEOMETRY DiskGeometry;
|
DISK_GEOMETRY DiskGeometry;
|
||||||
|
IO_STATUS_BLOCK Iosb;
|
||||||
ULONG ReturnSize;
|
ULONG ReturnSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG DiskCount;
|
ULONG DiskNumber;
|
||||||
IO_STATUS_BLOCK Iosb;
|
|
||||||
WCHAR Buffer[MAX_PATH];
|
WCHAR Buffer[MAX_PATH];
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
|
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
|
||||||
SCSI_ADDRESS ScsiAddress;
|
SCSI_ADDRESS ScsiAddress;
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST));
|
List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST));
|
||||||
if (List == NULL)
|
if (List == NULL)
|
||||||
|
@ -96,11 +177,11 @@ CreatePartitionList(SHORT Left,
|
||||||
Sdi.NumberOfDisks * sizeof(DISKENTRY));
|
Sdi.NumberOfDisks * sizeof(DISKENTRY));
|
||||||
List->DiskCount = Sdi.NumberOfDisks;
|
List->DiskCount = Sdi.NumberOfDisks;
|
||||||
|
|
||||||
for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++)
|
for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
|
||||||
{
|
{
|
||||||
swprintf(Buffer,
|
swprintf(Buffer,
|
||||||
L"\\Device\\Harddisk%d\\Partition0",
|
L"\\Device\\Harddisk%d\\Partition0",
|
||||||
DiskCount);
|
DiskNumber);
|
||||||
RtlInitUnicodeString(&Name,
|
RtlInitUnicodeString(&Name,
|
||||||
Buffer);
|
Buffer);
|
||||||
|
|
||||||
|
@ -144,17 +225,17 @@ CreatePartitionList(SHORT Left,
|
||||||
sizeof(SCSI_ADDRESS));
|
sizeof(SCSI_ADDRESS));
|
||||||
|
|
||||||
|
|
||||||
List->DiskArray[DiskCount].DiskSize =
|
List->DiskArray[DiskNumber].DiskSize =
|
||||||
DiskGeometry.Cylinders.QuadPart *
|
DiskGeometry.Cylinders.QuadPart *
|
||||||
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
||||||
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
||||||
(ULONGLONG)DiskGeometry.BytesPerSector;
|
(ULONGLONG)DiskGeometry.BytesPerSector;
|
||||||
List->DiskArray[DiskCount].DiskNumber = DiskCount;
|
List->DiskArray[DiskNumber].DiskNumber = DiskNumber;
|
||||||
List->DiskArray[DiskCount].Port = ScsiAddress.PortNumber;
|
List->DiskArray[DiskNumber].Port = ScsiAddress.PortNumber;
|
||||||
List->DiskArray[DiskCount].Bus = ScsiAddress.PathId;
|
List->DiskArray[DiskNumber].Bus = ScsiAddress.PathId;
|
||||||
List->DiskArray[DiskCount].Id = ScsiAddress.TargetId;
|
List->DiskArray[DiskNumber].Id = ScsiAddress.TargetId;
|
||||||
|
|
||||||
List->DiskArray[DiskCount].FixedDisk = TRUE;
|
List->DiskArray[DiskNumber].FixedDisk = TRUE;
|
||||||
|
|
||||||
|
|
||||||
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
|
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
|
||||||
|
@ -171,31 +252,9 @@ CreatePartitionList(SHORT Left,
|
||||||
8192);
|
8192);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
AddPartitionList(DiskNumber,
|
||||||
List->DiskArray[DiskCount].PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap,
|
&List->DiskArray[DiskNumber],
|
||||||
0,
|
LayoutBuffer);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
|
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
|
||||||
|
@ -203,9 +262,9 @@ CreatePartitionList(SHORT Left,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* mark removable disk entry */
|
/* mark removable disk entry */
|
||||||
List->DiskArray[DiskCount].FixedDisk = FALSE;
|
List->DiskArray[DiskNumber].FixedDisk = FALSE;
|
||||||
List->DiskArray[DiskCount].PartCount = 0;
|
List->DiskArray[DiskNumber].PartCount = 0;
|
||||||
List->DiskArray[DiskCount].PartArray = NULL;
|
List->DiskArray[DiskNumber].PartArray = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,9 +380,8 @@ PrintPartitionData(PPARTLIST List,
|
||||||
|
|
||||||
ULONGLONG PartSize;
|
ULONGLONG PartSize;
|
||||||
PCHAR Unit;
|
PCHAR Unit;
|
||||||
PCHAR PartType;
|
|
||||||
UCHAR Attribute;
|
UCHAR Attribute;
|
||||||
|
PCHAR PartType;
|
||||||
|
|
||||||
Width = List->Right - List->Left - 1;
|
Width = List->Right - List->Left - 1;
|
||||||
Height = List->Bottom - List->Top - 1;
|
Height = List->Bottom - List->Top - 1;
|
||||||
|
@ -336,6 +394,10 @@ PrintPartitionData(PPARTLIST List,
|
||||||
|
|
||||||
PartEntry = &List->DiskArray[DiskIndex].PartArray[PartIndex];
|
PartEntry = &List->DiskArray[DiskIndex].PartArray[PartIndex];
|
||||||
|
|
||||||
|
/* Determine partition type */
|
||||||
|
PartType = NULL;
|
||||||
|
if (PartEntry->Unpartitioned == FALSE)
|
||||||
|
{
|
||||||
if ((PartEntry->PartType == PARTITION_FAT_12) ||
|
if ((PartEntry->PartType == PARTITION_FAT_12) ||
|
||||||
(PartEntry->PartType == PARTITION_FAT_16) ||
|
(PartEntry->PartType == PARTITION_FAT_16) ||
|
||||||
(PartEntry->PartType == PARTITION_HUGE) ||
|
(PartEntry->PartType == PARTITION_HUGE) ||
|
||||||
|
@ -352,17 +414,18 @@ PrintPartitionData(PPARTLIST List,
|
||||||
{
|
{
|
||||||
PartType = "NTFS"; /* FIXME: Not quite correct! */
|
PartType = "NTFS"; /* FIXME: Not quite correct! */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PartType = "Unknown";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */
|
if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */
|
||||||
{
|
{
|
||||||
PartSize = (PartEntry->PartSize + (1 << 29)) >> 30;
|
PartSize = (PartEntry->PartSize + (1 << 29)) >> 30;
|
||||||
Unit = "GB";
|
Unit = "GB";
|
||||||
}
|
}
|
||||||
else if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
|
else
|
||||||
|
#endif
|
||||||
|
if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
|
||||||
{
|
{
|
||||||
PartSize = (PartEntry->PartSize + (1 << 19)) >> 20;
|
PartSize = (PartEntry->PartSize + (1 << 19)) >> 20;
|
||||||
Unit = "MB";
|
Unit = "MB";
|
||||||
|
@ -370,29 +433,58 @@ PrintPartitionData(PPARTLIST List,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PartSize = (PartEntry->PartSize + (1 << 9)) >> 10;
|
PartSize = (PartEntry->PartSize + (1 << 9)) >> 10;
|
||||||
Unit = "kB";
|
Unit = "KB";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PartEntry->DriveLetter != (CHAR)0)
|
|
||||||
|
if (PartEntry->Unpartitioned == TRUE)
|
||||||
{
|
{
|
||||||
sprintf(LineBuffer,
|
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->DriveLetter,
|
||||||
PartIndex,
|
|
||||||
PartEntry->PartNumber,
|
|
||||||
PartEntry->PartType,
|
PartEntry->PartType,
|
||||||
PartType,
|
|
||||||
PartSize,
|
PartSize,
|
||||||
Unit);
|
Unit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(LineBuffer,
|
sprintf(LineBuffer,
|
||||||
" %d: nr: %d type: %x (%s) %I64u %s",
|
"%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,
|
||||||
|
PartSize,
|
||||||
|
Unit);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(LineBuffer,
|
||||||
|
"-- %s (%d: nr: %d type: %x) %I64u %s",
|
||||||
|
PartEntry->FileSystemName,
|
||||||
PartIndex,
|
PartIndex,
|
||||||
PartEntry->PartNumber,
|
PartEntry->PartNumber,
|
||||||
PartEntry->PartType,
|
PartEntry->PartType,
|
||||||
PartType,
|
|
||||||
PartSize,
|
PartSize,
|
||||||
Unit);
|
Unit);
|
||||||
}
|
}
|
||||||
|
@ -435,7 +527,6 @@ PrintDiskData(PPARTLIST List,
|
||||||
ULONGLONG DiskSize;
|
ULONGLONG DiskSize;
|
||||||
PCHAR Unit;
|
PCHAR Unit;
|
||||||
SHORT PartIndex;
|
SHORT PartIndex;
|
||||||
BOOL PartPrinted;
|
|
||||||
|
|
||||||
DiskEntry = &List->DiskArray[DiskIndex];
|
DiskEntry = &List->DiskArray[DiskIndex];
|
||||||
|
|
||||||
|
@ -448,21 +539,20 @@ PrintDiskData(PPARTLIST List,
|
||||||
coPos.X = List->Left + 1;
|
coPos.X = List->Left + 1;
|
||||||
coPos.Y = List->Top + 1 + List->Line;
|
coPos.Y = List->Top + 1 + List->Line;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
|
if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
|
||||||
{
|
{
|
||||||
DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
|
DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
|
||||||
Unit = "GB";
|
Unit = "GB";
|
||||||
}
|
}
|
||||||
else if (DiskEntry->DiskSize >= 0xA00000ULL) /* 10 MB */
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
|
DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
|
||||||
|
if (DiskSize == 0)
|
||||||
|
DiskSize = 1;
|
||||||
Unit = "MB";
|
Unit = "MB";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DiskSize = (DiskEntry->DiskSize + (1 << 9)) >> 10;
|
|
||||||
Unit = "kB";
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(LineBuffer,
|
sprintf(LineBuffer,
|
||||||
"%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
|
"%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
|
||||||
|
@ -494,26 +584,20 @@ PrintDiskData(PPARTLIST List,
|
||||||
PrintEmptyLine(List);
|
PrintEmptyLine(List);
|
||||||
|
|
||||||
|
|
||||||
PartPrinted = FALSE;
|
|
||||||
|
|
||||||
/* Print partition lines*/
|
/* 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,
|
PrintPartitionData(List,
|
||||||
DiskIndex,
|
DiskIndex,
|
||||||
PartIndex);
|
PartIndex);
|
||||||
PartPrinted = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print separator line */
|
/* Print separator line */
|
||||||
if (PartPrinted == TRUE)
|
|
||||||
{
|
|
||||||
PrintEmptyLine(List);
|
PrintEmptyLine(List);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -582,7 +666,7 @@ DrawPartitionList(PPARTLIST List)
|
||||||
coPos,
|
coPos,
|
||||||
&Written);
|
&Written);
|
||||||
|
|
||||||
/* draw upper right corner */
|
/* draw lower right corner */
|
||||||
coPos.X = List->Right;
|
coPos.X = List->Right;
|
||||||
coPos.Y = List->Bottom;
|
coPos.Y = List->Bottom;
|
||||||
FillConsoleOutputCharacter(0xD9, // '+',
|
FillConsoleOutputCharacter(0xD9, // '+',
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS text-mode setup
|
* PROJECT: ReactOS text-mode setup
|
||||||
* FILE: subsys/system/usetup/partlist.h
|
* FILE: subsys/system/usetup/partlist.h
|
||||||
|
@ -50,6 +50,11 @@ typedef struct _PARTENTRY
|
||||||
ULONG PartType;
|
ULONG PartType;
|
||||||
|
|
||||||
CHAR DriveLetter;
|
CHAR DriveLetter;
|
||||||
|
CHAR VolumeLabel[17];
|
||||||
|
CHAR FileSystemName[9];
|
||||||
|
|
||||||
|
BOOL Unpartitioned;
|
||||||
|
|
||||||
BOOL Used;
|
BOOL Used;
|
||||||
} PARTENTRY, *PPARTENTRY;
|
} PARTENTRY, *PPARTENTRY;
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,13 @@
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <ntdll/rtl.h>
|
#include <ntdll/rtl.h>
|
||||||
|
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
#include <reactos/resource.h>
|
||||||
|
|
||||||
#include "usetup.h"
|
#include "usetup.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "partlist.h"
|
#include "partlist.h"
|
||||||
|
#include "inicache.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,14 +60,16 @@
|
||||||
|
|
||||||
HANDLE ProcessHeap;
|
HANDLE ProcessHeap;
|
||||||
|
|
||||||
BOOL PartDataValid = FALSE;
|
BOOLEAN PartDataValid;
|
||||||
PARTDATA PartData;
|
PARTDATA PartData;
|
||||||
|
|
||||||
CHAR InstallDir[51];
|
WCHAR InstallDir[51];
|
||||||
|
|
||||||
UNICODE_STRING SourcePath;
|
UNICODE_STRING SourcePath;
|
||||||
UNICODE_STRING SourceRootPath;
|
UNICODE_STRING SourceRootPath;
|
||||||
|
|
||||||
|
PINICACHE IniCache;
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
* Confirm quit setup
|
||||||
* RETURNS
|
* RETURNS
|
||||||
|
@ -97,65 +313,15 @@ PrintString(char* fmt,...)
|
||||||
static BOOL
|
static BOOL
|
||||||
ConfirmQuit(PINPUT_RECORD Ir)
|
ConfirmQuit(PINPUT_RECORD Ir)
|
||||||
{
|
{
|
||||||
SHORT xScreen;
|
|
||||||
SHORT yScreen;
|
|
||||||
SHORT yTop;
|
|
||||||
SHORT xLeft;
|
|
||||||
BOOL Result = FALSE;
|
BOOL Result = FALSE;
|
||||||
PUSHORT pAttributes = NULL;
|
|
||||||
PUCHAR pCharacters = NULL;
|
|
||||||
COORD Pos;
|
|
||||||
|
|
||||||
GetScreenSize(&xScreen, &yScreen);
|
PopupError("ReactOS is not completely installed on your\n"
|
||||||
yTop = (yScreen - 10) / 2;
|
"computer. If you quit Setup now, you will need to\n"
|
||||||
xLeft = (xScreen - 52) / 2;
|
"run Setup again to install ReactOS.\n"
|
||||||
|
"\n"
|
||||||
/* Save screen */
|
" * Press ENTER to continue Setup.\n"
|
||||||
#if 0
|
" * Press F3 to quit Setup.",
|
||||||
Pos.X = 0;
|
"F3= Quit ENTER = Continue");
|
||||||
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,
|
|
||||||
"+----------------------------------------------------+");
|
|
||||||
|
|
||||||
while(TRUE)
|
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);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start page
|
* Start page
|
||||||
* RETURNS
|
* RETURNS
|
||||||
|
@ -211,6 +354,12 @@ static ULONG
|
||||||
StartPage(PINPUT_RECORD Ir)
|
StartPage(PINPUT_RECORD Ir)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
WCHAR FileNameBuffer[MAX_PATH];
|
||||||
|
UNICODE_STRING FileName;
|
||||||
|
|
||||||
|
PINICACHESECTION Section;
|
||||||
|
PWCHAR Value;
|
||||||
|
|
||||||
|
|
||||||
SetStatusText(" Please wait...");
|
SetStatusText(" Please wait...");
|
||||||
|
|
||||||
|
@ -226,12 +375,91 @@ StartPage(PINPUT_RECORD Ir)
|
||||||
PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
|
PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Open and load txtsetup.sif here. A pointer (or handle) to the
|
/* Load txtsetup.sif from install media. */
|
||||||
* ini data should be stored in a global variable.
|
wcscpy(FileNameBuffer, SourceRootPath.Buffer);
|
||||||
* The full path to txtsetup.sif is created by appending '\txtsetup.sif'
|
wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
|
||||||
* to the unicode string SourceRootPath.
|
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");
|
SetStatusText(" ENTER = Continue");
|
||||||
|
|
||||||
|
@ -246,6 +474,9 @@ StartPage(PINPUT_RECORD Ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return(START_PAGE);
|
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, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
|
||||||
SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
|
SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
|
||||||
|
|
||||||
strcpy(InstallDir, "\\reactos");
|
wcscpy(InstallDir, L"\\reactos");
|
||||||
Length = strlen(InstallDir);
|
Length = wcslen(InstallDir);
|
||||||
|
|
||||||
SetInputTextXY(8, 11, 51, InstallDir);
|
SetInputTextXY(8, 11, 51, InstallDir);
|
||||||
|
|
||||||
|
@ -632,6 +863,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
||||||
}
|
}
|
||||||
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||||
{
|
{
|
||||||
|
|
||||||
return(PREPARE_COPY_PAGE);
|
return(PREPARE_COPY_PAGE);
|
||||||
}
|
}
|
||||||
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
|
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
|
||||||
|
@ -647,7 +879,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
||||||
{
|
{
|
||||||
if (Length < 50)
|
if (Length < 50)
|
||||||
{
|
{
|
||||||
InstallDir[Length] = Ir->Event.KeyEvent.uChar.AsciiChar;
|
InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
|
||||||
Length++;
|
Length++;
|
||||||
InstallDir[Length] = 0;
|
InstallDir[Length] = 0;
|
||||||
SetInputTextXY(8, 11, 51, InstallDir);
|
SetInputTextXY(8, 11, 51, InstallDir);
|
||||||
|
@ -662,24 +894,14 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
|
||||||
static ULONG
|
static ULONG
|
||||||
PrepareCopyPage(PINPUT_RECORD Ir)
|
PrepareCopyPage(PINPUT_RECORD Ir)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
WCHAR PathBuffer[MAX_PATH];
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
PINICACHESECTION Section;
|
||||||
CHAR PathBuffer[MAX_PATH];
|
PINICACHEITERATOR Iterator;
|
||||||
UNICODE_STRING PathName;
|
PWCHAR KeyName;
|
||||||
HANDLE DirectoryHandle;
|
PWCHAR KeyValue;
|
||||||
NTSTATUS Status;
|
|
||||||
PCHAR End;
|
|
||||||
ULONG Length;
|
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. ");
|
SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
|
||||||
|
|
||||||
|
@ -701,110 +923,132 @@ PrepareCopyPage(PINPUT_RECORD Ir)
|
||||||
SetHighlightedTextXY(50, 12, "Done");
|
SetHighlightedTextXY(50, 12, "Done");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* create directories */
|
/* create directories */
|
||||||
SetInvertedTextXY(8, 14, "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 */
|
||||||
/* create the systemroot directory */
|
swprintf(PathBuffer,
|
||||||
sprintf(PathBuffer,
|
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||||
"\\Device\\Harddisk%lu\\Partition%lu",
|
|
||||||
PartData.DiskNumber,
|
PartData.DiskNumber,
|
||||||
PartData.PartNumber);
|
PartData.PartNumber);
|
||||||
if (InstallDir[0] != '\\')
|
if (InstallDir[0] != L'\\')
|
||||||
strcat(PathBuffer, "\\");
|
wcscat(PathBuffer, L"\\");
|
||||||
strcat(PathBuffer, InstallDir);
|
wcscat(PathBuffer, InstallDir);
|
||||||
|
|
||||||
/* remove trailing backslash */
|
/* Remove trailing backslash */
|
||||||
Length = strlen(PathBuffer);
|
Length = wcslen(PathBuffer);
|
||||||
if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
|
if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
|
||||||
PathBuffer[Length - 1] = 0;
|
PathBuffer[Length - 1] = 0;
|
||||||
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&PathName,
|
/* Create the install directory */
|
||||||
PathBuffer);
|
Status = CreateDirectory(PathBuffer);
|
||||||
|
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
|
||||||
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);
|
DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
|
||||||
|
|
||||||
|
PopupError("Setup could not create the install directory.",
|
||||||
|
"ENTER = Reboot computer");
|
||||||
|
|
||||||
|
while(TRUE)
|
||||||
|
{
|
||||||
|
ConInKey(Ir);
|
||||||
|
|
||||||
|
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
|
||||||
|
{
|
||||||
|
return(QUIT_PAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintTextXY(6, 25, "Created directory.");
|
|
||||||
NtClose (DirectoryHandle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&PathName);
|
/* Enumerate the directory values and create the subdirectories */
|
||||||
|
Iterator = IniCacheFindFirstValue(Section,
|
||||||
|
&KeyName,
|
||||||
/* create the subdirectories */
|
&KeyValue);
|
||||||
|
if (Iterator != NULL)
|
||||||
/* 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]);
|
do
|
||||||
|
|
||||||
|
|
||||||
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);
|
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
|
else if (KeyValue[0] != L'\\')
|
||||||
{
|
{
|
||||||
PrintTextXY(6, 25, "Created directory.");
|
DPRINT("RelativePath: '%S'\n", KeyValue);
|
||||||
NtClose (DirectoryHandle);
|
swprintf(PathBuffer,
|
||||||
}
|
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||||
|
PartData.DiskNumber,
|
||||||
|
PartData.PartNumber);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&PathName);
|
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));
|
||||||
|
|
||||||
|
IniCacheFindClose(Iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1066,12 +1310,14 @@ NtProcessStartup(PPEB Peb)
|
||||||
0,0,0,0,0);
|
0,0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PartDataValid = FALSE;
|
||||||
|
|
||||||
Page = START_PAGE;
|
Page = START_PAGE;
|
||||||
while (Page != REBOOT_PAGE)
|
while (Page != REBOOT_PAGE)
|
||||||
{
|
{
|
||||||
ClearScreen();
|
ClearScreen();
|
||||||
|
|
||||||
SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup ");
|
SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
|
||||||
|
|
||||||
switch (Page)
|
switch (Page)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue