Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

Why does my lister program not work when I request to list specific file extensions?

$
0
0

I have created a function ListFilesBFS which lists folders and files using BFS and the output file undergoes compression and encryption. This works fine.

I tried to go 1 step further to also include a command argument to specify the type of extension that I want to list and created another function ListFilesByExtensionBFS. I managed to get the output file which lists the files based on the specific extension but my compression fails. Would like to seek some wisdom on this.

#include <iostream>#include <fstream>#include <Windows.h>#include <string>#include <vector>#include <queue>#include <compressapi.h> //Linker to Cabinet.lib#include <codecvt>#include <stdio.h>#include <bcrypt.h>#pragma comment(lib, "bcrypt.lib")#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)#define STATUS_UNSUCCESSFUL         ((NTSTATUS)0xC0000001L)// Function to list files in BFS ordervoid ListFilesBFS(const std::wstring& inputDirectoryPath, std::wofstream& out) {    // Create a queue to hold directory paths to be processed    std::queue<std::wstring> pathsQueue;    // Push the input directory path to start the traversal    pathsQueue.push(inputDirectoryPath);    // Loop until all directories have been processed    while (!pathsQueue.empty()) {        // Get the current directory path from the front of the queue        std::wstring currentPath = pathsQueue.front();        // Remove element at front of the queue        // FIFO        pathsQueue.pop();        // Construct the search path with extended-length path format        std::wstring searchPath = LR"(\\?\)" + currentPath + L"\\*";        // Find the first file or directory in the current directory        WIN32_FIND_DATAW findFileData;        HANDLE hFind = FindFirstFileW(searchPath.c_str(), &findFileData);        if (hFind == INVALID_HANDLE_VALUE) {            // If unable to traverse the directory, print error and continue to next iteration            std::wcerr << L"Error traversing directory: " << currentPath << std::endl;            continue;        }        // Iterate through all files and directories in the current directory        do {            // Get the name of the file or directory            std::wstring fileName = findFileData.cFileName;            // Ignore '.' and '..' directories            if (fileName != L"." && fileName != L"..") {                // Construct the full path of the file or directory                std::wstring fullPath = currentPath + L"\\" + fileName;                // Convert FILETIME to SYSTEMTIME                SYSTEMTIME creationTime;                FileTimeToSystemTime(&findFileData.ftCreationTime, &creationTime);                // Format the creation time string                wchar_t creationTimeString[20]; // Buffer for the formatted time string                swprintf(creationTimeString, 20, L"%04d/%02d/%02d %02d:%02d:%02d",                         creationTime.wYear, creationTime.wMonth, creationTime.wDay,                         creationTime.wHour, creationTime.wMinute, creationTime.wSecond);                // Construct the string containing file information                std::wstring fileInfo = fullPath + L" " + std::to_wstring(findFileData.nFileSizeLow) + L" " + creationTimeString;                // Write the file information string to the output file stream                out << fileInfo << std::endl;                // If it's a directory, add it to the queue for further traversal                if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {                    pathsQueue.push(fullPath);                }            }        } while (FindNextFileW(hFind, &findFileData) != 0);        // Check for errors or end of directory        DWORD dwError = GetLastError();        if (dwError != ERROR_NO_MORE_FILES){            std::wcerr << L"Error while traversing directory: " << dwError << std::endl;        }        // Close the handle to the directory        FindClose(hFind);    }}// Function to list files in BFS ordervoid ListFilesByExtensionBFS(const std::wstring& inputDirectoryPath, const std::wstring& extension, std::wofstream& out) {    // Create a queue to hold directory paths to be processed    std::queue<std::wstring> pathsQueue;    // Push the input directory path to start the traversal    pathsQueue.push(inputDirectoryPath);    // Loop until all directories have been processed    while (!pathsQueue.empty()) {        // Get the current directory path from the front of the queue        std::wstring currentPath = pathsQueue.front();        // Remove element at front of the queue        // FIFO        pathsQueue.pop();        // Construct the search path with extended-length path format        std::wstring searchPath = LR"(\\?\)" + currentPath + L"\\*";        // Find the first file or directory in the current directory        WIN32_FIND_DATAW findFileData;        HANDLE hFind = FindFirstFileW(searchPath.c_str(), &findFileData);        if (hFind == INVALID_HANDLE_VALUE) {            // If unable to traverse the directory, print error and continue to next iteration            std::wcerr << L"Error traversing directory: " << currentPath << std::endl;            continue;        }        // Iterate through all files and directories in the current directory        do {            // Get the name of the file or directory            std::wstring fileName = findFileData.cFileName;            // Ignore '.' and '..' directories            if (fileName != L"." && fileName != L"..") {                // Construct the full path of the file or directory                std::wstring fullPath = currentPath + L"\\" + fileName;                // Convert FILETIME to SYSTEMTIME                SYSTEMTIME creationTime;                FileTimeToSystemTime(&findFileData.ftCreationTime, &creationTime);                // Format the creation time string                wchar_t creationTimeString[20]; // Buffer for the formatted time string                swprintf(creationTimeString, 20, L"%04d/%02d/%02d %02d:%02d:%02d",                         creationTime.wYear, creationTime.wMonth, creationTime.wDay,                         creationTime.wHour, creationTime.wMinute, creationTime.wSecond);                // If it's a directory, add it to the queue for further traversal                if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {                    pathsQueue.push(fullPath);                } else {                    // Check if the file has the specified extension                    std::wstring::size_type dotPos = fileName.rfind(L'.');                    if (dotPos != std::wstring::npos && fileName.substr(dotPos + 1) == extension){                        // Format the file information string                        std::wstring fileInfo = fullPath + L" " + std::to_wstring(findFileData.nFileSizeLow) + L" " + creationTimeString;                        // Write the file information string to the output file stream                        out << fileInfo << std::endl;                    }                }            }        } while (FindNextFileW(hFind, &findFileData) != 0);        // Close the handle to the directory        FindClose(hFind);    }}bool CompressWithLZMS(const wchar_t* inFile, const wchar_t* outFile){    // Open input file    HANDLE hInFile = CreateFileW(inFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);    if (hInFile == INVALID_HANDLE_VALUE){        std::wcerr << L"Failed to open input file: " << inFile << std::endl;        return false;    }    // Get input file size    DWORD dwFileSize = GetFileSize(hInFile, NULL);    if (dwFileSize == INVALID_FILE_SIZE){        CloseHandle(hInFile);        std::wcerr << L"Failed to get input file size." << std::endl;        return false;    }    // Allocate buffer to hold input file data    BYTE* pInputBuffer = new BYTE[dwFileSize];    DWORD dwBytesRead;    if (!ReadFile(hInFile, pInputBuffer, dwFileSize, &dwBytesRead, NULL)){        CloseHandle(hInFile);        delete[] pInputBuffer;        std::wcerr << L"Failed to read input file." << std::endl;        return false;    }    // Close input file handle    CloseHandle(hInFile);    // Create compressor    COMPRESSOR_HANDLE hCompressor;    if (!::CreateCompressor(COMPRESS_ALGORITHM_LZMS, NULL, &hCompressor)){        delete[] pInputBuffer;        std::wcerr << L"Failed to create compressor." << std::endl;        return false;    }    // Estimate maximum possible size of compressed data    ULONG cbCompressedData = dwFileSize / 2;    // Allocate buffer to hold compressed data    BYTE* pCompressedBuffer = new BYTE[cbCompressedData];    // Compress data    SIZE_T cbWritten;    if (!Compress(hCompressor, pInputBuffer, dwFileSize, pCompressedBuffer, cbCompressedData, &cbWritten)){        delete[] pInputBuffer;        delete[] pCompressedBuffer;        CloseCompressor(hCompressor);        std::wcerr << L"Compression failed." << std::endl;        return false;    }    // Write compressed data to output file    HANDLE hOutFile = CreateFileW(outFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);    if (hOutFile == INVALID_HANDLE_VALUE){        delete[] pInputBuffer;        delete[] pCompressedBuffer;        CloseCompressor(hCompressor);        std::wcerr << L"Failed to create output file: " << outFile << std::endl;        return false;    }    //change cbWritten to static_cast<DWORD>(cbWritten)    DWORD dwBytesWritten;    if (!WriteFile(hOutFile, pCompressedBuffer, static_cast<DWORD>(cbWritten), &dwBytesWritten, NULL)){        delete[] pInputBuffer;        delete[] pCompressedBuffer;        CloseHandle(hOutFile);        CloseCompressor(hCompressor);        std::wcerr << L"Failed to write compressed data to output file." << std::endl;        return false;    }    // Cleanup    delete[] pInputBuffer;    delete[] pCompressedBuffer;    CloseHandle(hOutFile);    CloseCompressor(hCompressor);    return true;}// Function to decrypt using AES256 algorithmvoid EncryptDecryptString(const std::wstring& inputString, const std::wstring& outputFile, bool encrypt){// Encryption code here}// Entry point of the programint wmain(int argc, wchar_t* argv[]) {    // Check if the command-line arguments are valid    if (argc != 4 && !(argc == 2 && std::wstring(argv[1]) == L"-help")) {        // Display usage information if incorrect arguments provided        std::wcerr << L"Usage: " << argv[0] << L" -x <input_directory_path> <output_file_path>" << std::endl;        return 1;    }    // If the help option is provided, display help information    if (argc == 2 && std::wstring(argv[1]) == L"-help") {        std::wcout << L"Usage: " << argv[0] << L" -x <input_directory_path> <output_file_path>" << std::endl;        std::wcout << L"Options:" << std::endl;        std::wcout << L"  -x: Perform operation to list files in BFS order" << std::endl;        std::wcout << L"  -help: Show help information" << std::endl;        std::wcout << L"Example:" << std::endl;        std::wcout << L"  " << argv[0] << L" -x C:\\InputDirectory C:\\OutputFile.txt" << std::endl;        return 0;    }    // Check if the operation option is correct    if (wcscmp(argv[1], L"-x") != 0) {        std::wcerr << L"Invalid option. Use -x to specify the operation." << std::endl;        return 1;    }    // Get the input directory path and output file path    std::wstring inputDirectoryPath = argv[2];    std::wstring outputFile = argv[3];    // Open the output file    std::wofstream out(outputFile);    if (!out.is_open()) {        std::wcerr << L"Unable to open output file." << std::endl;        return 1;    }    // Create a locale object with std::codecvt_utf8 facet    std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);    // Imbue the file stream with system default locale    out.imbue(loc);    // Call the appropriate function based on the number of arguments    if (argc == 4){        // If there are 4 arguments, call the original ListFileBFS function        ListFilesBFS(inputDirectoryPath, out);    } else {        // If there are 5 arguments, the extension is provided, call the modified ListFilesByExtensionBFS function        std::wstring extension = argv[4[;        ListFilesByExtensionBFS(inputDirectoryPath, extension, out);    }    // Close the output file    out.close();    const wchar_t* compressedFile = L"compressed.lzms";    // Compress the file using LZMS compression algorithm    if (!CompressWithLZMS(outputFile.c_str(), compressedFile)){        std::wcerr << L"Compression failed." << std::endl;        return 1;    }    std::wcout << L"Compression successful. Compressed file: " << compressedFile << std::endl;    const wchar_t* encryptedFile = L"encrypted.aes";    EncryptDecryptString(compressedFile, encryptedFile, true);    std::wcout << L"Encryption successful. Encrypted fileL " << encryptedFile << std::endl;    return 0;}

Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>