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

📄 expios.c

📁 grub for dos ,people can use it in dos for calling linux
💻 C
字号:
// This utility is used to test the expansion function

#ifdef __unix
#include <unistd.h>
#else
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

#ifndef O_BINARY
#define O_BINARY	0
#endif

#define	grub_putstr	puts

void quit(char* msg)
{
  grub_putstr(msg);
  exit(1);
}

static int ibuf_pos;
static char *ibuf_ptr,*obuf_ptr;
static unsigned short ibuf_tab[16];

void ibuf_init(char* buf)
{
  int i;

  ibuf_ptr=buf;
  ibuf_pos=0;

  // ibuf_tab[i]=(1<<(i+1))-1
  ibuf_tab[0]=1;
  for (i=1;i<16;i++)
    ibuf_tab[i]=ibuf_tab[i-1]*2+1;
}

unsigned short ibuf_read(int nbits)
{
  unsigned short res;

  res=(unsigned short)((*((unsigned long*)ibuf_ptr)>>ibuf_pos) & ibuf_tab[nbits-1]);
  ibuf_pos+=nbits;
  if (ibuf_pos>=8)
    {
      ibuf_ptr+=(ibuf_pos>>3);
      ibuf_pos&=7;
    }
  return res;
}

#define obuf_init(buf)		obuf_ptr=buf
#define obuf_putc(ch)		*(obuf_ptr++)=ch
#define obuf_copy(ofs,len)	do { for (;len>0;obuf_ptr++,len--) *(obuf_ptr)=*(obuf_ptr-ofs); } while (0)
// Don't use memcpy, otherwise we could be screwed !

int expand_block(int nsec)
{
  while (nsec>0)
    {
      int cnt;

      cnt=0x200;
      while (1)
        {
          int flg,ofs,bts,bse,del,len;

          flg=ibuf_read(2);

          if (flg==0) ofs=ibuf_read(6); else
            if (flg==3)
              {
                if (ibuf_read(1))
                  {
                    ofs=ibuf_read(12)+0x140;
                    if (ofs==0x113F)
                      break;
                  }
                else
                  ofs=ibuf_read(8)+0x40;
              } else
                {
                  char ch;

                  cnt--;
                  if (cnt<0)
                    {
                      grub_putstr("Data corrupted");
                      return 1;
                    }
                  ch=ibuf_read(7);
                  if (flg & 1)
                    ch|=0x80;
                  obuf_putc(ch);
                  continue;
                }
          if (ofs==0)
            {
              grub_putstr("Data corrupted");
              return 1;
            }
          bse=2;
          del=0;
          for (bts=0;bts<9;bts++)
            {
              if (ibuf_read(1))
                break;
              bse+=del+1;
              del=del*2+1;
            }
          if (bts==9)
            {
              grub_putstr("Data corrupted");
              return 1;
            }
          len=(bts)?bse+ibuf_read(bts):bse;
          if ((cnt=cnt-len)<0)
            {
              grub_putstr("Data corrupted");
              return 1;
            }
          obuf_copy(ofs,len);
        }
      nsec--;
      if ((cnt) && (nsec))
        {
          grub_putstr("Data corrupted");
          return 1;
        }
    }
  return 0;
}

long expand_file(char* src,char* dst)
{
  ibuf_init(src);
  obuf_init(dst);

  if (ibuf_read(16)!=0x4D43)
    {
      grub_putstr("First CM signature not found");
      return -1;
    }
  while (1)
    {
      unsigned short flg,len;

      flg=ibuf_read(8);
      len=ibuf_read(16);
      if (len==0)
        {
          int n;

          n=(ibuf_ptr-src) & 0xF;
          if ((n) || (ibuf_pos))
            {
              ibuf_ptr+=16-n;
              ibuf_pos=0;
            }
          if (ibuf_read(16)!=0x4D43)
            {
              grub_putstr("Second CM signature not found");
              return -1;
            }
          return obuf_ptr-dst;
        }
      if (flg==0)
        {
          memcpy(obuf_ptr,ibuf_ptr,len);
          ibuf_ptr+=len;
          obuf_ptr+=len;
        }
      else
        {
          char* save_ptr;
          unsigned short sec;

          sec=(ibuf_read(16)+511)>>9;
          save_ptr=ibuf_ptr;
          if (ibuf_read(16)!=0x5344)
            {
              grub_putstr("0x5344 signature not found");
              return -1;
            }
          ibuf_read(16);
          if (expand_block(sec))
            return -1;
          ibuf_ptr=save_ptr+len;
          ibuf_pos=0;
        }
    }
}

int main(int argc,char** argv)
{
  int hd;
  char *src,*dst;
  long len0,len1;

  if (argc<2)
    {
      grub_putstr("Usage:\n expios input [output]");
      exit(1);
    }
  if ((hd=open(argv[1],O_RDONLY | O_BINARY))<0)
    quit("Can\'t open input file");
  if ((len0=lseek(hd,0,SEEK_END))==-1L)
    quit("Can\'t get the file size");
  if (len0>=0xA0000)
    quit("File too large to be IO.SYS");
  lseek(hd,0,SEEK_SET);
  if (((src=malloc(len0))==NULL) || ((dst=malloc(0xA0000))==NULL))
    quit("Not enough memory");
  if (read(hd,src,len0)!=len0)
    quit("Read from input file fails");
  close(hd);
  if ((*((unsigned short*)src)!=0x5A4D) || (*((unsigned short*)(src+0x7FE))!=0x534D))
    quit("Input file is not a valid IO.SYS");
  memcpy(dst,src,0x800);
  if ((len1=expand_file(src+0x800,dst+0x800))<0)
    exit(1);
  len1+=0x800;
  free(src);
  if (argc>=3)
    {
      if ((hd=open(argv[2],O_RDWR | O_CREAT | O_TRUNC | O_BINARY,S_IREAD | S_IWRITE))<0)
        quit("Can\'t open output file");
      if (write(hd,dst,len1)!=len1)
        quit("Write to output file fails");
      close(hd);
    }
  free(dst);
  return 0;
}

⌨️ 快捷键说明

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