示例#1
0
VOID UiUnInitialize(PCSTR BootText)
{
	UiDrawBackdrop();
	UiDrawStatusText("Booting...");
	UiInfoBox(BootText);

	UiVtbl.UnInitialize();
}
示例#2
0
VOID
WinLdrSetupEms(IN PCHAR BootOptions)
{
	PCHAR RedirectPort;

    /* Start fresh */
	RtlZeroMemory(&LoaderRedirectionInformation, sizeof(HEADLESS_LOADER_BLOCK));
        
	/* Use a direction port if one was given, or use ACPI to detect one instead */
	RedirectPort = strstr(BootOptions, "/redirect=");

	if (RedirectPort)
	{
		RedirectPort = strstr(RedirectPort, "com");
		if (RedirectPort)
		{
			RedirectPort += sizeof("com") - 1;
			LoaderRedirectionInformation.PortNumber = atoi(RedirectPort);
		}
		else
		{
			RedirectPort = strstr(RedirectPort, "usebiossettings");
			if (RedirectPort)
			{
				UiDrawStatusText("ACPI SRT Table Not Supported...");
			}
			else
			{
				LoaderRedirectionInformation.PortAddress = (PUCHAR)strtoul(RedirectPort, 0, 16);
				if (LoaderRedirectionInformation.PortAddress)
				{
					LoaderRedirectionInformation.PortNumber = 3;
				}
			}
		}
	}
	
	/* Use a direction baudrate if one was given */
	RedirectPort = strstr(BootOptions, "/redirectbaudrate=");
	if (RedirectPort)
	{
		if (strstr(RedirectPort, "115200"))
		{
			LoaderRedirectionInformation.BaudRate = 115200;
		}
		else if (strstr(RedirectPort, "57600"))
		{
			LoaderRedirectionInformation.BaudRate = 57600;
		}
		else if (strstr(RedirectPort, "19200"))
		{
			LoaderRedirectionInformation.BaudRate = 19200;
		}
		else
		{
			LoaderRedirectionInformation.BaudRate = 9600;
		}	
	}
	
	/* Enable headless support if parameters were found */
	if (LoaderRedirectionInformation.PortNumber)
	{
		if (!LoaderRedirectionInformation.BaudRate)
		{
			LoaderRedirectionInformation.BaudRate = 9600;
		}
		
		WinLdrInitializeHeadlessPort();
	}
}
示例#3
0
VOID
LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
                 IN USHORT OperatingSystemVersion)
{
    ULONG_PTR SectionId;
    PCSTR SectionName = OperatingSystem->SystemPartition;
    CHAR  SettingsValue[80];
    BOOLEAN HasSection;
    CHAR  BootOptions2[256];
    PCHAR File;
    CHAR FileName[512];
    CHAR BootPath[512];
    LPCSTR LoadOptions;
    LPSTR BootOptions;
    BOOLEAN BootFromFloppy;
    ULONG i, ErrorLine;
    HINF InfHandle;
    INFCONTEXT InfContext;
    PLOADER_PARAMETER_BLOCK LoaderBlock;
    PSETUP_LOADER_BLOCK SetupBlock;
    LPCSTR SystemPath;
    LPCSTR SourcePaths[] =
    {
        "", /* Only for floppy boot */
#if defined(_M_IX86)
        "I386\\",
#elif defined(_M_MPPC)
        "PPC\\",
#elif defined(_M_MRX000)
        "MIPS\\",
#endif
        "reactos\\",
        NULL
    };

    /* Get OS setting value */
    SettingsValue[0] = ANSI_NULL;
    IniOpenSection("Operating Systems", &SectionId);
    IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));

    /* Open the operating system section specified in the .ini file */
    HasSection = IniOpenSection(SectionName, &SectionId);

    UiDrawBackdrop();
    UiDrawProgressBarCenter(1, 100, "Loading NT...");

    /* Read the system path is set in the .ini file */
    if (!HasSection ||
        !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
    {
        MachDiskGetBootPath(BootPath, sizeof(BootPath));
    }

    /* Append a backslash */
    if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
        strcat(BootPath, "\\");

    /* Read booting options */
    if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions2, sizeof(BootOptions2)))
    {
        /* Get options after the title */
        PCSTR p = SettingsValue;
        while (*p == ' ' || *p == '"')
            p++;
        while (*p != '\0' && *p != '"')
            p++;
        strcpy(BootOptions2, p);
        TRACE("BootOptions: '%s'\n", BootOptions2);
    }

    /* Check if a ramdisk file was given */
    File = strstr(BootOptions2, "/RDPATH=");
    if (File)
    {
        /* Copy the file name and everything else after it */
        strcpy(FileName, File + 8);

        /* Null-terminate */
        *strstr(FileName, " ") = ANSI_NULL;

        /* Load the ramdisk */
        RamDiskLoadVirtualFile(FileName);
    }

    TRACE("BootPath: '%s'\n", BootPath);

    /* And check if we booted from floppy */
    BootFromFloppy = strstr(BootPath, "fdisk") != NULL;

    /* Open 'txtsetup.sif' from any of source paths */
    File = BootPath + strlen(BootPath);
    for (i = BootFromFloppy ? 0 : 1; ; i++)
    {
        SystemPath = SourcePaths[i];
        if (!SystemPath)
        {
            ERR("Failed to open txtsetup.sif\n");
            return;
        }
        sprintf(File, "%stxtsetup.sif", SystemPath);
        if (InfOpenFile (&InfHandle, BootPath, &ErrorLine))
        {
            sprintf(File, "%s", SystemPath);
            break;
        }
    }

    TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);

    /* Get Load options - debug and non-debug */
    if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext))
    {
        ERR("Failed to find 'SetupData/OsLoadOptions'\n");
        return;
    }

    if (!InfGetDataField(&InfContext, 1, &LoadOptions))
    {
        ERR("Failed to get load options\n");
        return;
    }

#if DBG
    /* Get debug load options and use them */
    if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext))
    {
        LPCSTR DbgLoadOptions;

        if (InfGetDataField(&InfContext, 1, &DbgLoadOptions))
            LoadOptions = DbgLoadOptions;
    }
#endif

    /* Copy loadoptions (original string will be freed) */
    BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
    strcpy(BootOptions, LoadOptions);

    TRACE("BootOptions: '%s'\n", BootOptions);

    UiDrawStatusText("Setup is loading...");

    /* Allocate and minimalistic-initialize LPB */
    AllocateAndInitLPB(&LoaderBlock);

    /* Allocate and initialize setup loader block */
    SetupBlock = &WinLdrSystemBlock->SetupBlock;
    LoaderBlock->SetupLdrBlock = SetupBlock;

    /* Set textmode setup flag */
    SetupBlock->Flags = SETUPLDR_TEXT_MODE;

    /* Load NLS data, they are in system32 */
    strcpy(FileName, BootPath);
    strcat(FileName, "system32\\");
    SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);

    /* Get a list of boot drivers */
    SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath);

    /* Close the inf file */
    InfCloseFile(InfHandle);

    /* Load ReactOS */
    LoadAndBootWindowsCommon(_WIN32_WINNT_WS03,
                             LoaderBlock,
                             BootOptions,
                             BootPath,
                             TRUE);
}
示例#4
0
文件: setupldr.c 项目: GYGit/reactos
VOID
LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
                 IN USHORT OperatingSystemVersion)
{
    ULONG_PTR SectionId;
    PCSTR SectionName = OperatingSystem->SystemPartition;
    CHAR  SettingsValue[80];
    BOOLEAN HasSection;
    CHAR  BootOptions2[256];
    PCHAR File;
    CHAR FileName[512];
    CHAR BootPath[512];
    LPCSTR LoadOptions;
    LPSTR BootOptions;
    BOOLEAN BootFromFloppy;
    ULONG i, ErrorLine;
    HINF InfHandle;
    INFCONTEXT InfContext;
    PLOADER_PARAMETER_BLOCK LoaderBlock;
    PSETUP_LOADER_BLOCK SetupBlock;
    LPCSTR SystemPath;
    LPCSTR SourcePaths[] =
    {
        "", /* Only for floppy boot */
#if defined(_M_IX86)
        "I386\\",
#elif defined(_M_MPPC)
        "PPC\\",
#elif defined(_M_MRX000)
        "MIPS\\",
#endif
        "reactos\\",
        NULL
    };

    /* Get OS setting value */
    SettingsValue[0] = ANSI_NULL;
    IniOpenSection("Operating Systems", &SectionId);
    IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));

    /* Open the operating system section specified in the .ini file */
    HasSection = IniOpenSection(SectionName, &SectionId);

    UiDrawBackdrop();
    UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");

    /* Read the system path is set in the .ini file */
    if (!HasSection ||
        !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
    {
        /*
         * IMPROVE: I don't want to call MachDiskGetBootPath here as a
         * default choice because I can call it after (see few lines below).
         * Also doing the strcpy call as it is done in winldr.c is not
         * really what we want. Instead I reset BootPath here so that
         * we can build the full path using the general code from below.
         */
        // MachDiskGetBootPath(BootPath, sizeof(BootPath));
        // strcpy(BootPath, SectionName);
        BootPath[0] = '\0';
    }

    /*
     * Check whether BootPath is a full path
     * and if not, create a full boot path.
     *
     * See FsOpenFile for the technique used.
     */
    if (strrchr(BootPath, ')') == NULL)
    {
        /* Temporarily save the boot path */
        strcpy(FileName, BootPath);

        /* This is not a full path. Use the current (i.e. boot) device. */
        MachDiskGetBootPath(BootPath, sizeof(BootPath));

        /* Append a path separator if needed */
        if (FileName[0] != '\\' && FileName[0] != '/')
            strcat(BootPath, "\\");

        /* Append the remaining path */
        strcat(BootPath, FileName);
    }

    /* Append a backslash if needed */
    if ((strlen(BootPath) == 0) || BootPath[strlen(BootPath) - 1] != '\\')
        strcat(BootPath, "\\");

    /* Read booting options */
    if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions2, sizeof(BootOptions2)))
    {
        /* Get options after the title */
        PCSTR p = SettingsValue;
        while (*p == ' ' || *p == '"')
            p++;
        while (*p != '\0' && *p != '"')
            p++;
        strcpy(BootOptions2, p);
        TRACE("BootOptions: '%s'\n", BootOptions2);
    }

    /* Check if a ramdisk file was given */
    File = strstr(BootOptions2, "/RDPATH=");
    if (File)
    {
        /* Copy the file name and everything else after it */
        strcpy(FileName, File + 8);

        /* Null-terminate */
        *strstr(FileName, " ") = ANSI_NULL;

        /* Load the ramdisk */
        if (!RamDiskLoadVirtualFile(FileName))
        {
            UiMessageBox("Failed to load RAM disk file %s", FileName);
            return;
        }
    }

    TRACE("BootPath: '%s'\n", BootPath);

    /* And check if we booted from floppy */
    BootFromFloppy = strstr(BootPath, "fdisk") != NULL;

    /* Open 'txtsetup.sif' from any of source paths */
    File = BootPath + strlen(BootPath);
    for (i = BootFromFloppy ? 0 : 1; ; i++)
    {
        SystemPath = SourcePaths[i];
        if (!SystemPath)
        {
            UiMessageBox("Failed to open txtsetup.sif");
            return;
        }
        strcpy(File, SystemPath);
        strcpy(FileName, BootPath);
        strcat(FileName, "txtsetup.sif");
        if (InfOpenFile(&InfHandle, FileName, &ErrorLine))
        {
            break;
        }
    }

    TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);

    /* Get Load options - debug and non-debug */
    if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext))
    {
        ERR("Failed to find 'SetupData/OsLoadOptions'\n");
        return;
    }

    if (!InfGetDataField(&InfContext, 1, &LoadOptions))
    {
        ERR("Failed to get load options\n");
        return;
    }

#if DBG
    /* Get debug load options and use them */
    if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext))
    {
        LPCSTR DbgLoadOptions;

        if (InfGetDataField(&InfContext, 1, &DbgLoadOptions))
            LoadOptions = DbgLoadOptions;
    }
#endif

    /* Copy loadoptions (original string will be freed) */
    BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
    strcpy(BootOptions, LoadOptions);

    TRACE("BootOptions: '%s'\n", BootOptions);

    UiDrawStatusText("Setup is loading...");

    /* Allocate and minimalistic-initialize LPB */
    AllocateAndInitLPB(&LoaderBlock);

    /* Allocate and initialize setup loader block */
    SetupBlock = &WinLdrSystemBlock->SetupBlock;
    LoaderBlock->SetupLdrBlock = SetupBlock;

    /* Set textmode setup flag */
    SetupBlock->Flags = SETUPLDR_TEXT_MODE;

    /* Load NLS data, they are in system32 */
    strcpy(FileName, BootPath);
    strcat(FileName, "system32\\");
    SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);

    /* Get a list of boot drivers */
    SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath);

    /* Close the inf file */
    InfCloseFile(InfHandle);

    /* Load ReactOS Setup */
    LoadAndBootWindowsCommon(_WIN32_WINNT_WS03,
                             LoaderBlock,
                             BootOptions,
                             BootPath,
                             TRUE);
}
示例#5
0
VOID
LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
                 IN USHORT OperatingSystemVersion)
{
    CHAR FileName[512];
    CHAR BootPath[512];
    LPCSTR LoadOptions, BootOptions;
    BOOLEAN BootFromFloppy;
    ULONG i, ErrorLine;
    HINF InfHandle;
    INFCONTEXT InfContext;
    PLOADER_PARAMETER_BLOCK LoaderBlock;
    PSETUP_LOADER_BLOCK SetupBlock;
    LPCSTR SystemPath;
    LPCSTR SourcePaths[] =
    {
        "\\", /* Only for floppy boot */
#if defined(_M_IX86)
        "\\I386\\",
#elif defined(_M_MPPC)
        "\\PPC\\",
#elif defined(_M_MRX000)
        "\\MIPS\\",
#endif
        "\\reactos\\",
        NULL
    };

    /* Get boot path */
    MachDiskGetBootPath(BootPath, sizeof(BootPath));

    /* And check if we booted from floppy */
    BootFromFloppy = strstr(BootPath, "fdisk") != NULL;

    /* Open 'txtsetup.sif' from any of source paths */
    for (i = BootFromFloppy ? 0 : 1; ; i++)
    {
        SystemPath = SourcePaths[i];
        if (!SystemPath)
        {
            ERR("Failed to open txtsetup.sif\n");
            return;
        }
        sprintf(FileName, "%stxtsetup.sif", SystemPath);
        if (InfOpenFile (&InfHandle, FileName, &ErrorLine))
        {
            strcat(BootPath, SystemPath);
            break;
        }
    }

    TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);

    /* Get Load options - debug and non-debug */
    if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext))
    {
        ERR("Failed to find 'SetupData/OsLoadOptions'\n");
        return;
    }

    if (!InfGetDataField(&InfContext, 1, &LoadOptions))
    {
        ERR("Failed to get load options\n");
        return;
    }

    BootOptions = LoadOptions;

#if DBG
    /* Get debug load options and use them */
    if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext))
    {
        if (InfGetDataField(&InfContext, 1, &LoadOptions))
            BootOptions = LoadOptions;
    }
#endif

    TRACE("BootOptions: '%s'\n", BootOptions);

    UiDrawStatusText("Setup is loading...");

    /* Allocate and minimalistic-initialize LPB */
    AllocateAndInitLPB(&LoaderBlock);

    /* Allocate and initialize setup loader block */
    SetupBlock = &WinLdrSystemBlock->SetupBlock;
    LoaderBlock->SetupLdrBlock = SetupBlock;

    /* Set textmode setup flag */
    SetupBlock->Flags = SETUPLDR_TEXT_MODE;

    /* Load NLS data, they are in system32 */
    strcpy(FileName, BootPath);
    strcat(FileName, "system32\\");
    SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);

    /* Get a list of boot drivers */
    SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath);

    /* Load ReactOS */
    LoadAndBootWindowsCommon(_WIN32_WINNT_WS03,
                             LoaderBlock,
                             BootOptions,
                             BootPath,
                             TRUE);
}
示例#6
0
BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
{
	int		width = 8;
	unsigned int	height = 1;
	int		curline = 0;
	int		k;
	size_t		i , j;
	int		x1, x2, y1, y2;
	char	temp[260];
	char	key;
	int		EditBoxLine;
	ULONG		EditBoxStartX, EditBoxEndX;
	int		EditBoxCursorX;
	unsigned int	EditBoxTextCount;
	int		EditBoxTextDisplayIndex;
	BOOLEAN	ReturnCode;
	PVOID	ScreenBuffer;

	// Save the screen contents
	ScreenBuffer = MmHeapAlloc(UiScreenWidth * UiScreenHeight * 2);
	TuiSaveScreen(ScreenBuffer);

	// Find the height
	for (i=0; i<strlen(MessageText); i++)
	{
		if (MessageText[i] == '\n')
			height++;
	}

	// Find the width
	for (i=0,j=0,k=0; i<height; i++)
	{
		while ((MessageText[j] != '\n') && (MessageText[j] != 0))
		{
			j++;
			k++;
		}

		if (k > width)
			width = k;

		k = 0;
		j++;
	}

	// Calculate box area
	x1 = (UiScreenWidth - (width+2))/2;
	x2 = x1 + width + 3;
	y1 = ((UiScreenHeight - height - 2)/2) + 1;
	y2 = y1 + height + 4;

	// Draw the box
	TuiDrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor));

	// Draw the text
	for (i=0,j=0; i<strlen(MessageText)+1; i++)
	{
		if ((MessageText[i] == '\n') || (MessageText[i] == 0))
		{
			temp[j] = 0;
			j = 0;
			UiDrawText(x1+2, y1+1+curline, temp, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor));
			curline++;
		}
		else
			temp[j++] = MessageText[i];
	}

	EditBoxTextCount = 0;
	EditBoxLine = y2 - 2;
	EditBoxStartX = x1 + 3;
	EditBoxEndX = x2 - 3;
	UiFillArea(EditBoxStartX, EditBoxLine, EditBoxEndX, EditBoxLine, ' ', ATTR(UiEditBoxTextColor, UiEditBoxBgColor));

	// Show the cursor
	EditBoxCursorX = EditBoxStartX;
	MachVideoSetTextCursorPosition(EditBoxCursorX, EditBoxLine);
	MachVideoHideShowTextCursor(TRUE);

	// Draw status text
	UiDrawStatusText("Press ENTER to continue, or ESC to cancel");

	VideoCopyOffScreenBufferToVRAM();

	for (;;)
	{
		if (MachConsKbHit())
		{
			key = MachConsGetCh();
			if(key == KEY_EXTENDED)
			{
				key = MachConsGetCh();
			}

			if(key == KEY_ENTER)
			{
				ReturnCode = TRUE;
				break;
			}
			else if(key == KEY_ESC)
			{
				ReturnCode = FALSE;
				break;
			}
			else if (key == KEY_BACKSPACE) // Remove a character
			{
				if (EditBoxTextCount)
				{
					EditBoxTextCount--;
					EditTextBuffer[EditBoxTextCount] = 0;
				}
				else
				{
					MachBeep();
				}
			}
			else // Add this key to the buffer
			{
				if (EditBoxTextCount < Length - 1)
				{
					EditTextBuffer[EditBoxTextCount] = key;
					EditBoxTextCount++;
					EditTextBuffer[EditBoxTextCount] = 0;
				}
				else
				{
					MachBeep();
				}
			}
		}

		// Draw the edit box background
		UiFillArea(EditBoxStartX, EditBoxLine, EditBoxEndX, EditBoxLine, ' ', ATTR(UiEditBoxTextColor, UiEditBoxBgColor));

		// Fill the text in
		if (EditBoxTextCount > (EditBoxEndX - EditBoxStartX))
		{
			EditBoxTextDisplayIndex = EditBoxTextCount - (EditBoxEndX - EditBoxStartX);
			EditBoxCursorX = EditBoxEndX;
		}
		else
		{
			EditBoxTextDisplayIndex = 0;
			EditBoxCursorX = EditBoxStartX + EditBoxTextCount;
		}
		UiDrawText(EditBoxStartX, EditBoxLine, &EditTextBuffer[EditBoxTextDisplayIndex], ATTR(UiEditBoxTextColor, UiEditBoxBgColor));

		// Move the cursor
		MachVideoSetTextCursorPosition(EditBoxCursorX, EditBoxLine);

		TuiUpdateDateTime();

		VideoCopyOffScreenBufferToVRAM();
	}

	// Hide the cursor again
	MachVideoHideShowTextCursor(FALSE);

	// Restore the screen contents
	TuiRestoreScreen(ScreenBuffer);
	MmHeapFree(ScreenBuffer);

	return ReturnCode;
}
示例#7
0
VOID TuiMessageBoxCritical(PCSTR MessageText)
{
	int		width = 8;
	unsigned int	height = 1;
	int		curline = 0;
	int		k;
	size_t		i , j;
	int		x1, x2, y1, y2;
	char	temp[260];
	char	key;

	// Find the height
	for (i=0; i<strlen(MessageText); i++)
	{
		if (MessageText[i] == '\n')
			height++;
	}

	// Find the width
	for (i=0,j=0,k=0; i<height; i++)
	{
		while ((MessageText[j] != '\n') && (MessageText[j] != 0))
		{
			j++;
			k++;
		}

		if (k > width)
			width = k;

		k = 0;
		j++;
	}

	// Calculate box area
	x1 = (UiScreenWidth - (width+2))/2;
	x2 = x1 + width + 3;
	y1 = ((UiScreenHeight - height - 2)/2) + 1;
	y2 = y1 + height + 4;

	// Draw the box
	TuiDrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor));

	// Draw the text
	for (i=0,j=0; i<strlen(MessageText)+1; i++)
	{
		if ((MessageText[i] == '\n') || (MessageText[i] == 0))
		{
			temp[j] = 0;
			j = 0;
			UiDrawText(x1+2, y1+1+curline, temp, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor));
			curline++;
		}
		else
			temp[j++] = MessageText[i];
	}

	// Draw OK button
	strcpy(temp, "   OK   ");
	UiDrawText(x1+((x2-x1)/2)-3, y2-2, temp, ATTR(COLOR_BLACK, COLOR_GRAY));

	// Draw status text
	UiDrawStatusText("Press ENTER to continue");

	VideoCopyOffScreenBufferToVRAM();

	for (;;)
	{
		if (MachConsKbHit())
		{
			key = MachConsGetCh();
			if(key == KEY_EXTENDED)
				key = MachConsGetCh();

			if(key == KEY_ENTER)
				break;
			else if(key == KEY_SPACE)
				break;
			else if(key == KEY_ESC)
				break;
		}

		TuiUpdateDateTime();

		VideoCopyOffScreenBufferToVRAM();
	}

}