提交 38e78095 创建 作者: 赵鹏翀's avatar 赵鹏翀

Initial commit

上级
/*.img
/bochs
/Debug
/Release
*.bak
*.lst
*.o
\ No newline at end of file
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: 8253.c
描述: PC 机 8253 可编程定时计数器 (Programmable Interval Timer) 的初始化。
*******************************************************************************/
#include "ki.h"
VOID
KiInitializePit(
VOID
)
{
//
// 初始化 8253 每秒钟中断 100 次。
//
WRITE_PORT_UCHAR((PUCHAR)0x43, 0x34);
WRITE_PORT_UCHAR((PUCHAR)0x40, (UCHAR)(11932 & 0xFF));
WRITE_PORT_UCHAR((PUCHAR)0x40, (UCHAR)((11932 >> 8) & 0xFF));
//
// 打开 8253 中断。
//
KeEnableDeviceInterrupt(INT_TIMER, TRUE);
}
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: 8259.c
描述: PC 机 8259 可编程中断控制器 (Programmable Interrupt Controller) 的控制。
*******************************************************************************/
#include "ki.h"
//
// 8259 可编程中断控制器 (PIC) 的寄存器地址
//
#define PIC1_PORT0 0x20 // master PIC
#define PIC1_PORT1 0x21
#define PIC2_PORT0 0x0A0 // slave PIC
#define PIC2_PORT1 0x0A1
//
// 8259 可编程中断控制器 (PIC) 的命令
//
#define PIC1_EOI_MASK 0x60
#define PIC2_EOI 0x62
#define OCW2_NON_SPECIFIC_EOI 0x20
#define OCW3_READ_ISR 0xb
#define OCW3_READ_IRR 0xa
VOID
KiInitializePic(
VOID
)
/*++
功能描述:
初始化8259可编程中断控制器。
参数:
无。
返回值:
无。
--*/
{
ASSERT((PIC1_VECTOR & 0x07) == 0);
ASSERT((PIC2_VECTOR & 0x07) == 0);
//
// 初始化 PIC
//
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT0, 0x11); // Master, ICW1.
WRITE_PORT_UCHAR((PUCHAR)PIC2_PORT0, 0x11); // Slave, ICW1.
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT1, PIC1_VECTOR); // Master, ICW2. Set int number as PIC1_VECTOR.
WRITE_PORT_UCHAR((PUCHAR)PIC2_PORT1, PIC2_VECTOR); // Slave, ICW2. Set int number as PIC2_VECTOR.
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT1, 0x04); // Master, ICW3. IR2 -> slave.
WRITE_PORT_UCHAR((PUCHAR)PIC2_PORT1, 0x02); // Slave, ICW3. -> master IR2.
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT1, 0x01); // Master, ICW4.
WRITE_PORT_UCHAR((PUCHAR)PIC2_PORT1, 0x01); // Slave, ICW4.
//
// 关闭所有设备的中断
//
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT1, 0xFF); // Master 8259, OCW1.
WRITE_PORT_UCHAR((PUCHAR)PIC2_PORT1, 0xFF); // Slave 8259, OCW1.
}
VOID
KeEnableDeviceInterrupt(
ULONG IntVector,
BOOL Enable
)
/*++
功能描述:
屏蔽或允许指定外部设备的中断请求。
参数:
IntVector -- 外部设备的中断向量号。
Enable -- TRUE 则允许中断请求,FALSE 则屏蔽中断请求。
返回值:
无。
--*/
{
PUCHAR Port;
UCHAR OCW1;
ASSERT(PIC1_VECTOR == (IntVector & ~0x07) ||
PIC2_VECTOR == (IntVector & ~0x07));
//
// 根据设备中断号选择相应的 PIC 的端口地址。
//
if (PIC1_VECTOR == (IntVector & ~0x07)) {
Port = (PUCHAR)PIC1_PORT1;
} else if (PIC2_VECTOR == (IntVector & ~0x07)) {
Port = (PUCHAR)PIC2_PORT1;
}
//
// 读取 OCW1 状态字。
//
OCW1 = READ_PORT_UCHAR(Port);
//
// 根据开关动作要求,修改 OCW1 对应的状态位。
//
if (Enable) {
OCW1 = OCW1 & ~(1 << (IntVector & 0x07));
} else {
OCW1 = OCW1 | (1 << (IntVector & 0x07));
}
//
// 回写 OCW1 状态字
//
WRITE_PORT_UCHAR(Port, OCW1);
}
VOID
Ki8259EOI(
VOID
)
/*++
功能描述:
向 8259 发送中断结束命令。
参数:
无。
返回值:
无。
警告:
不要在此函数中插入断点。即使调试到此函数中,也不要使用“逐过程”
或者“跳出”等单步调试功能,这些操作会产生不可预测的调试结果。
建议使用“继续调试”功能继续调试。
--*/
{
WRITE_PORT_UCHAR((PUCHAR)PIC1_PORT0, 0x20);
}
EOS 核心源代码协议
允许所有人复制和发布本协议文件的完整版本,但不允许对它进行任何修改。
该协议用于控制与之配套的软件,并且管理您使用遵守该协议软件的方法。下面授予
您的各项权利受限于该协议。只有当您是合格的教育机构并且从北京英真时代科技有限
公司购买了该软件授权时才能够享有这些权利。
在您的教育机构中,您可以为了任何非商业的目的来使用、修改该软件,包括制作合理
数量的拷贝。非商业的目的可以是教学、科研以及个人的实验行为。您可以将拷贝发布
到机构内部安全的服务器上,并且可以在合格用户的个人主机上安装。
您可以在研究论文、书籍或者其他教育资料中使用该软件的代码片断,或者在以教学和
研究为目的的网站、在线公共论坛中发布该软件的代码片断。在您使用的单个代码片断
中源代码的数量不能超过 50 行。如您想使用该软件中的大量源代码,
请联系 support@tevation.com。
您不能为了商业目的使用或者分发该软件以及从该软件衍生出的任何形式的任何产品。
商业目的可以是经营、许可、出售该软件或者为了在商业产品中使用该软件而分发该软件。
如果您希望将您的与该软件有关的产品商业化,或者希望与工业伙伴合作研究,您需要
联系 sales@tevation.com 来咨询商业授权协议。
您可以为了非商业的目的分发该软件并且修改该软件,但是只能是对于其他该软件的合法
用户(例如,将修改的版本分发给其他大学的学生或者教授进行联合学术研究)。只有从
北京英真时代科技有限公司购买了该软件授权的合格教育机构,才是合法用户。您不能为
该软件或者该软件的衍生产品授予比该协议所提供的更加广泛的权利。
您还必须遵守下面的条款:
1. 您不会从该软件中移除任何版权信息或者布告,也不会对该软件中的二进制部分进行
逆向工程或者反编译。
2. 无论您以任何形式分发该软件,您都必须同时分发该协议。
3. 如果您修改了该软件或者创造了该软件的衍生产品,并且分发了修改后的版本或者衍生
产品,您需要在被修改文件中的显著位置添加布告来说明您修改的内容和修改日期,这样
接收者就会知道他们收到的不是原始的软件。
4. 该软件没有任何担保,包括明示的、暗喻的。在适用法律所允许的最大范围
内,北京英真时代科技有限公司或其供应商绝不就因使用或不能使用本“软件”所引起的或
有关的任何间接的、意外的、直接的、非直接的、特殊的、惩罚性的或其它任何损害赔偿
(包括但不限于因人身伤害或财产损坏而造成的损害赔偿,因利润损失、营业中断、商业
信息的遗失而造成的损害赔偿,因未能履行包括诚信或相当注意在内的任何责任致使隐私
泄露而造成的损害赔偿,因疏忽而造成的损害赔偿,或因任何金钱上的损失或任何其它损失
而造成的损害赔偿)承担赔偿责任,即使北京英真时代科技有限公司或其任何供应商事先被
告知该损害发生的可能性。即使补救措施未能达到预定目的,本损害赔偿排除条款将仍然有
效。
5. 您不能使用该软件来帮助开发任何为下列目的而设计的软件程序: (a) 对计算机系统有害
的或者故意干扰操作的,包括计算机系统中的任何数据和信息;(b) 秘密获取或者维持对计算
机系统高级访问权限,有自我繁殖能力,能够在不被发现的情况下执行,包括但不限于所谓
的 "rootkit" 软件程序,病毒或者蠕虫。
6. 如果您以任何方式违背了此协议,此协议赋予您的权利就会立即终止。
7. 北京英真时代科技有限公司保留在此协议中明确授予您的权利之外的所有权利。
版本: 2008.09.16
(C) 2008 北京英真时代科技有限公司(http://www.engintime.com)。保留所有权利。
差异被折叠。
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: bugcheck.c
描述: PC 机 KeBugCheck 的实现,KeBugCheck 依赖硬件平台。
*******************************************************************************/
#include "ki.h"
//
// VGA缓冲位置,和内存映射相关。
//
#define VGA_BUFFER 0x800B8000
VOID
KeBugCheck(
IN PCSTR Format,
...
)
{
PCHAR DestPtr, SrcPtr;
PULONG Pos;
va_list argptr;
//
// 关闭中断。
//
KeEnableInterrupts(FALSE);
//
// 从第0页开始显示。
//
WRITE_PORT_UCHAR((PUCHAR)0x03D4, (UCHAR)0x0C);
WRITE_PORT_UCHAR((PUCHAR)0x03D5, (UCHAR)0x00);
WRITE_PORT_UCHAR((PUCHAR)0x03D4, (UCHAR)0x0D);
WRITE_PORT_UCHAR((PUCHAR)0x03D5, (UCHAR)0x00);
//
// 隐藏光标(放到第二页)。
//
WRITE_PORT_UCHAR((PUCHAR)0x03D4, (UCHAR)0x0E);
WRITE_PORT_UCHAR((PUCHAR)0x03D5, (UCHAR)0x07);
WRITE_PORT_UCHAR((PUCHAR)0x03D4, (UCHAR)0x0F);
WRITE_PORT_UCHAR((PUCHAR)0x03D5, (UCHAR)0xD0);
//
// 刷第一页的缓冲区为蓝底白字。
//
for(Pos = (PULONG)VGA_BUFFER; Pos < (PULONG)VGA_BUFFER + 1000; Pos++) {
*Pos = 0x1F001F00;
}
//
// 格式化字符串,用第二页视频缓冲区作为格式化输出缓冲区。
//
va_start(argptr, Format);
vsprintf((PCHAR)VGA_BUFFER + 4000, Format, argptr);
//
// 显示标题。
//
DestPtr = (PCHAR)VGA_BUFFER;
SrcPtr = "This Message is print by KeBugCheck().";
while(*SrcPtr != 0)
{
*DestPtr = *SrcPtr++;
DestPtr += 2;
}
//
// 显示正文。
//
DestPtr = (PCHAR)VGA_BUFFER + 160;
for (SrcPtr = (PCHAR)VGA_BUFFER + 4000; *SrcPtr!=0; SrcPtr++)
{
if ('\n' == *SrcPtr)
{
DestPtr = DestPtr - (DestPtr - (PCHAR)VGA_BUFFER) % 160 + 80;
}
else if ('\t' == *SrcPtr)
{
DestPtr = (PCHAR)(((ULONG_PTR)DestPtr + 0x10) & ~0xF);
}
else
{
*DestPtr = *SrcPtr;
DestPtr += 2;
}
}
/* 死循环。*/
while(1);
}
差异被折叠。
;***
;
; Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
;
; 只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
; 如果您不接受,不能使用这些代码。
;
; 文件名: cpu.asm
;
; 描述:
;
;
;
;*******************************************************************************/
;
; 导出符号
;
global _KiInitializeProcessor
global _KeCodeSegmentSelector
global _KeDataSegmentSelector
global _Gdt
global _CsDesc
global _DsDesc
;
; 用于定义 i386 描述符的宏,三个参数分别是 基址、界限、属性(属性见下面定义)
;
%macro Descriptor 3
dw %2 & 0xFFFF ; 段界限 1 (2 字节)
dw %1 & 0xFFFF ; 段基址 1 (2 字节)
db (%1 >> 16) & 0xFF ; 段基址 2 (1 字节)
dw ((%2 >> 8) & 0x0F00) | (%3 & 0xF0FF); 属性 1 + 段界限 2 + 属性 2 (2 字节)
db (%1 >> 24) & 0xFF ; 段基址 3 (1 字节)
%endmacro ; 共 8 字节
;
; 描述符属性
;
DA_32 equ 0x4000 ; 32 位段
DA_LIMIT_4K equ 0x8000 ; 段界限粒度为 4K 字节
DA_DRW equ 0x92 ; 存在的可读写数据段属性值
DA_CR equ 0x9A ; 存在的可执行可读代码段属性值
[section .data]
;
; 定义全局描述符表
;
; 段基址, 段界限, 属性
_Gdt: Descriptor 0, 0, 0 ; 空描述符
_CsDesc: Descriptor 0, 0x0FFFFF, DA_CR | DA_32 | DA_LIMIT_4K ; 0 ~ 4G 的代码段
_DsDesc: Descriptor 0, 0x0FFFFF, DA_DRW | DA_32 | DA_LIMIT_4K ; 0 ~ 4G 的数据段
GDT_SIZE equ $ - _Gdt ; 全局描述符表的长度
_KeCodeSegmentSelector dw _CsDesc - _Gdt ; 代码段选择子
_KeDataSegmentSelector dw _DsDesc - _Gdt ; 数据段选择子
[section .text]
_KiInitializeProcessor:
;{
push ebp
mov ebp, esp
;
; 加载全局描述符表。
;
push dword _Gdt
push word GDT_SIZE
lgdt [esp]
add esp, 6
;
; 设置代码段和数据段的选择子。
; 注意:设置代码段选择子只能通过一个长跳转实现。
;
jmp dword (_CsDesc - _Gdt):.SET_DS
.SET_DS:
mov ax, (_DsDesc - _Gdt)
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
leave
ret
;}
差异被折叠。
差异被折叠。
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: dispatch.c
描述: Inerrupt dispatch module for the KE subcomponent of EOS
*******************************************************************************/
#include "ki.h"
#include "ps.h"
//
// 向 8259 发送 EOI 命令
//
VOID
Ki8259EOI(
VOID
);
//
// 外设中断处理函数指针。
//
ISR KeIsrClock = NULL;
ISR KeIsrKeyBoard = NULL;
ISR KeIsrCom1 = NULL;
ISR KeIsrCom2 = NULL;
ISR KeIsrLPT1 = NULL;
ISR KeIsrLPT2 = NULL;
ISR KeIsrFloppy = NULL;
ISR KeIsrHD = NULL;
ISR KeIsrFPU = NULL;
ISR KeIsrPS2 = NULL;
VOID
KiDispatchInterrupt(
ULONG IntNumber
)
/*++
功能描述:
派遣外设中断给适当的中断处理程序。
参数:
IntNumber - 当前中断向量号。
返回值:
无。
--*/
{
//
// 根据向量号调用相应的中断处理程序。如果中断处理程序指针为NULL,则忽略之。
//
switch (IntNumber)
{
case INT_TIMER:
KiIsrTimer();
break;
case INT_KEYBOARD:
if (NULL != KeIsrKeyBoard)
KeIsrKeyBoard();
break;
case INT_COM2:
if (NULL != KeIsrCom2)
KeIsrCom2();
break;
case INT_COM1:
if (NULL != KeIsrCom1)
KeIsrCom1();
break;
case INT_LPT2:
if (NULL != KeIsrLPT2)
KeIsrLPT2();
break;
case INT_FLOPPY:
if (NULL != KeIsrFloppy)
KeIsrFloppy();
break;
case INT_LPT1:
if (NULL != KeIsrLPT1)
KeIsrLPT1();
break;
case INT_CLOCK:
if (NULL != KeIsrClock)
KeIsrClock();
break;
case INT_PS2:
if (NULL != KeIsrPS2)
KeIsrPS2();
break;
case INT_FPU:
if (NULL != KeIsrFPU)
KeIsrFPU();
break;
case INT_HD:
if (NULL != KeIsrHD)
KeIsrHD();
break;
default:
ASSERT(FALSE);
break;
}
//
// 发送 EOI 命令给可编程中断控制器 8259。
// 警告:
// 不要在此行代码处插入断点。即使调试到此行代码,也不要使用“逐过程”
// 单步调试,此操作会产生不可预测的调试结果。建议使用“继续调试”功
// 能继续调试。
Ki8259EOI();
}
BOOL
KiDispatchException(
ULONG ExceptionNumber,
ULONG ErrorCode,
PCONTEXT Context
)
/*++
功能描述:
派遣异常给适当的异常处理程序。
参数:
ExceptionNumber - 异常向量号。
ErrorCode - 异常错误码。
Context - 发生异常的CPU上下文环境。
返回值:
FALSE:从异常返回线程时不要执行线程调度。
TRUE:从异常返回线程时需要执行线程调度。
警告:
在此函数中的任何位置插入断点都会造成调试失败。
--*/
{
//
// 非调试情况下,如果是中断服务程序产生了异常则直接蓝屏,否则交由进程管理器
// 处理线程产生的异常。
// 注意:中断深度大于0则说明当前执行在中断环境中。由于异常处理也是执行在中断
// 环境中的,所以如果是中断服务程序产生异常则会嵌套进入异常处理中断服务程序。
// 这时得到的中断深度应大于1。
//
if (KeGetIntNesting() > 1) {
KeBugCheck( "Interrupt service routine error!\n\
Exception number is %d.\n\
Error code is %d.\n\
Register value:\n\
\tEAX:0x%.8X\tEBX:0x%.8X\tECX:0x%.8X\n\
\tEDX:0x%.8X\tESI:0x%.8X\tEDI:0x%.8X\n\
\tESP:0x%.8X\tEBP:0x%.8X\tEIP:0x%.8X\n\
\tEFLAGS:0x%.8X\n\
\tCS:0x%.4X\tSS:0x%.4X\tDS:0x%.4X\n\
\tES:0x%.4X\tFS:0x%.4X\tGS:0x%.4X\n",
ExceptionNumber, ErrorCode,
Context->Eax, Context->Ebx, Context->Ecx,
Context->Edx, Context->Esi, Context->Edi,
Context->Esp, Context->Ebp, Context->Eip,
Context->EFlag,
Context->SegCs, Context->SegSs, Context->SegDs,
Context->SegEs, Context->SegFs, Context->SegGs );
} else {
PsHandleException(ExceptionNumber, ErrorCode, Context);
}
return TRUE;
}
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: eos.h
描述: EOS 内核导出头文件,EOS 应用程序需包含此头文件。
*******************************************************************************/
#ifndef _EOS_
#define _EOS_
#ifdef __cplusplus
extern "C"
{
#endif
#include "eosdef.h"
#include "error.h"
EOSAPI
VOID
DebugBreak(
VOID
);
EOSAPI
BOOL
CloseHandle(
IN HANDLE Handle
);
EOSAPI
PVOID
VirtualAlloc(
IN PVOID Address,
IN SIZE_T Size,
IN ULONG AllocationType
);
EOSAPI
BOOL
VirtualFree(
IN PVOID Address,
IN SIZE_T Size,
IN ULONG FreeType
);
EOSAPI
BOOL
CreateProcess(
IN PCSTR ImageName,
IN PCSTR CmdLine,
IN ULONG CreateFlags,
IN PSTARTUPINFO StartupInfo,
OUT PPROCESS_INFORMATION ProcInfo
);
EOSAPI
HANDLE
CreateThread(
IN SIZE_T StackSize,
IN PTHREAD_START_ROUTINE StartAddr,
IN PVOID ThreadParam,
IN ULONG CreateFlags,
OUT PULONG ThreadId OPTIONAL
);
EOSAPI
HANDLE
OpenProcess(
IN ULONG ProcessId
);
EOSAPI
HANDLE
OpenThread(
IN ULONG ThreadId
);
EOSAPI
BOOL
TerminateProcess(
IN HANDLE Handle,
IN ULONG ExitCode
);
EOSAPI
BOOL
TerminateThread(
IN HANDLE Handle,
IN ULONG ExitCode
);
EOSAPI
VOID
ExitProcess(
IN ULONG ExitCode
);
EOSAPI
VOID
ExitThread(
IN ULONG ExitCode
);
EOSAPI
VOID
Sleep(
IN ULONG Milliseconds
);
EOSAPI
ULONG
GetLastError(
VOID
);
EOSAPI
VOID
SetLastError(
IN ULONG ErrCode
);
EOSAPI
HANDLE
GetStdHandle(
IN ULONG StdHandle
);
EOSAPI
VOID
GetImageNameAndCmdLine(
OUT PCHAR ImageNameBuffer,
OUT PCHAR CmdLineBuffer
);
EOSAPI
BOOL
GetExitCodeProcess(
IN HANDLE ProcessHandle,
OUT PULONG ExitCode
);
EOSAPI
BOOL
GetExitCodeThread(
IN HANDLE ThreadHandle,
OUT PULONG ExitCode
);
EOSAPI
HANDLE
CreateEvent(
IN BOOL ManualReset,
IN BOOL InitialState,
IN PCSTR Name
);
EOSAPI
BOOL
SetEvent(
IN HANDLE Handle
);
EOSAPI
BOOL
ResetEvent(
IN HANDLE Handle
);
EOSAPI
HANDLE
CreateMutex(
IN BOOL InitialOwner,
IN PCSTR Name
);
EOSAPI
BOOL
ReleaseMutex(
IN HANDLE Handle
);
EOSAPI
HANDLE
CreateSemaphore(
IN LONG InitialCount,
IN LONG MaximumCount,
IN PSTR Name
);
EOSAPI
BOOL
ReleaseSemaphore(
IN HANDLE Handle,
IN LONG ReleaseCount,
IN PLONG PreviousCount
);
EOSAPI
ULONG
WaitForSingleObject(
IN HANDLE Handle,
IN ULONG Milliseconds
);
EOSAPI
HANDLE
CreateFile(
IN PCSTR FileName,
IN ULONG DesiredAccess,
IN ULONG ShareMode,
IN ULONG CreationDisposition,
IN ULONG FlagsAndAttributes
);
EOSAPI
BOOL
ReadFile(
IN HANDLE Handle,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead
);
EOSAPI
BOOL
WriteFile(
IN HANDLE Handle,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten
);
EOSAPI
BOOL
DeleteFile(
IN PCSTR FileName
);
EOSAPI
BOOL
GetFileTime(
IN HANDLE FileHandle,
OUT PFILETIME CreationTime,
OUT PFILETIME LastAccessTime,
OUT PFILETIME LastWriteTime
);
EOSAPI
ULONG
GetFileSize(
IN HANDLE FileHandle
);
EOSAPI
ULONG
SetFilePointer(
IN HANDLE FileHandle,
IN LONG DistanceToMove,
IN ULONG MoveMethod
);
EOSAPI
ULONG
GetFileAttributes(
IN PCSTR FileName
);
EOSAPI
BOOL
SetFileAttributes(
IN PCSTR FileName,
IN ULONG FileAttributes
);
EOSAPI
BOOL
CreateDirectory(
IN PCSTR PathName
);
EOSAPI
BOOL
RemoveDirectory(
IN PCSTR PathName
);
EOSAPI
BOOL
SetConsoleCursorPosition(
IN HANDLE Handle,
IN COORD CursorPosition
);
EOSAPI
ULONG
GetCurrentThreadId(
VOID
);
EOSAPI
BOOL
SuspendThread(
IN HANDLE hThread
);
EOSAPI
BOOL
ResumeThread(
IN HANDLE hThread
);
#ifdef __cplusplus
}
#endif
#endif // _EOS_
差异被折叠。
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: error.h
描述: EOS 错误码常量的定义。
*******************************************************************************/
#ifndef _ERROR_
#define _ERROR_
#define NO_ERROR 0L
#define ERROR_FILE_NOT_FOUND 2L
#define ERROR_PATH_NOT_FOUND 3L
#define ERROR_ACCESS_DENIED 5L
#define ERROR_INVALID_HANDLE 6L
#define ERROR_NOT_ENOUGH_MEMORY 8L
#define ERROR_SHARING_VIOLATION 32L
#define ERROR_WRONG_DISK 34L
#define ERROR_NOT_SUPPORTED 50L
#define ERROR_INVALID_PARAMETER 87L
#define ERROR_PROC_NOT_FOUND 127L
#define ERROR_SIGNAL_REFUSED 156L
#define ERROR_BAD_PATHNAME 161L
#define ERROR_ALREADY_EXISTS 183L
#define ERROR_BAD_EXE_FORMAT 193L
#define ERROR_FILENAME_EXCED_RANGE 206L
#define WAIT_TIMEOUT 258L
#define ERROR_NOT_OWNER 288L
#define ERROR_TOO_MANY_POSTS 298L
#define ERROR_INVALID_ADDRESS 487L
#define ERROR_IO_PENDING 997L
#define ERROR_NOACCESS 998L
#define ERROR_FLOPPY_UNKNOWN_ERROR 1124L
#define ERROR_NOT_FOUND 1168L
#define ERROR_FILE_CORRUPT 1392L
#define ERROR_TIMEOUT 1460L
#define ERROR_INVALID_COMMAND_LINE 1639L
#define ERROR_UNKNOWN 7499L
#endif // _ERROR_
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: event.c
描述: 进程同步对象之事件的实现。
*******************************************************************************/
#include "psp.h"
VOID
PsInitializeEvent(
IN PEVENT Event,
IN BOOL ManualReset,
IN BOOL InitialState
)
/*++
功能描述:
初始化事件结构体。
参数:
Event -- 事件结构体指针。
ManualReset -- 是否初始化为手动事件。TRUE 为手动,FALSE 为自动。
InitialState -- 事件初始化的状态。TRUE 为有效,FALSE 为无效。
返回值:
无。
--*/
{
Event->IsManual = ManualReset;
Event->IsSignaled = InitialState;
ListInitializeHead(&Event->WaitListHead);
}
STATUS
PsWaitForEvent(
IN PEVENT Event,
IN ULONG Milliseconds
)
/*++
功能描述:
阻塞等待事件直到事件变为 Signaled 状态。如果等待的是自动事件,成功等待后会复位
事件为 Nonsignaled 状态。
参数:
Event -- 事件结构体指针。
Milliseconds -- 等待时间上限,如果等待超时则返回STATUS_TIMEOUT。如果为INFINIT
则永久等待直到等待成功。
返回值:
STATUS_SUCCESS表示等待成功,STATUS_TIMEOUT表示等待超时。
--*/
{
STATUS Status;
BOOL IntState;
IntState = KeEnableInterrupts(FALSE);
//
// 如果事件处于 Signaled 状态那么立刻返回成功,否则当前线程阻塞等待事件。
//
if (Event->IsSignaled) {
//
// 如果是自动事件,那么成功等待的同时还要复位事件。
//
if (!Event->IsManual) {
Event->IsSignaled = FALSE;
}
Status = STATUS_SUCCESS;
} else {
//
// 按照FCFS原则阻塞在事件等待队列的队尾。
//
Status = PspWait(&Event->WaitListHead, Milliseconds);
}
KeEnableInterrupts(IntState);
return Status;
}
VOID
PsSetEvent(
IN PEVENT Event
)
/*++
功能描述:
使事件变为 Singnaled 状态。如果事件的等待队列上有线程正在等待,等待线程将被唤醒。
参数:
Event -- 事件结构体指针。
返回值:
无。
--*/
{
BOOL IntState = KeEnableInterrupts(FALSE);
//
// 如果事件处于 Nonsignaled 状态,则修改事件为 Signaled 状态。
//
if (!Event->IsSignaled) {
Event->IsSignaled = TRUE;
while (Event->IsSignaled && !ListIsEmpty(&Event->WaitListHead)) {
//
// 事件处于 Signaled 状态且等待队列非空,按照 FCFS 的原则唤醒等待队列的队首线程。
//
PspWakeThread(&Event->WaitListHead, STATUS_SUCCESS);
//
// 如果是自动事件,那么在通知一个线程后事件即被复位(变为 Nonsignaled 状态)。
//
if (!Event->IsManual) {
Event->IsSignaled = FALSE;
}
}
//
// 可能有线程被唤醒,执行线程调度。
//
PspThreadSchedule();
}
KeEnableInterrupts(IntState);
}
VOID
PsResetEvent(
IN PEVENT Event
)
/*++
功能描述:
复位事件状态为 Nonsignaled 状态。
参数:
Event -- 事件结构体指针。
返回值:
无。
--*/
{
BOOL IntState = KeEnableInterrupts(FALSE);
Event->IsSignaled = FALSE;
KeEnableInterrupts(IntState);
}
//////////////////////////////////////////////////////////////////////////
//
// 下面是和事件对象类型相关的代码。
//
//
// 事件对象类型指针。
//
POBJECT_TYPE PspEventType;
VOID
PspOnCreateEventObject(
IN PVOID EventObject,
IN ULONG_PTR CreateParam
)
/*++
功能描述:
事件对象的构造函数,被ObCreateObject调用。
参数:
EventObject -- 新创建的事件对象的指针。
CreateParam -- 构造参数,位0标志是否为手动事件,位1标志初始状态。
返回值:
无。
--*/
{
PsInitializeEvent( (PEVENT)EventObject,
(CreateParam & 0x1) != 0,
(CreateParam & 0x2) != 0 );
}
VOID
PspCreateEventObjectType(
VOID
)
/*++
功能描述:
创建事件对象类型。
参数:
无。
返回值:
无。
--*/
{
STATUS Status;
OBJECT_TYPE_INITIALIZER Initializer;
Initializer.Create = PspOnCreateEventObject;
Initializer.Delete = NULL;
Initializer.Wait = (OB_WAIT_METHOD)PsWaitForEvent;
Initializer.Read = NULL;
Initializer.Write = NULL;
Status = ObCreateObjectType("EVENT", &Initializer, &PspEventType);
if (!EOS_SUCCESS(Status)) {
KeBugCheck("Failed to create event object type!");
}
}
STATUS
PsCreateEventObject(
IN BOOL ManualReset,
IN BOOL InitialState,
IN PCSTR EventName,
OUT PHANDLE EventHandle
)
/*++
功能描述:
创建事件对象。
参数:
ManualReset -- 是否初始化为手动事件。
InitialState -- 事件初始化的状态。
EventName -- 名称字符串指针,如果为NULL则创建一个匿名对象,否则尝试打开已存在的命
名对象,如果命名对象不存在则创建一个新的命名对象。
EventHandle -- 输出新创建或打开的事件对象句柄。
返回值:
如果成功则返回STATUS_SUCCESS。
--*/
{
STATUS Status;
PVOID EventObject;
ULONG_PTR CreateParam = 0;
if (ManualReset) {
CreateParam |= 0x1;
}
if (InitialState) {
CreateParam |= 0x2;
}
//
// 创建事件对象。
//
Status = ObCreateObject( PspEventType,
EventName,
sizeof(EVENT),
CreateParam,
&EventObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
//
// 为事件对象创建句柄。
//
Status = ObCreateHandle(EventObject, EventHandle);
if (!EOS_SUCCESS(Status)) {
ObDerefObject(EventObject);
}
return Status;
}
STATUS
PsSetEventObject(
HANDLE Handle
)
/*++
功能描述:
使事件对象变为 Singnaled 状态。如果事件的等待队列上有线程正在等待,等待线程将被唤醒。
参数:
Handle -- 事件对象的句柄。
返回值:
如果成功则返回STATUS_SUCCESS。
--*/
{
STATUS Status;
PEVENT Event;
//
// 由事件对象句柄得到对象指针。
//
Status = ObRefObjectByHandle(Handle, PspEventType, (PVOID*)&Event);
if (EOS_SUCCESS(Status)) {
PsSetEvent(Event);
//
// 关闭事件对象指针。
//
ObDerefObject(Event);
}
return Status;
}
STATUS
PsResetEventObject(
HANDLE Handle
)
/*++
功能描述:
复位事件对象状态为 Nonsignaled 状态。
参数:
Handle -- 事件对象的句柄。
返回值:
如果成功则返回STATUS_SUCCESS。
--*/
{
STATUS Status;
PEVENT Event;
//
// 由事件对象句柄得到对象指针。
//
Status = ObRefObjectByHandle(Handle, PspEventType, (PVOID*)&Event);
if (EOS_SUCCESS(Status)) {
PsResetEvent(Event);
//
// 关闭对象指针。
//
ObDerefObject(Event);
}
return Status;
}
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: fat12.h
描述: FAT12文件系统驱动程序的内部头文件。
*******************************************************************************/
#ifndef _FAT12_
#define _FAT12_
#include "eosdef.h"
#pragma pack(1) // 通知编译器按照单个字节方式对齐下列结构体中的成员
//
// BIOS Parameter Block (BPB) 结构体。大小为 25 个字节。
//
typedef struct _BIOS_PARAMETER_BLOCK {
USHORT BytesPerSector; // 每扇区字节数
UCHAR SectorsPerCluster; // 每簇扇区数
USHORT ReservedSectors; // 保留扇区数
UCHAR Fats; // FAT表的数量
USHORT RootEntries; // 根目录项数
USHORT Sectors; // 扇区总数
UCHAR Media; // 介质描述
USHORT SectorsPerFat; // 每FAT表占用的扇区数
USHORT SectorsPerTrack; // 每磁道扇区数
USHORT Heads; // 磁头数
ULONG HiddenSectors; // 引导扇区前的扇区数
ULONG LargeSectors; // 扇区总数(Sectors 为 0 时使用)
} BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK;
//
// 引导扇区结构体。只包含引导扇区开始的 62 个字节,不包含余下的 450 个字节。
//
typedef struct _BOOT_SECTOR {
UCHAR Jump[3]; // 跳转指令。 偏移 00。
UCHAR Oem[8]; // OEM。 偏移 03。
BIOS_PARAMETER_BLOCK Bpb; // BPB。 偏移 11。
UCHAR DriveNumber; // 物理驱动器编号。 偏移 36。
UCHAR Reserved; // 保留。 偏移 37。
UCHAR Signature; // 扩展引导扇区标志。 偏移 38。
UCHAR Id[4]; // 卷序列号。 偏移 39。
UCHAR VolumeLabel[11]; // 卷标。 偏移 43。
UCHAR SystemId[8]; // 文件系统类型。 偏移 54。
} BOOT_SECTOR, *PBOOT_SECTOR;
#pragma pack() // 恢复默认对齐方式
//
// 复制字符的宏
//
#define CopyUchar1(dest, src) \
*((PUCHAR)(dest)) = *((PUCHAR)(src)) \
#define CopyUchar2(dest, src) { \
*((PUCHAR)(dest)) = *((PUCHAR)(src)); \
*((PUCHAR)(dest) + 1) = *((PUCHAR)(src) + 1); \
}
#define CopyUchar3(dest, src) { \
*((PUCHAR)(dest)) = *((PUCHAR)(src)); \
*((PUCHAR)(dest) + 1) = *((PUCHAR)(src) + 1); \
*((PUCHAR)(dest) + 2) = *((PUCHAR)(src) + 2); \
}
#define CopyUchar4(dest, src) { \
*((PUCHAR)(dest)) = *((PUCHAR)(src)); \
*((PUCHAR)(dest) + 1) = *((PUCHAR)(src) + 1); \
*((PUCHAR)(dest) + 2) = *((PUCHAR)(src) + 2); \
*((PUCHAR)(dest) + 3) = *((PUCHAR)(src) + 3); \
}
//
// Fat 文件系统使用的时间\日期结构体。Note that the
// following structure is a 32 bits long but USHORT aligned.
//
typedef struct _FAT_TIME {
USHORT DoubleSeconds : 5;
USHORT Minute : 6;
USHORT Hour : 5;
} FAT_TIME, *PFAT_TIME;
typedef struct _FAT_DATE {
USHORT Day : 5;
USHORT Month : 4;
USHORT Year : 7; // 从 1980 年起始。
} FAT_DATE, *PFAT_DATE;
//
// 目录项结构体 (Directory Entry)。大小为 32 个字节。
//
typedef struct _DIRENT {
CHAR Name[11]; // 文件名 8 字节,扩展名 3 字节
UCHAR Attributes; // 文件属性
UCHAR Reserved[10]; // 保留未用
FAT_TIME LastWriteTime; // 文件最后修改时间
FAT_DATE LastWriteDate; // 文件最后修改日期
USHORT FirstCluster; // 文件的第一个簇号
ULONG FileSize; // 文件大小
} DIRENT, *PDIRENT;
//
// Fat12 文件系统设备对象的扩展结构体——卷控制块(Volume Control Block)。
//
typedef struct _VCB {
//
// 文件系统下层的软盘或者硬盘卷设备对象(目前仅仅是软盘)。
//
PDEVICE_OBJECT DiskDevice;
//
// 文件系统的参数。
//
BIOS_PARAMETER_BLOCK Bpb;
//
// 文件分配表(File Allocation Table)缓冲区。FAT12 的 FAT 表最大不过 6KB,所以
// 完全加载到内存中比较合适。
//
PVOID Fat;
//
// 根目录起始扇区、根目录大小以及根目录文件链表头。
//
ULONG FirstRootDirSector;
ULONG RootDirSize;
LIST_ENTRY FileListHead;
//
// 文件数据区的起始扇区以及簇的总数。
//
ULONG FirstDataSector;
USHORT NumberOfClusters;
}VCB, *PVCB;
//
// 文件控制块(File Control Block)。
//
typedef struct _FCB {
//
// 文件名字符串。
//
CHAR Name[13];
//
// 文件属性。
//
BOOLEAN AttrReadOnly;
BOOLEAN AttrHidden;
BOOLEAN AttrSystem;
BOOLEAN AttrDirectory;
//
// 共享属性。
//
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
//
// 文件最后修改时间。
//
FAT_TIME LastWriteTime;
FAT_DATE LastWriteDate;
//
// 文件的第一个簇号和文件的大小。
//
USHORT FirstCluster;
ULONG FileSize;
//
// 目录项结构体在目录文件内的偏移。
//
ULONG DirEntryOffset;
//
// 文件打开计数器。归档文件每被打开一次,OpenCount 增加 1;目录内每打开一个文
// 件,目录文件的 OpenCount 增加 1。关闭文件时,OpenCount 减小 1。如果变为 0
// 则释放 FCB 节点,同时文件所在目录的 OpenCount 递归减小 1。
//
ULONG OpenCount;
//
// 文件所在目录的指针,如果为 NULL 说明文件位于根目录。
//
struct _FCB *ParentDirectory;
//
// 文件所在目录的已打开文件链表项。
//
LIST_ENTRY FileListEntry;
//
// 目录的已打开文件链表头,当 AttrDirectory 为 TRUE 时有效。
//
LIST_ENTRY FileListHead;
}FCB, *PFCB;
//
// 文件属性的位定义
//
#define DIRENT_ATTR_READ_ONLY 0x01
#define DIRENT_ATTR_HIDDEN 0x02
#define DIRENT_ATTR_SYSTEM 0x04
#define DIRENT_ATTR_DIRECTORY 0x10
#define DIRENT_ATTR_ARCHIVE 0x20
//
// 计算簇的大小
//
#define FatBytesPerCluster(B) ((ULONG)((B)->BytesPerSector * (B)->SectorsPerCluster))
//
// 计算 FAT 表的大小
//
#define FatBytesPerFat(B) ((ULONG)((B)->BytesPerSector * (B)->SectorsPerFat))
//
// 计算根目录的起始扇区
//
#define FatFirstRootDirSector(B) ((B)->ReservedSectors + ((B)->Fats * (B)->SectorsPerFat))
//
// 计算根目录的大小
//
#define FatRootDirSize(B) ((ULONG)((B)->RootEntries * sizeof(DIRENT)))
//
// 计算根目录的扇区数量
//
#define FatRootDirSectors(B) ((ULONG)((FatRootDirSize(B) + ((B)->BytesPerSector - 1)) / (B)->BytesPerSector))
//
// 计算数据区的起始扇区
//
#define FatFirstDataSector(B) (FatFirstRootDirSector(B) + FatRootDirSectors(B))
//
// 计算簇的数量
//
#define FatNumberOfClusters(B) \
((((B)->Sectors ? (B)->Sectors : (B)->LargeSectors) \
\
- ((B)->ReservedSectors + \
(B)->Fats * (B)->SectorsPerFat + \
FatRootDirSectors(B) ) ) \
\
/ \
\
(B)->SectorsPerCluster) \
STATUS
FatCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PCSTR FileName,
IN ULONG CreationDisposition,
IN OUT PFILE_OBJECT FileObject
);
VOID
FatClose(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PFILE_OBJECT FileObject
);
STATUS
FatRead(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
OUT PVOID Buffer,
IN ULONG Request,
OUT PULONG Result
);
STATUS
FatWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PVOID Buffer,
IN ULONG Request,
OUT PULONG Result
);
STATUS
FatQuery(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
OUT PFILE_INFO FileInfo
);
STATUS
FatSet(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PSET_FILE_INFO FileInfo
);
STATUS
FatAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT NextLayerDevice,
IN USHORT DeviceNumber,
OUT PDEVICE_OBJECT *DeviceObject
);
//
// 判断文件或者文件夹路径名称是否有效。
//
BOOL
FatCheckPath(
IN PCSTR PathName,
IN BOOL IsDirectoryName
);
USHORT
FatGetFatEntryValue(
IN PVCB Vcb,
IN USHORT Index
);
STATUS
FatSetFatEntryValue(
IN PVCB Vcb,
IN USHORT Index,
IN USHORT Value12
);
STATUS
FatOpenExistingFile(
IN PDEVICE_OBJECT DeviceObject,
IN PCSTR FileName,
IN OUT PFILE_OBJECT FileObject
);
STATUS
FatWriteDirEntry(
IN PVCB Vcb,
IN PFCB Fcb
);
VOID
FatCloseFile(
IN PFCB Fcb
);
STATUS
FatReadFile(
IN PVCB Vcb,
IN PFCB Fcb,
IN ULONG Offset,
IN ULONG BytesToRead,
OUT PVOID Buffer,
OUT PULONG BytesRead
);
STATUS
FatWriteFile(
IN PVCB Vcb,
IN PFCB File,
IN ULONG Offset,
IN ULONG BytesToWrite,
OUT PVOID Buffer,
OUT PULONG BytesWriten
);
#endif // _FAT12_
差异被折叠。
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: generr.c
描述: 内部状态码到错误码的转换。
*******************************************************************************/
#include "rtl.h"
//
// 此一维数组描述了内部状态码和错误码的对应关系。内部状态码
// 在奇数下标处,错误码在偶数下标处。多个内部状态码可以对应
// 同一个错误码。
//
CONST ULONG CodePairs[] = {
STATUS_SUCCESS, NO_ERROR,
STATUS_TIMEOUT, ERROR_TIMEOUT,
STATUS_NOTHING_TO_TERMINATE, ERROR_PROC_NOT_FOUND,
STATUS_PENDING, ERROR_IO_PENDING,
STATUS_OBJECT_NAME_EXISTS, ERROR_ALREADY_EXISTS,
STATUS_FILE_ALLREADY_EXISTS, ERROR_ALREADY_EXISTS,
STATUS_NOT_SUPPORTED, ERROR_NOT_SUPPORTED,
STATUS_ACCESS_VIOLATION, ERROR_NOACCESS,
STATUS_ACCESS_DENIED, ERROR_ACCESS_DENIED,
STATUS_INVALID_PARAMETER, ERROR_INVALID_PARAMETER,
STATUS_OBJECT_NAME_NOT_FOUND, ERROR_FILE_NOT_FOUND,
STATUS_OBJECT_ID_NOT_FOUND, ERROR_FILE_NOT_FOUND,
STATUS_OBJECT_NAME_COLLISION, ERROR_ALREADY_EXISTS,
STATUS_MAX_HANDLE_EXCEEDED, ERROR_TOO_MANY_POSTS,
STATUS_OBJECT_TYPE_MISMATCH, ERROR_INVALID_HANDLE,
STATUS_INVALID_HANDLE, ERROR_INVALID_HANDLE,
STATUS_NO_MEMORY, ERROR_NOT_ENOUGH_MEMORY,
STATUS_FREE_VM_NOT_AT_BASE, ERROR_INVALID_ADDRESS,
STATUS_MEMORY_NOT_ALLOCATED, ERROR_INVALID_ADDRESS,
STATUS_INVALID_ADDRESS, ERROR_INVALID_ADDRESS,
STATUS_INVALID_DESTINATION_ADDRESS, ERROR_INVALID_ADDRESS,
STATUS_INVALID_SOURCE_ADDRESS, ERROR_INVALID_ADDRESS,
STATUS_MUTEX_NOT_OWNED, ERROR_NOT_OWNER,
STATUS_SEMAPHORE_LIMIT_EXCEEDED, ERROR_TOO_MANY_POSTS,
STATUS_SUSPEND_COUNT_EXCEEDED, ERROR_SIGNAL_REFUSED,
STATUS_FILE_CORRUPT_ERROR, ERROR_FILE_CORRUPT,
STATUS_PATH_NOT_FOUND, ERROR_PATH_NOT_FOUND,
STATUS_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND,
STATUS_PATH_SYNTAX_BAD, ERROR_BAD_PATHNAME,
STATUS_PATH_TOO_LONG, ERROR_FILENAME_EXCED_RANGE,
STATUS_FILE_NAME_COLLISION, ERROR_ALREADY_EXISTS,
STATUS_FLOPPY_UNKNOWN_ERROR, ERROR_FLOPPY_UNKNOWN_ERROR,
STATUS_WRONG_VOLUME, ERROR_WRONG_DISK,
STATUS_PROCESS_IS_TERMINATING, ERROR_ACCESS_DENIED,
STATUS_SHARING_VIOLATION, ERROR_SHARING_VIOLATION,
STATUS_INVALID_APP_IMAGE, ERROR_BAD_EXE_FORMAT,
STATUS_SYMBOL_NOT_FOUND, ERROR_NOT_FOUND,
STATUS_INVALID_COMMAND_LINE, ERROR_INVALID_COMMAND_LINE,
0xffffffff, 0
};
ULONG
TranslateStatusToError(
CONST STATUS status
)
/*++
功能描述:
将内部状态码转换为错误码。
参数:
status -- 输入内部状态码。
返回值:
返回错误码。
--*/
{
LONG Index;
ASSERT(0 == sizeof(CodePairs) % 2);
for(Index = 0; CodePairs[Index] != 0xffffffff; Index += 2) {
if(status == CodePairs[Index])
return CodePairs[Index + 1];
}
ASSERT(FALSE);
return ERROR_UNKNOWN;
}
;***
;
; Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
;
; 只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
; 如果您不接受,不能使用这些代码。
;
; 文件名: hal386.asm
;
; 描述:
;
;
;
;*******************************************************************************/
global _WRITE_PORT_UCHAR
global _READ_PORT_UCHAR
global _WRITE_PORT_USHORT
global _READ_PORT_USHORT
global _WRITE_PORT_ULONG
global _READ_PORT_ULONG
global _BitScanForward
global _BitScanReverse
global _KeEnableInterrupts
global _KiHaltProcessor
global _MiFlushSingleTlb
global _MiFlushEntireTlb
global _MiSetPageDirectory
[section .text]
_READ_PORT_UCHAR:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
xor eax, eax
in al, dx
nop
nop
leave
ret
;}
_READ_PORT_USHORT:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
xor eax, eax
in ax, dx
nop
nop
leave
ret
;}
_READ_PORT_ULONG:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
in eax, dx
nop
nop
leave
ret
;}
_WRITE_PORT_UCHAR:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
mov eax, [ebp + 12]
out dx, al
nop
nop
leave
ret
;}
_WRITE_PORT_USHORT:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
mov eax, [ebp + 12]
out dx, ax
nop
nop
leave
ret
;}
_WRITE_PORT_ULONG:
;{
push ebp
mov ebp, esp
mov edx, [ebp + 8]
mov eax, [ebp + 12]
out dx, eax
nop
nop
leave
ret
;}
_BitScanForward:
;{
push ebp
mov ebp, esp
bsf eax, dword [ebp + 12]
jz .ERROR
mov ecx, [ebp + 8]
mov [ecx], eax
mov eax, 1
jmp .RETURN
.ERROR:
xor eax, eax
.RETURN:
leave
ret
;}
_BitScanReverse:
;{
push ebp
mov ebp, esp
bsr eax, dword [ebp + 12]
jz .ERROR
mov ecx, [ebp + 8]
mov [ecx], eax
mov eax, 1
jmp .RETURN
.ERROR:
xor eax, eax
.RETURN:
leave
ret
;}
_KeEnableInterrupts:
;{
push ebp
mov ebp, esp
pushf ; store current eflags
cmp dword [ebp + 8], 0 ; if (EnableInt)
je .ELSE ; {
sti ; Enable interrupts.
jmp .END_IF ; }
.ELSE: ; else {
cli ; Disable interrupts.
.END_IF: ; }
pop eax ; eax = old eflags
and eax, 1 << 9 ; clear all flags except interrupt flag
leave
ret ; return eax
;}
_KiHaltProcessor:
;{
hlt
ret
;}
_MiSetPageDirectory:
;{
mov eax, [esp + 4]
shl eax, 12
mov cr3, eax
ret
;}
_MiFlushSingleTlb:
;{
mov eax, [esp + 4]
invlpg [eax]
ret
;}
_MiFlushEntireTlb:
;{
mov eax, cr3
mov cr3, eax
ret
;}
;***
;
; Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
;
; 只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
; 如果您不接受,不能使用这些代码。
;
; 文件名: int.asm
;
; 描述:
;
;
;
;*******************************************************************************/
;
; 导出符号
;
global _KeIsrStack
global _KiIntNesting
global _KiInitializeInterrupt
global _KeGetIntNesting
global _KeEnableInterrupts
;
; 导入符号
;
extern _KiDispatchException
extern _KiDispatchInterrupt
extern _PspSelectNextThread
;
; CONTEXT 结构体的大小以及各个域的偏移量
;
CONTEXT_SIZE equ 64
OFF_EAX equ 0 * 4
OFF_ECX equ 1 * 4
OFF_EDX equ 2 * 4
OFF_EBX equ 3 * 4
OFF_ESP equ 4 * 4
OFF_EBP equ 5 * 4
OFF_ESI equ 6 * 4
OFF_EDI equ 7 * 4
OFF_EIP equ 8 * 4
OFF_EFLAGS equ 9 * 4
OFF_CS equ 10 * 4
OFF_SS equ 11 * 4
OFF_DS equ 12 * 4
OFF_ES equ 13 * 4
OFF_FS equ 14 * 4
OFF_GS equ 15 * 4
;
; 用于设置中断描述符的宏,三个参数分别是 中断描述符表地址、中断号、中断处理程序入口地址
;
%macro SET_INT_DESC 3
push eax
mov eax, %3
mov word [%1 + %2 * 8 + 0], ax
mov word [%1 + %2 * 8 + 2], 0x0008
mov byte [%1 + %2 * 8 + 5], 0x8E
shr eax, 16
mov word [%1 + %2 * 8 + 6], ax
pop eax
%endmacro
;
; 数据节
;
[section .data]
_Idt times 2048 db 0 ; 中断描述符表
_KiIntNesting dd 1 ; 系统启动时,KiSystemStartup在ISR栈中执行。
_KeIsrStack dd 0 ; ISR栈指针
_IntNumber dd 0 ; 中断号
_ErrorCode dd 0 ; 异常错误码
_ContextPtr dd 0 ; 当前线程 CONTEXT 的指针
_RetAddress dd 0 ; 返回地址
_EaxValue dd 0 ; 用于暂存 EAX
_EbxValue dd 0 ; 用于暂存 EBX
;
; 代码节
;
[section .text]
_KiInitializeInterrupt:
;{
push ebp
mov ebp, esp
;
; 初始化中断描述符表的所有表项为默认值
;
xor edi, edi
.LOOP:
SET_INT_DESC _Idt, edi, Exp_3
inc edi
cmp edi, 256
jb .LOOP
;
; 设置中断描述符表中要用到的表项
;
SET_INT_DESC _Idt, 0, Exp_0
SET_INT_DESC _Idt, 1, Exp_1
SET_INT_DESC _Idt, 3, Exp_3
SET_INT_DESC _Idt, 4, Exp_4
SET_INT_DESC _Idt, 5, Exp_5
SET_INT_DESC _Idt, 6, Exp_6
SET_INT_DESC _Idt, 7, Exp_7
SET_INT_DESC _Idt, 8, Exp_8
SET_INT_DESC _Idt, 9, Exp_9
SET_INT_DESC _Idt, 10, Exp_10
SET_INT_DESC _Idt, 11, Exp_11
SET_INT_DESC _Idt, 12, Exp_12
SET_INT_DESC _Idt, 13, Exp_13
SET_INT_DESC _Idt, 14, Exp_14
SET_INT_DESC _Idt, 16, Exp_16
SET_INT_DESC _Idt, 32, Int_32
SET_INT_DESC _Idt, 33, Int_33
SET_INT_DESC _Idt, 35, Int_35
SET_INT_DESC _Idt, 36, Int_36
SET_INT_DESC _Idt, 37, Int_37
SET_INT_DESC _Idt, 38, Int_38
SET_INT_DESC _Idt, 39, Int_39
SET_INT_DESC _Idt, 40, Int_40
SET_INT_DESC _Idt, 44, Int_44
SET_INT_DESC _Idt, 45, Int_45
SET_INT_DESC _Idt, 46, Int_46
SET_INT_DESC _Idt, 48, Int_48
;
; 加载中断描述符表
;
push dword _Idt
push word 2048
lidt [esp]
add esp, 6
leave
ret
;}
Exp_0:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 0
jmp Exception
Exp_1:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 1
jmp Exception
Exp_3:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 3
jmp Exception
Exp_4:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 4
jmp Exception
Exp_5:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 5
jmp Exception
Exp_6:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 6
jmp Exception
Exp_7:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 7
jmp Exception
Exp_8:
pop dword [_ErrorCode]
mov dword [_IntNumber], 8
jmp Exception
Exp_9:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 9
jmp Exception
Exp_10:
pop dword [_ErrorCode]
mov dword [_IntNumber], 10
jmp Exception
Exp_11:
pop dword [_ErrorCode]
mov dword [_IntNumber], 11
jmp Exception
Exp_12:
pop dword [_ErrorCode]
mov dword [_IntNumber], 12
jmp Exception
Exp_13:
pop dword [_ErrorCode]
mov dword [_IntNumber], 13
jmp Exception
Exp_14:
pop dword [_ErrorCode]
mov dword [_IntNumber], 14
jmp Exception
Exp_16:
mov dword [_ErrorCode], 0
mov dword [_IntNumber], 16
jmp Exception
Int_32:
mov dword [_IntNumber], 32
jmp Interrupt
Int_33:
mov dword [_IntNumber], 33
jmp Interrupt
Int_35:
mov dword [_IntNumber], 35
jmp Interrupt
Int_36:
mov dword [_IntNumber], 36
jmp Interrupt
Int_37:
mov dword [_IntNumber], 37
jmp Interrupt
Int_38:
mov dword [_IntNumber], 38
jmp Interrupt
Int_39:
mov dword [_IntNumber], 39
jmp Interrupt
Int_40:
mov dword [_IntNumber], 40
jmp Interrupt
Int_44:
mov dword [_IntNumber], 44
jmp Interrupt
Int_45:
mov dword [_IntNumber], 45
jmp Interrupt
Int_46:
mov dword [_IntNumber], 46
jmp Interrupt
Int_48:
call IntEnter
mov dword [_KiIntNesting], 1
push dword 1
call IntExit
;
; 异常处理
;
Exception:
;{
;
; 调用中断进入函数,保存被中断的 CPU 现场环境并构造中断堆栈帧
;
call IntEnter
;
; 以异常号、错误码、CONTEXT指针为参数,调用异常派遣函数KiDispatchException。
; 注意:KiDispatchException有返回值,返回值的意义如下:
; 0:返回线程时不执行线程调度,直接返回到产生异常的那个线程。
; 非0:返回线程时执行线程调度,返回到调度程序确定应该执行的线程。
;
push eax ; eax是IntEnter的返回值,指向产生异常的CONTEXT
push dword [_ErrorCode]
push dword [_IntNumber]
call _KiDispatchException
add esp, 12
;
; 以KiDispatchException的返回值为参数调用中断返回函数。
;
push eax
call IntExit
;}
;
; 中断处理
;
Interrupt:
;{
;
; 调用中断进入函数,保存被中断的 CPU 现场环境并构造中断堆栈帧。
; 然后打开中断(设备中断可嵌套)。
;
call IntEnter
sti
;
; 以中断号作为参数调用中断派遣函数(无返回值)
;
push dword [_IntNumber]
call _KiDispatchInterrupt
add esp, 4
;
; 关中断,然后调用中断返回函数(执行线程调度)
;
cli
push dword 1
call IntExit
;}
;
; 中断进入函数。
;
IntEnter:
;{
;
; 取消 call 对 esp 值的影响,并暂存 eax 和 ebx
;
pop dword [_RetAddress]
mov [_EaxValue], eax
mov [_EbxValue], ebx
;
; 增加中断嵌套深度。
;
inc dword [_KiIntNesting]
cmp dword [_KiIntNesting], 1
jne .NESTED_INT
;
; 线程被中断,此时 [_ContextPtr] 指向被中断线程的 CONTEXT。
; 使 ebx 指向中断栈的基址,eax 指向线程的 CONTEXT。
;
mov ebx, [_KeIsrStack]
mov eax, [_ContextPtr]
jmp .SAVE_CONTEXT
.NESTED_INT:
;
; 嵌套中断,在当前中断栈顶开辟 CONTEXT 空间。
; 使 ebx 指向深度增加后的栈顶,eax 指向栈中的 CONTEXT。
;
mov ebx, esp
sub ebx, CONTEXT_SIZE
mov eax, ebx
.SAVE_CONTEXT:
;
; 将 CPU 现场保存到 eax 指向的 CONTEXT 结构体中
;
mov [eax + OFF_ECX], ecx
mov ecx, [_EaxValue]
mov [eax + OFF_EAX], ecx
mov ecx, [_EbxValue]
mov [eax + OFF_EBX], ecx
mov [eax + OFF_EDX], edx
mov [eax + OFF_ESP], esp
mov [eax + OFF_EBP], ebp
mov [eax + OFF_ESI], esi
mov [eax + OFF_EDI], edi
xor ecx, ecx
mov cx, ds
mov [eax + OFF_DS], ecx
mov cx, es
mov [eax + OFF_ES], ecx
mov cx, fs
mov [eax + OFF_FS], ecx
mov cx, gs
mov [eax + OFF_GS], ecx
mov cx, ss
mov [eax + OFF_SS], ecx
pop dword [eax + OFF_EIP]
pop dword [eax + OFF_CS]
pop dword [eax + OFF_EFLAGS]
mov [eax + OFF_ESP], esp
;
; 在 ebx 指向的位置构造一个最外层调用帧
;
mov esp, ebx
push dword 0 ; ret address of call instruction
push dword 0 ; old value of ebp (push ebp)
mov ebp, esp
;
; 返回
;
jmp dword [_RetAddress]
;}
;
; 中断退出函数。
;
IntExit:
;{
cli
push ebp
mov ebp, esp
;
; 如果中断嵌套计数器为1则返回到线程,否则返回到被嵌套中断。
;
cmp dword [_KiIntNesting], 1
je .RETURN_TO_THREAD
;
; 返回到被嵌套中断,使EAX指向保存在中断栈中的CONTEXT结构体。
;
mov eax, [ebp]
add eax, 8
jmp .RESTORE_CONTEXT
.RETURN_TO_THREAD:
;
; 根据参数确定是否执行线程调度,如果需要调度则返回到调度程序确定的
; 下一个应该该运行的线程,否则返回到被中断线程。
;
cmp dword [ebp + 8], 0
jne .SELECT_NEXT_THREAD
;
; 不调度,使EAX指向被中断的线程的CONTEXT结构体。
;
mov eax, [_ContextPtr]
jmp .RESTORE_CONTEXT
.SELECT_NEXT_THREAD:
;
; 调用PspSelectNextThread,其返回下一个应该运行线程的CONTEXT指针。
; 注意:要保存指针值到[_ContextPtr],当线程被中断时还将使用。
;
call _PspSelectNextThread
mov [_ContextPtr], eax
.RESTORE_CONTEXT:
;
; 恢复 CPU 环境为 EAX 指向的 CONTEXT
;
mov ebx, [eax + OFF_EBX]
mov ecx, [eax + OFF_ECX]
mov edx, [eax + OFF_EDX]
mov edi, [eax + OFF_EDI]
mov esi, [eax + OFF_ESI]
mov ebp, [eax + OFF_EBP]
mov esp, [eax + OFF_ESP]
mov ds, [eax + OFF_DS]
mov es, [eax + OFF_ES]
mov fs, [eax + OFF_FS]
mov gs, [eax + OFF_GS]
mov ss, [eax + OFF_SS]
push dword [eax + OFF_EFLAGS]
push dword [eax + OFF_CS]
push dword [eax + OFF_EIP]
mov eax, [eax + OFF_EAX]
; 减少中断嵌套深度。
dec dword [_KiIntNesting]
; 中断返回,开始执行选中的线程。
iret
;}
_KeGetIntNesting:
;{
push ebp
mov ebp, esp
mov eax, [_KiIntNesting]
leave
ret
;}
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: io.c
描述: IO模块接口函数的实现。
*******************************************************************************/
#include "iop.h"
STATUS
IoCreateFile(
IN PSTR FileName,
IN ULONG DesiredAccess,
IN ULONG ShareMode,
IN ULONG CreationDisposition,
IN ULONG FlagsAndAttributes,
OUT PHANDLE FileHandle
)
/*++
功能描述:
创建或打开文件。目标可以是位于磁盘文件系统中的文件,也可以是IO设备。
参数:
FileName -- 期望创建或打开的文件的名称。
DesiredAccess -- 期望获得的文件访问权限,包括GENERIC_READ和GENERIC_WRITE。
ShareMode -- 对象的共享模式,包括FILE_SHARE_READ和FILE_SHARE_WRITE。
CreationDisposition -- 函数的执行动作,取决于文件是否已经存在。可以取值如下:
CREATE_ALWAYS:创建一个大小为0的新文件,如果文件已经存在则覆盖已存在文件;
CREATE_NEW:创建一个大小为0的新文件,如果文件已经存在则返回失败;
OPEN_ALWAYS:打开一个文件,如果文件不存在则创建一个新文件;
OPEN_EXISTING:打开一个文件,如果文件不存在则返回失败;
TRUNCATE_EXISTING:打开一个文件并截断之大小为0,如果文件不存在则返回失败。
FlagsAndAttributes -- 文件的属性和标志,可以包括如下:
FILE_ATTRIBUTE_READONLY: 只读文件;
FILE_ATTRIBUTE_HIDDEN:隐藏文件;
FILE_ATTRIBUTE_SYSTEM:系统文件;
FileHandle -- 指针,指向用于输出文件对象指针的缓冲区。
返回值:
如果成功则返回STATUS_SUCCESS或STATUS_FILE_ALLREADY_EXISTS。
--*/
{
STATUS Status;
PFILE_OBJECT FileObject;
//
// 只能打开数据文件,不能打开目录文件。
//
if ((FlagsAndAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
return STATUS_INVALID_PARAMETER;
}
//
// 不能直接创建目录文件。
//
if ((FlagsAndAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
return STATUS_INVALID_PARAMETER;
}
//
// 自动补充FILE_ATTRIBUTE_ARCHIVE属性。
//
FlagsAndAttributes |= FILE_ATTRIBUTE_ARCHIVE;
Status = IopCreateFileObject( FileName,
DesiredAccess,
ShareMode,
CreationDisposition,
FlagsAndAttributes,
&FileObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
Status = ObCreateHandle(FileObject, FileHandle);
if (!EOS_SUCCESS(Status)) {
ObDerefObject(FileObject);
}
return Status;
}
STATUS
IoCreateDirectory(
IN PSTR PathName
)
/*++
功能描述:
创建一个目录。
参数:
PathName -- 目录路径字符串。
返回值:
如果成功则返回STATUS_SUCCESS。
--*/
{
STATUS Status;
PFILE_OBJECT NewFile;
Status = IopCreateFileObject( PathName,
0,
0,
CREATE_NEW,
FILE_ATTRIBUTE_DIRECTORY,
&NewFile );
if (EOS_SUCCESS(Status)) {
ObDerefObject(NewFile);
}
return Status;
}
STATUS
IoGetFileTime(
IN HANDLE FileHandle,
OUT PFILETIME CreationTime,
OUT PFILETIME LastAccessTime,
OUT PFILETIME LastWriteTime
)
{
STATUS Status;
PFILE_OBJECT FileObject;
FILE_INFO FileInfo;
Status = ObRefObjectByHandle(FileHandle, IopFileObjectType, (PVOID*)&FileObject);
if (EOS_SUCCESS(Status)) {
Status = IopQueryFileObjectInfo(FileObject, &FileInfo);
if (EOS_SUCCESS(Status)) {
*CreationTime = FileInfo.CreationTime;
*LastAccessTime = FileInfo.LastAccessTime;
*LastWriteTime = FileInfo.LastWriteTime;
}
ObDerefObject(FileObject);
}
return Status;
}
STATUS
IoGetFileSize(
IN HANDLE FileHandle,
OUT PULONG FileSize
)
{
STATUS Status;
PFILE_OBJECT FileObject;
FILE_INFO FileInfo;
Status = ObRefObjectByHandle(FileHandle, IopFileObjectType, (PVOID*)&FileObject);
if (EOS_SUCCESS(Status)) {
Status = IopQueryFileObjectInfo(FileObject, &FileInfo);
if (EOS_SUCCESS(Status)) {
*FileSize = FileInfo.FileSize;
}
ObDerefObject(FileObject);
}
return Status;
}
//
// 设置文件读写位置。
//
STATUS
IoSetFilePointer(
IN HANDLE FileHandle,
IN LONG DistanceToMove,
IN ULONG MoveMethod,
OUT PULONG NewFilePointer
)
{
STATUS Status;
PFILE_OBJECT FileObject;
FILE_INFO FileInfo;
if (MoveMethod != FILE_BEGIN && MoveMethod != FILE_CURRENT && MoveMethod != FILE_END) {
return STATUS_INVALID_PARAMETER;
}
Status = ObRefObjectByHandle(FileHandle, IopFileObjectType, (PVOID*)&FileObject);
if (!EOS_SUCCESS(Status)) {
return Status;
}
//
// 互斥访问文件对象。
//
PsWaitForMutex(&FileObject->Mutex, INFINITE);
Status = IopQueryFileObjectInfo(FileObject, &FileInfo);
if (EOS_SUCCESS(Status)) {
if (FILE_BEGIN == MoveMethod) {
if (DistanceToMove <= 0) {
FileObject->CurrentByteOffset = 0;
} else if ((ULONG)DistanceToMove >= FileInfo.FileSize) {
FileObject->CurrentByteOffset = FileInfo.FileSize;
} else {
FileObject->CurrentByteOffset = DistanceToMove;
}
} else if (FILE_CURRENT == MoveMethod) {
if (DistanceToMove < 0 && (ULONG)(-DistanceToMove) > FileObject->CurrentByteOffset) {
FileObject->CurrentByteOffset = 0;
} else if (DistanceToMove > 0 && FileObject->CurrentByteOffset + DistanceToMove >= FileInfo.FileSize) {
FileObject->CurrentByteOffset = FileInfo.FileSize;
} else {
FileObject->CurrentByteOffset += DistanceToMove;
}
} else {
if (DistanceToMove >= 0) {
FileObject->CurrentByteOffset = FileInfo.FileSize;
} else if ((ULONG)(-DistanceToMove) >= FileInfo.FileSize) {
FileObject->CurrentByteOffset = 0;
} else {
FileObject->CurrentByteOffset = FileInfo.FileSize + DistanceToMove;
}
}
*NewFilePointer = FileObject->CurrentByteOffset;
Status = STATUS_SUCCESS;
}
PsReleaseMutex(&FileObject->Mutex);
return Status;
}
//
// 得到文件的属性值。
//
STATUS
IoGetFileAttributes(
IN PSTR FileName,
OUT PULONG FileAttributes
)
{
STATUS Status;
PFILE_OBJECT FileObject;
FILE_INFO FileInfo;
//
// 共享打开文件。
//
Status = IopCreateFileObject( FileName,
0,
FILE_SHARE_READ | FILE_SHARE_READ,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE,
&FileObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
Status = IopQueryFileObjectInfo( FileObject, &FileInfo);
//
// 关闭文件。
//
ObDerefObject(FileObject);
if (EOS_SUCCESS(Status)) {
*FileAttributes = FileInfo.FileAttributes;
}
return Status;
}
//
// 修改文件的属性值。
//
STATUS
IoSetFileAttributes(
IN PSTR FileName,
IN ULONG FileAttributes
)
{
STATUS Status;
PFILE_OBJECT FileObject;
SET_FILE_INFO FileInfo;
if ((FileAttributes & ~(FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) != 0) {
return STATUS_INVALID_PARAMETER;
}
if ((FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == 0) {
FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
}
//
// 独占打开文件。
//
Status = IopCreateFileObject( FileName,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE,
&FileObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
FileInfo.FileInfoClass = FileAttributesInfo;
FileInfo.u.AttributesInfo.FileAttributes = FileAttributes;
Status = IopSetFileObjectInfo(FileObject, &FileInfo);
//
// 关闭文件。
//
ObDerefObject(FileObject);
return Status;
}
//
// 删除文件。
//
STATUS
IoDeleteFile(
IN PSTR FileName
)
{
STATUS Status;
PFILE_OBJECT FileObject;
SET_FILE_INFO FileInfo;
//
// 独占打开文件。
//
Status = IopCreateFileObject( FileName,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE,
&FileObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
FileInfo.FileInfoClass = FileAttributesInfo;
FileInfo.u.DispositionInfo.DeleteFile = TRUE;
Status = IopSetFileObjectInfo(FileObject, &FileInfo);
//
// 关闭文件。
//
ObDerefObject(FileObject);
return Status;
}
//
// 删除一个目录。
//
STATUS
IoRemoveDirectory(
IN PSTR PathName
)
{
STATUS Status;
PFILE_OBJECT FileObject;
SET_FILE_INFO FileInfo;
//
// 独占目录打开文件。
//
Status = IopCreateFileObject( PathName,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_DIRECTORY,
&FileObject );
if (!EOS_SUCCESS(Status)) {
return Status;
}
FileInfo.FileInfoClass = FileAttributesInfo;
FileInfo.u.DispositionInfo.DeleteFile = TRUE;
Status = IopSetFileObjectInfo(FileObject, &FileInfo);
//
// 关闭文件。
//
ObDerefObject(FileObject);
return Status;
}
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: io.h
描述: IO 模块公共头文件。
*******************************************************************************/
#ifndef _IO_
#define _IO_
#include "eosdef.h"
//
// 初始化IO管理模块第一步。
//
VOID
IoInitializeSystem1(
VOID
);
//
// 初始化IO管理模块第二步。
//
VOID
IoInitializeSystem2(
VOID
);
//
// 创建或打开I/O对象。
//
STATUS
IoCreateFile(
IN PSTR FileName,
IN ULONG DesiredAccess,
IN ULONG ShareMode,
IN ULONG CreationDisposition,
IN ULONG FlagsAndAttributes,
OUT PHANDLE Handle
);
//
// 删除文件。
//
STATUS
IoDeleteFile(
IN PSTR FileName
);
//
// 得到文件的时间戳。
//
STATUS
IoGetFileTime(
IN HANDLE FileHandle,
OUT PFILETIME CreationTime,
OUT PFILETIME LastAccessTime,
OUT PFILETIME LastWriteTime
);
//
// 得到文件的长度。
//
STATUS
IoGetFileSize(
IN HANDLE FileHandle,
OUT PULONG FileSize
);
//
// 设置文件读写位置。
//
STATUS
IoSetFilePointer(
IN HANDLE FileHandle,
IN LONG DistanceToMove,
IN ULONG MoveMethod,
OUT PULONG NewFilePointer
);
//
// 得到文件的属性值。
//
STATUS
IoGetFileAttributes(
IN PSTR FileName,
OUT PULONG FileAttributes
);
//
// 修改文件的属性值。
//
STATUS
IoSetFileAttributes(
IN PSTR FileName,
IN ULONG FileAttributes
);
//
// 创建一个目录。
//
STATUS
IoCreateDirectory(
IN PSTR PathName
);
//
// 删除一个目录。
//
STATUS
IoRemoveDirectory(
IN PSTR PathName
);
//
// 打开指定序号的控制台。
//
STATUS
IoOpenConsole(
IN ULONG ConsoleIndex,
OUT PHANDLE Handle
);
//
// 设定控制台窗口的光标位置。
//
STATUS
IoSetConsoleCursorPosition(
IN HANDLE Handle,
IN COORD CursorPosition
);
#endif // _IO_
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: ioinit.c
描述: I/O模块的初始化,包括数据结构体的初始化和设备驱动的加载。
*******************************************************************************/
#include "iop.h"
STATUS
IopReadFileObject(
IN PFILE_OBJECT File,
IN PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead
);
STATUS
IopWriteFileObject(
IN PFILE_OBJECT File,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten
);
VOID
IopCloseFileObject(
IN PFILE_OBJECT FileObject
);
STATUS
IopReadConsoleInput(
IN PCONSOLE Console,
IN PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead
);
STATUS
IopWriteConsoleOutput(
IN PCONSOLE Console,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten
);
VOID
FloppyInitializeDriver(
PDRIVER_OBJECT DriverObject
);
VOID
FatInitializeDriver(
PDRIVER_OBJECT DriverObject
);
VOID
KbdInitializeDriver(
PDRIVER_OBJECT DriverObject
);
VOID
IopInitializeConsole(
VOID
);
VOID
SrlInitializeDriver(
PDRIVER_OBJECT DriverObject
);
VOID
IoInitializeSystem1(
VOID
)
/*++
功能描述:
I/O管理器第一步初始化,初始化不可阻塞,主要是创建IO对象类型。
参数:
无。
返回值:
无。
--*/
{
STATUS Status;
OBJECT_TYPE_INITIALIZER Initializer;
Initializer.Create = NULL;
Initializer.Delete = NULL;
Initializer.Wait = NULL;
Initializer.Read = NULL;
Initializer.Write = NULL;
//
// 创建驱动程序对象类型。
//
Status = ObCreateObjectType("DRIVER", &Initializer, &IopDriverObjectType);
if (!EOS_SUCCESS(Status)) {
KeBugCheck("Failed to create driver object type!");
}
//
// 创建设备对象类型。
//
Status = ObCreateObjectType("DEVICE", &Initializer, &IopDeviceObjectType);
if (!EOS_SUCCESS(Status)) {
KeBugCheck("Failed to create device object type!");
}
//
// 创建控制台对象类型。
//
Initializer.Read = (OB_READ_METHOD)IopReadConsoleInput;
Initializer.Write = (OB_WRITE_METHOD)IopWriteConsoleOutput;
Status = ObCreateObjectType("CONSOLE", &Initializer, &IopConsoleType);
if (!EOS_SUCCESS(Status)) {
KeBugCheck("Failed to create console object type!");
}
//
// 创建文件对象类型。
//
Initializer.Delete = (OB_DELETE_METHOD)IopCloseFileObject;
Initializer.Read = (OB_READ_METHOD)IopReadFileObject;
Initializer.Write = (OB_WRITE_METHOD)IopWriteFileObject;
Status = ObCreateObjectType("FILE", &Initializer, &IopFileObjectType);
if (!EOS_SUCCESS(Status)) {
KeBugCheck("Failed to create file object type!");
}
}
VOID
IoInitializeSystem2(
VOID
)
/*++
功能描述:
I/O管理器第二步初始化函数,可阻塞,安装驱动并初始化设备。
参数:
无。
返回值:
无。
--*/
{
STATUS Status;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
//
// 块设备层的初始化,必须在各种块设备对象及其驱动程序对象的初始化之前完成。
//
IopInitializeBlockDeviceLayer();
//
// EOS为了保持简单,不支持自动侦测硬件配置并安装驱动的功能,只能通过硬编码的
// 方式安装驱动程序并添加设备对象。
// 另外,为了方便调试驱动程序,驱动程序和内核编译在一起。
//
//
// 创建软驱驱动程序对象。
//
Status = IopCreateDriver("Floppy Driver", &DriverObject);
ASSERT(EOS_SUCCESS(Status));
if (EOS_SUCCESS(Status)) {
//
// 初始化软驱驱动程序对象。
//
FloppyInitializeDriver(DriverObject);
//
// 添加软驱设备对象,目前仅支持一个软驱。
//
Status = DriverObject->AddDevice(DriverObject, NULL, 0, &DeviceObject);
ASSERT(EOS_SUCCESS(Status));
}
//
// 如果软驱设备对象成功添加,那么在软驱之上安装FAT12文件系统驱动程序。
//
if (EOS_SUCCESS(Status)) {
//
// 创建FAT12文件系统驱动程序对象。
//
Status = IopCreateDriver("FAT12 Driver", &DriverObject);
ASSERT(EOS_SUCCESS(Status));
if (EOS_SUCCESS(Status)) {
//
// 初始化FAT12文件系统驱动程序对象。
//
FatInitializeDriver(DriverObject);
//
// 在软驱设备对象之上添加FAT12文件系统设备对象。
//
Status = DriverObject->AddDevice(DriverObject, DeviceObject, 0, &DeviceObject);
ASSERT(EOS_SUCCESS(Status));
}
}
//
// 创建键盘驱动程序对象。
//
Status = IopCreateDriver("Keyboard Driver", &DriverObject);
ASSERT(EOS_SUCCESS(Status));
if (EOS_SUCCESS(Status)) {
//
// 初始化键盘驱动程序对象。
//
KbdInitializeDriver(DriverObject);
//
// 添加键盘设备对象。
//
Status = DriverObject->AddDevice(DriverObject, NULL, 0, &DeviceObject);
ASSERT(EOS_SUCCESS(Status));
}
//
// 创建串口驱动程序对象。
//
Status = IopCreateDriver("Serial Driver", &DriverObject);
ASSERT(EOS_SUCCESS(Status));
if (EOS_SUCCESS(Status)) {
//
// 初始化串口驱动程序对象。
//
SrlInitializeDriver(DriverObject);
//
// 分别添加 COM1 和 COM2 对应的串口设备对象。
//
Status = DriverObject->AddDevice(DriverObject, NULL, 0, &DeviceObject);
ASSERT(EOS_SUCCESS(Status));
Status = DriverObject->AddDevice(DriverObject, NULL, 1, &DeviceObject);
ASSERT(EOS_SUCCESS(Status));
}
//
// 初始化控制台I/O模块。
//
IopInitializeConsole();
}
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: iomgr.c
描述: 驱动程序对象和设备对象的管理,目前仅实现了驱动对象和设备对象的创建。
*******************************************************************************/
#include "iop.h"
//
// I/O管理器用到的各种对象类型。
//
POBJECT_TYPE IopDriverObjectType;
POBJECT_TYPE IopDeviceObjectType;
POBJECT_TYPE IopFileObjectType;
POBJECT_TYPE IopConsoleType;
STATUS
IopCreateDriver(
IN PCSTR DriverName,
OUT PDRIVER_OBJECT *DriverObject
)
/*++
功能描述:
创建驱动程序对象。
参数:
DriverName - 驱动程序的名称。
DriverObject - 指针,指向用于保存新建驱动程序对象指针的变量。
返回值:
如果成功则返回STATUS_SUCCESS。
--*/
{
STATUS Status;
PDRIVER_OBJECT NewDriver;
Status = ObCreateObject( IopDriverObjectType,
DriverName,
sizeof(DRIVER_OBJECT),
0,
(PVOID*)&NewDriver );
if (!EOS_SUCCESS(Status)) {
return Status;
} else if (STATUS_OBJECT_NAME_EXISTS == Status) {
ObDerefObject(NewDriver);
return STATUS_OBJECT_NAME_COLLISION; // 在创建驱动程序时不允许重名。
}
ListInitializeHead(&NewDriver->DeviceListHead);
NewDriver->AddDevice = NULL;
NewDriver->Create = NULL;
NewDriver->Close = NULL;
NewDriver->Read = NULL;
NewDriver->Write = NULL;
NewDriver->Query = NULL;
NewDriver->Set = NULL;
*DriverObject = NewDriver;
return STATUS_SUCCESS;
}
STATUS
IopCreateDevice(
IN PDRIVER_OBJECT DriverObject,
IN ULONG DeviceExtensionSize,
IN PCSTR DeviceName OPTIONAL,
IN USHORT DeviceNumber,
IN BOOL IsBlockDevice,
OUT PDEVICE_OBJECT *DeviceObject
)
/*++
功能描述:
创建设备对象。
参数:
DriverObject - 驱动程序对象指针。
DeviceExtensionSize - 设备对象扩展结构尺寸。
DeviceName - 设备名称字符串。
IsBlockDevice - 是否是块设备。
DeviceNumber - 设备编号,具体请参看DEVICE_OJECT结构体。
DeviceObject - 如果创建成功将返回设备对象指针。
返回值:
成功返回 STATUS_SUCCESS。
--*/
{
STATUS Status;
PDEVICE_OBJECT NewDevice;
ASSERT(NULL != DriverObject);
//
// 创建一个设备对象。
//
Status = ObCreateObject( IopDeviceObjectType,
DeviceName,
sizeof(DEVICE_OBJECT) + DeviceExtensionSize,
0,
(PVOID)&NewDevice );
if (!EOS_SUCCESS(Status)) {
return Status;
} else if (STATUS_OBJECT_NAME_EXISTS == Status) {
ObDerefObject(NewDevice);
return STATUS_OBJECT_NAME_COLLISION; // 在创建驱动程序时不允许重名。
}
//
// 设置设备扩展结构指针。
//
if (DeviceExtensionSize != 0) {
NewDevice->DeviceExtension = (PVOID)(NewDevice + 1);
memset(NewDevice->DeviceExtension, 0, DeviceExtensionSize);
} else {
NewDevice->DeviceExtension = NULL;
}
NewDevice->IsBlockDevice = IsBlockDevice;
NewDevice->DriverObject = DriverObject;
NewDevice->DeviceNumber = DeviceNumber;
NewDevice->OpenCount = 0;
NewDevice->ShareRead = FALSE;
NewDevice->ShareWrite = FALSE;
PsInitializeMutex(&NewDevice->Mutex, FALSE);
//
// 将设备对象插入驱动程序的设备链表中。
//
ListInsertTail(&DriverObject->DeviceListHead, &NewDevice->DeviceListEntry);
*DeviceObject = NewDevice;
return STATUS_SUCCESS;
}
差异被折叠。
/***
Copyright (c) 2008 北京英真时代科技有限公司。保留所有权利。
只有您接受 EOS 核心源代码协议(参见 License.txt)中的条款才能使用这些代码。
如果您不接受,不能使用这些代码。
文件名: ke.h
描述: 系统支撑模块对外接口的头文件,供内核其它模块使用。
*******************************************************************************/
#ifndef _KE_
#define _KE_
#include "rtl.h"
#ifdef _I386
//
// i386处理器上下文环境结构体。
// 注意:不要调整结构体中的变量顺序,内核汇编代码、内核调试器都已约定如此。
//
typedef struct _CONTEXT
{
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Eip;
ULONG EFlag;
ULONG SegCs;
ULONG SegSs;
ULONG SegDs;
ULONG SegEs;
ULONG SegFs;
ULONG SegGs;
}CONTEXT, *PCONTEXT;
//
// I386程序状态字寄存器PSW(EFLAGS)的位掩码.
//
#define PSW_MASK_CF (1<<0)
#define PSW_MASK_PF (1<<2)
#define PSW_MASK_AF (1<<4)
#define PSW_MASK_ZF (1<<6)
#define PSW_MASK_SF (1<<7)
#define PSW_MASK_TF (1<<8)
#define PSW_MASK_IF (1<<9)
#define PSW_MASK_DF (1<<10)
#define PSW_MASK_OF (1<<11)
//
// 代码段和数据段选择子常量
//
extern CONST ULONG KeCodeSegmentSelector;
extern CONST ULONG KeDataSegmentSelector;
//
// i386 异常编号。
//
#define EXP_DIVIDE_ERROR 0x00 // Fault
#define EXP_DEBUG 0x01 // Fault / Trap
#define EXP_BREAKPOINT 0x03 // Trap
#define EXP_OVERFLOW 0x04 // Trap
#define EXP_BOUNDS_CHECK 0x05 // Fault
#define EXP_BAD_CODE 0x06 // Fault
#define EXP_NO_CORPROCESSOR 0x07 // Fault
#define EXP_DOUBLE_FAULT 0x08 // Abort, ErrorCode
#define EXP_CORPROCESSOR_OVERRUN 0x09 // Abort
#define EXP_INVALID_TSS 0x0A // Fault, ErrorCode
#define EXP_SEGMENT_NOT_PRESENT 0x0B // Fault, ErrorCode
#define EXP_STACK_FAULT 0x0C // Fault, ErrorCode
#define EXP_GENERAL_PROTECTION_FAULT 0x0D // Fault, ErrorCode
#define EXP_PAGE_FAULT 0x0E // Fault, ErrorCode
#define EXP_CORPROCESSOR_ERROR 0x10 // Fault
//
// 设备中断号。
//
#define PIC1_VECTOR 0x20
#define PIC2_VECTOR 0x28
#define INT_TIMER 0x20 // 编号 32。8253 可编程定时计数器。
#define INT_KEYBOARD 0x21 // 编号 33。键盘。
#define INT_COM2 0x23 // 编号 35。串口 2。
#define INT_COM1 0x24 // 编号 36。串口 1。
#define INT_LPT2 0x25 // 编号 37。并口 2。
#define INT_FLOPPY 0x26 // 编号 38。软盘驱动器。
#define INT_LPT1 0x27 // 编号 39。并口 1。
#define INT_CLOCK 0x28 // 编号 40。实时时钟。
#define INT_PS2 0x2C // 编号 44。PS2 接口。
#define INT_FPU 0x2D // 编号 45。浮点处理单元。
#define INT_HD 0x2E // 编号 46。硬盘。
typedef VOID (*ISR)(VOID);
//
// 各设备对应的中断向量。
//
extern ISR KeIsrKeyBoard;
extern ISR KeIsrCom2;
extern ISR KeIsrCom1;
extern ISR KeIsrLPT2;
extern ISR KeIsrFloppy;
extern ISR KeIsrLPT1;
extern ISR KeIsrClock;
extern ISR KeIsrPS2;
extern ISR KeIsrFPU;
extern ISR KeIsrHD;
//
// 开关某一设备的中断。
//
VOID
KeEnableDeviceInterrupt(
ULONG IntVector,
BOOL Enable
);
//
// 触发专用于线程调度的软中断,在中断返回时会执行线程调度。
// 注意:在中断中执行 KeThreadSchedule 会使所有外层嵌套中断丢失,直接返回线程环境。
//
#define KeThreadSchedule() __asm("int $48")
#endif
//
// ISR服务程序专用栈指针(指向栈底)。
//
extern PVOID KeIsrStack;
#ifdef _DEBUG
extern volatile long Tick; // 从开机开始算起的滴答数(10ms/滴答)
extern volatile ULONG StopKeyboard;
#endif
//
// 开/关外部中断并返回调用前的开关状态
//
BOOL
KeEnableInterrupts(
IN BOOL EnableInt
);
//
// 得到当前中断嵌套深度,返回 0 说明当前执行在非中断环境中。
//
ULONG
KeGetIntNesting(
VOID
);
//
// 计时器能够识别的时间范围。
//
#define KTIMER_MAXIMUM 0x7FFFFFFF
#define KTIMER_MINIMUM 0x0000000A
//
// 计时器回调函数的类型定义。
//
typedef VOID (*PKTIMER_ROUTINE)(ULONG_PTR);
//
// 计时器结构体。
//
typedef struct _KTIMER
{
ULONG IntervalTicks;
ULONG ElapsedTicks;
PKTIMER_ROUTINE TimerRoutine;
ULONG_PTR Parameter;
LIST_ENTRY TimerListEntry;
}KTIMER, *PKTIMER;
//
// 初始化计时器。
//
VOID
KeInitializeTimer(
IN PKTIMER Timer,
IN ULONG Milliseconds,
IN PKTIMER_ROUTINE TimerRoutine,
IN ULONG_PTR Parameter
);
//
// 注册计时器。
//
VOID
KeRegisterTimer(
IN PKTIMER Timer
);
//
// 注销计时器。
//
VOID
KeUnregisterTimer(
IN PKTIMER Timer
);
//
// 系统失败处理函数。
//
VOID
KeBugCheck(
IN PCSTR Format,
...
);
#endif // _KE_
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论