⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 page2.cpp

📁 一个简单的操作系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	if(j>=DISK_NUM)
	return(-5);
	fat[j].item=0; /*-将该空闲块设置为已分配-*/

	/*-------------填写目录项----------*/
	strcpy(cur_dir->directitem[i].name,name);
	cur_dir->directitem[i].firstdisk=j;   /*-指向子目录(其实就是其本身)的起始盘块号-*/
	cur_dir->directitem[i].size=ROOT_DISK_SIZE;
	cur_dir->directitem[i].property='1';
	  /*-extend_name是文件扩展名,目录没有,这里可以省略-*/
 
  
	  /*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/
	cur_mkdir=(struct direct *)malloc(sizeof(struct FCB));
  
	/*-初始化目录-*/
	for( k=0;k<MSD;k++) /*-子目录都初始化为空-*/
	{
		cur_mkdir->directitem[k].firstdisk ='F';
		strcpy( cur_mkdir->directitem[k].name,"");
		cur_mkdir->directitem[k].property = '0';
		cur_mkdir->directitem[k].size =0;
		cur_mkdir->directitem[k].extend_name=' ';  
	}
 
	/*-----------------更新磁盘中fat表---------------------*/
	if((fp=fopen("disk.dat","rb+"))==NULL)
	{
		printf("Error:\nCannot open file\n");
		return -11;                                
	} 
	fseek(fp,j,0);
    fwrite(&fat[j].item,1,1,fp);

	/*----------------更新当前目录下的目录项---------------*/
 
	fseek(fp,(curdir_block*64+8*i),0);
	fwrite(&cur_dir->directitem[i],sizeof(struct FCB),1,fp);
 
	/*-----------------把新建目录的目录项写入磁盘-----------*/
	fseek(fp,(cur_dir->directitem[i].firstdisk*DISKSIZE),0);
	fwrite(cur_mkdir,sizeof(struct direct),1,fp);
  	fclose(fp);
	return 0;
}
/*----------------------------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------打开文件----------------------------------------------*/

int CPage2::open(char *name)
{
	 int i, j;
    char extend=' ';
    char name_temp[3]={0};
	
    for(i=0;i<5;)
    if(name[i]!='.')
	{

		name_temp[i]=name[i];
		i++;
	}
	else 
	{      
		i++;
		extend=name[i];
		break;
	}   
   
    for(j=0;j<MSD;j++) /*检查创建文件是否与已存在的文件重名*/
    {
		int k=0;
		while((cur_dir->directitem[j].name[k]!=NULL)&&k<3)
			k++;
		if(k!=int(strlen(name)-2)) continue;
		k=0;
		while(k<int(strlen(name)-2))
		{
			if(cur_dir->directitem[j].name[k]==name_temp[k]) k++;
			else break;
		}          
		if(k>=int(strlen(name)-2)) k=-1;
		if((k==-1)&&(cur_dir->directitem[j].extend_name==extend))
		break;   
    }
    
    if(j>=MSD) /*文件不存在*/
            return(-1);
 /*--------是文件还是目录-----------------------*/  
	if(cur_dir->directitem[j].property=='1')/*是目录,不可打开读写*/
    return(-4);
    i=j;
    /*--------文件是否打开-----------------------*/        
    for(j=0;j<MOFN;j++)
    {
        if(!strcmp(u_opentable.openitem[j].name,name))
		break;
    } 
    if(j<MOFN)  /*文件已经打开*/
        return(-2);
                       
    if(u_opentable.cur_size>=MOFN) /*文件打开太多*/
        return(-3); 

    /*--------查找一个空闲用户打开表项-----------------------*/    
    for(j=0;j<MOFN;j++)
    {
        if(u_opentable.openitem[j].firstdisk=='F')
        break;    
    }
    /*--------------填写表项的相关信息------------------------*/
	
    u_opentable.openitem[j].firstdisk=cur_dir->directitem[i].firstdisk;
    strcpy(u_opentable.openitem[j].name,name);
    u_opentable.openitem[j].size=cur_dir->directitem[i].size;
    u_opentable.cur_size++;
	
    /*----------返回用户打开表表项的序号--------------------------*/
    return(j);
}

void CPage2::print()
{
//	m_display+="****************************************************************  \r\n \t\t  DOS 模拟系统 \r\n ---------------------------------------------------------------------------- \r\n \t\t 创建文件  create 文件名\r\n\t\t 删除文件  delete 文件名\r\n\t\t 显示文件  type 文件名\r\n\t\t 复制文件  copy (路径)文件名   (路径)文件名\r\n\t\t 编辑文件  edit\r\n\t\t 创建子目录  mkdir 目录名\r\n\t\t 删除子目录  deldir 目录名\r\n\t\t 显示当前目录的子目录 dir\r\n\t\t 移动文件    move  (路径)文件名   路径\r\n\t\t 磁盘格式化   format\r\n\t\t 退出系统      halt\r\n\t\t 显示帮助信息   help  \r\n\t---------------------------------------------------------------\r\n";
//	 m_display+="***********************************************************************  \r\n \t\t DOS模拟系统 \r\n --------------------------------------------------------- \r\n \t\t 创建文件: create 文件名\r\n\t\t 删除文件:delete 文件名\r\n\t\t 显示文件:type 文件名\r\n\t\t 编辑文件:edit\r\n\t\t 创建子目录:mkdir 目录名\r\n\t\t 删除子目录:rmdir 目录名\r\n\t\t 显示当前目录的子目录:dir\r\n\t\t 改变目录路径:chdir 目录名 \r\n\t\t 移动文件:move  (路径)文件名   路径\r\n\t\t 磁盘格式化:format\r\n\t\t 退出系统: halt\r\n\t\t 显示帮助信息: help \r\n\t    ---------------------------------------------------------------------------\r\n";
	 m_display+="***********************************************************************  \r\n \t\t DOS模拟系统 \r\n --------------------------------------------------------- \r\n \t\t 创建文件: create 文件名\r\n\t\t 删除文件:delete 文件名\r\n\t\t 显示文件:type 文件名\r\n\t\t 编辑文件:edit  文件名\r\n\t\t 创建子目录:mkdir 目录名\r\n\t\t 删除子目录:rmdir 目录名\r\n\t\t 显示当前目录的子目录:dir\r\n\t\t 改变目录路径:chdir 目录名 \r\n\t\t 显示帮助信息: help \r\n\t    ---------------------------------------------------------------------------\r\n";

}
/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------读文件------------------------------------------------*/

int CPage2::read(int fd, char *buf)
{
		
		int len=u_opentable.openitem[fd].size;
	int i,item,temp;
	int ilen1, modlen;

	item =u_opentable.openitem[fd].firstdisk;
	if(len>u_opentable.openitem[fd].size) /*--欲读出的文件长度比实际文件长度长-*/
	return(-1);

	ilen1 = len/DISKSIZE;
	modlen = len%DISKSIZE;
	if(modlen!=0)
	ilen1 = ilen1+1; /*--计算文件所占磁盘的块数-*/

	for(i=0;i<ilen1;i++)
	{
		if(i==ilen1-1) /*--如果在最后一个磁盘块-*/
		{
			if((fp=fopen("disk.dat","rb"))==NULL)
			{
				printf("Error:\nCannot open file\n");
				return -2;                                
			} 
			fseek(fp,item*64,0);
			temp=len-i*DISKSIZE;
			fread(&buf[i*DISKSIZE],temp,1,fp);
			fclose(fp);
		}
		else /*--不在最后一块磁盘块-*/
		{
			if((fp=fopen("disk.dat","rb"))==NULL)
			{	
				printf("Error:\nCannot open file\n");
				return -2;                                
			} 
			fseek(fp,item*64,0);
			fread(&buf[i*DISKSIZE],DISKSIZE,1,fp);
		    fclose(fp);
			item = fat[item].item; /*-查找下一盘块-*/
		//	first =fdisk+item*DISKSIZE;
			/*CString strLine;
			 m_display+=buf;
			 m_display+="\r\n";
			strLine.Format("%s",m_display);
			GetDlgItem(IDC_EDIT1)->SetWindowText(strLine);*/
		}
	}
	return len;
}
/*----------------------------------------------------------------------------------------------*/
/*---------------------------------------删除子目录---------------------------------------------*/

int CPage2::rmdir(char *name)
{
	
	struct direct *temp_curdir;
    int i,j;
	int k,q,l;
  
	for(j=0;j<MSD;j++) /*-判断是否有重名-*/
	{
		for(k=0;k<(int)strlen(name);)
		{
			 if(cur_dir->directitem[j].name[k]==name[k])  k++;
			 else break;
			 if(k==(int)strlen(name)) {k=-1; break;}
		}
		if((cur_dir->directitem[j].property=='1')&&(k==-1))
		break;
	}
	if(j<MSD)  /*-如果有重名-*/
	{
		i=j;
	    temp_curdir=(struct direct *)malloc(sizeof(struct direct));
		q=cur_dir->directitem[i].firstdisk;
		if((fp=fopen("disk.dat","rb"))==NULL)
		{
			printf("Error:\nCannot open file\n");
			return -11;                                
		} 
		fseek(fp,q*64,0);
		fread(temp_curdir,sizeof(struct direct),1,fp);
		fclose(fp);
		for(l=0;l<MSD;l++) if(temp_curdir->directitem[l].firstdisk!='F') break;
		if(l<MSD)  
		{
			printf("Error:the directory is not empty!\n"); 
			return 0;
		}
		fat[q].item='F'; /*-将该空闲块设置为已分配-*/
		/*-------------填写目录项----------*/
		for(k=0;k<3;k++) cur_dir->directitem[i].name[k]=' ';
		cur_dir->directitem[i].firstdisk='F';   /*-指向子目录(其实就是其本身)的起始盘块号-*/
		cur_dir->directitem[i].size=0;
		cur_dir->directitem[i].property='0';
		  /*-extend_name是文件扩展名,目录没有,这里可以省略-*/
  
		/*-----------------更新磁盘中fat表---------------------*/
		if((fp=fopen("disk.dat","rb+"))==NULL)
		{
			printf("Error:\nCannot open file\n");
			return -11;                                
		} 
		fseek(fp,q,0);
		fwrite(&fat[j].item,1,1,fp);

		/*----------------更新当前目录下的目录项---------------*/
 
		fseek(fp,(curdir_block*64+8*i),0);
		fwrite(&cur_dir->directitem[i],sizeof(struct FCB),1,fp);
   		fclose(fp);
	}
	return 0;

}
/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------写文件------------------------------------------------*/

int CPage2::write(int fd, char *buf, int len)
{
	char item1;
	int i, j;
	short ilen1, ilen2, modlen, temp;
	/*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/
	char Space = 32; /*SPACE的ASCII码值*/
	char Endter= '\n';
 
	for(i=0;i<len;i++)
	{
		if(buf[i] == '$') /*用 $ 字符作为空格*/
		buf[i] = Space;
		else if(buf[i] == '#')
		buf[i] = Endter;
	}

	 /*----------读取用户打开表对应表项第一个盘块号-----------------------*/

	item1 = u_opentable.openitem[fd].firstdisk;

	/*-------------找到当前目录所对应表项的序号-------------------------*/
	for(i=0;i<MSD;i++)
	{
		if(cur_dir->directitem[i].firstdisk==item1)
		break;
	}
	temp = i; /*-存放当前目录项的下标-*/

	 /*------找到的item 是该文件的最后一块磁盘块-------------------*/
	//printf("%d\n",fat[item1].item);
	while((fat[item1].item!='F') &&fat[item1].item>2)                //fat[item1].item>2这个很重要
	{
	   item1=fat[item1].item; /*-查找该文件的下一盘块--*/
	}

	 /*-----计算除该文件的最末地址-------*/
	// first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;
	 if((fp=fopen("disk.dat","rb+"))==NULL)
	 {
		 printf("Error:\nCannot open file\n");
		 return -11;                                
	 }	  
      
		 /*-----如果最后磁盘块剩余的大小大于要写入的文件的大小,把内容写回磁盘-------*/
	 if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len)
	 {
		 fseek(fp,item1*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE,0); //计算除该文件的最末地址:item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE
		 fwrite(buf,len,1,fp);
		 u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; //修改文件打开表
		/*----------修改目录项,并写入磁盘------------------*/
		 cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
		 fseek(fp,curdir_block*64+temp*8+6,0);
		 fwrite(&cur_dir->directitem[temp].size,2,1,fp);
		
	 }
	 else
	 {
	     for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++)
		 {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ 
			 fseek(fp,item1*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE,0);
			 fwrite(buf,(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE),1,fp);
		 }
	   /*-----计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-------*/
	     ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);
	     ilen2 = ilen1/DISKSIZE;  
	     modlen = ilen1%DISKSIZE;
	     if(modlen>0)
		 ilen2 = ilen2+1; /*--还需要多少块磁盘块-*/
		  /*调试时特别注意*/
	     for(j=0;j<ilen2;j++)
		 {
			for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/
			{
				if(fat[i].item=='F')
				break;
			}
		    if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/
		    return(-1);
    
		   if(j==ilen2-1) /*--如果是最后要分配的一块-*/
		   {
			   fseek(fp,i*DISKSIZE,0);
			   fwrite(&buf[DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE+j*DISKSIZE],modlen,1,fp);
		   }
		   else/*-如果不是要最后分配的一块--*/
		   {
			  fseek(fp,i*DISKSIZE,0);
			  fwrite(&buf[DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE+j*DISKSIZE],DISKSIZE,1,fp);
		   }
	/*-------------更新FAT表-----------------------------*/
		  fat[item1].item = i;  /*--找到一块后将它的序号存放在上一块的指针中-*/
		  fat[i].item = 0;  /*--它的指针为 0 (即没有下一块)-*/
		  fseek(fp,item1,0);
		  fwrite(&fat[item1].item ,1,1,fp);
		  fseek(fp,i,0);
		  fwrite(&fat[i].item,1,1,fp);
		  item1=i;
	   }
		 /*--修改文件打开表用户的长度-*/
	   u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;
	   /*--修改目录项的文件长度,并写回磁盘-*/
	   cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
	   fseek(fp,curdir_block*64+temp*8+6,0);
	   fwrite(&cur_dir->directitem[temp].size,2,1,fp);
	}
	   

	fclose(fp);
	return 0;
}

void CPage2::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
		CWnd   *pWnd=GetDlgItem(IDC_STATE);   
          CDC   *pControlDC=pWnd->GetDC();   
          pWnd->Invalidate();   
          pWnd->UpdateWindow();   
          
		 if(color==-1) 
		 {
			  pControlDC->SelectStockObject(R2_BLACK);  
			 for(int i=0;i<128;i++)
			 pControlDC->Rectangle(hardisk_state[i].x1,hardisk_state[i].y1,hardisk_state[i].x2,hardisk_state[i].y2);   //画矩形
			
		 }
		
		 else
		 {
			 pControlDC->SelectStockObject(BLACK_BRUSH); 
			 pControlDC->Rectangle(hardisk_state[disk_num1].x1,hardisk_state[disk_num1].y1,hardisk_state[disk_num1].x2,hardisk_state[disk_num1].y2);   //画矩形

		 }

			 pWnd->ReleaseDC(pControlDC);   


	// Do not call CDialog::OnPaint() for painting messages
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -