📄 aescryptworkerthreads.cpp
字号:
/*
* 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 + -