⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccmprs.cpp

📁 A command-line file compression utility for Windows NT. It allows you to select files for NTFS fil
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//**************************************************************************
//
//  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 + -