自己实现磁盘格式化

来源:互联网 发布:电影资源整站源码 编辑:程序博客网 时间:2024/06/05 19:34

导读:
  如果想在自己的应用程序中加入操作系统的Format(格式化)功能,就象系统的那个format utility,应该怎么做呢?用Google搜索的话,中文资料最多的一篇是《磁盘格式化的编程实现》,讲的是借用SHFormatDrive函数来调用系统的格式化工具完成格式化功能。有没有办法使用自己的代码实现呢?参考sysinternals里的一篇文章,尝试用FMIFS.dll里的一个未公开函数实现了Format功能,所有的参数都由自己给定,比如每簇大小、文件系统等待。这里我只演示了最基本的功能,如果要想程序更健壮些,则还需要做更多的工作。
  FormatEx函数原型:
  VOID FormatEx ( PWCHAR DriveRoot,
  DWORD MediaFlag ,
  PWCHAR Format,
  PWCHAR Label,
  BOOL QuickFormat,
  DWORD ClusterSize,
  PFMIFSCALLBACK Callback);
  其中FMIFSCALLBACK是:
  typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)(
  CALLBACKCOMMAND Command,
  DWORD SubAction,
  PVOID ActionInfo );
  下面是具体工作:
  先定义一个头文件Fmifs.h:
  //======================================================================
  //
  // Fmifs.h
  //
  //======================================================================
  //
  // Output command
  //
  typedef struct {
  DWORD Lines;
  PCHAR Output;
  } TEXTOUTPUT, *PTEXTOUTPUT;
  //
  // Callback command types
  //
  typedef enum {
  PROGRESS,
  DONEWITHSTRUCTURE,
  UNKNOWN2,
  UNKNOWN3,
  UNKNOWN4,
  UNKNOWN5,
  INSUFFICIENTRIGHTS,
  UNKNOWN7,
  UNKNOWN8,
  UNKNOWN9,
  UNKNOWNA,
  DONE,
  UNKNOWNC,
  UNKNOWND,
  OUTPUT,
  STRUCTUREPROGRESS
  } CALLBACKCOMMAND;
  //
  // FMIFS callback definition
  //
  typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)( CALLBACKCOMMAND Command, DWORD SubAction, PVOID ActionInfo );
  //
  // Chkdsk command in FMIFS
  //
  typedef VOID (__stdcall *PCHKDSK)( PWCHAR DriveRoot,
  PWCHAR Format,
  BOOL CorrectErrors,
  BOOL Verbose,
  BOOL CheckOnlyIfDirty,
  BOOL ScanDrive,
  PVOID Unused2,
  PVOID Unused3,
  PFMIFSCALLBACK Callback );
  //
  // Format command in FMIFS
  //
  // media flags
  #define FMIFS_HARDDISK 0xC
  #define FMIFS_FLOPPY?? 0x8
  typedef VOID (__stdcall *PFORMATEX)( PWCHAR DriveRoot,
   DWORD MediaFlag,
   PWCHAR Format,
   PWCHAR Label,
   BOOL QuickFormat,
   DWORD ClusterSize,
   PFMIFSCALLBACK Callback );
  //
  // Enable/Disable volume compression
  //
  typedef BOOLEAN (__stdcall *PENABLEVOLUMECOMPRESSION)(PWCHAR DriveRoot,
  BOOL Enable );
  //////////////////////////////////////////////////////////////////////////
  下面是主文件:
  #include "stdafx.h"
  #include
  #include
  #include "fmifs.h"
  #define _UNICODE 1
  #include "tchar.h"
  BOOL?Error = FALSE;
  BOOL?QuickFormat = FALSE;
  DWORD?? ClusterSize = 0;
  BOOL?CompressDrive = FALSE;
  BOOL??? GotALabel = FALSE;
  PWCHAR? Label = L"";
  PWCHAR? Drive = NULL;
  PWCHAR? Format = L"FAT32";
  WCHAR? RootDirectory[MAX_PATH];
  WCHAR? LabelString[12];
  PFORMATEX?? FormatEx;
  PENABLEVOLUMECOMPRESSION EnableVolumeCompression;
  typedef struct {
  WCHAR? SizeString[16];
  DWORD? ClusterSize;
  } SIZEDEFINITION, *PSIZEDEFINITION;
  SIZEDEFINITION LegalSizes[] = {
  { L"512", 512 },
  { L"1024", 1024 },
  { L"2048", 2048 },
  { L"4096", 4096 },
  { L"8192", 8192 },
  { L"16K", 16384 },
  { L"32K", 32768 },
  { L"64K", 65536 },
  { L"128K", 65536 * 2 },
  { L"256K", 65536 * 4 },
  { L"", 0 },
  };
  //----------------------------------------------------------------------
  //
  // FormatExCallback
  //
  // The file system library will call us back with commands that we
  // can interpret. If we wanted to halt the chkdsk we could return FALSE.
  //
  //----------------------------------------------------------------------
  BOOLEAN __stdcall FormatExCallback( CALLBACKCOMMAND Command, DWORD Modifier, PVOID Argument )
  {
  PDWORD percent;
  PTEXTOUTPUT output;
  PBOOLEAN status;
  static createStructures = FALSE;
  //
  // We get other types of commands, but we don't have to pay attention to them
  //
  switch( Command ) {
  case PROGRESS:
  percent = (PDWORD) Argument;
  _tprintf(L"%d percent completed./r", *percent);
  break;
  case OUTPUT:
  output = (PTEXTOUTPUT) Argument;
  fprintf(stdout, "%s", output->Output);
  break;
  case DONE:
  status = (PBOOLEAN) Argument;
  if( *status == FALSE ) {
  _tprintf(L"FormatEx was unable to complete successfully./n/n");
  Error = TRUE;
  }
  break;
  }
  return TRUE;
  }
  //----------------------------------------------------------------------
  //
  // LoadFMIFSEntryPoints
  //
  // Loads FMIFS.DLL and locates the entry point(s) we are going to use
  //
  //----------------------------------------------------------------------
  BOOLEAN LoadFMIFSEntryPoints()
  {
  LoadLibrary( "fmifs.dll" );
  if( !(FormatEx = (PFORMATEX) GetProcAddress( GetModuleHandle( "fmifs.dll"),
  "FormatEx" )) ) {
  return FALSE;
  }
  if( !(EnableVolumeCompression = (PENABLEVOLUMECOMPRESSION) GetProcAddress( GetModuleHandle( "fmifs.dll"),
  "EnableVolumeCompression" )) ) {
  return FALSE;
  }
  return TRUE;
  }
  int main( int argc, WCHAR *argv[] )
  {
  if( argv[1][1] != L':' ) return 0;
  Drive = argv[1];
  wcscpy( RootDirectory, Drive );
  RootDirectory[2] = L'//';
  RootDirectory[3] = (WCHAR) 0;
  DWORD media;
  DWORD driveType;
  driveType = GetDriveTypeW( RootDirectory );
  if( driveType != DRIVE_FIXED )
  media = FMIFS_FLOPPY;
  if( driveType == DRIVE_FIXED )
  media = FMIFS_HARDDISK;
  //
  // Get function pointers
  //
  if( !LoadFMIFSEntryPoints()) {
  _tprintf(L"Could not located FMIFS entry points./n/n");
  return -1;
  }
  FormatEx( RootDirectory, media, Format, Label, QuickFormat,
  ClusterSize, FormatExCallback );
  return 0;
  }
  2006-12-01 18:58评论 (1)编辑收藏
  Google的Web Office计划着实吸引了很多人,因此今天决定试用一下,以下是几点体会:
  1)界面简洁,功能实用
  比起功能强大的MS Office Word来说,这个编辑器的功能当然只能是小屋见大屋,不过有朋友说从二八定律来看,最有用也最常用的功能一般只占到20%,而这20%Google的Web Docs则都具备了。这一点我深以为然。
  2)不需任何安装,随时随地使用
  只要能上网,就可以随时随地使用,不需任何安装。这恐怕是Web Office最大的好处。
  3)支持多种格式的生成
  编辑完成后,支持如DOC,PDF,RTF,HTML等多种格式的生成。 且是在本地硬盘保存。需要做的只是单击File菜单下的Save as Word或者Save as PDF等等。的确相当方便。
  
  
  如果想试用,可访问下面地址:
  Google Spreadsheets 试用排队地址 : http://www.google.com/googlespreadsheets/try_out.html
  
  2006-11-13 23:24评论 (0)编辑收藏
  在使用ADO进行数据库编程时,发现ACCESS数据库文件越来越大。即使清空了数据库库表中的全部表项,mdb文件也会越来越大。
  经过分析和查资料了解到主要是Access文件中缓存的缘故,可以通过执行Access应用程序中“实用数据库工具”中的“压缩和修复数据库”菜单命令来解决上面的问题。
  为了在程序中解决上面问题,则编写了下面代码,注意路径和文件名就可以了。
  为了使用后面的函数,首先在StdAfx.h中加一行:
  #import "C:/PROGRAM FILES/COMMON FILES/System/ado/MSJRO.DLL" no_namespace
  然后调用下面的函数即可:
  void CompactDB()
  {
  try
  {
  IJetEnginePtr jet(__uuidof(JetEngine));
  jet->CompactDatabase( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=File.mdb;Jet OLEDB:Database Password=test",
  "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=File2.mdb;"
  "Jet OLEDB:Engine Type=5");
  }
  catch(_com_error &e)
  {
  ::MessageBox(NULL, (LPCTSTR)e.Description( ), "", MB_OK) ;
  }
  DeleteFile("File.mdb");
  CFile::Rename("File2.mdb","File.mdb");
  }
  
  2006-09-13 20:06评论 (0)编辑收藏
  内查找和外查找:都在内存中查找即内查找,外查找还涉及外存,比如硬盘等。
  分类包括:
  1、线性表的查找
  又分顺序查找、二分查找和分块查找。
  1)二分查找又叫折半查找
  折半查找要求线性表有序。
  有序是指存在某个关键字的序列。
  基本思想是拆半。
  二分查找可以用二叉树来描述,按照二分查找的思想建立一棵二叉树,此树称为二分查找的“判定树”。
  二分查找的最坏性能和平均性能相近。
  2)分块查找
  线性表分成块,每块内部不要求有序,但块块之间应有序
  2、树表查找
  1)二叉排序树
  左子树非空,则左树上所有节点均小于根。
  右子树非空,则右树上的所有节点均大于根。
  左右子树分别仍是二叉排序树
  二叉排序树中的“中序遍历”是递增序列。
  同一序列,构成的二叉排序树可能不同。
  2)平衡的二叉排序树
  要求二叉排序树的左子树和右子树的高度最多相差1
  这个差被成为平衡因子
  平衡二叉树避免了顺序查找行为的出现。
  3)B树
  前面方法都只适用于内查找,B树则适合外查找。
  B-树是平衡二叉树的一种。
  定义一个m阶的B树
  每个节点至多有m个孩子
  根节点有两个孩子或者为空
  每个节点至少有(m/2的上限)个孩子(除了根和叶)。
  叶在同一层,且叶中没有关键信息。
  有K个孩子的非叶节点恰好有k-1个关键字。
  查找B树时,给定关键字的查找首先从根开始,一定能确定要找的K在Ki和Ki+1之间。在这之间重复寻找,直到成功或者返回指针为空。
  文件系统NTFS对目录索引的管理使用B树。
  
  
  
  2006-09-11 17:32评论 (0)编辑收藏
  关于MYSQL安装、运行以及创建库表的基本入门问题介绍
  2006-05-19 20:28评论 (0)编辑收藏
  前几天听李德毅院士做《信息时代的信息能力》报告,做的笔记摘录如下:
  >信息时代三要素:
  物质- 没有物质,世界上什么都不存在
  能量-没有能量,世界上什么都不会发生
  信息-没有信息,世界上什么都没有意义
  >宏观的更宏观,微观的更微观。
  比如物理学: 天体物理学 <<---- 经典物理学 -〉 分子物理学 -〉 原子物理学 -〉 粒子物理学
  结果发现,宏观和微观的理论最终将交汇成一体。
  >信息时代更关注:
  Emurgence 突变
  Evolution 演变
  >“Complex System”(复杂系统)将成为为新的学科作为人们研究的对象
  包括:Complex Network,这类学科的主要研究在不同的粒度上表现出来的行为
  >周光召有句名言:在交叉学科的研究中实现创新。
  >“小世界模型”“无尺度网络”
  网络的规模可以很大,但网络直径的平均值却不大。
  比如:六度空间
  无尺度网络说明有时候计算平均值的统计学没有意义。
  比如:我的收入和比尔盖茨收入的平均值有什么意义呢?
  因此,在朴素分布的另一面,幂率分布同样有研究的意义。
  比如,二八定律是幂率分布很好的例子。
  >发展是硬道理,但硬发展不一定有道理。
  
  
  2006-05-13 06:06评论 (0)编辑收藏
  这几天构造一个DNS报文,查了好些资料,好象许多朋友对UDP报文的校验和老是出问题,自己试了一些例子代码,也有问题。所以花了一些时间,做了一个成功的例子,在Linux下GCC通过并验证成功。
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  unsigned short checksum(unsigned short *buffer, int size)
  {
  unsigned long cksum=0;
  while (size >1)
  {
  cksum += *buffer++;
  size -= sizeof(unsigned short);
  }
  if (size)
  {
  cksum += *(unsigned char *)buffer;
  }
  cksum = (cksum >>16) + (cksum &0xffff);
  cksum += (cksum >>16);
  return (unsigned short)(~cksum);
  }
  void CalculateCheckSum(
  void *iphdr,
  struct udphdr *udphdr,
  char *payload,
  int payloadlen)
  {
  struct iphdr *v4hdr=NULL;
  unsigned long zero=0;
  char buf[1000],
  *ptr=NULL;
  int chksumlen=0,
  i;
  
  ptr = buf;
  v4hdr = (struct iphdr *)iphdr;
  // Include the source and destination IP addresses
  memcpy(ptr, &v4hdr->saddr, sizeof(v4hdr->saddr));
  ptr += sizeof(v4hdr->saddr);
  chksumlen += sizeof(v4hdr->saddr);
  memcpy(ptr, &v4hdr->daddr, sizeof(v4hdr->daddr));
  ptr += sizeof(v4hdr->daddr);
  chksumlen += sizeof(v4hdr->daddr);
  
  // Include the 8 bit zero field
  memcpy(ptr, &zero, 1);
  ptr++;
  chksumlen += 1;
  // Protocol
  memcpy(ptr, &v4hdr->protocol, sizeof(v4hdr->protocol));
  ptr += sizeof(v4hdr->protocol);
  chksumlen += sizeof(v4hdr->protocol);
  // UDP length
  memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
  ptr += sizeof(udphdr->len);
  chksumlen += sizeof(udphdr->len);
  
  // UDP source port
  memcpy(ptr, &udphdr->source, sizeof(udphdr->source));
  ptr += sizeof(udphdr->source);
  chksumlen += sizeof(udphdr->source);
  // UDP destination port
  memcpy(ptr, &udphdr->dest, sizeof(udphdr->dest));
  ptr += sizeof(udphdr->dest);
  chksumlen += sizeof(udphdr->dest);
  // UDP length again
  memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
  ptr += sizeof(udphdr->len);
  chksumlen += sizeof(udphdr->len);
  
  // 16-bit UDP checksum, zero
  memcpy(ptr, &zero, sizeof(unsigned short));
  ptr += sizeof(unsigned short);
  chksumlen += sizeof(unsigned short);
  // payload
  memcpy(ptr, payload, payloadlen);
  ptr += payloadlen;
  chksumlen += payloadlen;
  // pad to next 16-bit boundary
  for(i=0 ;i   {
  printf("pad one byte/n");
  *ptr = 0;
  ptr++;
  chksumlen++;
  }
  // Compute the checksum and put it in the UDP header
  udphdr->check = checksum((unsigned short *)buf, chksumlen);
  return;
  }
  void main()
  {
  int sock;
  unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct udphdr);
  char DNS_Data[] = "/x71/x79/x81/x80/x00/x01"
  "/x00/x02/x00/x04/x00/x04/x03/x77/x77/x77/x03/x61/x62/x63/x03/x63"
  "/x6f/x6d/x00/x00/x01/x00/x01/xc0/x0c/x00/x05/x00/x01/x00/x00/x02"
  "/xe8/x00/x02/xc0/x10/xc0/x10/x00/x01/x00/x01/x00/x00/x02/xe9/x00"
  "/x04/x0a/xb5/x84/xfa/xc0/x10/x00/x02/x00/x01/x00/x00/xda/xeb/x00"
  "/x0d/x06/x73/x65/x6e/x73/x30/x31/x03/x64/x69/x67/xc0/x14/xc0/x10"
  "/x00/x02/x00/x01/x00/x00/xda/xeb/x00/x09/x06/x73/x65/x6e/x73/x30"
  "/x32/xc0/x4e/xc0/x10/x00/x02/x00/x01/x00/x00/xda/xeb/x00/x09/x06"
  "/x6f/x72/x6e/x73/x30/x31/xc0/x4e/xc0/x10/x00/x02/x00/x01/x00/x00"
  "/xda/xeb/x00/x09/x06/x6f/x72/x6e/x73/x30/x32/xc0/x4e/xc0/x75/x00"
  "/x01/x00/x01/x00/x00/x7a/x36/x00/x04/x0a/xbb/xbd/x2c/xc0/x8a/x00"
  "/x01/x00/x01/x00/x00/x1b/x96/x00/x04/x0a/xbb/xbe/x2c/xc0/x47/x00"
  "/x01/x00/x01/x00/x00/x92/xb1/x00/x04/x0a/xb5/x86/x10/xc0/x60/x00"
  "/x01/x00/x01/x00/x00/x92/xb1/x00/x04/x0a/xb5/x87/xc7";
  
  buffer_size += sizeof(DNS_Data);
  unsigned char buffer[buffer_size];
  memset (buffer, 0, buffer_size);
  struct iphdr *ip = (struct iphdr *)buffer;
  struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));
  if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1) {
  perror("socket()");
  exit(EXIT_FAILURE);
  }
  int o = 1;
  if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&o,sizeof(o)) == -1) {
  perror("setsockopt()");
  exit(EXIT_FAILURE);
  }
  ip->version = 4;
  ip->ihl = 5;
  ip->id = htonl(random());
  ip->saddr = inet_addr("1.0.0.1");
  ip->daddr = inet_addr("10.0.0.63");
  ip->ttl = 255;
  ip->protocol = IPPROTO_UDP;
  ip->tot_len = buffer_size;
  ip->check = 0;
  udp->source = htons(53);
  udp->dest = htons(1234);
  udp->len = htons(buffer_size - sizeof(struct iphdr));
  udp->check = 0;
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = udp->source;
  addr.sin_addr.s_addr = ip->saddr;
  memcpy(buffer+sizeof(struct iphdr) + sizeof(struct udphdr),DNS_Data,sizeof(DNS_Data));
  CalculateCheckSum(ip,udp,DNS_Data,sizeof(DNS_Data));
  if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&addr,
  sizeof(struct sockaddr_in))) == -1) {
  perror("send()");
  exit(1);
  }
  else
  printf("OK/n");
  }
  
  上面代码构造了一个DNS应答报文。用抓包程序抓下来验证正确。
  2006-04-20 23:35评论 (0)编辑收藏
  
  以下为各栏位的简要说明:
  QID
  DNS 查询封包编号,作为确认依据。
  QR
  查询封包为 0 ﹔回应为 1 。长度为 1 byte 。
  OPCodes
  封包类别(QUERY, IQUERY, STATUS, Reserved)。长度为 4 bytes。
  Flags
  共 4 bytes ,各表示:AA(Authoritative Answer)、TC(Truncation)、RD(Recursion Desired)、RA(Recursion Avalable)。
  Reserved
  保留未用。
  RCodes
  回应讯息,长 4 bytes ,除 0 及 6-15 保留未用外,1-5 分别为:Format Error、Server Failure、Name Error、Not Implemented、Refused。
  Question Section、Answer Section、Authority Section、Additional Records Section
  每一 Section 分为 NAME、TYPE、CLASS 三个子栏位,分别作为查询、应答、授权、额外记录等封包之资讯,及各自长度。
  好了﹐关于 DNS 协定的讨论﹐暂时介绍到这里﹐相信上面说的这些也够您消化的了。
  DNS 协定之 RFC 文件
  RFC-822﹑RFC-883﹑RFC-920﹑RFC-973﹑RFC-974﹑RFC-1032﹑RFC-1033﹑RFC-1034﹑RFC-1035﹑RFC-1101﹑RFC-1296
  2006-04-19 21:17评论 (0)编辑收藏
  Linux 命令速查
  Monday, 2. January 2006, 09:28:48
  FreeBSD, Linux, Shell
  一. 启动,关机,登入,登出相关命令
  登录
  登出
  登出
  停止系统
  停止系统
  重启动
  切断电源
  把内存里的内容写入磁盘
  安装lilo启动管理程序
  安装lilo启动管理程序
  二. Shell相关命令
  切换Shell
  显示命令履历
  设置命令别名
  取消命令别名
  显示命令所在位置
  查询命令种类
  显示字符串或者变量内容
  设置/显示Shell变量
  显示环境变量
  设置环境变量
  设置临时环境变量
  释放环境变量
  设置环境变量
  释放环境变量
  执行文件当中的命令
  查询命令手册
  查询超文本命令手册
  显示命令简介
  通过关键字查询手册
  三. 用户管理相关命令
  切换到其他用户
  追加用户
  追加用户
  删除用户
  修改用户设置
  修改用户私人信息
  追加组
  删除组
  修改组设置
  更改密码
  显示用户名
  显示登录用户帐号
  显示所有登录用户信息
  查询登录用户信息
  查询登录用户信息
  显示指定用户的ID信息
  显示指定用户的所属组
  显示指定用户的个人信息
  开关与他人收发消息
  给其他用户发消息
  给所有用户发消息
  和其他用户聊天
  四. 系统消息相关命令
  显示/设置当前时间
  显示系统运行时间
  显示机器的核心构架(如i386)
  显示操作系统信息
  显示终端名
  显示登录/登出在履历
  显示非法登录信息
  显示当前键盘配置
  变更键盘配置
  查询磁盘使用信息
  查询磁盘使用信息
  显示系统启动消息
  

原创粉丝点击