1 Commits

Author SHA1 Message Date
b74c31f17c configure.ps1: Fix path handling and improve reliability
- Use $PSScriptRoot for reliable source directory detection
- Use Join-Path for proper path construction
- Validate BUILD_TYPE against Debug/Release
- Fix CMake argument quoting
- Use Write-Error for error messages
2025-10-10 16:26:28 +02:00
37 changed files with 146 additions and 2129 deletions

View File

@@ -53,9 +53,8 @@ implement any environment subsystem to support applications that are strictly wr
* NT drivers compatibility layer
# Requirements
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
right now, but there are plans to add BIOS support in the future.
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
# Source structure
| Directory | Description |

View File

@@ -1,8 +1,6 @@
# XT Boot Sector
PROJECT(BOOTSECT)
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
# Compile boot sectors
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)

View File

@@ -1,144 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/amd64/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 1GB of memory */
pushaw
pushw %es
cld
movw $(0x1000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x2000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x3000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x3000 / 16), %ax
movw %ax, %es
xorw %di, %di
movw $512, %cx
movl $0x00000083, %eax
.BuildPageMapLoop:
/* Identity map 512 pages of 2MB */
movl %eax, %es:(%di)
addl $2097152, %eax
addw $0x08, %di
loop .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID, long mode and PAE */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
movl $0x01, %eax
cpuid
testl $0x40, %edx
jz CpuUnsupported
movl $0x80000000, %eax
cpuid
cmpl $0x80000000, %eax
jbe CpuUnsupported
movl $0x80000001, %eax
cpuid
testl $0x20000000, %edx
jz CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to long mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
xorl %edx, %edx
pushl %edx
pushl %eax
cli
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl %cr4, %eax
orl $0x00A0, %eax
movl %eax, %cr4
movl $0x00001000, %eax
movl %eax, %cr3
movl $0xC0000080, %ecx
rdmsr
orl $0x00000100, %eax
wrmsr
movl %cr0, %eax
orl $0x80000001, %eax
movl %eax, %cr0
ljmp $0x10, $.Stage2LongMode
.code64
.Stage2LongMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x18, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popq %rax
xorq %rbx, %rbx
xorq %rcx, %rcx
xorq %rdx, %rdx
xorq %rsi, %rsi
xorq %rdi, %rdi
xorq %rbp, %rbp
jmp *%rax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x0000000000000000
.quad 0x00AF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.quad 0x00CF9B000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTX64 EFI"

View File

@@ -121,15 +121,15 @@ VerifyBiosParameterBlock:
ja FsError
ReadExtraCode:
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
/* Read second VBR sector with extra boot code */
movl HiddenSectors - Start(%bp), %eax
addl $0x02, %eax
movw $0x03, %cx
movw $0x01, %cx
xorw %bx, %bx
movw %bx, %es
movw $0x7E00, %bx
call ReadSectors
jmp StartExtraCode
jmp StartSectors
ReadSectors:
/* Check for extended BIOS functions and use it only if available */
@@ -139,22 +139,18 @@ ReadSectors:
movw $0x55AA, %bx
movb DriveNumber - Start(%bp), %dl
int $0x13
jc .ReadCHS
jc ReadCHS
cmpw $0xAA55, %bx
jne .ReadCHS
jne ReadCHS
testb $0x01, %cl
jz .ReadCHS
jz ReadCHS
/* Verify drive size and determine whether to use CHS or LBA */
cmpl %edi, %eax
jnb .ReadLBA
jnb ReadLBA
.ReadCHS:
ReadCHS:
/* Read sectors using CHS */
popal
.CHSLoop:
/* Read sector by sector using CHS */
pushw %cx
pushal
xorl %edx, %edx
@@ -180,11 +176,11 @@ ReadSectors:
movw %es, %dx
addw $0x20, %dx
movw %dx, %es
loop .CHSLoop
loop ReadCHS
popw %es
ret
.ReadLBA:
ReadLBA:
/* Prepare DAP packet and read sectors using LBA */
popal
pushw %cx
@@ -213,19 +209,19 @@ ReadSectors:
movw %dx, %es
popw %bx
subw %si, %cx
jnz .ReadLBA
jnz ReadLBA
popw %es
ret
DiskError:
/* Display disk error message and reboot */
movw $.MsgDiskError, %si
movw $msgDiskError, %si
call Print
jmp Reboot
FsError:
/* Display FS error message and reboot */
movw $.MsgFsError, %si
movw $msgFsError, %si
call Print
jmp Reboot
@@ -233,297 +229,48 @@ Print:
/* Simple routine to print messages */
lodsb
orb %al, %al
jz .DonePrint
jz DonePrint
movb $0x0E, %ah
movw $0x07, %bx
int $0x10
jmp Print
.DonePrint:
DonePrint:
retw
Reboot:
/* Display a message, wait for a key press and reboot */
movw $.MsgAnyKey, %si
movw $msgAnyKey, %si
call Print
xorw %ax, %ax
int $0x16
int $0x19
.MsgAnyKey:
.ascii "Press any key to restart...\r\n\0"
msgAnyKey:
.ascii "Press any key to restart\r\n"
.MsgDiskError:
.ascii "Disk error!\r\n\0"
msgDiskError:
.ascii "Disk error\r\n"
.MsgFsError:
.ascii "File system error!\r\n\0"
msgFsError:
.ascii "File system error\r\n"
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
.fill (510 - (. - Start)), 1, 0
.word 0xAA55
StartExtraCode:
/* Load XTLDR file from disk */
call LoadStage2
/* Enable A20 gate */
call EnableA20
/* Call architecture specific initialization code */
call InitializeCpu
/* Jump to Stage2 */
call RunStage2
Clear8042:
/* Clear 8042 PS/2 buffer */
nop
nop
nop
nop
inb $0x64, %al
cmpb $0xff, %al
je .Clear8042_Done
testb $0x02, %al
jnz Clear8042
.Clear8042_Done:
ret
EnableA20:
/* Enable A20 gate */
pushaw
call Clear8042
movb $0xD1, %al
outb %al, $0x64
call Clear8042
movb $0xDF, %al
outb %al, $0x60
call Clear8042
movb $0xFF, %al
outb %al, $0x64
call Clear8042
popaw
ret
FindFatEntry:
/* Find a file or directory in the FAT table */
pushw %bx
pushw %cx
pushw %dx
pushw %si
pushw %di
.FindFatCluster:
/* Find FAT32 cluster holding the entry */
cmp $0x0FFFFFF8, %eax
jae .FindEntryFail
pushl %eax
movw $0x0200, %bx
movw %bx, %es
call ReadCluster
popl %eax
movb SectorsPerCluster - Start(%bp), %cl
shlw $0x04, %cx
xorw %di, %di
.FindEntryLoop:
/* Find the entry */
movb %es:(%di), %al
cmpb $0x00, %al
je .FindEntryFail
cmpb $0xE5, %al
je .FindSkipEntry
movb %es:0x0B(%di), %ah
cmpb $0x0F, %ah
je .FindSkipEntry
pushw %di
pushw %si
pushw %cx
movw $0x0B, %cx
repe cmpsb
popw %cx
popw %si
popw %di
jnz .FindSkipEntry
movw %es:0x1A(%di), %ax
movw %es:0x14(%di), %dx
shll $0x10, %edx
orl %edx, %eax
clc
jmp .FindEntryDone
.FindSkipEntry:
/* Skip to the next entry */
addw $0x20, %di
decw %cx
jnz .FindEntryLoop
call GetFatEntry
jmp .FindFatCluster
.FindEntryFail:
/* Error, file/directory not found */
stc
.FindEntryDone:
/* Clean up the stack */
popw %di
popw %si
popw %dx
popw %cx
popw %bx
ret
GetFatEntry:
/* Get FAT32 sector and offset from FAT table */
shll $0x02, %eax
movl %eax, %ecx
xorl %edx, %edx
movzwl BytesPerSector - Start(%bp), %ebx
pushl %ebx
divl %ebx
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
movl HiddenSectors - Start(%bp), %ebx
addl %ebx, %eax
popl %ebx
decl %ebx
andl %ebx, %ecx
movzwl ExtendedFlags - Start(%bp), %ebx
andw $0x0F, %bx
jz LoadFatSector
cmpb FatCopies - Start(%bp), %bl
jae FsError
pushl %eax
movl BigSectorsPerFat - Start(%bp), %eax
mull %ebx
popl %edx
addl %edx, %eax
LoadFatSector:
/* Load FAT32 sector from disk */
pushl %ecx
movw $0x9000, %bx
movw %bx, %es
cmpl %esi, %eax
je .LoadFatSectorDone
movl %eax, %esi
xorw %bx, %bx
movw $0x01, %cx
call ReadSectors
.LoadFatSectorDone:
/* Clean up the stack */
popl %ecx
movl %es:(%ecx), %eax
andl $0x0FFFFFFF, %eax
ret
LoadStage2:
/* Load Stage2 executable, first find file in the path */
movl $0xFFFFFFFF, %esi
pushl %esi
movl 0x7C2C, %eax
movw $.EfiDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.BootDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.Stage2FileName, %si
call FindFatEntry
jc Stage2NotLoaded
popl %esi
/* Load XTLDR file from disk */
cmpl $0x02, %eax
jb FileNotFound
cmpl $0x0FFFFFF8, %eax
jae FileNotFound
movw $(0xF800 / 16), %bx
movw %bx, %es
.LoadStage2Loop:
/* Load file data from disk */
pushl %eax
xorw %bx, %bx
pushw %es
call ReadCluster
popw %es
xorw %bx, %bx
movb SectorsPerCluster - Start(%bp), %bl
shlw $0x05, %bx
movw %es, %ax
addw %bx, %ax
movw %ax, %es
popl %eax
pushw %es
call GetFatEntry
popw %es
cmpl $0x0FFFFFF8, %eax
jb .LoadStage2Loop
ret
ParseExecutableHeader:
/* Parse Stage2 PE/COFF executable header */
pushw %es
movw $(0xF800 / 16), %ax
movw %ax, %es
movl %es:60, %eax
addl $(4 + 20), %eax
movl %es:16(%eax), %eax
addl $0xF800, %eax
popw %es
ret
ReadCluster:
/* Read FAT32 cluster from disk */
decl %eax
decl %eax
xorl %edx, %edx
movzbl SectorsPerCluster - Start(%bp), %ebx
mull %ebx
pushl %eax
xorl %edx, %edx
movzbl FatCopies - Start(%bp), %eax
mull BigSectorsPerFat - Start(%bp)
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
addl HiddenSectors - Start(%bp), %eax
popl %ebx
addl %ebx, %eax
xorw %bx, %bx
movzbw SectorsPerCluster - Start(%bp), %cx
call ReadSectors
ret
/* Include architecture specific code */
.include ARCH_ESP_SOURCE
CpuUnsupported:
/* Display CPU unsupported message and reboot */
popal
movw $.MsgCpuUnsupported, %si
StartSectors:
/* Print message */
movw $msgUnavailable, %si
call Print
jmp Reboot
FileNotFound:
/* Display XTLDR not found message and reboot */
movw $.MsgXtLdrNotFound, %si
call Print
jmp Reboot
/* Wait for key press and reboot */
xorw %ax, %ax
int $0x16
int $0x19
Stage2NotLoaded:
/* Clean up the stack and display XTLDR not found message and reboot */
popl %esi
jmp FileNotFound
msgUnavailable:
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
.BootDirName:
/* Boot directory name */
.ascii "BOOT "
.EfiDirName:
/* EFI directory name */
.ascii "EFI "
.MsgCpuUnsupported:
.ascii "CPU not supported!\r\n\0"
.MsgXtLdrNotFound:
.ascii "XTLDR Stage2 not found!\r\n\0"
/* Fill the rest of the extra VBR with zeros and add signature */
.fill (2043 - (. - Start)), 1, 0
.ascii "XTLDR"
/* Fill the rest of the extra VBR with zeros */
.fill (1024 - (. - Start)), 1, 0

View File

@@ -1,124 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/i686/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 16MB of memory */
pushaw
pushw %es
cld
movw $(0x1000 >> 0x04), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x03), %eax
stosl
movl $(0x3000 | 0x03), %eax
stosl
movl $(0x4000 | 0x03), %eax
stosl
movl $(0x5000 | 0x03), %eax
stosl
xorl %eax, %eax
movw $(1024 - 4), %cx
rep stosl
movl $0x00000003, %eax
movl $4, %edx
movw $(0x2000 >> 0x04), %bx
.BuildPageMapLoop:
/* Identity map 1024 pages of 4KB */
movw %bx, %es
xorw %di, %di
pushl %edx
movw $1024, %cx
.FillPageMapTable:
/* Fill the page table */
movl %eax, %es:(%di)
addl $4096, %eax
addw $0x04, %di
loop .FillPageMapTable
popl %edx
addw $(0x1000 >> 0x04), %bx
decl %edx
jnz .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to protected mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
pushl %eax
cli
movl %cr0, %eax
orl $0x01, %eax
movl %eax, %cr0
ljmp $0x08, $.Stage2ProtectedMode
.code32
.Stage2ProtectedMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popl %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
xorl %esi, %esi
xorl %edi, %edi
xorl %ebp, %ebp
movl $0x1000, %ebx
movl %ebx, %cr3
movl %cr0, %ebx
orl $0x80000000, %ebx
movl %ebx, %cr0
jmp *%eax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x00CF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTIA32EFI"

View File

@@ -4,7 +4,6 @@
* FILE: boot/bootsect/amd64/mbrboot.S
* DESCRIPTION: XT Boot Loader MBR boot code
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <aiken@codingworkshop.eu.org>
*/
.text
@@ -42,7 +41,7 @@ RealStart:
movw %ax, %ss
/* Print welcome message */
leaw .MsgXtosBoot, %si
leaw msgXtosBoot, %si
call Print
/* Get BIOS boot drive and partition table offset */
@@ -91,19 +90,19 @@ PartitionFound:
InvalidSignature:
/* Invalid signature error */
leaw .MsgInvalidSignature, %si
leaw msgInvalidSignature, %si
call Print
jmp HaltSystem
PartitionNotFound:
/* Active partition not found error */
leaw .MsgPartitionNotFound, %si
leaw msgPartitionNotFound, %si
call Print
jmp HaltSystem
VbrReadFail:
/* VBR read failed error */
leaw .MsgVbrReadFail, %si
leaw msgVbrReadFail, %si
call Print
jmp HaltSystem
@@ -137,16 +136,16 @@ DonePrint:
/* Storage for the LBA start */
.long 0
.MsgInvalidSignature:
msgInvalidSignature:
.asciz "Invalid partition signature!"
.MsgPartitionNotFound:
msgPartitionNotFound:
.asciz "Bootable partition not found!"
.MsgVbrReadFail:
msgVbrReadFail:
.asciz "VBR read failed!"
.MsgXtosBoot:
msgXtosBoot:
.asciz "Starting XTOS boot loader...\r\n"
/* Fill the rest of the MBR with zeros and add MBR signature at the end */

View File

@@ -16,7 +16,6 @@ list(APPEND LIBXTLDR_SOURCE
# Specify list of source code files
list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
${XTLDR_SOURCE_DIR}/biosutil.cc
${XTLDR_SOURCE_DIR}/bootutil.cc
${XTLDR_SOURCE_DIR}/config.cc
${XTLDR_SOURCE_DIR}/console.cc
@@ -39,9 +38,6 @@ add_executable(xtldr ${XTLDR_SOURCE})
# Add linker libraries
target_link_libraries(xtldr libxtos)
# Add linker options
target_link_options(xtldr PRIVATE /ALIGN:512)
# Set proper binary name and install target
if(ARCH STREQUAL "i686")
set(BINARY_NAME "bootia32")
@@ -53,6 +49,5 @@ set_install_target(xtldr efi/boot)
# Set loader entrypoint and subsystem
set_entrypoint(xtldr "BlStartXtLoader")
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
set_linker_map(xtldr TRUE)
set_subsystem(xtldr efi_application)

View File

@@ -1,190 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/biosutil.cc
* DESCRIPTION: Legacy BIOS support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.hh>
/**
* Clears the entire screen and moves the cursor to the top-left corner.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ClearScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Fill the entire screen with blank characters */
for(Index = 0; Index < VgaWidth * VgaHeight; Index++)
{
VgaBuffer[Index] = Blank;
}
/* Reset cursor position to the top-left corner */
CursorX = 0;
CursorY = 0;
/* Update the hardware cursor position */
UpdateCursor();
}
/**
* Formats the input string and prints it out to the screen.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT PrintContext;
VA_LIST Arguments;
/* Initialise the print contexts */
PrintContext.WriteWideCharacter = PutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Format and print the string to the stdout */
RTL::WideString::FormatWideString(&PrintContext, (PWCHAR)Format, Arguments);
/* Clean up the va_list */
VA_END(Arguments);
}
/**
* Writes a single wide character to the screen using legacy BIOS VGA text mode.
*
* @param Character
* The wide character to be printed.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
BiosUtils::PutChar(IN WCHAR Character)
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT VgaCharacter;
/* Handle special characters */
if(Character == L'\n')
{
/* Move to the next line */
CursorX = 0;
CursorY++;
}
else if(Character == L'\r')
{
/* Move to the beginning of the current line */
CursorX = 0;
}
else
{
/* Print character and move cursor to the right */
VgaCharacter = (0x0F << 8) | (Character & 0xFF);
VgaBuffer[CursorY * VgaWidth + CursorX] = VgaCharacter;
CursorX++;
}
/* Handle moving to the next line if cursor is at the end of the line */
if(CursorX >= VgaWidth)
{
CursorX = 0;
CursorY++;
}
/* Handle scrolling if cursor is at the end of the screen */
if(CursorY >= VgaHeight)
{
ScrollScreen();
CursorY = VgaHeight - 1;
}
/* Update the hardware cursor position */
UpdateCursor();
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Scrolls the entire screen content up by one line and clears the last line.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ScrollScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Move every line up by one */
for(Index = 0; Index < (VgaHeight - 1) * VgaWidth; Index++)
{
VgaBuffer[Index] = VgaBuffer[Index + VgaWidth];
}
/* Clear the last line */
for(Index = (VgaHeight - 1) * VgaWidth; Index < VgaHeight * VgaWidth; Index++)
{
VgaBuffer[Index] = Blank;
}
}
/**
* Updates the hardware cursor position on the screen.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::UpdateCursor()
{
USHORT Position;
/* Calculate cursor position */
Position = CursorY * VgaWidth + CursorX;
/* Send command to set the high byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0E);
HL::IoPort::WritePort8(0x3D5, (UCHAR)((Position >> 8) & 0xFF));
/* Send command to set the low byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0F);
HL::IoPort::WritePort8(0x3D5, (UCHAR)(Position & 0xFF));
}

View File

@@ -10,18 +10,6 @@
#include <xtldr.hh>
/* Legacy BIOS cursor X position */
USHORT BiosUtils::CursorX = 0;
/* Legacy BIOS cursor Y position */
USHORT BiosUtils::CursorY = 0;
/* Legacy BIOS screen height */
CONST USHORT BiosUtils::VgaHeight = 25;
/* Legacy BIOS screen width */
CONST USHORT BiosUtils::VgaWidth = 80;
/* XT Boot Loader menu list */
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;

View File

@@ -15,25 +15,6 @@
#include <libxtos.hh>
class BiosUtils
{
private:
STATIC USHORT CursorX;
STATIC USHORT CursorY;
STATIC CONST USHORT VgaHeight;
STATIC CONST USHORT VgaWidth;
public:
STATIC XTCDECL VOID ClearScreen();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
private:
STATIC XTCDECL VOID ScrollScreen();
STATIC XTCDECL VOID UpdateCursor();
};
class BootUtils
{
public:

View File

@@ -236,15 +236,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
PWCHAR Modules;
EFI_STATUS Status;
/* Check if system is EFI-based and provided parameters are valid */
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
{
/* Invalid parameters, print error message using BIOS calls and hang */
BiosUtils::ClearScreen();
BiosUtils::Print(L"XTLDR requires EFI-based system!");
for(;;);
}
/* Initialize XTLDR and */
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);

View File

@@ -1,3 +1,2 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x000000000000F800)
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)

View File

@@ -1,3 +1,2 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x0000F800)
set(BASEADDRESS_XTOSKRNL 0x00400000)

View File

@@ -64,17 +64,11 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
set(BINARY_NAME "${NAME}.bin")
set(OBJECT_NAME "${NAME}.obj")
get_directory_property(DEFS COMPILE_DEFINITIONS)
foreach(def ${DEFS})
list(APPEND ASM_DEFS "-D${def}")
endforeach()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
COMMAND ${CMAKE_ASM_COMPILER}
/nologo
--target=i386-none-elf
${ASM_DEFS}
-I${CMAKE_CURRENT_SOURCE_DIR}
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
-c -- ${SOURCE}

View File

@@ -272,18 +272,11 @@ typedef struct _KIDTENTRY
{
USHORT OffsetLow;
USHORT Selector;
union
{
struct
{
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
};
USHORT Access;
};
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;

View File

@@ -58,6 +58,12 @@
#define KIDT_ACCESS_RING0 0x00
#define KIDT_ACCESS_RING3 0x60
/* IDT gate types */
#define KIDT_TASK 0x05
#define KIDT_CALL 0x0C
#define KIDT_INTERRUPT 0x0E
#define KIDT_TRAP 0x0F
/* TSS Offsets */
#define KTSS_ESP0 0x04
#define KTSS_CR3 0x1C
@@ -278,18 +284,7 @@ typedef struct _KIDTENTRY
{
USHORT Offset;
USHORT Selector;
union
{
struct
{
UCHAR Reserved;
UCHAR Type:4;
UCHAR Flag:1;
UCHAR Dpl:2;
UCHAR Present:1;
};
USHORT Access;
};
USHORT Access;
USHORT ExtendedOffset;
} KIDTENTRY, *PKIDTENTRY;

View File

@@ -150,23 +150,21 @@ typedef enum _KTHREAD_STATE
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
{
DispatcherLock,
ExpansionLock,
UnusedSpareLock,
PfnLock,
SystemSpaceLock,
VacbLock,
MasterLock,
NonPagedAllocPoolLock,
NonPagedPoolLock,
IoCancelLock,
WorkQueueLock,
IoVpbLock,
IoDatabaseLock,
IoCompletionLock,
FileSystemLock,
FsStructLock,
AfdWorkQueueLock,
BcbLock,
NonPagedPoolLock,
ReservedSystemLock,
TimerTableLock,
MmNonPagedPoolLock,
MaximumLock
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;

View File

@@ -49,10 +49,6 @@
#define PFL_DIGIT_PRECISION 0x00002000
#define PFL_THOUSANDS_GROUPING 0x00004000
/* Cryptographic related definitions */
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20
/* Runtime Library routine callbacks */
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
@@ -99,12 +95,4 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
LONG Flags;
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
/* Runtime Library SHA-1 context structure definition */
typedef struct _RTL_SHA1_CONTEXT
{
ULONG State[5];
ULONG Count[2];
UCHAR Buffer[SHA1_BLOCK_SIZE];
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
#endif /* __XTDK_RTLTYPES_H */

View File

@@ -12,9 +12,8 @@
#ifdef __cplusplus
/* C++ definitions */
#define NULLPTR nullptr
#define VIRTUAL virtual
#define XTCLINK extern "C"
#define NULLPTR nullptr
/* C++ boolean type */
typedef bool BOOLEAN, *PBOOLEAN;
@@ -25,9 +24,8 @@
typedef wchar_t wchar;
#else
/* C definitions */
#define NULLPTR ((void *)0)
#define VIRTUAL
#define XTCLINK
#define NULLPTR ((void *)0)
/* C boolean type */
typedef enum _BOOLEAN

View File

@@ -80,10 +80,6 @@
/* Macro that returns offset of the virtual address */
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
/* Macros for bitwise rotating */
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
/* Macro for rounding down */
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
@@ -108,7 +104,7 @@
/* Variadic ABI functions */
typedef __builtin_va_list VA_LIST, *PVA_LIST;
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
(Type)(__builtin_va_arg(Marker, Type)))
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)

View File

@@ -71,8 +71,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)

View File

@@ -249,34 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/**
@@ -636,9 +636,6 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -650,22 +647,15 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type)
IN USHORT Access)
{
/* Set the handler's address */
/* Setup the gate */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
/* Set the code segment selector */
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].Dpl = Access;
Idt[Vector].IstIndex = Ist;
Idt[Vector].Present = 1;
Idt[Vector].Reserved1 = 0;
Idt[Vector].Type = Type;
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
}

View File

@@ -242,34 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
}
/**
@@ -656,9 +656,6 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -670,21 +667,13 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type)
IN USHORT Access)
{
/* Set the handler's address */
/* Setup the gate */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
/* Set the code segment selector */
Idt[Vector].Access = 0x8000 | (Access << 8);
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].Present = 1;
Idt[Vector].Type = Type;
}
/**

View File

@@ -67,8 +67,7 @@ namespace AR
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
IN USHORT Access);
};
}

View File

@@ -72,8 +72,7 @@ namespace AR
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
IN USHORT Access);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);

View File

@@ -22,48 +22,6 @@ namespace KE
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
};
class LowerRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
LowerRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::LowerRunLevel(RunLevel);
}
~LowerRunLevel()
{
KE::RunLevel::RaiseRunLevel(PreviousRunLevel);
}
LowerRunLevel(const LowerRunLevel&) = delete;
LowerRunLevel& operator=(const LowerRunLevel&) = delete;
};
class RaiseRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
RaiseRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::RaiseRunLevel(RunLevel);
}
~RaiseRunLevel()
{
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
}
RaiseRunLevel(const RaiseRunLevel&) = delete;
RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;
};
}
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */

View File

@@ -17,73 +17,12 @@ namespace KE
{
class SpinLock
{
private:
STATIC KSPIN_LOCK DispatcherLockQueue;
STATIC KSPIN_LOCK ExpansionLockQueue;
STATIC KSPIN_LOCK FileSystemLockQueue;
STATIC KSPIN_LOCK IoCancelLockQueue;
STATIC KSPIN_LOCK IoCompletionLockQueue;
STATIC KSPIN_LOCK IoDatabaseLockQueue;
STATIC KSPIN_LOCK IoVpbLockQueue;
STATIC KSPIN_LOCK MasterLockQueue;
STATIC KSPIN_LOCK NonPagedAllocLockQueue;
STATIC KSPIN_LOCK NonPagedPoolLockQueue;
STATIC KSPIN_LOCK PfnLockQueue;
STATIC KSPIN_LOCK SystemSpaceLockQueue;
STATIC KSPIN_LOCK TimerTableLockQueue;
STATIC KSPIN_LOCK VacbLockQueue;
STATIC KSPIN_LOCK WorkLockQueue;
public:
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTAPI VOID InitializeAllLocks();
STATIC XTAPI VOID InitializeLockQueues();
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
};
class QueuedSpinLockGuard
{
private:
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
public:
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
QueuedLockLevel = LockLevel;
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
}
~QueuedSpinLockGuard()
{
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
}
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
};
class SpinLockGuard
{
private:
PKSPIN_LOCK SpinLock;
public:
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
{
KE::SpinLock::AcquireSpinLock(SpinLock);
}
~SpinLockGuard()
{
KE::SpinLock::ReleaseSpinLock(SpinLock);
}
SpinLockGuard(const SpinLockGuard&) = delete;
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
};
}

View File

@@ -19,8 +19,6 @@
#include <rtl/llist.hh>
#include <rtl/math.hh>
#include <rtl/memory.hh>
#include <rtl/sha1.hh>
#include <rtl/slist.hh>
#include <rtl/string.hh>
#include <rtl/widestr.hh>

View File

@@ -4,7 +4,6 @@
* FILE: xtoskrnl/includes/rtl/llist.hh
* DESCRIPTION: Linked list manipulation routines
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_LLIST_HH
@@ -19,7 +18,6 @@ namespace RTL
class LinkedList
{
public:
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
@@ -29,10 +27,6 @@ namespace RTL
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
};
}

View File

@@ -1,37 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/sha1.hh
* DESCRIPTION: SHA1 computation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SHA1_HH
#define __XTOSKRNL_RTL_SHA1_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SHA1
{
public:
STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,
IN SIZE_T BufferSize,
OUT PUCHAR Digest);
private:
STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
OUT PUCHAR Digest);
STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,
IN PCUCHAR Data,
IN ULONG Length);
STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);
STATIC XTAPI VOID TransformData(IN OUT PULONG State,
IN PCUCHAR Buffer);
};
}
#endif /* __XTOSKRNL_RTL_SHA1_HH */

View File

@@ -1,39 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/slist.hh
* DESCRIPTION: Singly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SLIST_HH
#define __XTOSKRNL_RTL_SLIST_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SinglyList
{
public:
STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
};
}
#endif /* __XTOSKRNL_RTL_SLIST_HH */

View File

@@ -12,6 +12,12 @@
/* Kernel initialization block passed by boot loader */
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;
/* Kernel initial process */
EPROCESS KE::KProcess::InitialProcess;
@@ -20,54 +26,3 @@ ETHREAD KE::KThread::InitialThread = {};
/* Kernel UBSAN active frame flag */
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
/* Kernel dispatcher lock queue */
KSPIN_LOCK KE::SpinLock::DispatcherLockQueue;
/* Kernel expansion lock queue */
KSPIN_LOCK KE::SpinLock::ExpansionLockQueue;
/* Kernel file system structures lock queue */
KSPIN_LOCK KE::SpinLock::FileSystemLockQueue;
/* Kernel IO cancel lock queue */
KSPIN_LOCK KE::SpinLock::IoCancelLockQueue;
/* Kernel IO completion lock queue */
KSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;
/* Kernel IO database lock queue */
KSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;
/* Kernel IO VPB lock queue */
KSPIN_LOCK KE::SpinLock::IoVpbLockQueue;
/* Kernel cache master lock queue */
KSPIN_LOCK KE::SpinLock::MasterLockQueue;
/* Kernel non-paged allocator lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;
/* Kernel non-paged pool lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;
/* Kernel PFN lock queue */
KSPIN_LOCK KE::SpinLock::PfnLockQueue;
/* Kernel system space lock queue */
KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;
/* Kernel Timer table lock queue */
KSPIN_LOCK KE::SpinLock::TimerTableLockQueue;
/* Kernel VACB lock queue */
KSPIN_LOCK KE::SpinLock::VacbLockQueue;
/* Kernel work queue lock queue */
KSPIN_LOCK KE::SpinLock::WorkLockQueue;
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;

View File

@@ -4,7 +4,6 @@
* FILE: xtoskrnl/ke/spinlock.cc
* DESCRIPTION: Spinlocks support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
@@ -57,78 +56,6 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Initializes all kernel spinlocks.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeAllLocks()
{
/* Initialize all spin locks */
InitializeSpinLock(&DispatcherLockQueue);
InitializeSpinLock(&PfnLockQueue);
InitializeSpinLock(&SystemSpaceLockQueue);
}
/**
* Initializes spinlock queues for current processor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeLockQueues()
{
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
/* Get current processor control block */
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
/* Initialize PCB lock queues */
ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;
ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;
ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;
ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;
ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;
ControlBlock->LockQueue[PfnLock].Next = NULLPTR;
ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;
ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;
ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;
ControlBlock->LockQueue[VacbLock].Next = NULLPTR;
ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;
ControlBlock->LockQueue[MasterLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;
ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;
ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;
ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;
ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;
ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;
ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;
ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;
ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;
ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;
ControlBlock->LockQueue[BcbLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;
ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;
ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;
}
/**
* Initializes a kernel spinlock object.
*
@@ -185,29 +112,3 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
/* Add an explicit memory barrier */
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Tests a kernel spin lock.
*
* @param SpinLock
* Supplies a pointer to the kernel spin lock.
*
* @return This routine returns TRUE if the lock is free, FALSE otherwise.
*
* @since XT 1.0
*/
XTFASTCALL
BOOLEAN
TestSpinLock(IN PKSPIN_LOCK SpinLock)
{
/* Check if the lock is free */
if(*SpinLock)
{
/* Spinlock is busy, yield processor and return FALSE */
AR::CpuFunc::YieldProcessor();
return FALSE;
}
/* Spinlock is free, return TRUE */
return TRUE;
}

View File

@@ -83,7 +83,7 @@ MM::PageMap::GetPteAddress(PVOID Address)
/* Calculate offset and return PTE address */
Offset = ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) << PageMapInfo.PteShift);
return (PMMPTE)(PageMapInfo.PteBase + Offset);
return (PMMPTE)(MM_PTE_BASE + Offset);
}
/**

View File

@@ -2,7 +2,7 @@
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/llist.cc
* DESCRIPTION: Doubly linked list manipulation routines
* DESCRIPTION: Linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
@@ -10,35 +10,10 @@
/**
* Retrieves the first entry from a doubly linked list without removing it from the list.
* This routine initializes a structure representing the head of a double-linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PLIST_ENTRY
RTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead)
{
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Empty list, return NULLPTR */
return NULLPTR;
}
/* Return first entry in the list */
return ListHead->Flink;
}
/**
* Initializes a structure representing the head of a doubly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
* Pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
@@ -48,16 +23,15 @@ XTCDECL
VOID
RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)
{
/* Initialize list head */
ListHead->Blink = ListHead;
ListHead->Flink = ListHead;
}
/**
* Initializes a structure representing the head of a 32bit doubly linked list.
* This routine initializes a structure representing the head of a 32bit double-linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
* Pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
@@ -67,19 +41,18 @@ XTCDECL
VOID
RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)
{
/* Initialize list head */
ListHead->Blink = PtrToUlong(ListHead);
ListHead->Flink = PtrToUlong(ListHead);
}
/**
* Inserts an entry at the head of a doubly linked list.
* This routine inserts an entry at the head of a doubly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
* Pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
* Pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
@@ -90,7 +63,6 @@ VOID
RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
/* Insert entry at the head of the list */
Entry->Flink = ListHead->Flink;
Entry->Blink = ListHead;
ListHead->Flink->Blink = Entry;
@@ -98,13 +70,13 @@ RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
}
/**
* Inserts an entry at the tail of a doubly linked list.
* This routine inserts an entry at the tail of a doubly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
* Pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
* Pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
@@ -115,7 +87,6 @@ VOID
RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
/* Insert entry at the tail of the list */
Entry->Flink = ListHead;
Entry->Blink = ListHead->Blink;
ListHead->Blink->Flink = Entry;
@@ -126,9 +97,9 @@ RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
* Pointer to a structure that represents the head of the list.
*
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
* @return TRUE if there are currently no entries in the list or FALSE otherwise.
*
* @since XT 1.0
*/
@@ -136,15 +107,14 @@ XTCDECL
BOOLEAN
RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)
{
/* Check if the list is empty */
return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));
}
/**
* Detects a loop in a doubly linked list.
* This routine detects a loop in a doubly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
* Pointer to a structure that represents the head of the list.
*
* @return TRUE if linked list contains a loop or FALSE otherwise.
*
@@ -187,10 +157,10 @@ RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead)
}
/**
* Removes an entry from a doubly linked list.
* This routine removes an entry from a doubly linked list.
*
* @param Entry
* Supplies a pointer to the entry that will be removed from the list.
* Pointer to the entry that will be removed from the list.
*
* @return This routine does not return any value.
*
@@ -200,91 +170,6 @@ XTCDECL
VOID
RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)
{
/* Remove entry from the list */
Entry->Flink->Blink = Entry->Blink;
Entry->Blink->Flink = Entry->Flink;
}
/**
* Splices a doubly linked list at the head of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @param SpliceList
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList)
{
PLIST_ENTRY FirstEntry, LastEntry;
/* Check if the list to splice is empty */
if(SpliceList->Flink == SpliceList)
{
/* Nothing to splice, return */
return;
}
/* Get first and last entries of the list to splice */
FirstEntry = SpliceList->Flink;
LastEntry = SpliceList->Blink;
/* Splice the list at the head of destination */
FirstEntry->Blink = ListHead;
LastEntry->Flink = ListHead->Flink;
ListHead->Flink->Blink = LastEntry;
ListHead->Flink = FirstEntry;
/* Reinitialize the source list to empty */
SpliceList->Blink = SpliceList;
SpliceList->Flink = SpliceList;
}
/**
* Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to the head of the destination list.
*
* @param SpliceList
* Supplies a pointer to the head of the list that will be spliced.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList)
{
PLIST_ENTRY FirstEntry, LastEntry;
/* Check if the list to splice is empty */
if(SpliceList->Flink == SpliceList)
{
/* Nothing to splice, return */
return;
}
/* Get first and last entries of the list to splice */
FirstEntry = SpliceList->Flink;
LastEntry = SpliceList->Blink;
/* Splice the list at the tail of destination */
FirstEntry->Blink = ListHead->Blink;
LastEntry->Flink = ListHead;
ListHead->Blink->Flink = FirstEntry;
ListHead->Blink = LastEntry;
/* Reinitialize the source list to empty */
SpliceList->Blink = SpliceList;
SpliceList->Flink = SpliceList;
}

View File

@@ -1,322 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/sha1.cc
* DESCRIPTION: SHA1 computation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Computes the SHA-1 hash of a buffer in a single step.
*
* @param Buffer
* Supplies a pointer to the buffer containing the data to be hashed.
*
* @param BufferSize
* Specifies the size of the buffer in bytes.
*
* @param Digest
* Supplies a pointer to the buffer that receives the 20-byte SHA-1 hash digest.
*
* @return This routine returns STATUS_SUCCESS if the hash was computed successfully,
* or STATUS_INVALID_PARAMETER if an invalid parameter was supplied.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
RTL::SHA1::ComputeDigest(IN PCUCHAR Buffer,
IN SIZE_T BufferSize,
OUT PUCHAR Digest)
{
RTL_SHA1_CONTEXT Context;
XTSTATUS Status;
/* Validate input parameters */
if(!Digest || (!Buffer && BufferSize > 0))
{
/* Invalid parameters, return error */
return STATUS_INVALID_PARAMETER;
}
/* Initialize SHA-1 context */
Status = InitializeContext(&Context);
if(Status != STATUS_SUCCESS)
{
/* Failed to initialize SHA-1 context, return error */
return Status;
}
/* Hash data and compute SHA-1 digest */
HashData(&Context, Buffer, BufferSize);
ComputeHash(&Context, Digest);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Finalizes the SHA-1 hash computation and provides the digest.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure.
*
* @param Digest
* Supplies a pointer to a buffer that receives the 20-byte SHA-1 hash digest.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
OUT PUCHAR Digest)
{
ULONG Index, PaddingLength;
UCHAR Padding[64];
UCHAR Bits[8];
/* Zero padding and append 0x80 to it */
RTL::Memory::ZeroMemory(Padding, 64);
Padding[0] = 0x80;
/* Encode the total message length in bits as a Big Endian 64-bit integer */
*(PULONG)(Bits) = RTL::Endianness::SwapByte32(Context->Count[1]);
*(PULONG)(Bits + 4) = RTL::Endianness::SwapByte32(Context->Count[0]);
/* Calculate padding length needed to align the message to 56 bytes */
Index = (Context->Count[0] >> 3) & 0x3F;
PaddingLength = (Index < 56) ? (56 - Index) : (120 - Index);
/* Append the padding bytes to the message stream to satisfy the block boundary */
HashData(Context, Padding, PaddingLength);
/* Append bits before final transformation */
HashData(Context, Bits, 8);
/* Store hash to output in Big Endian format */
Digest[0] = (UCHAR)((Context->State[0] >> 24) & 0xFF);
Digest[1] = (UCHAR)((Context->State[0] >> 16) & 0xFF);
Digest[2] = (UCHAR)((Context->State[0] >> 8) & 0xFF);
Digest[3] = (UCHAR)(Context->State[0] & 0xFF);
Digest[4] = (UCHAR)((Context->State[1] >> 24) & 0xFF);
Digest[5] = (UCHAR)((Context->State[1] >> 16) & 0xFF);
Digest[6] = (UCHAR)((Context->State[1] >> 8) & 0xFF);
Digest[7] = (UCHAR)(Context->State[1] & 0xFF);
Digest[8] = (UCHAR)((Context->State[2] >> 24) & 0xFF);
Digest[9] = (UCHAR)((Context->State[2] >> 16) & 0xFF);
Digest[10] = (UCHAR)((Context->State[2] >> 8) & 0xFF);
Digest[11] = (UCHAR)(Context->State[2] & 0xFF);
Digest[12] = (UCHAR)((Context->State[3] >> 24) & 0xFF);
Digest[13] = (UCHAR)((Context->State[3] >> 16) & 0xFF);
Digest[14] = (UCHAR)((Context->State[3] >> 8) & 0xFF);
Digest[15] = (UCHAR)(Context->State[3] & 0xFF);
Digest[16] = (UCHAR)((Context->State[4] >> 24) & 0xFF);
Digest[17] = (UCHAR)((Context->State[4] >> 16) & 0xFF);
Digest[18] = (UCHAR)((Context->State[4] >> 8) & 0xFF);
Digest[19] = (UCHAR)(Context->State[4] & 0xFF);
/* Clear context memory for security */
RTL::Memory::ZeroMemory(Context, sizeof(RTL_SHA1_CONTEXT));
}
/**
* Updates the SHA-1 context with the provided data buffer.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure.
*
* @param Data
* Supplies a pointer to the buffer containing the data to be hashed.
*
* @param Length
* Specifies the length of the data buffer in bytes.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::HashData(IN OUT PRTL_SHA1_CONTEXT Context,
IN PCUCHAR Data,
IN ULONG Length)
{
ULONG Index, Input, PartialLength;
/* Calculate byte offset within the 64-byte block buffer */
Index = (Context->Count[0] >> 3) & 0x3F;
/* Update the total bit count, handling overflow from low to high word */
if((Context->Count[0] += (Length << 3)) < (Length << 3))
{
/* Increment high 32-bit counter on low counter overflow */
Context->Count[1]++;
}
/* Add the high-order bits of the length (bytes -> bits overflow) to the high counter */
Context->Count[1] += (Length >> 29);
/* Calculate the number of bytes required to fill the remaining buffer space */
PartialLength = 64 - Index;
/* Transform as many times as possible */
if(Length >= PartialLength)
{
/* Fill the buffer partially and transform */
RTL::Memory::CopyMemory(&Context->Buffer[Index], Data, PartialLength);
TransformData(Context->State, Context->Buffer);
/* Process remaining full 64-byte blocks directly from the input pointer */
for(Input = PartialLength; Input + 63 < Length; Input += 64)
{
/* Transform the full block without copying to the internal buffer */
TransformData(Context->State, &Data[Input]);
}
/* Reset buffer index to indicate the buffer is now empty */
Index = 0;
}
else
{
/* No full block was formed, begin copying from the start of input */
Input = 0;
}
/* Buffer remaining input */
RTL::Memory::CopyMemory(&Context->Buffer[Index], &Data[Input], Length - Input);
}
/**
* Initializes a SHA-1 context structure with the standard initial hash values.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure to initialize.
*
* @return This routine returns STATUS_SUCCESS if the context was initialized successfully,
* or STATUS_INVALID_PARAMETER if the pointer is NULLPTR.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
RTL::SHA1::InitializeContext(OUT PRTL_SHA1_CONTEXT Context)
{
/* Validate input parameter */
if(!Context)
{
/* Invalid parameter, return error */
return STATUS_INVALID_PARAMETER;
}
/* Initialize hash constants defined by FIPS 180-4 */
Context->State[0] = 0x67452301;
Context->State[1] = 0xEFCDAB89;
Context->State[2] = 0x98BADCFE;
Context->State[3] = 0x10325476;
Context->State[4] = 0xC3D2E1F0;
Context->Count[0] = 0;
Context->Count[1] = 0;
/* Clear buffer */
RTL::Memory::ZeroMemory(Context->Buffer, SHA1_BLOCK_SIZE);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Transforms a single 64-byte block using the SHA-1 compression function.
*
* @param State
* Supplies a pointer to the array containing the current hash state variables.
*
* @param Buffer
* Supplies a pointer to the 64-byte input buffer to be transformed.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::TransformData(IN OUT PULONG State,
IN PCUCHAR Buffer)
{
ULONG Constant, Function, Index, TempHash;
ULONG TempState[5];
ULONG Stack[80];
/* Initialize working variables with current state */
TempState[0] = State[0];
TempState[1] = State[1];
TempState[2] = State[2];
TempState[3] = State[3];
TempState[4] = State[4];
/* Initialize the first 16 words of the message schedule from the input buffer */
for(Index = 0; Index < 16; Index++)
{
/* Convert input words from Little Endian to Big Endian required by SHA-1 */
Stack[Index] = RTL::Endianness::SwapByte32(((const PULONG)Buffer)[Index]);
}
/* Expand the message to 80 words using the SHA-1 algorithm */
for(Index = 16; Index < 80; Index++)
{
/* Compute the next word value based on XOR and left rotation */
Stack[Index] = ROTATE_LEFT((Stack[Index - 3] ^ Stack[Index - 8] ^ Stack[Index - 14] ^ Stack[Index - 16]), 1);
}
/* Execute the main compression loop for 80 rounds */
for(Index = 0; Index < 80; Index++)
{
/* Determine the logical function and constant based on the current round */
if(Index < 20)
{
/* Set the constant defined by FIPS 180-4 for rounds 0-19 and calculate the logical function */
Constant = 0x5A827999;
Function = (TempState[1] & TempState[2]) | ((~TempState[1]) & TempState[3]);
}
else if(Index < 40)
{
/* Set the constant defined by FIPS 180-4 for rounds 20-39 and calculate the logical function */
Constant = 0x6ED9EBA1;
Function = TempState[1] ^ TempState[2] ^ TempState[3];
}
else if(Index < 60)
{
/* Set the constant defined by FIPS 180-4 for rounds 40-59 and calculate the logical function */
Constant = 0x8F1BBCDC;
Function = (TempState[1] & TempState[2]) | (TempState[1] & TempState[3]) | (TempState[2] & TempState[3]);
}
else
{
/* Set the constant defined by FIPS 180-4 for rounds 60-79 and calculate the logical function */
Constant = 0xCA62C1D6;
Function = TempState[1] ^ TempState[2] ^ TempState[3];
}
/* Calculate the temporary hash value for this round */
TempHash = ROTATE_LEFT(TempState[0], 5) + Function + TempState[4] + Constant + Stack[Index];
TempState[4] = TempState[3];
TempState[3] = TempState[2];
TempState[2] = ROTATE_LEFT(TempState[1], 30);
TempState[1] = TempState[0];
TempState[0] = TempHash;
}
/* Add the compressed chunk to the current hash value */
State[0] += TempState[0];
State[1] += TempState[1];
State[2] += TempState[2];
State[3] += TempState[3];
State[4] += TempState[4];
/* Clear sensitive data from stack */
RTL::Memory::ZeroMemory(Stack, sizeof(Stack));
}

View File

@@ -1,390 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/slist.cc
* DESCRIPTION: Singly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Retrieves the first entry from a singly linked list without removing it from the list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Empty list, return NULLPTR */
return NULLPTR;
}
/* Return first entry in the list */
return ListHead->Next.Next;
}
/**
* Initializes a structure representing the head of a singly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::SinglyList::InitializeListHead(IN PSINGLE_LIST_HEADER ListHead)
{
/* Initialize the singly linked list head */
ListHead->Alignment = 0;
}
/**
* Inserts an entry at the head of a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine returns a pointer to the original first entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY OriginalEntry;
/* Store the original first entry */
OriginalEntry = ListHead->Next.Next;
/* Insert entry at the head of the list and increment depth and sequence */
Entry->Next = ListHead->Next.Next;
ListHead->Next.Next = Entry;
ListHead->Depth++;
ListHead->Sequence++;
/* Return original first entry */
return OriginalEntry;
}
/**
* Inserts an entry at the tail of a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine returns a pointer to the original last entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY CurrentEntry, OriginalEntry;
/* Set Next pointer of the new entry to NULLPTR */
Entry->Next = NULLPTR;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Store the original last entry */
OriginalEntry = ListHead->Next.Next;
/* Insert entry at the head */
ListHead->Next.Next = Entry;
}
else
{
/* Traverse the list to find the last entry */
CurrentEntry = ListHead->Next.Next;
while(CurrentEntry->Next != NULLPTR)
{
/* Move to the next entry */
CurrentEntry = CurrentEntry->Next;
}
/* Store the original last entry */
OriginalEntry = CurrentEntry;
/* Insert entry at the tail */
CurrentEntry->Next = Entry;
}
/* Increment list depth and sequence */
ListHead->Depth++;
ListHead->Sequence++;
/* Return original last entry */
return OriginalEntry;
}
/**
* Indicates whether a singly linked list structure is empty, or not initialized at all.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
RTL::SinglyList::ListEmpty(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list is empty */
return (ListHead == NULLPTR || ListHead->Next.Next == NULLPTR);
}
/**
* Queries the current depth (number of entries) of a singly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the singly linked list.
*
* @return This routine returns the number of entries currently in the list, or zero if the list head is NULLPTR.
*
* @since XT 1.0
*/
XTAPI
USHORT
RTL::SinglyList::QueryListDepth(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list head is initialized and valid */
if(ListHead == NULLPTR)
{
/* Return zero */
return 0;
}
/* Return the list depth */
return ListHead->Depth;
}
/**
* Removes an entry from a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be removed from the list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::SinglyList::RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY PreviousEntry;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* List is empty, nothing to remove, return */
return;
}
/* Check if the entry is the first one */
if(ListHead->Next.Next == Entry)
{
/* Remove the first entry and decrement depth */
ListHead->Next.Next = Entry->Next;
ListHead->Depth--;
/* Nothing else to do, return */
return;
}
/* Find the previous entry */
PreviousEntry = ListHead->Next.Next;
while(PreviousEntry->Next != Entry)
{
/* Move to the next entry */
PreviousEntry = PreviousEntry->Next;
/* Check if we reached the end of the list */
if(PreviousEntry == NULLPTR)
{
/* Entry not found, return */
return;
}
}
/* Remove the entry and decrement depth */
PreviousEntry->Next = Entry->Next;
ListHead->Depth--;
}
/**
* Splices a singly linked list at the head of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @param SpliceList
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
*
* @return This routine returns a pointer to the original first entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList)
{
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
/* Store the original last entry */
OriginalEntry = ListHead->Next.Next;
/* Check if the list to splice is empty */
if(ListEmpty(SpliceList))
{
/* Nothing to splice, return original first entry */
return OriginalEntry;
}
/* Find the last entry of the list to splice */
LastEntry = SpliceList->Next.Next;
while(LastEntry->Next != NULLPTR)
{
/* Move to the next entry */
LastEntry = LastEntry->Next;
}
/* Splice the list at the head of destination */
LastEntry->Next = ListHead->Next.Next;
ListHead->Next.Next = SpliceList->Next.Next;
/* Update depth and sequence of the destination list */
ListHead->Depth += SpliceList->Depth;
ListHead->Sequence++;
/* Reinitialize the source list to empty */
SpliceList->Next.Next = NULLPTR;
SpliceList->Depth = 0;
/* Return the original last entry */
return OriginalEntry;
}
/**
* Splices a singly linked list at the tail of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to the head of the destination list.
*
* @param SpliceList
* Supplies a pointer to the head of the list that will be spliced.
*
* @return This routine returns a pointer to the original last entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList)
{
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
/* Check if the destination list is empty */
if(ListEmpty(ListHead))
{
/* Destination is empty, original last entry is NULLPTR */
OriginalEntry = NULLPTR;
/* Move the splice list to the destination head */
ListHead->Next.Next = SpliceList->Next.Next;
}
else
{
/* Find the last entry of the destination list */
LastEntry = ListHead->Next.Next;
while(LastEntry->Next != NULLPTR)
{
/* Move to the next entry */
LastEntry = LastEntry->Next;
}
/* Store the original last entry */
OriginalEntry = LastEntry;
/* Splice the list at the tail of destination */
LastEntry->Next = SpliceList->Next.Next;
}
/* Update depth and sequence of the destination list */
ListHead->Depth += SpliceList->Depth;
ListHead->Sequence++;
/* Reinitialize the source list to empty */
SpliceList->Next.Next = NULLPTR;
SpliceList->Depth = 0;
/* Return the original last entry */
return OriginalEntry;
}
/**
* Retrieves the first entry from a singly linked list and removes it from the list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
{
PSINGLE_LIST_ENTRY Entry;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* List is empty, return NULLPTR */
return NULLPTR;
}
/* Get the first entry */
Entry = ListHead->Next.Next;
/* Remove entry from the list */
ListHead->Next.Next = Entry->Next;
ListHead->Depth--;
/* Return the first entry */
return Entry;
}