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

📄 aescryptworkerthreads.cpp

📁 AES, 即Advanced Encryption Standard高级加密标准模块, 它是目前国际上最先进的加密技术, 是基于DES之后的最新发布的高段加密标准. 该标准由美国NIST(Nation
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
 *  AESCryptWorkerThreads.cpp
 *
 *  Copyright (C) 2006, 2007
 *  Paul E. Jones <paulej@arid.us>
 *  All Rights Reserved.
 *
 ******************************************************************************
 *  $Id: AESCryptWorkerThreads.cpp,v 1.11 2008/03/25 20:53:21 paulej Exp $
 ******************************************************************************
 *
 *  This module implements the AESCryptWorkerThreads class, which is
 *  responsible for all background encryption and decryption functions.
 *
 */


#include "stdafx.h"
#include "AESCryptWorkerThreads.h"
#include "PasswdDialog.h"
#include "ErrorHandling.h"
#include "BufferedFile.h"
#include "ProgressDialog.h"
#include <time.h>

extern "C" {
#include "aes.h"
#include "sha256.h"
}

#define FOOTPRINT_V0  53
#define FOOTPRINT_V1  134

/*
 * Function prototype used later
 */
DWORD WINAPI ThreadInit(LPVOID lpParameter);

/*
 * AESCryptWorkerThreads Constructor
 */
AESCryptWorkerThreads::AESCryptWorkerThreads()
{
    InitializeCriticalSection(&Critical_Section);
    Thread_Count = 0;
}

/*
 * AESCryptWorkerThreads Destructor
 */
AESCryptWorkerThreads::~AESCryptWorkerThreads()
{
    HANDLE handle;

    // Wait for any active threads to complete
    // In theory, this block of code should never run, since
    // the IsBusy() call should be made and the class should
    // not be destroyed.  But, just in case...
    while(1)
    {
        EnterCriticalSection(&Critical_Section);
        if (Thread_Count == 0)
        {
            LeaveCriticalSection(&Critical_Section);
            break;
        }
        LeaveCriticalSection(&Critical_Section);
        Sleep(200);
    }

    // Release any thread handles not already released
    while (!Terminated_Threads.empty())
    {
        handle = Terminated_Threads.front();
        WaitForSingleObject(&handle, INFINITE);
        CloseHandle(handle);
        Terminated_Threads.pop_front();
    }
    DeleteCriticalSection(&Critical_Section);
}

/*
 * IsBusy()
 *
 * Are there worker threads working?
 */
bool AESCryptWorkerThreads::IsBusy()
{
    bool busy = false;

    EnterCriticalSection(&Critical_Section);
    if (Thread_Count > 0)
    {
        busy = true;
    }
    LeaveCriticalSection(&Critical_Section);

    return busy;
}

/*
 * BeginWork
 *
 */
void AESCryptWorkerThreads::ProcessFiles(   StringList *file_list,
                                            bool encrypt)
{
    PasswdDialog dlg;

    // Prompt the user for a password
    if (dlg.DoModal(::GetActiveWindow(), (encrypt ? 1 : 0)) == IDOK)
    {
        if (StartThread(file_list,
                        dlg.passwd,
                        encrypt) == false)
        {
            // We were unable to start a thread, so we must clean up
            // the file list.
            delete file_list;
        }
    }
    else
    {
        // The user canceled the operation, so delete the file list
        delete file_list;
    }
}

/*
 * StartThread
 *
 * This function will start a new thread to encrypt or decrypt files
 * as requested by the user.
 */
bool AESCryptWorkerThreads::StartThread(StringList *file_list,
                                        TCHAR *passwd,
                                        bool encrypt)
{
    WorkerData *worker_data = NULL;
    DWORD thread_id;
    HANDLE thread_handle;

    try
    {
        worker_data = new WorkerData;
        worker_data->file_list = file_list;
        worker_data->encrypt = encrypt;
        _tcscpy_s(worker_data->passwd, MAX_PASSWD_LEN+1, passwd);
        worker_data->aes_crypt_worker_threads = this;
    }
    catch(...)
    {
        ::ReportError(  _T("Memory allocation failed"),
                        ERROR_SUCCESS);
    }

    if (worker_data != NULL)
    {
        // We do not want the new thread to come before we're ready.
        // We want the thread to know its handle before it starts
        // doing any real work.
        EnterCriticalSection(&Critical_Section);

        // Create the thread
        thread_handle = CreateThread(   NULL,
                                        0,
                                        ThreadInit,
                                        (LPVOID) worker_data,
                                        0,
                                        &thread_id);

        if (thread_handle != NULL)
        {
            // Let the thread know its handle
            worker_data->thread_handle = thread_handle;

            // Increase the internal thread counter
            Thread_Count++;

            // Let the thread in
            LeaveCriticalSection(&Critical_Section);

            // We successfully created the thread and handed
            // the list of files to that thread for processing.
            return true;
        }
        else
        {
            // Let go of the critical section
            LeaveCriticalSection(&Critical_Section);

            // Free the memory allocated for the worker_data structure
            delete worker_data;
            
            ::ReportError(  _T("Thread creation failed"),
                            ERROR_SUCCESS);
        }
    }

    // Returning false means something failed and caller must
    // delete the file list, since posession was not transferred
    // to a thread
    return false;
}

/*
 * ThreadEntry
 *
 * This is where the thread comes back into the class to get some work
 * done.
 */
void AESCryptWorkerThreads::ThreadEntry(WorkerData *worker_data)
{
    HANDLE          handle;

    // Try to enter the critical section
    EnterCriticalSection(&Critical_Section);

    // Release any thread handles not already released
    while (!Terminated_Threads.empty())
    {
        handle = Terminated_Threads.front();
        WaitForSingleObject(&handle, INFINITE);
        CloseHandle(handle);
        Terminated_Threads.pop_front();
    }

    // OK, we're in sync with our caller and cleaned up old threads
    LeaveCriticalSection(&Critical_Section);

    if (worker_data->encrypt)
    {
        EncryptFiles(   worker_data->file_list,
                        worker_data->passwd);
    }
    else
    {
        DecryptFiles(   worker_data->file_list,
                        worker_data->passwd);
    }

    // Delete the file list
    delete worker_data->file_list;

    // Once we are done with what we wanted to do, then decrement the
    // thread count, clean up memory, etc.
    EnterCriticalSection(&Critical_Section);
    Thread_Count--;
    Terminated_Threads.push_back(worker_data->thread_handle);
    LeaveCriticalSection(&Critical_Section);
    
    // Delete the worker data structure
    delete worker_data;
}

/*
 *  DoMessageLoop
 *
 *  This routine will service the windows message queues for the running
 *  thread so that messages are delivered and windows are properly updated.
 */
inline void AESCryptWorkerThreads::DoMessageLoop()
{
    MSG msg;

    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

/*
 * ThreadInit
 *
 * This is a C function where the thread starts life.
 */
DWORD WINAPI ThreadInit(LPVOID lpParameter)
{
    WorkerData *worker_data =
                        (WorkerData*) lpParameter;

    worker_data->aes_crypt_worker_threads->ThreadEntry(worker_data);

    return 0;
}

/*
 * EncryptFiles
 *
 * This function is called by the worker thread to encrypt a list of files.
 */
void AESCryptWorkerThreads::EncryptFiles(
                                StringList  *file_list,
                                TCHAR       *passwd)
{
    aes_context                 aes_ctx;
    sha256_context              sha_ctx;
    std::basic_string<TCHAR>    in_file, out_file;
    BufferedFile                in_buffered_file,
                                out_buffered_file;
    DWORD                       result_code;
    unsigned char               IV[16];
    unsigned char               buffer[32];
    unsigned char               iv_key[48];
    unsigned char               digest[32];
    LARGE_INTEGER               file_size; // 64-bit integer structure
    ULONGLONG                   bytes_left;
    int                         i, j, n;
    DWORD                       bytes_written, bytes_read;
    unsigned char               ipad[64];
    unsigned char               opad[64];
    bool                        error_abort = false;
    ProgressDialog              dlg;
    time_t                      current_time;
    clock_t                     last_clock_time;
    ULONGLONG                   last_percent, current_percent;
    HCRYPTPROV                  hProv;


    // Passing a non-zero instructs the dialog to display
    // "Encrypting..."
    dlg.Create(NULL,1);

    // Prepare for random number generation
    if (!CryptAcquireContext(   &hProv,
                                NULL,

⌨️ 快捷键说明

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