30天自制操作系统(第28天)

时间:2024-03-09 17:28:40
打开文件
关闭文件
文件定位
获取文件大小
文件读取
EDX=21
EBX= 文件名
EAX= 文件句柄(为 0 时表示打开失败)(由操作系统返回)
EDX=22
EAX= 文件句柄
EDX=23
EAX= 文件句柄
ECX= 定位模式
        =0:定位的起点为文件开头
        =1:定位的起点为当前的访问位置
        =2:定位的起点为文件末尾
EBX= 定位偏移量
EDX=24
EAX= 文件句柄
ECX= 文件大小获取模式
       =0:普通文件大小
       =1:当前读取位置从文件开头起算的偏移量
       =2:当前读取位置从文件末尾起算的偏移量
EAX= 文件大小(由操作系统返回)
EDX=25
EAX= 文件句柄
EBX= 缓冲区地址
ECX= 最大读取字节数
EAX= 本次读取到的字节数(由操作系统返回)
/*                    bootpack.h                    */
struct TASK {
    (中略)
    int ds_base, cons_stack;
    struct FILEHANDLE *fhandle; /*从此开始*/
    int *fat; /*到此结束*/
};
struct FILEHANDLE { /*从此开始*/
    char *buf;
    int size;
    int pos;
}; /*到此结束*/

/*                    console.c                    */
void console_task(struct SHEET *sheet, int memtotal)
{
    (中略)
    struct FILEHANDLE fhandle[8];
    (中略)
    for (i = 0; i < 8; i++) 
        fhandle[i].buf = 0; /*未使用标记*/
    task->fhandle = fhandle;
    task->fat = fat;
    (中略)
}

if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {//cmd_app代码片段
    (中略)
    start_app(0x1b, 0 * 8 + 4, esp, 1 * 8 + 4, &(task->tss.esp0));
    (中略)
    for (i = 0; i < 8; i++) { /*将未关闭的文件关闭*/ /*从此开始*/
        if (task->fhandle[i].buf != 0) {
            memman_free_4k(memman, (int) task->fhandle[i].buf, task->fhandle[i].size);
            task->fhandle[i].buf = 0;
        }
    } /*到此结束*/
    (中略)
}

int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax){
	(中略)
	struct FILEINFO *finfo;
	struct FILEHANDLE *fh;
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	(中略)
/*开始*/}else if(edx == 21){//打开文件
		for(i = 0; i < 8; i++){
			if(task->fhandle[i].buf == 0)
				break;
		}
		fh = &task->fhandle[i];
		reg[7] = 0;
		if(i < 8){
			finfo = file_search((char*)ebx+ds_base, (struct FILEINFO*)(ADR_DISKIMG+0x002600), 224);
			if(finfo != 0){
				reg[7] = (int)fh;
				fh->buf = (char *) memman_alloc_4k(memman, finfo->size);
				fh->size = finfo->size;
				fh->pos = 0;
				file_loadfile(finfo->clustno, finfo->size, fh->buf, task->fat, (char *)
					(ADR_DISKIMG+0x003e00));
			}
		}
	}else if(edx == 22){//关闭文件
		fh = (struct FILEHANDLE*)eax;
		memman_free_4k(memman, (int)fh->buf, fh->size);//与打开文件操作中的memman_alloc_4k对应
		fh->buf = 0;
	}else if(edx == 23){//文件定位
		fh = (struct FILEHANDLE*)eax;
		if(ecx == 0){//定位的起点为文件开头
			fh->pos = ebx;
		}else if(ecx == 1){//定位的起点为当前的访问位置
			fh->pos += ebx;
		}else if(ecx == 2){//定位的起点为文件末尾
			fh->pos = fh->size + ebx;
		}
		if(fh->pos < 0)fh->pos = 0;
		if(fh->pos > fh->size)fh->pos = fh->size;
	}else if(edx == 24){//获取文件大小
		fh = (struct FILEHANDLE*)eax;
		if(ecx == 0){//普通文件大小
			reg[7] = fh->size;
		}else if(ecx == 1){//当前读取位置从文件开头起算的偏移量
			reg[7] = fh->pos;
		}else if(ecx == 2){//当前读取位置从文件末尾起算的偏移量
			reg[7] = fh->pos - fh->size;
		}
	}else if(edx == 25){//文件读取,写入到ebx缓存区中
		fh = (struct FILEHANDLE*)eax;
		for(i = 0; i < ecx; i++){
			if(fh->pos == fh->size)break;
			*((char *) ebx + ds_base + i) = fh->buf[fh->pos];
			fh->pos++;
		}
		reg[7] = i;
/*结束*/}
	return 0;
}