欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
一个碎片整理程序的实现
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 

申明: 代码是网上收集的,原则上只供学习使用

//====================================================================

//

// Defrag.h

//

// Copyright (C) 1997 Mark Russinovich

//

// Header file for defragmentation demonstration program. This file

// includes definitions for defragmentation File System Control

// commands, as well as the undocumented NtFsControl call.

//

//====================================================================

 

//--------------------------------------------------------------------

//                     D E F I N E S

//--------------------------------------------------------------------

 

 

//

// File System Control commands related to defragging

//

#define FSCTL_READ_MFT_RECORD                0x90068

#define FSCTL_GET_VOLUME_BITMAP            0x9006F

#define FSCTL_GET_RETRIEVAL_POINTERS    0x90073

#define FSCTL_MOVE_FILE                            0x90074

 

//

// return code type

//

typedef UINT NTSTATUS;

 

//

// Error codes returned by NtFsControlFile (see NTSTATUS.H)

//

#define STATUS_SUCCESS                          ((NTSTATUS)0x00000000L)

#define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0x80000005L)

#define STATUS_INVALID_PARAMETER         ((NTSTATUS)0xC000000DL)

#define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)

#define STATUS_ALREADY_COMMITTED         ((NTSTATUS)0xC0000021L)

#define STATUS_INVALID_DEVICE_REQUEST    ((NTSTATUS)0xC0000010L)

 

 

//--------------------------------------------------------------------

//       F S C T L  S P E C I F I C   T Y P E D E F S 

//--------------------------------------------------------------------

 

 

//

// This is the definition for a VCN/LCN (virtual cluster/logical cluster)

// mapping pair that is returned in the buffer passed to

// FSCTL_GET_RETRIEVAL_POINTERS

//

typedef struct {

      ULONGLONG               Vcn;

      ULONGLONG               Lcn;

} MAPPING_PAIR, *PMAPPING_PAIR;

 

//

// This is the definition for the buffer that FSCTL_GET_RETRIEVAL_POINTERS

// returns. It consists of a header followed by mapping pairs

//

typedef struct {

      ULONG                  NumberOfPairs;

      ULONGLONG               StartVcn;

      MAPPING_PAIR      Pair[1];

} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR;

 

 

//

// This is the definition of the buffer that FSCTL_GET_VOLUME_BITMAP

// returns. It consists of a header followed by the actual bitmap data

//

typedef struct {

      ULONGLONG               StartLcn;

      ULONGLONG               ClustersToEndOfVol;

      BYTE                     Map[1];

} BITMAP_DESCRIPTOR, *PBITMAP_DESCRIPTOR;

 

 

//

// This is the definition for the data structure that is passed in to

// FSCTL_MOVE_FILE

//

typedef struct {

     HANDLE            FileHandle;

     ULONG             Reserved;  

     LARGE_INTEGER     StartVcn;

     LARGE_INTEGER     TargetLcn;

     ULONG             NumVcns;

     ULONG             Reserved1;    

} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR;

 

 

//--------------------------------------------------------------------

//     N T F S C O N T R O L F I L E   D E F I N I T I O N S

//--------------------------------------------------------------------

 

//

// Prototype for NtFsControlFile and data structures

// used in its definition

//

 

//

// Io Status block (see NTDDK.H)

//

typedef struct _IO_STATUS_BLOCK {

    NTSTATUS Status;

    ULONG Information;

} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

 

 

//

// Apc Routine (see NTDDK.H)

//

typedef VOID (*PIO_APC_ROUTINE) (

                      PVOID ApcContext,

                      PIO_STATUS_BLOCK IoStatusBlock,

                      ULONG Reserved

                 );

 

 

//

// The undocumented NtFsControlFile

//

// This function is used to send File System Control (FSCTL)

// commands into file system drivers. Its definition is

// in ntdll.dll (ntdll.lib), a file shipped with the NTDDK.

//

NTSTATUS (__stdcall *NtFsControlFile)(

                            HANDLE FileHandle,

                            HANDLE Event,                       // optional

                            PIO_APC_ROUTINE ApcRoutine,          // optional

                            PVOID ApcContext,                 // optional

                            PIO_STATUS_BLOCK IoStatusBlock,   

                            ULONG FsControlCode,

                            PVOID InputBuffer,                 // optional

                            ULONG InputBufferLength,

                            PVOID OutputBuffer,                     // optional

                            ULONG OutputBufferLength

                 );

 

 

 

//====================================================================

//

// Defrag.c

//

// Copyright (C) 1997 Mark Russinovich

//

// This program demonstrates the use of NT 4.0 FAT and NTFS cluster

// movement File System Control functions.

//

//====================================================================

#include <windows.h>

#include <stdio.h>

#include <conio.h>

#include "defrag.h"

 

//--------------------------------------------------------------------

//                         D E F I N E S

//--------------------------------------------------------------------

 

//

// Interval at which output is paused (in lines)

//

#define PAUSEINTERVAL   24

 

//

// Size of the buffer we read file mapping information into.

// The buffer is big enough to hold the 16 bytes that

// come back at the head of the buffer (the number of entries

// and the starting virtual cluster), as well as 512 pairs

// of [virtual cluster, logical cluster] pairs.

//

#define FILEMAPSIZE         (512+2)

 

//

// Size of the bitmap buffer we pass in. Its large enough to

// hold information for the 16-byte header that's returned

// plus the indicated number of bytes, each of which has 8 bits

// (imagine that!)

//

#define BITMAPBYTES       4096

#define BITMAPSIZE         (BITMAPBYTES+2*sizeof(ULONGLONG))

 

//

// Invalid longlong number

//

#define LLINVALID      ((ULONGLONG) -1)

 

//--------------------------------------------------------------------

//                        G L O B A L S

//--------------------------------------------------------------------

 

//

// Handle for the raw volume that was opened

//

HANDLE          VolumeHandle;

 

//

// Buffer to read file mapping information into

//

ULONGLONG    FileMap[ FILEMAPSIZE ];

 

//

// Buffer thats passed to bitmap function

//

BYTE         BitMap[ BITMAPSIZE ];

 

//

// Bit shifting array for efficient processing of the bitmap

//

BYTE         BitShift[] = { 1, 2, 4, 8, 16, 32, 64, 128 };

 

 

//--------------------------------------------------------------------

//                      F U N C T I O N S

//--------------------------------------------------------------------

 

//--------------------------------------------------------------------

//

// PrintNtError

//

// Translates an NTDLL error code into its text equivalent. This

// only deals with ones commonly returned by defragmenting FS Control

// commands.

//--------------------------------------------------------------------

void PrintNtError( NTSTATUS Status )

{

      switch( Status ) {

      case STATUS_SUCCESS:

           printf("STATUS_SUCCESS\n\n");

           break;

      case STATUS_INVALID_PARAMETER:

           printf("STATUS_INVALID_PARAMETER\n\n");

           break;

      case STATUS_BUFFER_TOO_SMALL:

           printf("STATUS_BUFFER_TOO_SMALL\n\n");

           break;

      case STATUS_ALREADY_COMMITTED:

           printf("STATUS_ALREADY_COMMITTED\n\n");

           break;

      case STATUS_INVALID_DEVICE_REQUEST:

           printf("STATUS_INVALID_DEVICE_REQUEST\n\n");

           break;

      default:

           printf("0x%08x\n\n", Status );

           break;

      }          

}

 

 

//--------------------------------------------------------------------

//

// PrintWin32Error

//

// Translates a Win32 error into a text equivalent

//

//--------------------------------------------------------------------

void PrintWin32Error( DWORD ErrorCode )

{

      LPVOID lpMsgBuf;

 

      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

                            NULL, ErrorCode,

                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

                            (LPTSTR) &lpMsgBuf, 0, NULL );

      printf("%s\n", lpMsgBuf );

      LocalFree( lpMsgBuf );

}

 

 

//--------------------------------------------------------------------

//

// PrintHelp

//

//--------------------------------------------------------------------

void PrintHelp()

{

      printf("\nCommands:\n\n");

      printf("Dump bitmap free clusters:\n");

      printf("     b [offset]\n");

      printf("Enumerate clusters of file:\n");

      printf("     n [filename]\n");

      printf("Move clusters:\n");

      printf("     m [file] [off] [tgt] [numclust]\n");

      printf("Quit:\n");

      printf("     q\n");

      printf("\n");

}

 

//--------------------------------------------------------------------

//

// PauseOutput

//

// After n lines have printed, stop and wait for the user to continue.

// 'q' causes the function to return false.

//

//--------------------------------------------------------------------

BOOL PauseOutput( DWORD Count )

{

      char     key;

 

      if( !(Count % PAUSEINTERVAL )) {

           printf("more ('q' to quit): ");

           fflush(stdout);

           key = getch();

           printf("\n");

           if( key == 'q' ) {

                 printf("\nEnumeration aborted.\n\n");

                 return FALSE;

           }

      }

      return TRUE;

}

 

 

//--------------------------------------------------------------------

//

// OpenVolume

//

// Open the volume for defragging, a flag that is new for NT 4.0.

//

//--------------------------------------------------------------------

DWORD OpenVolume( int DriveId )

{

      static char             volumeName[] = "\\\\.\\A:";

 

      //

      // open the volume

      //

      volumeName[4] = DriveId + 'A';

      VolumeHandle = CreateFile( volumeName, GENERIC_READ,

                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,

                            0, 0 );

      if( VolumeHandle == INVALID_HANDLE_VALUE )  {

 

           return GetLastError();

      }

 

      return ERROR_SUCCESS;

}

 

 

//--------------------------------------------------------------------

//

// DumpBitmap

//

// Start at the offset specified (if any) and dumps all the free

// clusters on the volume to the end of the volume or until

// the user stops the dump with a 'q'.

//

//--------------------------------------------------------------------

void DumpBitmap( char *argument )

{

      DWORD                                 status;

      PBITMAP_DESCRIPTOR            bitMappings;

      ULONGLONG                          cluster;

      ULONGLONG                          numFree;

      ULONGLONG                          startLcn;

      ULONGLONG                          nextLcn;

      ULONGLONG                          lastLcn;

      IO_STATUS_BLOCK                      ioStatus;

      ULONGLONG                          i;

      int                                   lines;

 

      //

      // Start scanning at the cluster offset the user specifies

      //

      bitMappings = (PBITMAP_DESCRIPTOR) BitMap;

      cluster = 0;

      nextLcn = 0;

      lines = 0;

      lastLcn = LLINVALID;

      sscanf( argument, " %I64d ", &nextLcn );

      while( !(status = NtFsControlFile( VolumeHandle, NULL, NULL, 0, &ioStatus,

                                  FSCTL_GET_VOLUME_BITMAP,

                                  &nextLcn, sizeof( cluster ),

                                  bitMappings, BITMAPSIZE )) ||

                  status == STATUS_BUFFER_OVERFLOW ||

                  status == STATUS_PENDING ) {

 

           //

           // If the operation is pending, wait for it to finish

           //

           if( status == STATUS_PENDING ) {

                

                 WaitForSingleObject( VolumeHandle, INFINITE );

                

                 //

                 // Get the status from the status block

                 //

                 if( ioStatus.Status != STATUS_SUCCESS &&

                      ioStatus.Status != STATUS_BUFFER_OVERFLOW ) {

 

                      printf("\nGet Volume Bitmap: ");

                      PrintNtError( ioStatus.Status );

                      return;

                 }

           }

 

           //

           // Print the range we're starting at

           //

           if( !lines ) {

          

                 printf("\nFree clusters starting at offset: %I64d\n",

                                  bitMappings->StartLcn );

           }

 

           //

           // Scan through the returned bitmap info, looking for empty clusters

           //

           startLcn = bitMappings->StartLcn;

           numFree = 0;

           cluster = LLINVALID;

           for( i = 0; i < min( bitMappings->ClustersToEndOfVol, 8*BITMAPBYTES); i++ ) {

 

                 if( !(bitMappings->Map[ i/8 ] & BitShift[ i % 8 ])) {

 

                      //

                      // Cluster is free

                      //

                      if( cluster == LLINVALID ) {

 

                            cluster = startLcn + i;

                            numFree = 1;

 

                      } else {

 

                            numFree++;

                      }

                 } else {

 

                      //

                      // Cluster is not free

                      //

                      if( cluster != LLINVALID ) {

                           

                            if( lastLcn == cluster ) {

 

                                  lastLcn = LLINVALID;

                            } else {

 

                                  //

                                  // See if we should continue

                                  //

                                  if( !PauseOutput( ++lines ) ) {

                                      

                                       return;

                                  }

 

                                  printf("   LCN: %I64d LEN: %I64d\n", cluster, numFree );

                                  numFree = 0;

                                  lastLcn = cluster;

                                  cluster = LLINVALID;

                            }

                      }

                 }

           }

 

           //

           // See if we should continue

           //

           if( !PauseOutput( ++lines ) ) {

                

                 return;

           }

 

           //

           // Print any remaining

           //

           if( cluster != LLINVALID && lastLcn != cluster ) {

                

                 printf("   LCN: %I64d LEN: %I64d\n", cluster, numFree );

                 numFree = 0;

                 cluster = LLINVALID;

           }

 

           //

           // End of volume?

           //

           if( status != STATUS_BUFFER_OVERFLOW ) {

 

                 printf("End of volume.\n\n");

                 return;

           }                    

 

           //

           // Move to the next block

           //

           nextLcn = bitMappings->StartLcn + i;

      }

 

      //

      // We only get here when there's an error

      //

      printf("\nGet Volume Bitmap: ");

      PrintNtError( status );

}

 

 

//--------------------------------------------------------------------

//

// DumpFile

//

// Dumps the clusters belonging to the specified file until the

// end of the file or the user stops the dump.

//

//--------------------------------------------------------------------

void DumpFile( int drive, char *argument )

{

      DWORD                                 status;

      int                                   i;

      HANDLE                                 sourceFile;

      char                                 fileName[MAX_PATH];

      IO_STATUS_BLOCK                      ioStatus;

      ULONGLONG                          startVcn;

      PGET_RETRIEVAL_DESCRIPTOR    fileMappings;

      int                                   lines = 0;

 

      //

      // Make the name into a real pathname

      //

      if( strlen( argument ) > 1 && argument[0] != '\\' &&

           argument[0] != 'A'+drive &&

           argument[0] != 'a'+drive )

           sprintf(fileName, "%C:\\%s", drive+'A', argument );

      else if( strlen( argument ) > 1 && argument[0] == '\\')

           sprintf(fileName, "%C:%s", drive+'A', argument );

      else

           strcpy(fileName, argument );

 

      printf("\nClusters for file: %s\n", fileName );

 

      //

      // Open the file

      //

      sourceFile = CreateFile( fileName, GENERIC_READ,

                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,

                            FILE_FLAG_NO_BUFFERING, 0 );

      if( sourceFile == INVALID_HANDLE_VALUE ) {

           printf("Failed to open file: ");

           PrintWin32Error( GetLastError() );

           return;

      }

 

      //

      // Start dumping the mapping information. Go until we hit the end of the

      // file.

      //

      startVcn = 0;

      fileMappings = (PGET_RETRIEVAL_DESCRIPTOR) FileMap;

      while( !(status = NtFsControlFile( sourceFile, NULL, NULL, 0, &ioStatus,

                                  FSCTL_GET_RETRIEVAL_POINTERS,

                                  &startVcn, sizeof( startVcn ),

                                  fileMappings, FILEMAPSIZE * sizeof(LARGE_INTEGER) ) ) ||

                  status == STATUS_BUFFER_OVERFLOW ||

                  status == STATUS_PENDING ) {

 

           //

           // If the operation is pending, wait for it to finish

           //

           if( status == STATUS_PENDING ) {

                

                 WaitForSingleObject( sourceFile, INFINITE );

 

                 //

                 // Get the status from the status block

                 //

                 if( ioStatus.Status != STATUS_SUCCESS &&

                      ioStatus.Status != STATUS_BUFFER_OVERFLOW ) {

 

                      printf("Enumerate file clusters: ");

                      PrintNtError( ioStatus.Status );

                      return;

                 }

           }

 

           //

           // Loop through the buffer of number/cluster pairs, printing them

           // out.

           //

           startVcn = fileMappings->StartVcn;

           for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ ) {

 

                 //

                 // See if we should continue

                 //

                 if( !PauseOutput( ++lines ) ) {

                     

                      return;

                 }   

 

                 //

                 // On NT 4.0, a compressed virtual run (0-filled) is

                 // identified with a cluster offset of -1

                 //

                 if( fileMappings->Pair[i].Lcn == LLINVALID ) {

                      printf("   VCN: %I64d VIRTUAL LEN: %I64d\n",

                                       startVcn, fileMappings->Pair[i].Vcn - startVcn );

                 } else {

                      printf("   VCN: %I64d LCN: %I64d LEN: %I64d\n",

                                       startVcn, fileMappings->Pair[i].Lcn,

                                       fileMappings->Pair[i].Vcn - startVcn );

                 }

                 startVcn = fileMappings->Pair[i].Vcn;

           }

 

           //

           // If the buffer wasn't overflowed, then we're done

           //

           if( !status ) break;

      }

      CloseHandle( sourceFile );

 

      //

      // Print any error code

      //

      printf("Enumerate file clusters: ");

      PrintNtError( status );

}

 

//--------------------------------------------------------------------

//

// MoveClusterUsage

//

// Prints the syntax of the demonstration program's move file command.

//

//--------------------------------------------------------------------

void MoveClusterUsage()

{

      printf("\nMove File's syntax is:\n   m [filename] [fileoffset] [target] [numclusters]\n\n");

      printf("Example:\n   m c:\\foo\\bar 5 3455 10\n");

      printf("   c:\\foo\\bar       File to move\n");

      printf("   5                Start offset (in clusters) of the cluster in file to move\n");

      printf("   3455             Target cluster on drive\n");

      printf("   10               Number of clusters to move\n");

      printf("\n   This would direct 10 clusters, starting at offset 5 clusters\n"

           "   in the file, to be moved to logical cluster 3455 on the volume.\n\n");

      return;

}

 

//--------------------------------------------------------------------

//

// MoveCluster

//

// This uses the FSCT_MOVE_FILE interface to move the clusters of a

// file specified by the user as arguments. MoveFile requires a

// file handle, an offset within the file, the number of sectors of

// the file to move, and the target cluster on the drive to move the

// clusters to.

//

//--------------------------------------------------------------------

void MoveCluster( int drive, char *argument )

{

      DWORD                                 status;

      IO_STATUS_BLOCK                      ioStatus;

      char                                 *argptr;

      HANDLE                                 sourceFile;

      char                                 fileName[MAX_PATH];

      LARGE_INTEGER                    startVcn, targetLcn;

      DWORD                                 numClusters;

      MOVEFILE_DESCRIPTOR               moveFile;

 

      //

      // First, we have to extract the file name

      //

      argptr = argument;

      while( *argptr && *argptr != ' ' ) argptr++;

      if( !*argptr ) {

 

           MoveClusterUsage();

           return;

      }

 

      //

      // Make the name into a real pathname

      //

      *argptr = 0;

      if( strlen( argument ) > 1 && argument[0] != '\\' &&

           argument[0] != 'A'+drive &&

           argument[0] != 'a'+drive )

           sprintf(fileName, "%C:\\%s", drive+'A', argument );

      else if( strlen( argument ) > 1 && argument[0] == '\\')

           sprintf(fileName, "%C:%s", drive+'A', argument );

      else

           strcpy(fileName, argument );

 

      //

      // Get numeric parameters

      //

      argument = argptr+1;

      if( sscanf( argument, " %I64d %I64d %d ", &startVcn, &targetLcn, &numClusters ) != 3) {

 

           MoveClusterUsage();

           return;

      }

     

      //

      // Tell user what we're going to try

      //

      printf("\nMoving file %s:\n", fileName );

      printf("   Start Offset: %I64d\n", startVcn );

      printf("   Number of Clusters: %d\n", numClusters );

      printf("   Target Cluster: %I64d\n", targetLcn );

 

      //

      // Open the file

      //

      sourceFile = CreateFile( fileName, GENERIC_READ,

                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,

                            FILE_FLAG_NO_BUFFERING, 0 );

      if( sourceFile == INVALID_HANDLE_VALUE ) {

           printf("Failed to open file: ");

           PrintWin32Error( GetLastError() );

           return;

      }

 

      //

      // Setup movefile descriptor and make the call

      //

      moveFile.FileHandle = sourceFile;

      moveFile.StartVcn = startVcn;

      moveFile.TargetLcn = targetLcn;

      moveFile.NumVcns = numClusters;

 

      status = NtFsControlFile( VolumeHandle, NULL, NULL, 0, &ioStatus,

                                  FSCTL_MOVE_FILE,

                                  &moveFile, sizeof( moveFile ),

                                  NULL, 0 );

 

      //

      // If the operation is pending, wait for it to finish

      //

      if( status == STATUS_PENDING ) {

          

           WaitForSingleObject( sourceFile, INFINITE );

 

           status = ioStatus.Status;

      }

 

      //

      // Print status

      //

      printf("Move cluster status: ");

      PrintNtError( status );

}

 

//--------------------------------------------------------------------

//

// ExtractCommand

//

// Given a command line, searches for 1 character command, and then

// returns a pointer to first non-whitespace following.

//

//--------------------------------------------------------------------

char ExtractCommand( char *command, char **argument )

{

      char     cmdChar;

 

      //

      // Look for the command character

      //

      while( *command && *command == ' ') command++;

 

      if( !*command) return (char) 0;

 

      cmdChar = *command;

 

      command++;

 

      //

      // Now look for argument

      //

      while( *command && *command == ' ' ) command++;

      *argument = command;

 

      return cmdChar;

}

 

 

//--------------------------------------------------------------------

//

// main

//

// Process simple commands for enumerating the clusters of a file,

// reading the volume bitmap, and moving a cluster of a particular

// file.

//

//--------------------------------------------------------------------

int main( int argc, char *argv[])

{

      DWORD                                 status;

      int                                   drive;

      char                                 command[256];

      char                                 *argument;

      char                                 cmdChar;

 

      //

      // Get the drive to open off the command line

      //

      if( argc != 2) {

           printf("Usage: %s <drive letter>\n", argv[0] );

           exit(1);

      }

 

      printf("\nNT 4.0 Defragmentation Demonstration Program V1.0\n");

      printf("Copyright (C) 1997 Mark Russinovich\n");

      printf("\n\n");

 

      if( argv[1][0] >= 'a' && argv[1][0] <= 'z' ) {

           drive = argv[1][0] - 'a';

      } else if( argv[1][0] >= 'A' && argv[1][0] <= 'Z' ) {

           drive = argv[1][0] - 'A';

      } else if( argv[1][0] == '/' ) {

           printf("Usage: %s <drive letter>\n", argv[0] );

           exit(1);

      } else {

           printf("illegal drive: %c\n", argv[1][0] );

           exit(1);

      }

 

      //

      // Get the NtFsControlFile entry point

      //

      if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),

                 "NtFsControlFile" )) ) {

 

           printf("Could not find NtFsControlFile entry point in NTDLL.DLL\n");

           exit(1);

      }

 

      //

      // Open the volume

      //

      printf("Opening volume: %c\n", drive+'A' );

      status = OpenVolume(drive);

      printf("Open status: ");

      PrintWin32Error( status );

      if( status != ERROR_SUCCESS ) {

 

           printf("Exiting.\n");

           exit(0);

      }

 

      //

      // Get commands

      //

      printf("Enter commands ('?' for help):\n\n");

      while(1) {

 

           printf(": ");

           fflush(stdout );

           gets( command );

 

           cmdChar = ExtractCommand( command, &argument );

 

           switch( cmdChar ) {

 

           //

           // Dump bitmap information

           //

           case 'b':

           case 'B':

 

                 DumpBitmap( argument );

                 break;

 

           //

           // Help

           //

           case '?':

           case 'H':

           case 'h':

                 PrintHelp();

                 break;

 

           //

           // Move Cluster

           //

           case 'm':

           case 'M':

                 MoveCluster( drive, argument );

                 break;

 

           //

           // Get cluster map for file specified by name

           //

           case 'N':

           case 'n':

                 DumpFile( drive, argument );

                 break;

 

           //

           // Quit

           //

           case 'Q':

           case 'q':

                 printf("\nQuiting\n");

                 exit(0);

                 break;

 

           case 0:

                 break;

 

           default:

                 printf("\nInvalid command\n\n");

                 break;

           }

      }

                           

      return 0;

}

 


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步