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

📄 partition.c

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Rule format: * * +------+------+------+------+ * |drive |offset|expect| set  | * +------+------+------+------+ *     0      1      2      3 */static void add_rule(unsigned char bios,unsigned char offset,  unsigned char expect,unsigned char set){    int i;    if (curr_prt_map == PRTMAP_SIZE)	cfg_error("Too many change rules (more than %s)",PRTMAP_SIZE);    if (verbose >= 3)	printf("  Adding rule: disk 0x%02x, offset 0x%x, 0x%02x -> 0x%02x\n",	    bios,PART_TABLE_OFFSET+offset,expect,set);    prt_map[curr_prt_map] = (set << 24) | (expect << 16) | (offset << 8) | bios;    for (i = 0; i < curr_prt_map; i++) {	if (prt_map[i] == prt_map[curr_prt_map])	  die("Repeated rule: disk 0x%02x, offset 0x%x, 0x%02x -> 0x%02x",	    bios,PART_TABLE_OFFSET+offset,expect,set);	if ((prt_map[i] & 0xffff) == ((offset << 8) | bios) &&	  (prt_map[i] >> 24) == expect)	    die("Redundant rule: disk 0x%02x, offset 0x%x: 0x%02x -> 0x%02x "	      "-> 0x%02x",bios,PART_TABLE_OFFSET+offset,	     (prt_map[i] >> 16) & 0xff,expect,set);    }    curr_prt_map++;}#endifstatic int has_partition;static CHANGE_RULE *may_change(unsigned char sys_ind){    CHANGE_RULE *cr = change_rules;        while (cr) {        if (cr->normal == sys_ind || cr->hidden == sys_ind) return cr;        cr = cr->next;    }    return NULL;}void do_cr_auto(void){    GEOMETRY geo;    struct stat st;    char *table, *table2, *other;    int partition, pfd, i, j;    struct partition part_table[PART_MAX];    if (autoauto) has_partition = 0;    other = cfg_get_strg(cf_top, "other");    if (verbose > 4) printf("do_cr_auto: other=%s has_partition=%d\n",        other, has_partition);#if 0    i = other[strlen(other)-1] - '0';    if (i>PART_MAX || i<1) return;#endif    table = cfg_get_strg(cf_other,"table");    table2 = boot_mbr(other, 1);	/* get possible default */    if (!table) table = table2;        if (!table && autoauto) return;    if (table && autoauto && !table2) cfg_error("TABLE may not be specified");       if (has_partition) cfg_error("AUTOMATIC must be before PARTITION");    if (!table) cfg_error("TABLE must be set to use AUTOMATIC");    /*         */    if (stat(table,&st) < 0) die("stat %s: %s",table,strerror(errno));    geo_get(&geo,st.st_rdev & D_MASK(st.st_rdev),-1,1);    partition = st.st_rdev & P_MASK(st.st_rdev);    if (!S_ISBLK(st.st_mode) || partition)	cfg_error("\"%s\" doesn't contain a primary partition table",table);    pfd = open(table, O_RDONLY);    if (pfd<0) die("Cannot open %s", table);    if (lseek(pfd, PART_TABLE_OFFSET, SEEK_SET)!=PART_TABLE_OFFSET)	die("Cannot seek to partition table of %s", table);    if (read(pfd, part_table, sizeof(part_table))!=sizeof(part_table))	die("Cannot read Partition Table of %s", table);    close(pfd);    partition = other[strlen(other)-1] - '0';    if (verbose > 3) printf("partition = %d\n", partition);    for (j=i=0; i<PART_MAX; i++)	if (may_change(part_table[i].sys_ind)) j++;    if (j>1)#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY)    for (i=0; i<PART_MAX; i++) {    	CHANGE_RULE *cr;	if ((cr=may_change(part_table[i].sys_ind))) {	    j = i*PARTITION_ENTRY + PART_TYPE_ENT_OFF;	    if (autoauto && !nowarn) {	    	fflush(stdout);	        fprintf(errstd, "Warning: CHANGE AUTOMATIC assumed after \"other=%s\"\n", other);	        autoauto = 0;  /* suppress further warnings */	    }    	    if (i == partition-1)		add_rule(geo.device, j, cr->hidden, cr->normal);	    else		add_rule(geo.device, j, cr->normal, cr->hidden);	}    }#else    if (!nowarn) fprintf(errstd,       "Warning:  This LILO is compiled without REWRITE_TABLE;\n"       "   unable to generate CHANGE/AUTOMATIC change-rules\n");#endif}void do_cr_part(void){    GEOMETRY geo;    struct stat st;    char *tmp;    int partition,part_base;    tmp = cfg_get_strg(cf_change,"partition");    if (stat(tmp,&st) < 0) die("stat %s: %s",tmp,strerror(errno));    geo_get(&geo,st.st_rdev & D_MASK(st.st_rdev),-1,1);    partition = st.st_rdev & P_MASK(st.st_rdev);    if (!S_ISBLK(st.st_mode) || !partition || partition > PART_MAX)	cfg_error("\"%s\" isn't a primary partition",tmp);    part_base = (partition-1)*PARTITION_ENTRY;    has_partition = 1;       cfg_init(cf_change_dsc);    (void) cfg_parse(cf_change_dsc);    tmp = cfg_get_strg(cf_change_dsc,"set");    if (tmp) {#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY)	CHANGE_RULE *walk;	char *here;	int hidden;	here = (void*)NULL;	/* quiet GCC */	hidden = 0;		/* quiet GCC */	if (strlen(tmp) < 7 || !(here = strrchr(tmp,'_')) ||	  ((hidden = strcasecmp(here+1,"normal")) &&	  strcasecmp(here+1,"hidden")))	    cfg_error("Type name must end with _normal or _hidden");	*here = 0;	for (walk = change_rules; walk; walk = walk->next)	    if (!strcasecmp(walk->type,tmp)) break;	if (!walk) cfg_error("Unrecognized type name");	add_rule(geo.device,part_base+PART_TYPE_ENT_OFF,hidden ? walk->normal :	  walk->hidden,hidden ? walk->hidden : walk->normal);#else	die("This LILO is compiled without REWRITE_TABLE and doesn't support "	  "the SET option");#endif    }    if (cfg_get_flag(cf_change_dsc,"activate")) {#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY)	add_rule(geo.device,part_base+PART_ACT_ENT_OFF,0x00,0x80);	if (cfg_get_flag(cf_change_dsc,"deactivate"))	    cfg_error("ACTIVATE and DEACTIVATE are incompatible");#else	die("This LILO is compiled without REWRITE_TABLE and doesn't support "	  "the ACTIVATE option");#endif    }    if (cfg_get_flag(cf_change_dsc,"deactivate"))#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY)	add_rule(geo.device,part_base+PART_ACT_ENT_OFF,0x80,0x00);#else	die("This LILO is compiled without REWRITE_TABLE and doesn't support "	  "the DEACTIVATE option");#endif    cfg_unset(cf_change,"partition");}void do_change(void){    cfg_init(cf_change);    has_partition = 0;    (void) cfg_parse(cf_change);}void preload_types(void){#if 0 /* don't know if it makes sense to add these too */    add_type("Netware", 0x64, 0x74);    add_type("OS2_BM", 0x0a, 0x1a);#endif    add_type("OS2_HPFS", 0x07, 0x17);    add_type("FAT16_lba", PART_FAT16_LBA, -1);    add_type("FAT32_lba", PART_FAT32_LBA, -1);    add_type("FAT32", PART_FAT32, -1);    add_type("NTFS", PART_NTFS, -1);    add_type("DOS16_big", PART_DOS16_BIG, -1);    add_type("DOS16_small", PART_DOS16_SMALL, -1);    add_type("DOS12", PART_DOS12, -1);}#define PART_BEGIN	0x1be#define PART_NUM	4#define PART_SIZE	16#define PART_ACTIVE	0x80#define PART_INACTIVE	0void do_activate(char *where, char *which){    struct stat st;    int fd,number,count;    unsigned char flag, ptype;    if ((fd = open(where, !which ? O_RDONLY : O_RDWR)) < 0)	die("open %s: %s",where,strerror(errno));    if (fstat(fd,&st) < 0) die("stat %s: %s",where,strerror(errno));    if (!S_ISBLK(st.st_mode)) die("%s: not a block device",where);    if (verbose >= 1) {       printf("st.st_dev = %04X, st.st_rdev = %04X\n",       				(int)st.st_dev, (int)st.st_rdev);    }    if ((st.st_rdev & has_partitions(st.st_rdev)) != st.st_rdev)        die("%s is not a master device with a primary partition table", where);    if (!which) {	/* one argument: display active partition */	for (count = 1; count <= PART_NUM; count++) {	    if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE,0) < 0)		die("lseek: %s",strerror(errno));	    if (read(fd,&flag,1) != 1) die("read: %s",strerror(errno));	    if (flag == PART_ACTIVE) {		printf("%s%d\n",where,count);		exit(0);	    }	}	die("No active partition found on %s",where);    }    number = to_number(which);    if (number < 1 || number > 4)	die("%s: not a valid partition number (1-4)",which);    for (count = 1; count <= PART_NUM; count++) {	if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE+4,0) < 0)	    die("lseek: %s",strerror(errno));	if (read(fd,&ptype,1) != 1) die("read: %s",strerror(errno));	if (count == number && ptype==0) die("Cannot activate an empty partition");    }    if (test) {        printf("The partition table of  %s  has *NOT* been updated\n",where);    }    else for (count = 1; count <= PART_NUM; count++) {	if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE,0) < 0)	    die("lseek: %s",strerror(errno));	flag = count == number ? PART_ACTIVE : PART_INACTIVE;	if (write(fd,&flag,1) != 1) die("write: %s",strerror(errno));    }    exit(0);}void do_install_mbr(char *where, char *what){    int fd, i;#ifndef LCF_BUILTIN    int nfd;#endif    struct stat st;    char buf[SECTOR_SIZE];        if (!what) what = DFL_MBR;    if ((fd=open(where,O_RDWR)) < 0) die("Cannot open %s: %s", where,strerror(errno));    if (fstat(fd,&st) < 0) die("stat: %s : %s", where,strerror(errno));    if (!S_ISBLK(st.st_mode)) die("%s not a block device",where);    if (st.st_rdev != (st.st_rdev & has_partitions(st.st_rdev)))	die("%s is not a master device with a primary parition table",where);    if (read(fd,buf,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",where, strerror(errno));#ifndef LCF_BUILTIN        if ((nfd=open(what,O_RDONLY)) < 0) die("Cannot open %s: %s",what,strerror(errno));    if (read(nfd,buf,MAX_BOOT_SIZE) != MAX_BOOT_SIZE) die("read %s: %s",what,strerror(errno));#else    memcpy(buf, Mbr.data, MAX_BOOT_SIZE);#endif        *(unsigned short*)&buf[BOOT_SIG_OFFSET] = BOOT_SIGNATURE;    if (zflag) {        char *p = buf+MAX_BOOT_SIZE;        for (i=0; i<8; i++) *p++ = 0;    } else if (*(int*)&buf[PART_TABLE_OFFSET - 6] == 0) {    	i = st.st_rdev;    	i %= 271;		/* modulo a prime number; eg, 2551, 9091 */        srand(time(NULL));	/* seed the random number generator */        while (i--) rand();        *(int*)&buf[PART_TABLE_OFFSET - 6] = rand();  /* insert serial number */        if (*(short*)&buf[PART_TABLE_OFFSET - 2] == 0)            *(short*)&buf[PART_TABLE_OFFSET - 2] = MAGIC_SERIAL;    }        if (lseek(fd,0,SEEK_SET) != 0) die("seek %s; %s", where, strerror(errno));    if (!test) {	if (write(fd,buf,SECTOR_SIZE) != SECTOR_SIZE)		die("write %s: %s",where,strerror(errno));    }    close(fd);#ifndef LCF_BUILTIN    close(nfd);#endif    printf("The Master Boot Record of  %s  has %sbeen updated.\n", where, test ? "*NOT* " : "");    sync();    exit(0);}

⌨️ 快捷键说明

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