?? defrag.c
字號:
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("http://www.ntinternals.com\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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -