CUnrarDLL.h
// CUnrarDLL.h : header file // #ifndef _C_UNRARDLL_H #define _C_UNRARDLL_H struct RARHeaderData { char ArcName[260]; char FileName[260]; unsigned int Flags; unsigned int PackSize; unsigned int UnpSize; unsigned int HostOS; unsigned int FileCRC; unsigned int FileTime; unsigned int UnpVer; unsigned int Method; unsigned int FileAttr; char *CmtBuf; unsigned int CmtBufSize; unsigned int CmtSize; unsigned int CmtState; }; struct RARHeaderDataEx { char ArcName[1024]; wchar_t ArcNameW[1024]; char FileName[1024]; wchar_t FileNameW[1024]; unsigned int Flags; unsigned int PackSize; unsigned int PackSizeHigh; unsigned int UnpSize; unsigned int UnpSizeHigh; unsigned int HostOS; unsigned int FileCRC; unsigned int FileTime; unsigned int UnpVer; unsigned int Method; unsigned int FileAttr; char *CmtBuf; unsigned int CmtBufSize; unsigned int CmtSize; unsigned int CmtState; unsigned int Reserved[1024]; }; struct RAROpenArchiveData { char *ArcName; unsigned int OpenMode; unsigned int OpenResult; char *CmtBuf; unsigned int CmtBufSize; unsigned int CmtSize; unsigned int CmtState; }; struct RAROpenArchiveDataEx { char *ArcName; wchar_t *ArcNameW; unsigned int OpenMode; unsigned int OpenResult; char *CmtBuf; unsigned int CmtBufSize; unsigned int CmtSize; unsigned int CmtState; unsigned int Flags; unsigned int Reserved[32]; }; / // CUnrarDLL definitions #include <vector> using namespace std; struct CUnrarFile { CString fileName; __int64 packSize; __int64 unpackSize; }; class CUnrarDLL { // Construction public: CUnrarDLL(); // Constructor ~CUnrarDLL(); // Deconstructor // Load the DLL, automatically called in the constructor bool LoadDLL(); // Unload the DLL, automatically called in the destructor void UnloadDLL(); // Set the unrar directory void SetOutputDirectory(LPCSTR outDir) { unrarDir = outDir; } // Get the unrar directory CString GetOutputDirectory() { return unrarDir; } // Open a RAR file into the class bool OpenRARFile(LPCSTR rarPath) { currentRar = rarPath; return OpenRAR(currentRar.GetBuffer(currentRar.GetLength())); } // Get the opened RAR path CString GetCurrentRAR() { return currentRar; } // Get a list of all the files in the current RAR in a CStringArray void ListFileNames(CStringArray* outList); // Get a file at a specified location CUnrarFile GetFileAt(int filePos) { return fileList.at(filePos); } // Get the number of files int GetNumberOfFiles() { return fileList.size(); } // UnRAR the archive bool UnRARArchive(); // Current error CString lastError; // Implementation protected: // Current information CString unrarDir; CString currentRar; // Open RAR bool OpenRAR(char* rarTo); // The DLL HINSTANCE unrarDLL; // Files vector<CUnrarFile> fileList; // Function pointers for accessing RAR information HANDLE (WINAPI *OpenArchiveEx)(RAROpenArchiveDataEx *pArchiveData); int (WINAPI *CloseArchive)(HANDLE hArcData); int (WINAPI *ReadRARHeader)(HANDLE hArcData, RARHeaderData *pHeaderData); int (WINAPI *ProcessRARFile)(HANDLE hArcData, int iOperation, char* strDestFolder, char* strDestName); int (WINAPI *ReadRARHeaderEx)(HANDLE hArcData,struct RARHeaderDataEx *HeaderData); }; #endif
CUnrarDLL.cpp
// CUnrarDLL.cpp : implementation file // #include "stdafx.h" #include "CUnrarDLL.h" / // CUnrarDLL class CUnrarDLL::CUnrarDLL() { // Load the DLL LoadDLL(); } CUnrarDLL::~CUnrarDLL() { // Load the DLL UnloadDLL(); } // Open the DLL // bool CUnrarDLL::LoadDLL() { // Attempt to load the DLL unrarDLL = LoadLibrary(_T("unrar.dll")); // It failed, update the error and return false if (unrarDLL == NULL) { lastError = "Load Error: unrar.dll could not be loaded"; return false; } // Otherwise true return true; } // Unload the DLL void CUnrarDLL::UnloadDLL() { FreeLibrary(unrarDLL); } // Open a RAR file bool CUnrarDLL::OpenRAR(char* rarTo) { // Is the DLL loaded? if (unrarDLL == NULL) { return false; } // Get the function pointers we need (FARPROC&)OpenArchiveEx = GetProcAddress(unrarDLL, _T("RAROpenArchiveEx")); (FARPROC&)CloseArchive = GetProcAddress(unrarDLL, _T("RARCloseArchive")); (FARPROC&)ProcessRARFile = GetProcAddress(unrarDLL, _T("RARProcessFile")); (FARPROC&)ReadRARHeaderEx = GetProcAddress(unrarDLL, _T("RARReadHeaderEx")); // Set up our RAR archive data RAROpenArchiveDataEx archiveData; ZeroMemory(&archiveData, sizeof(archiveData)); archiveData.ArcName = rarTo; archiveData.CmtBuf = NULL; archiveData.OpenMode = 0; // Open the archive into a handle HANDLE archiveHandle = OpenArchiveEx(&archiveData); // Did it fail? Update the error and return false if (archiveData.OpenResult != 0) { lastError = "Open Error: Failed to open RAR file"; return false; } char emptyBuf[16384]; // Declare our file struct CUnrarFile curFile; // Set up the header data RARHeaderDataEx headerData; headerData.CmtBuf = emptyBuf; headerData.CmtBufSize = sizeof(emptyBuf); // Declare variables int readHeaderCode, processFileCode; // Empty the vector fileList.clear(); // While we get a valid response to reading the header, continue while ((readHeaderCode = ReadRARHeaderEx(archiveHandle, &headerData)) == 0) { // Get the file size __int64 unpackSize = headerData.UnpSize+(((__int64)headerData.UnpSizeHigh) <<32); __int64 packSize = headerData.PackSize+(((__int64)headerData.PackSizeHigh) <<32); // Get the filename from the header data curFile.fileName = headerData.FileName; // Set pack/unpacked sizes curFile.packSize = packSize; curFile.unpackSize = unpackSize; // Push back this file into the vector fileList.push_back(curFile); // Invalid file? Break, we're done if ((processFileCode = ProcessRARFile(archiveHandle, 0, NULL, NULL)) != 0) { break; } } int totalNum = fileList.size(); // Close the archive CloseArchive(archiveHandle); return true; } // List all files in a RAR void CUnrarDLL::ListFileNames(CStringArray* outList) { // Clear the array outList->RemoveAll(); // Loop through the vector and get the filenames CUnrarFile curFile; for (int i = 0; i < fileList.size(); i++) { curFile = fileList.at(i); outList->Add(curFile.fileName); } } // UnRAR the archive to the specified location bool CUnrarDLL::UnRARArchive() { // Is the DLL loaded? if (unrarDLL == NULL) { return false; } // Get the function pointers we need (FARPROC&)OpenArchiveEx = GetProcAddress(unrarDLL, _T("RAROpenArchiveEx")); (FARPROC&)CloseArchive = GetProcAddress(unrarDLL, _T("RARCloseArchive")); (FARPROC&)ProcessRARFile = GetProcAddress(unrarDLL, _T("RARProcessFile")); (FARPROC&)ReadRARHeader = GetProcAddress(unrarDLL, _T("RARReadHeader")); // Set up our RAR archive data RAROpenArchiveDataEx archiveData; ZeroMemory(&archiveData, sizeof(archiveData)); archiveData.ArcName = currentRar.GetBuffer(currentRar.GetLength()); archiveData.CmtBuf = NULL; archiveData.OpenMode = 1; // Open the archive into a handle HANDLE archiveHandle = OpenArchiveEx(&archiveData); // Did it fail? Update the error and return false if (archiveData.OpenResult != 0) { lastError = "Open Error: Failed to open RAR file"; return false; } // Simple header data struct RARHeaderData headerData; headerData.CmtBuf = NULL; // Set variables int readHeaderCode, processFileCode; // While the header data is valid.. while ((readHeaderCode = ReadRARHeader(archiveHandle, &headerData)) == 0) { unrarDir.AnsiToOem(); // UnRAR this file processFileCode = ProcessRARFile(archiveHandle, 2, unrarDir.GetBuffer(unrarDir.GetLength()), NULL); // Did it go okay? If not, we're done if (processFileCode != 0) { break; } } // Close the archive CloseArchive(archiveHandle); return true; }