BOOL WFDoCompress()

in src/wffile.c [1082:1355]


BOOL WFDoCompress(
    HWND hDlg,
    LPTSTR DirectorySpec,
    LPTSTR FileSpec)
{
    LPTSTR DirectorySpecEnd;
    HANDLE FileHandle;
    USHORT State;
    ULONG  Length;
    HANDLE FindHandle;
    WIN32_FIND_DATA FindData;
    int MBRet;


    //
    //  If the file spec is null, then set the compression bit for
    //  the directory spec and get out.
    //
    lstrcpy(szGlobalDir, DirectorySpec);
    DisplayCompressProgress(PROGRESS_UPD_DIRECTORY);

    if (lstrlen(FileSpec) == 0)
    {
DoCompressRetryCreate:

        if (!OpenFileForCompress(&FileHandle, DirectorySpec))
        {
            goto DoCompressError;
        }

DoCompressRetryDevIo:

        State = 1;
        if (!DeviceIoControl( FileHandle,
                              FSCTL_SET_COMPRESSION,
                              &State,
                              sizeof(USHORT),
                              NULL,
                              0,
                              &Length,
                              FALSE ))
        {
DoCompressError:

            if (!bIgnoreAllErrors)
            {
                MBRet = CompressErrMessageBox( hDlg,
                                               DirectorySpec,
                                               &FileHandle );
                if (MBRet == WF_RETRY_CREATE)
                {
                    goto DoCompressRetryCreate;
                }
                else if (MBRet == WF_RETRY_DEVIO)
                {
                    goto DoCompressRetryDevIo;
                }
                else if (MBRet == IDABORT)
                {
                    //
                    //  Return error.
                    //  File handle closed by CompressErrMessageBox.
                    //
                    return (FALSE);
                }
                //
                //  Else (MBRet == IDIGNORE)
                //  Continue on as if the error did not occur.
                //
            }
        }
        if (INVALID_HANDLE_VALUE != FileHandle)
        {
            CloseHandle(FileHandle);
            FileHandle = INVALID_HANDLE_VALUE;
        }

        TotalDirectoryCount++;
        TotalFileCount++;

        DisplayCompressProgress(PROGRESS_UPD_DIRCNT);
        DisplayCompressProgress(PROGRESS_UPD_FILECNT);

        ChangeFileSystem(FSC_ATTRIBUTES, DirectorySpec, NULL);

        return (TRUE);
    }

    //
    //  Get a pointer to the end of the directory spec, so that we can
    //  keep appending names to the end of it.
    //
    DirectorySpecEnd = DirectorySpec + lstrlen(DirectorySpec);

    //
    //  List the directory that is being compressed and display
    //  its current compress attribute.
    //
    TotalDirectoryCount++;
    DisplayCompressProgress(PROGRESS_UPD_DIRCNT);

    //
    //  For every file in the directory that matches the file spec,
    //  open the file and compress it.
    //
    //  Setup the template for findfirst/findnext.
    //
    lstrcpy(DirectorySpecEnd, FileSpec);

    if ((FindHandle = FindFirstFile(DirectorySpec, &FindData)) != INVALID_HANDLE_VALUE)
    {
        do
        {
            //
            //  Make sure the user hasn't hit cancel.
            //
            if (bShowProgress && !hDlgProgress)
            {
                break;
            }

            //
            //  Skip over the . and .. entries.
            //
            if ( !lstrcmp(FindData.cFileName, SZ_DOT) ||
                 !lstrcmp(FindData.cFileName, SZ_DOTDOT) )
            {
                continue;
            }
            else if ( (DirectorySpecEnd == (DirectorySpec + 3)) &&
                      !lstrcmpi(FindData.cFileName, SZ_NTLDR) )
            {
                //
                //  Do not allow \NTLDR to be compressed.
                //  Put up OK message box and then continue.
                //
                lstrcpy(DirectorySpecEnd, FindData.cFileName);
                LoadString(hAppInstance, IDS_NTLDRCOMPRESSERR, szTitle, COUNTOF(szTitle));
                wsprintf(szMessage, szTitle, DirectorySpec);

                LoadString(hAppInstance, IDS_WINFILE, szTitle, COUNTOF(szTitle));

                MessageBox(hDlg, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);

                continue;
            }
            else
            {
                //
                //  Append the found file to the directory spec and
                //  open the file.
                //
                lstrcpy(DirectorySpecEnd, FindData.cFileName);

                if (GetFileAttributes(DirectorySpec) & ATTR_COMPRESSED)
                {
                    //
                    //  Already compressed, so just get the next file.
                    //
                    continue;
                }

CompressFileRetryCreate:

                if (!OpenFileForCompress(&FileHandle, DirectorySpec))
                {
                    goto CompressFileError;
                }

CompressFileRetryDevIo:

                //
                //  Compress the file.
                //
                if (!CompressFile(FileHandle, DirectorySpec, &FindData))
                {
CompressFileError:

                    if (!bIgnoreAllErrors)
                    {
                        MBRet = CompressErrMessageBox( hDlg,
                                                       DirectorySpec,
                                                       &FileHandle );
                        if (MBRet == WF_RETRY_CREATE)
                        {
                            goto CompressFileRetryCreate;
                        }
                        else if (MBRet == WF_RETRY_DEVIO)
                        {
                            goto CompressFileRetryDevIo;
                        }
                        else if (MBRet == IDABORT)
                        {
                            //
                            //  Return error.
                            //  File handle was closed by CompressErrMessageBox.
                            //
                            FindClose(FindHandle);
                            return (FALSE);
                        }
                        //
                        //  Else (MBRet == IDIGNORE)
                        //  Continue on as if the error did not occur.
                        //
                    }
                }
                if (INVALID_HANDLE_VALUE != FileHandle)
                {
                    //
                    // Close the file and get the next file.
                    //
                    CloseHandle(FileHandle);
                    FileHandle = INVALID_HANDLE_VALUE;
                }
            }

        } while (FindNextFile(FindHandle, &FindData));

        FindClose(FindHandle);

        ChangeFileSystem(FSC_ATTRIBUTES, DirectorySpec, NULL);
    }

    //
    //  If we are to do subdirectores, then look for every subdirectory
    //  and recursively call ourselves to list the subdirectory.
    //
    if (DoSubdirectories && hDlgProgress)
    {
        //
        //  Setup findfirst/findnext to search the entire directory.
        //
        lstrcpy(DirectorySpecEnd, SZ_STAR);

        if ((FindHandle = FindFirstFile(DirectorySpec, &FindData)) != INVALID_HANDLE_VALUE)
        {
            do
            {
                //
                //  Skip over the . and .. entries, otherwise recurse.
                //
                if ( !lstrcmp(FindData.cFileName, SZ_DOT) ||
                     !lstrcmp(FindData.cFileName, SZ_DOTDOT) )
                {
                    continue;
                }
                else
                {
                    //
                    //  If the entry is for a directory, then tack
                    //  on the subdirectory name to the directory spec
                    //  and recurse.
                    //
                    if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                    {
                        lstrcpy(DirectorySpecEnd, FindData.cFileName);
                        lstrcat(DirectorySpecEnd, SZ_BACKSLASH);

                        if (!WFDoCompress(hDlg, DirectorySpec, FileSpec))
                        {
                            FindClose(FindHandle);
                            return (FALSE);
                        }
                    }
                }

            } while (FindNextFile(FindHandle, &FindData));

            FindClose(FindHandle);
        }
    }

    return (TRUE);
}