bootvid.c
来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 291 行
C
291 行
/*
* ReactOS Boot video driver
*
* Copyright (C) 2003 Casper S. Hornstroup
* Copyright (C) 2004, 2005 Filip Navara
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id: bootvid.c 24684 2006-11-05 20:28:59Z ion $
*/
/* INCLUDES ******************************************************************/
#include "bootvid.h"
#include "resource.h"
#define NDEBUG
#include <debug.h>
//#define USE_PROGRESS_BAR
/* GLOBALS *******************************************************************/
static volatile LONG ShutdownNotify;
static KEVENT ShutdownCompleteEvent;
/* DATA **********************************************************************/
static RGBQUAD _MainPalette[16];
static UCHAR _Square1[9 * 4];
static UCHAR _Square2[9 * 4];
static UCHAR _Square3[9 * 4];
/* FUNCTIONS *****************************************************************/
static VOID NTAPI
BootVidAnimationThread(PVOID Ignored)
{
UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));
ULONG Iteration, Index, ClrUsed;
UINT AnimBarPos;
LARGE_INTEGER Interval;
/*
* Build a bitmap containing the fade in palette. The palette entries
* are then processed in a loop and set using VidBitBlt function.
*/
ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
PaletteBitmap->biBitCount = 4;
PaletteBitmap->biClrUsed = ClrUsed;
/*
* Main animation loop.
*/
for (Iteration = 0, AnimBarPos = 0; !ShutdownNotify; Iteration++)
{
if (Iteration <= PALETTE_FADE_STEPS)
{
for (Index = 0; Index < ClrUsed; Index++)
{
Palette[Index].rgbRed =
_MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS;
Palette[Index].rgbGreen =
_MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS;
Palette[Index].rgbBlue =
_MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS;
}
VidBitBlt(PaletteBitmapBuffer, 0, 0);
}
#ifdef USE_PROGRESS_BAR
else
{
break;
}
Interval.QuadPart = -PALETTE_FADE_TIME;
#else
#if 0
if (AnimBarPos == 0)
{
VidSolidColorFill(0x173, 354, 0x178, 354 + 9, 0);
}
else if (AnimBarPos > 3)
{
VidSolidColorFill(0xe3 + AnimBarPos * 8, 354,
0xe8 + AnimBarPos * 8, 354 + 9,
0);
}
if (AnimBarPos >= 3)
{
VidBufferToScreenBlt(_Square1, 0xeb + AnimBarPos * 8, 354, 6, 9, 4);
}
if (AnimBarPos >= 2 && AnimBarPos <= 16)
{
VidBufferToScreenBlt(_Square2, 0xf3 + AnimBarPos * 8, 354, 6, 9, 4);
}
if (AnimBarPos >= 1 && AnimBarPos <= 15)
{
VidBufferToScreenBlt(_Square3, 0xfb + AnimBarPos * 8, 354, 6, 9, 4);
}
#endif
if (Iteration <= PALETTE_FADE_STEPS)
{
Interval.QuadPart = -PALETTE_FADE_TIME;
if ((Iteration % 5) == 0)
AnimBarPos++;
}
else
{
Interval.QuadPart = -PALETTE_FADE_TIME * 5;
AnimBarPos++;
}
AnimBarPos = Iteration % 18;
#endif
/* Wait for a bit. */
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
DPRINT("Finishing bootvid thread.\n");
KeSetEvent(&ShutdownCompleteEvent, 0, FALSE);
PsTerminateSystemThread(0);
}
NTSTATUS NTAPI
BootVidDisplayBootLogo(PVOID ImageBase)
{
PBITMAPINFOHEADER BitmapInfoHeader;
LPRGBQUAD Palette;
static const ULONG BitmapIds[2] = {IDB_BOOTIMAGE, IDB_BAR};
PUCHAR BitmapData[2];
ULONG Index;
HANDLE BitmapThreadHandle;
CLIENT_ID BitmapThreadId;
NTSTATUS Status;
KeInitializeEvent(&ShutdownCompleteEvent, NotificationEvent, FALSE);
/*
* Get the bitmaps from the executable.
*/
for (Index = 0; Index < sizeof(BitmapIds) / sizeof(BitmapIds[0]); Index++)
{
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
LDR_RESOURCE_INFO ResourceInfo;
ULONG Size;
ResourceInfo.Type = /* RT_BITMAP */ 2;
ResourceInfo.Name = BitmapIds[Index];
ResourceInfo.Language = 0x09;
Status = LdrFindResource_U(
ImageBase,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrFindResource_U() failed with status 0x%.08x\n", Status);
return Status;
}
Status = LdrAccessResource(
ImageBase,
ResourceDataEntry,
(PVOID*)&BitmapData[Index],
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrAccessResource() failed with status 0x%.08x\n", Status);
return Status;
}
}
/*
* Initialize the graphics output.
*/
if (!VidInitialize(TRUE))
{
return STATUS_UNSUCCESSFUL;
}
/*
* Load the bar bitmap and get the square data from it.
*/
VidBitBlt(BitmapData[1], 0, 0);
VidScreenToBufferBlt(_Square1, 0, 0, 6, 9, 4);
VidScreenToBufferBlt(_Square2, 8, 0, 6, 9, 4);
VidScreenToBufferBlt(_Square3, 16, 0, 6, 9, 4);
/*
* Save the main image palette and replace it with black palette, so
* we can do fade in effect later.
*/
BitmapInfoHeader = (PBITMAPINFOHEADER)BitmapData[0];
Palette = (LPRGBQUAD)(BitmapData[0] + BitmapInfoHeader->biSize);
RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette));
RtlZeroMemory(Palette, sizeof(_MainPalette));
/*
* Display the main image.
*/
VidBitBlt(BitmapData[0], 0, 0);
/*
* Start a thread that handles the fade in and bar animation effects.
*/
Status = PsCreateSystemThread(
&BitmapThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&BitmapThreadId,
BootVidAnimationThread,
NULL);
if (!NT_SUCCESS(Status))
{
VidCleanUp();
return Status;
}
ZwClose(BitmapThreadHandle);
return STATUS_SUCCESS;
}
VOID NTAPI
BootVidUpdateProgress(ULONG Progress)
{
#ifdef USE_PROGRESS_BAR
if (ShutdownNotify == 0)
{
VidSolidColorFill(0x103, 354, 0x103 + (Progress * 120 / 100), 354 + 9, 1);
}
#endif
}
VOID NTAPI
BootVidFinalizeBootLogo(VOID)
{
InterlockedIncrement(&ShutdownNotify);
DPRINT1("Waiting for bootvid thread to finish.\n");
KeWaitForSingleObject(&ShutdownCompleteEvent, Executive, KernelMode,
FALSE, NULL);
DPRINT1("Bootvid thread to finish.\n");
//VidResetDisplay();
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?