《匠人手记》推荐网上购书渠道:
互动出版网(china-pub)购书入口   >>>
当当网(dangdang)购书入口   >>>
卓越亚马逊网 购书入口   >>>
淘宝网(taobao)购书入口   >>>
更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

 匠人观点: 好记性不如烂笔头  
 黑色幽默:三鹿门——后世畅想

锁硬盘逻辑盘程序
程序匠人 发表于 2006-3-31 19:40:00  阅读全文 | 回复(0) | 引用通告 | 编辑


锁硬盘逻辑盘程序


随着微处理器的更新换代,目前一般的中高档微机均配备有一个容量很大的硬盘机,小则几十MB,多则上百
MB。在硬盘上要同时安装许多公软件和用户文件,通常用户文件大多是个人的私有信息,不愿让他人随意查看
和复制。报刊上介绍了多种硬盘的加密方法,多数是独占整个硬盘,禁止让不知道口令的用户使用。本人通过
对硬盘逻辑盘结构的详细分析,提出了对硬盘的一个逻辑盘进行加密的有效方法,达到了独占一个硬盘逻辑盘
的目的,从而圆满地解决了上述问题。

一、逻辑盘的内部结构

FDISK把硬盘主引导记录存放在硬盘的第一个物理扇区,即0面0柱1扇区,在该扇区的1BEH-1FDH处(共64个字
节)是硬盘的分区表,我们称这个分区表为主分区表,它由4个16字节的登记项组成,每个登记项描述一个特定
的分区,其中各字节代表的意义见表1。
                    表1.分区表登记项各字节的意义
┌──┬──┬───────┬──┬───────┬───┬───┐
│ 意 │启动│   分区开始   │系统│   分区结束   │相对扇│扇 区 │
│ 义 │标志│头  扇区  柱体│标志│头  扇区  柱体│区数  │总 数 │
├──┼──┼───────┼──┼───────┼───┼───┤
│偏移│ 00 │01   02    03 │ 04 │05   06    07 │08-11 │12-15 │
└──┴──┴───────┴──┴───────┴───┴───┘
其中“系统标志”字节可以取以下不同的值:
    01:DOS分区,该分区FAT表每项为12位;
    02:XENIX分区;
    04:DOS分区,该分区FAT表每项为16位;
    05:扩展DOS分区;
    06:大DOS分区,为MS DOS 4.00以上DOS版本在管理大于32MB盘或逻辑分区时所使用的标志,分区的
    FAT表每项为16位。
MS/PC DOS 3.30的FDISK程序把初始DOS分区信息放在主分区表的第一个登记项,而第二个登记项为扩展DOS分
区信息,其余登记项为空。初始DOS分区代表C逻辑盘,扩展DOS分区的划分要根据它自己的分区表而定。扩展
DOS分区的第一个扇区上记录有该扩展DOS分区的划分信息,这个分区被称为第一扩展DOS分区表,其中的第一
个登记项记录着D逻辑盘的信息,第二个登记项记录了第二个扩展DOS分区的信息;第二个扩展DOS分区的第一
个扇区记录了该扩展DOS分区的信息,其第一个登记项记录了E逻辑盘的信息,第二个登记项记录了第三个扩展
DOS分区的信息;依此类推,可以找到所有扩展分区的信息。表2列出了一个62MB硬盘的所有分区信息。由表
2可以知道,FDISK把硬盘的分区信息,以链表格式存放在硬盘的不同物理扇区上,每一个逻辑盘均有一个对
应的分区信息表,且与一个物理扇区一一对应,如C盘与0面0柱1扇区对应,D盘与0面90柱1扇区对应。
                       表2. 一个62MB硬盘分区信息表
┌────┬───┬──┬─────┬─────┬───┬───┬──┐
│ 定  位 │系  统│启动│ 分区开始 │ 分区结束 │相  对│总  扇│逻辑│
│面 柱 扇│标  志│标志│面  柱  扇│面  柱  扇│扇  区│区  数│ 盘 │
├────┼───┼──┼─────┼─────┼───┼───┼──┤
│0   0  1│DOS-12│Yes │1    0  1 │7   89  26│    26│ 18694│  C │
│        │EXTEND│No  │0   90  1 │7  613  26│ 18720│108992│    │
├────┼───┼──┼─────┼─────┼───┼───┼──┤
│0  90  1│DOS-16│No  │1   90  1 │7  289  26│    26│ 41574│  D │
│        │EXTEND│No  │0  290  1 │7  389  26│ 41600│ 20800│    │
├────┼───┼──┼─────┼─────┼───┼───┼──┤
│0 290  1│DOS-16│No  │1  290  1 │7  389  26│    26│ 20774│  E │
│        │EXTEND│No  │0  390  1 │7  613  26│ 62400│ 46592│    │
├────┼───┼──┼─────┼─────┼───┼───┼──┤
│0 390  1│DOS-16│No  │1  390  1 │7  613  26│    26│ 46566│  F │
└────┴───┴──┴─────┴─────┴───┴───┴──┘

二、硬盘数据保密的原理

DOS对逻辑盘的管理是通过一个单链将若干个相互独立的连续盘区联系起来,每个连续的盘区均有一套完整的
分区引导记录、FAT、文件目标和数据区。DOS在启动过程中,根据每个分区表中每个登记项的系统标志字节的
内容来识别逻辑分区,如果该字节的值为DOS分区的有效值,则DOS将其视为有效分区,系统启动后,用户通过
一逻辑盘使用这个分区;否则认为是无效分区,系统启动后,不为这个分区分配逻辑盘符,用户也就无法使用
此分区,其数据也就暂时“隐含”起来了。
根据上述原理,我们可以使用BIOS提供的13H号中断完成硬盘分区表的读写和系统标志字节的更改,实现逻辑
分区的锁闭与解锁,达到个人数据和机密数据的安全与保密。

三、程序设计及其使用方法

程序设计的基本思路是:首先把分区表链读入内存,分析各分区的状态,根据用户的要求,若对某一分区加锁
,则判断该分区的当前状态,如已锁,则返回,否则,对代表该分区的登记项的系统标志字节求反,提示用户
输入口令,最后将修改了的分区表写回对应的物理扇区,重新启动机器后,该分区就“消失”了;解锁的过程
基本同上,不过多了一道校验口令的过程。
本人应用TURBO C 2.0编写了一个程序HDL.C,经过编译生成执行文件后,在DOS系统下直接运行,能方便地
完成硬盘逻辑分区的锁闭与解锁,并且可以加上用户自己的口令,某逻辑盘锁了以后,不知道口令的用户是
无法打开的。
    程序的使用方法很简单,其使用格式为:
        HDL <d:> </switch>
其中d为逻辑分区对应的盘符,如C、D等,switch为选择开关,可以选:
    L -- 为锁逻辑分区;
    U -- 为解锁逻辑分区;
尖括号代表参数可以缺省。例如直接执行“HDL”显示程序的帮助信息;执行“HDL D:”显示D逻辑盘的当
前状态;执行“HDL D: /L”锁D逻辑盘。

四、源程序清单
/********************************************************/
/*  程序名称: HDL.C 1.10                                */
/*  作    者: 董占山                                    */
/*  完成日期: 1992,1995                                 */
/*  用    途: 对指定的硬盘逻辑分区加锁或解锁            */
/*  编译方法: 用下列命令编译连接可以得到HDL.COM:        */
/*  tcc -mt hdl                                         */
/*  tlink c:\tc\lib\c0t+hdl,hdl,,c:\tc\lib\cs\lib /t    */
/********************************************************/

#i nclude <stdio.h>
#i nclude <process.h>
#i nclude <dos.h>
#i nclude <string.h>

#define TRUE 1;
#define FALSE 0;

/* 定义分区表结构 */
struct PartitionTypeTemp
     {
        unsigned char BootIndicator,StartHead,StartSector,StartCylinder,
      SysIndicator,EndHead,EndSector,EndCylinder;
        unsigned int  RelativeSector2,RelativeSector1,TotalSector2,
                      TotalSector1;
      } ;

/* 定义主引导记录的扇区结构 */
struct  MBRT
    {
         unsigned char MainBoot[446]; /* 引导程序 */
         struct PartitionTypeTemp PartitionTable[4]; /* 分区表 */
         unsigned char Token[2]; /* 启动标志 */
    } ;

struct MBRT Buffer[25];             /* 存储全部分区的信息 */
unsigned char DriveState[25];       /* 存储各个分区的当前状态 */
unsigned char DriveNum,Switch,Drive;/* 逻辑分区数等 */

void init(void);
void GetParameter(int argc, char *argv[]);
void GetAllPartition(void);
void Works(void);
void Help(void);
void GetDriveState(void);
void PrintError(char Str[]);
void ProcessAbsSector(unsigned char OperateType,unsigned char DriveType,
     unsigned char HeadNo,unsigned char StartCyl,unsigned char StartSec,
     unsigned char SectorNumber,struct MBRT *p);
void ReadPartition(struct MBRT *p,unsigned char StartCyl,unsigned char StartSec);
void WritePartition(struct MBRT *p,unsigned char StartCyl,unsigned char StartSec);
void GetAllPartition();
unsigned char FindExtendedPartition(struct MBRT p);
unsigned char FindDosPartition(struct MBRT p1);
void reboot(void);
char readkey(void);
char *ReadPassWord(void);
void SetPassword(struct MBRT *p1);
char GetPassword(struct MBRT p1);
void LockDrive(void);
void UnlockDrive(void);
void Works(void);
void GetDriveState(void);

/* 主程序 */
main(argc,argv)
int argc;
char *argv[];
{
  printf("HDL version 1.10 Copyright (C) 1992,1995 by Dong Zhanshan\n");
  printf("This program may lock and unlock the logical drive of hard disk.\n");
  init();
  GetParameter(argc,argv);
  GetAllPartition();
  if (Drive != '\0')
    if (Drive =='A' || Drive =='B')
       PrintError("This is a floppy diskette !\n");
    else if (Drive >= 'C')
if (Drive - 'B' > DriveNum)
   PrintError("There is not the logical drive !\n");
  switch (argc) {
      case 1  : Help(); break;
      case 2  : GetDriveState(); break;
      case 3  : Works();break;
      default : PrintError("Too many parameters !\n");
  }
  return 0;
}

/* 显示程序的使用方法 */
void Help()
{
  printf("Syntax:   HDL [d:] [/Switch]\n");
  printf("Switch:   L = Lock the specifed drive\n");
  printf("          U = Unlock the specifed drive\n");
  printf("Examples: HDL       -- Display help text\n");
  printf("          HDL D:    -- Display the state of drive D:\n");
  printf("          HDL D: /L -- Lock the drive D:\n");
  printf("          HDL D: /U -- Unlock the drive D:\n");
}

/* 显示错误信息并中断程序执行 */
void PrintError(s)
char *s;
{
  printf(s);
  exit(256);
}

/* 初始化数据变量 */
void init()
{
  unsigned int i;
  Drive = '\0';
  for (i=1; i<26; i++) DriveState[i] = FALSE;
}

/* 读取所有硬盘分区的信息 */
void GetAllPartition()
{
  unsigned char i,j,k,StartCyl,StartSec;
  struct MBRT p;
  i = 0;
  StartCyl = 0;
  StartSec = 1;
  do {
    ReadPartition(&p,StartCyl,StartSec);
    j = FindExtendedPartition(p);
    StartCyl = p.PartitionTable[j].StartCylinder;
    StartSec = p.PartitionTable[j].StartSector;
    Buffer[++i] = p;
    k = FindDosPartition(p);
    if ((p.PartitionTable[k].SysIndicator == 1)
|| (p.PartitionTable[k].SysIndicator == 4)
|| (p.PartitionTable[k].SysIndicator == 6))
    DriveState[i] = TRUE;
  } while (j != 0);
  DriveNum = i;
}

/* 执行读写指定磁盘物理扇区的信息 */
void ProcessAbsSector(OperateType,DriveType,HeadNo,StartCyl,StartSec,SectorNumber,p)
unsigned char OperateType,DriveType,HeadNo,StartCyl,StartSec,SectorNumber;
struct MBRT *p;
{
  asm push es
  asm push ds
  asm pop es
  asm mov bx,p              /* address of buffer */
  asm mov ch,StartCyl       /* starting cylinder */
  asm mov cl,StartSec       /* Starting sector */
  asm mov dh,HeadNo         /* Head No. */
  asm mov dl,DriveType      /* Drive type */
  asm mov ah,OperateType    /* operation */
  asm mov al,SectorNumber   /* Number of sector */
  asm int 0x13
  asm pop es
}

/* 读硬盘物理扇区 */
void ReadPartition(p,StartCyl,StartSec)
struct MBRT *p;
unsigned char StartCyl,StartSec;
{
  ProcessAbsSector(2,0x80,0,StartCyl,StartSec,1,p);
}

/* 写硬盘物理扇区 */
void WritePartition(p,StartCyl,StartSec)
struct MBRT *p;
unsigned char StartCyl,StartSec;
{
  ProcessAbsSector(3,0x80,0,StartCyl,StartSec,1,p);
}

/* 找扩展DOS分区在分区表中的位置 */
unsigned char FindExtendedPartition(p1)
struct MBRT p1;
{
  unsigned char i;
  for (i=0;i<4;i++) {
    if ((p1.PartitionTable[i].SysIndicator == 5)
       || ((~p1.PartitionTable[i].SysIndicator) == 5)) return(i);
  }
  return(0);
}

/* 找DOS分区在分区表中的位置 */
unsigned char FindDosPartition(p1)
struct MBRT p1;
{
  unsigned char i;
  for (i=0;i<4;i++) {
    if ((p1.PartitionTable[i].SysIndicator == 1)  /* FAT12 DOS分区 */
       || ((~p1.PartitionTable[i].SysIndicator) == 1)
       || (p1.PartitionTable[i].SysIndicator == 4)  /* FAT16 DOS分区 */
       || ((~p1.PartitionTable[i].SysIndicator) == 4)
       || (p1.PartitionTable[i].SysIndicator == 6)  /* 大DOS分区 */
       || ((~p1.PartitionTable[i].SysIndicator) == 6) ) return(i);
  }
  return(0);
}

/* 重新起动计算机 */
void reboot()
{
  __emit__(0xEA,0x00,0x00,0xFF,0xFF);   /* jmp FFFF:0000 */
}

/* 从键盘上读一个字符 */
char readkey()
{
  asm mov ah,07
  asm int 21h
}

/* 读口令字 */
char *ReadPassWord()
{
  char ch;
  char *tstr;
  static char tstr1[7];
  unsigned i;
  i = 0;
  tstr = tstr1;
  do {
    ch = readkey();
    switch ( ch ) {
      case '\0'  : ch = readkey();break;
      case '\r' : ;
      case '\x1B' : {
                    *tstr='\0';
                    break;
                    }
      default    : {
                     i++;
                     *tstr++=ch;
                     *tstr='\1';
                     putchar('X');
                     if (i==6) *tstr='\0';
                    }
    }
  } while (! *tstr=='\0');
  return(tstr1);
}

/* 设置口令 */
void SetPassword(p1)
struct MBRT *p1;
{
  char tstr1[7],tstr2[7],*ReadPassWord();
  do {
    printf("Please enter password: ");
    strcpy(tstr1,ReadPassWord());
    printf("\n");
    printf("Please enter password again: ");
    strcpy(tstr2,ReadPassWord());
    printf("\n");
  } while (strcmp(tstr1,tstr2));
  memcpy(&p1->MainBoot[437],tstr1,7);
}

/* 获取并校验口令 */
char GetPassword(p1)
struct MBRT p1;
{
  char tstr1[7],tstr2[7],*ReadPassWord();
  printf("Please enter password: ");
  strcpy(tstr1,ReadPassWord());
  printf("\n");
  memcpy(tstr2,&p1.MainBoot[437],7);
  return(! strcmp(tstr1,tstr2) );
}

/* 锁逻辑分区 */
void LockDrive()
{
  unsigned char StartCyl,StartSec,i,j;
  i = Drive - 'C' + 1;
  if (DriveState[i]) {
    if (i==1) {
       StartCyl = 0;
       StartSec = 1;
       }
    else  {
       j = FindExtendedPartition(Buffer[--i]);
       StartCyl = Buffer[i].PartitionTable[j].StartCylinder;
       StartSec = Buffer[i].PartitionTable[j].StartSector;
       }
    j = FindDosPartition(Buffer[++i]);
    Buffer[i].PartitionTable[j].SysIndicator =
       (~Buffer[i].PartitionTable[j].SysIndicator);
    SetPassword(&Buffer[i]);
    WritePartition(&Buffer[i],StartCyl,StartSec);
    printf("The drive %c: has been locked !\n",Drive);
    reboot();
    }
  else
    printf("The drive %c: is locked !\n",Drive);
}

/* 解锁逻辑分区 */
void UnlockDrive()
{
  unsigned char StartCyl,StartSec,i,j;
  i = Drive - 'C' + 1;
  if (! DriveState[i]) {
    if (GetPassword(Buffer[i])) {
       if (i==1) {
          StartCyl = 0;
          StartSec = 1;
          }
       else  {
          j = FindExtendedPartition(Buffer[--i]);
          StartCyl = Buffer[i].PartitionTable[j].StartCylinder;
          StartSec = Buffer[i].PartitionTable[j].StartSector;
          }
       j = FindDosPartition(Buffer[++i]);
       Buffer[i].PartitionTable[j].SysIndicator =
          (~Buffer[i].PartitionTable[j].SysIndicator);
       WritePartition(&Buffer[i],StartCyl,StartSec);
       printf("The drive %c: has been unlocked !\n",Drive);
       reboot();
       }
    else
       printf("Your password is error, the drive c%: may not be unlocked !\n",Drive);
    }
  else
    printf("The drive %c: is unlocked !\n",Drive);
}

/* 执行加锁和解锁任务 */
void Works()
{
  switch (Switch) {
    case 'L' : LockDrive();break;
    case 'U' : UnlockDrive();
  }
}

/* 取得指定逻辑分区的状态 */
void GetDriveState()
{
  unsigned char i;
  i = Drive - 'C' + 1;
  if (DriveState[i])
     printf("The drive %c: is unlocked !\n",Drive);
  else
     printf("The drive %c: is locked !\n",Drive);
}

/* 分析命令行参数 */
void GetParameter(argc,argv)
int argc;
char *argv[];
{
  char *TempStr,TempChar;
  if (argc > 1) {
    TempStr = argv[1];
    strupr(TempStr);
    if (TempStr[1]==':') {
      TempChar = TempStr[0];
      if (TempChar >= 'A' && TempChar <= 'Z')
         Drive = TempChar;
      else
         PrintError("Does not exist this drive !\n");
      }
    else
      PrintError("The first parameter is error !\n");
    }
  if (argc > 2) {
     TempStr = argv[2];
     strupr(TempStr);
     if (TempStr[0]=='/') {
       TempChar = TempStr[1];
       if (TempChar=='L' || TempChar=='U')
          Switch = TempChar;
       else
          PrintError("The switch is error !\n");
       }
     else
       PrintError("The second parameter is error !\n");
     }
}

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    往日酷贴

     
     
     

    大千八卦

    友情连接

    新浪新闻:
    新浪财经:
    AK58新闻:
    新浪股票:
    新浪股票:
    证券之星:

     [更多酷站连接]

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [柔月阁]

    [八楼的呼吸]

    [hotpower 的水潭]

    [xwj的文君阁]

    [所长的BLOG]

    [阿摆手记]

    [电子伙伴]

    [unaided的笔记]

    [小飞的笔记]

    [单片机开发联盟]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [数字电视之家]

    [SMARTCODE电子书斋]

    [软件开发之窗]

    [Armoric]

    [我爱研发网]

    [infernal的笔记]

    [雄鹰的空中加油站]

    [SunK]

    [逍遥电子]

    [ningpanda的博客]

    [C-Design]

    [一网见天下]

    [海边淘沙]

    [嵌入式365]

    [水牛的仓库]

    [股剩是怎样炼成的]

    [PIC论坛]

    [ICC AVR开发网]

    [中国高校自动化网]

     

     

     

    MCU博客-中国电子工程师博客网 

    大学生电子网 

     

     

     

     

     

    !!! 《匠人的百宝箱》 !!!