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

📄 cabinet.cpp

📁 使用的制作cab文件的源程序
💻 CPP
字号:
// Cabinet.cpp: implementation of the CCabinet class.
//
//////////////////////////////////////////////////////////////////////

#include "Cabinet.h"


//下面是压缩时用到的回调函数。
/*
 * 分配内存
 */
FNFCIALLOC(mem_alloc)
{
	return malloc(cb);
}


/*
 * 释放内存
 */
FNFCIFREE(mem_free)
{
	free(memory);
}

/*
 * 打开文件
 */
FNFCIOPEN(fci_open)
{
    return _open(pszFile, oflag, pmode);
}

/*
 * 读取文件
 */
FNFCIREAD(fci_read)
{
    return (unsigned int) _read(hf, memory, cb);
}

/*
 * 写文件
 */
FNFCIWRITE(fci_write)
{
    return (unsigned int) _write(hf, memory, cb);
}

/*
 * 关闭文件
 */
FNFCICLOSE(fci_close)
{
   return _close(hf);
}

FNFCISEEK(fci_seek)
{
    return _lseek(hf, dist, seektype);
}

FNFCIDELETE(fci_delete)
{
    return remove(pszFile);
}


FNFCIFILEPLACED(file_placed)
{
	return 0;
}


FNFCIGETTEMPFILE(get_temp_file)
{
    char    *psz;

    psz = _tempnam("","xx");            // Get a name
    if ((psz != NULL) && (strlen(psz) < (unsigned)cbTempName)) {
        strcpy(pszTempName,psz);        // Copy to caller's buffer
        free(psz);                      // Free temporary name buffer
        return TRUE;                    // Success
    }
    //** Failed
    if (psz) {
        free(psz);
    }

    return FALSE;
}


/*
 * 用于压缩过程中的提示信息显示,这里忽略。
 */
FNFCISTATUS(progress)
{
	return 0;
}

/*
 * 这里忽略。
 */
FNFCIGETNEXTCABINET(get_next_cabinet)
{
	return TRUE;
}


FNFCIGETOPENINFO(get_open_info)
{
	BY_HANDLE_FILE_INFORMATION	finfo;
	FILETIME					filetime;
	HANDLE						handle;
    DWORD                       attrs;
    int                         hf;

    /*
     * Need a Win32 type handle to get file date/time
     * using the Win32 APIs, even though the handle we
     * will be returning is of the type compatible with
     * _open
     */
	handle = CreateFile(
		pszName,
		GENERIC_READ,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
		NULL
	);
   
	if (handle == INVALID_HANDLE_VALUE)
	{
		return -1;
	}

	if (GetFileInformationByHandle(handle, &finfo) == FALSE)
	{
		CloseHandle(handle);
		return -1;
	}
   
	FileTimeToLocalFileTime(
		&finfo.ftLastWriteTime, 
		&filetime
	);

	FileTimeToDosDateTime(
		&filetime,
		pdate,
		ptime
	);

    attrs = GetFileAttributes(pszName);

    if (attrs == 0xFFFFFFFF)
    {
        /* failure */
        *pattribs = 0;
    }
    else
    {
        /*
         * Mask out all other bits except these four, since other
         * bits are used by the cabinet format to indicate a
         * special meaning.
         */
        *pattribs = (int) (attrs & (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));
    }

    CloseHandle(handle);


    /*
     * Return handle using _open
     */
	hf = _open( pszName, _O_RDONLY | _O_BINARY );

	if (hf == -1)
		return -1; // abort on error
   
	return hf;
}
//以上为压缩时需要的回调函数


//下面是解压缩时用到的回调函数。

FNALLOC(dmem_alloc)
{
	return malloc(cb);
}

FNFREE(dmem_free)
{
	free(pv);
}

FNOPEN(dfile_open)
{
	return _open(pszFile, oflag, pmode);
}

FNREAD(dfile_read)
{
	return _read(hf, pv, cb);
}

FNWRITE(dfile_write)
{
	return _write(hf, pv, cb);
}

FNCLOSE(dfile_close)
{
	return _close(hf);
}

FNSEEK(dfile_seek)
{
	return _lseek(hf, dist, seektype);
}

char	dest_dir[MAX_PATH];

FNFDINOTIFY(notification_function)
{
	switch (fdint)
	{
		case fdintCABINET_INFO: // general information about the cabinet
			return 0;

		case fdintPARTIAL_FILE: // first file in cabinet is continuation
			return 0;

		case fdintCOPY_FILE:	// file to be copied
		{
			int		handle;
			char	destination[256];

			sprintf(
					destination, 
					"%s%s",
					dest_dir,
					pfdin->psz1
				);

				handle = _open(
					destination,
					_O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL,
					_S_IREAD | _S_IWRITE 
				);

				return handle;
		}

		case fdintCLOSE_FILE_INFO:	// close the file, set relevant info
        {
            HANDLE  handle;
            DWORD   attrs;
            char    destination[256];

            sprintf(
                destination, 
                "%s%s",
                dest_dir,
                pfdin->psz1
            );

			_close(pfdin->hf);


            /*
             * Set date/time
             *
             * Need Win32 type handle for to set date/time
             */
            handle = CreateFile(
                destination,
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL
            );

            if (handle != INVALID_HANDLE_VALUE)
            {
                FILETIME    datetime;

                if (TRUE == DosDateTimeToFileTime(
                    pfdin->date,
                    pfdin->time,
                    &datetime))
                {
                    FILETIME    local_filetime;

                    if (TRUE == LocalFileTimeToFileTime(
                        &datetime,
                        &local_filetime))
                    {
                        (void) SetFileTime(
                            handle,
                            &local_filetime,
                            NULL,
                            &local_filetime
                        );
                     }
                }

                CloseHandle(handle);
            }

            /*
             * Mask out attribute bits other than readonly,
             * hidden, system, and archive, since the other
             * attribute bits are reserved for use by
             * the cabinet format.
             */
            attrs = pfdin->attribs;

            attrs &= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);

            (void) SetFileAttributes(
                destination,
                attrs
            );

			return TRUE;
        }

		case fdintNEXT_CABINET:	// file continued to next cabinet
			return 0;
	}

	return 0;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCabinet::CCabinet()
{

}

CCabinet::~CCabinet()
{

}

BOOL CCabinet::CreateCabinet(char *CABName)
{
	ERF				erf;
	CCAB			cab_parameters;

	char			*p;
	char			cabPath[MAX_PATH];
	char			cabName[MAX_PATH];

	if(CABName == NULL)
		return FALSE;

	p = strrchr(CABName, '\\');
	if (p == NULL)
	{
		strcpy(cabName, CABName);
		strcpy(cabPath, "");
	}
	else
	{
		strcpy(cabName, p+1);
		strncpy(cabPath, CABName, (int) (p-CABName)+1);
		cabPath[p - CABName + 1] = '\0';
	}


	memset(&cab_parameters, 0, sizeof(CCAB));

	cab_parameters.cb = MEDIA_SIZE;
	cab_parameters.cbFolderThresh = FOLDER_THRESHOLD;

	/*Don't reserve space for any extensions*/
	cab_parameters.cbReserveCFHeader = 0;
	cab_parameters.cbReserveCFFolder = 0;
	cab_parameters.cbReserveCFData   = 0;

	cab_parameters.iCab = 1;

	cab_parameters.iDisk = 0;

	/*Choose your own number*/
	cab_parameters.setID = 12345;

	/* where to store the created CAB files */
	strcpy(cab_parameters.szCabPath, cabPath);

	/* store name of CAB file */
	strcpy(cab_parameters.szCab, cabName);

	m_hfci = FCICreate(
		&erf,
		file_placed,
		mem_alloc,
		mem_free,
        fci_open,
        fci_read,
        fci_write,
        fci_close,
        fci_seek,
        fci_delete,
		get_temp_file,
        &cab_parameters,
        NULL
	);

	if (m_hfci == NULL)
	{
		return FALSE;
	}
	return TRUE;
}

BOOL CCabinet::AddFile2Cab(char *fileName)
{
	char			*p;
	char			srcName[MAX_PATH];

	if(fileName == NULL)
		return FALSE;

	p = strrchr(fileName, '\\');
	if (p == NULL)
	{
		strcpy(srcName, fileName);
	}
	else
	{
		strcpy(srcName, p+1);
	}

	if (FALSE == FCIAddFile(
			m_hfci,
			fileName,  /* file to add */
			srcName, /* file name in cabinet file */
			FALSE, /* file is not executable */
			get_next_cabinet,
			progress,
			get_open_info,
            COMPRESSION_TYPE))
		{
            (void) FCIDestroy(m_hfci);
			return FALSE;
		}
	return TRUE;
}

BOOL CCabinet::FlushCab()
{
	if (FALSE == FCIFlushCabinet(
		m_hfci,
		FALSE,
		get_next_cabinet,
		progress))
	{
        (void) FCIDestroy(m_hfci);
		return FALSE;
	}
    return FCIDestroy(m_hfci);
}

BOOL CCabinet::Compress(char *srcName, char *cabName)
{
	char	cab_name[MAX_PATH];

	if(srcName == NULL)
		return FALSE;
	if(cabName == NULL)
	{
		sprintf(cab_name, "%s.cab", srcName);
	}
	else
	{
		strcpy(cab_name, cabName);
	}
	if(CreateCabinet(cab_name)
		&& AddFile2Cab(srcName)
		&& FlushCab())
		return TRUE;
	else
		return FALSE;
}

BOOL CCabinet::Decompress(char *cabName, char *destPath)
{
	HFDI			hfdi;
	ERF				erf;
	FDICABINETINFO	fdici;
	int				hf;
	char			*p;
	char			cabinet_name[256];
	char			cabinet_path[256];

	if(cabName == NULL)
		return FALSE;

	hfdi = FDICreate(
		dmem_alloc,
		dmem_free,
		dfile_open,
		dfile_read,
		dfile_write,
		dfile_close,
		dfile_seek,
		cpu80386,
		&erf);

	if (hfdi == NULL)
	{
		return FALSE;
	}


	/*
	 * Is this file really a cabinet?
	 */
	hf = dfile_open(
		cabName,
		_O_BINARY | _O_RDONLY | _O_SEQUENTIAL,
		0
	);

	if (hf == -1)
	{
		(void) FDIDestroy(hfdi);
		return FALSE;
	}

	if (FALSE == FDIIsCabinet(
			hfdi,
			hf,
			&fdici))
	{
		_close(hf);
		(void) FDIDestroy(hfdi);
		return FALSE;
	}
	else
	{
		_close(hf);
	}

	p = strrchr(cabName, '\\');
	if (p == NULL)
	{
		strcpy(cabinet_name, cabName);
		strcpy(cabinet_path, "");
	}
	else
	{
		strcpy(cabinet_name, p+1);
		strncpy(cabinet_path, cabName, (int) (p-cabName)+1);
		cabinet_path[ (int) (p-cabName)+1 ] = '\0';
	}

	if(destPath == NULL)
		strcpy(dest_dir, cabinet_path);
	else
		strcpy(dest_dir, destPath);

	if (TRUE != FDICopy(
		hfdi,
		cabinet_name,
		cabinet_path,
		0,
		notification_function,
		NULL,
		NULL))
	{
		(void) FDIDestroy(hfdi);
		return FALSE;
	}

	if (FDIDestroy(hfdi) != TRUE)
	{
		return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -