?? ccmprs.cpp
字號:
//**************************************************************************
//
// CCMPRS -- Conditional File Compression Utility for Windows NT
//
// Written by Robert Epps
//
// This program and its source are in the public domain. If you find any
// bugs, or add features to this program, I'd like to hear about them!
// Please write to me at:
//
// Internet: robepps@valleynet.com
// CIS: 72560,3353
// AOL: RobertE49
//
//**************************************************************************
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//**************************************************************************
// Global variables representing the various options.
//**************************************************************************
char szFileSpec[_MAX_PATH]; // Path and filename of file(s) to examine
BOOL bRecurse = FALSE; // TRUE = recurse into subdirectories
BOOL bDecompress = FALSE; // TRUE = do decompression
BOOL bQuiet = FALSE; // TRUE = don't display any status info
double threshold = 0.75; // Allow compression if (compressed size) <= (uncompressed size) * threshold
double MinFileSize = 0; // Minimum uncompressed size for file to be compressed
char *szIgnoreExts; // Points to string containing extensions of files to ignore (command-delimited)
char *szExts; // Points to copy of above string, used for strtok() parsing
UINT nCompressed; // # of files compressed
UINT nDecompressed; // # of files decompressed
double sizechange; // Total size change after files compressed/decompressed
char szTemp[_MAX_PATH];
//**************************************************************************
// Routine to display helpful instructions.
//**************************************************************************
void DisplayUsage(void)
{
printf("CCMPRS -- Conditional File Compression/Decompression Utility\n\n");
printf("Command line format is:\n\n");
printf(" ccmprs filespec [options]\n\n");
printf("where filespec is the path and filename (wildcards allowed) of the\n");
printf("file(s) to be examined. The options are:\n\n");
printf(" -s : Examine files in subdirectories as well as the specified directory.\n");
printf(" -d : Decompress any compressed files encountered that do not meet the\n");
printf(" specified conditions for compression.\n");
printf(" -t# : Compress file only if resulting file size is # percent or less of\n");
printf(" the uncompressed size. If this option is not specified, the default\n");
printf(" is 75 percent.\n");
printf(" -m# : Compress file only if its uncompressed size is at least # bytes. If\n");
printf(" this option is not specified, the default is 0.\n");
printf(" -xa[,b[,c...]] : Ignore files with the specified extension(s). For example,\n");
printf(" -xzip,gif would ignore ZIP and GIF files.\n");
printf(" -q : Operate quietly, with no status info displayed.\n\n");
//printf("For example: ccmprs d:\\letters\\*.txt -s -t66.6 -m500000\n\n");
//printf("This would examine all uncompressed files with file extension .txt, in the\n");
//printf("directory d:\\letters and all of its subdirectories. Each file at least 500000\n");
//printf("bytes in length is compressed. If the size of the resulting compressed file is\n");
//printf("66.6%% or less of the uncompressed size, the file is left compressed, otherwise\n");
//printf("it is restored to its original uncompressed state.\n");
}
//**************************************************************************
//
// Routine returns TRUE if volume containing the specified path supports
// file compression, FALSE if not. The path is assumed to be a full path,
// either UNC or DOS format.
//
//**************************************************************************
BOOL DriveIsCompressible(LPSTR lpszFileSpec)
{
char szRoot[4];
DWORD dwFlags;
BOOL bRet = FALSE;
do
{
// Extract the root directory.
strncpy(szRoot, lpszFileSpec, 3);
szRoot[3] = 0;
// Get information on the volume.
if (!GetVolumeInformation(szRoot, NULL, 0, NULL, NULL, &dwFlags, NULL, NULL))
break;
// Return TRUE if volume supports file compression.
if (dwFlags & FS_FILE_COMPRESSION)
bRet = TRUE;
} while (FALSE);
return bRet;
}
//**************************************************************************
// Routine to read the command line parameters and set the various global
// variables accordingly.
//**************************************************************************
BOOL GetParameters(int ac, char *av[])
{
int i;
// For each item in the command line...
for (i = 1; i < ac; i++)
{
// Process option or file specification.
if (*av[i] == '-')
{
switch (*(av[i] + 1))
{
case 's': // The "look at subdirectories" option
case 'S':
bRecurse = TRUE;
break;
case 'q': // The "be quiet!" option
case 'Q':
bQuiet = TRUE;
break;
case 'd': // The "decompress" option
case 'D':
bDecompress = TRUE;
break;
case 'm': // The "minimum size" option
case 'M':
MinFileSize = atof(av[i] + 2);
if (MinFileSize < 0)
{
printf("Invalid minimum file size of %.0lf bytes specified.\n", MinFileSize);
return FALSE;
}
break;
case 't': // The "compression threshold" option
case 'T':
threshold = atof(av[i] + 2);
if (threshold <= 0 || threshold > 100.0)
{
printf("Invalid compression threshold of %lf%% specified.\n", threshold);
return FALSE;
}
threshold /= 100.0;
break;
case 'x': // The "ignore file extensions" option
case 'X':
if (*(av[i] + 2))
{
if (szIgnoreExts)
{
// Append extensions to current list of extensions.
char *p = (char *)realloc(szIgnoreExts, strlen(szIgnoreExts) + strlen(av[i] + 2) + 2);
if (p)
{
szIgnoreExts = p;
strcat(szIgnoreExts, ",");
strcat(szIgnoreExts, av[i] + 2);
strlwr(szIgnoreExts);
}
}
else
{
// Make new list of extensions.
szIgnoreExts = (char *)malloc(strlen(av[i] + 2) + 1);
if (szIgnoreExts)
{
strcpy(szIgnoreExts, av[i] + 2);
strlwr(szIgnoreExts);
}
}
}
break;
default:
printf("The -%c option is not a valid option.\n", *(av[i] + 1));
return FALSE;
}
}
else
{
_fullpath(szFileSpec, av[i], _MAX_PATH);
}
}
// Check for file name.
if (!szFileSpec[0])
{
printf("No file name was specified.\n");
return FALSE;
}
// Make sure that the drive supports compression.
if (!DriveIsCompressible(szFileSpec))
{
printf("The specified volume does not support file-level compression.\n");
return FALSE;
}
// Allocate space for copy of file extensions string.
if (szIgnoreExts)
{
szExts = (char *)malloc(strlen(szIgnoreExts) + 1);
if (!szExts)
{
free(szIgnoreExts);
szIgnoreExts = NULL;
}
}
return TRUE;
}
//**************************************************************************
//**************************************************************************
BOOL SetFileCompression(LPSTR lpszFile, BOOL bCompress)
{
HANDLE hFile;
USHORT uMode;
DWORD dwAttributes;
BOOL bRet = FALSE;
do
{
// Get the file's current compression state.
dwAttributes = GetFileAttributes(lpszFile);
if (dwAttributes == 0xFFFFFFFF)
break;
// If the file is already in the desired state, return now.
if (!bCompress == !(dwAttributes & FILE_ATTRIBUTE_COMPRESSED))
{
bRet = TRUE;
break;
}
// Open the file.
hFile = CreateFile(szTemp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY, NULL);
if (hFile == INVALID_HANDLE_VALUE)
break;
// Set the file's compression state.
uMode = bCompress ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
bRet = DeviceIoControl(hFile, FSCTL_SET_COMPRESSION, &uMode, sizeof(uMode), NULL, 0, &dwAttributes, NULL);
// Close the file.
CloseHandle(hFile);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -