Initial Commit
This commit is contained in:
273
database/FileZillaFTP/source/hash_thread.cpp
Normal file
273
database/FileZillaFTP/source/hash_thread.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
#include "StdAfx.h"
|
||||
#include "hash_thread.h"
|
||||
#include "misc\md5.h"
|
||||
#include "ServerThread.h"
|
||||
|
||||
#define SHA512_STANDALONE
|
||||
typedef unsigned int uint32;
|
||||
#include "hash_algorithms/int64.h"
|
||||
#include "hash_algorithms/sshsh512.c"
|
||||
#include "hash_algorithms/sshsha.c"
|
||||
|
||||
CHashThread::CHashThread()
|
||||
{
|
||||
m_filename = 0;
|
||||
m_quit = false;
|
||||
m_id = 0;
|
||||
m_active_id = 0;
|
||||
m_result = OK;
|
||||
m_hash = 0;
|
||||
m_server_thread = 0;
|
||||
m_algorithm = SHA512;
|
||||
|
||||
m_hThread = CreateThread(0, 0, &CHashThread::ThreadFunc, this, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
CHashThread::~CHashThread()
|
||||
{
|
||||
m_sync.Lock();
|
||||
m_quit = true;
|
||||
m_server_thread = 0;
|
||||
delete [] m_filename;
|
||||
delete [] m_hash;
|
||||
m_sync.Unlock();
|
||||
|
||||
WaitForSingleObject(m_hThread, INFINITE);
|
||||
|
||||
CloseHandle(m_hThread);
|
||||
}
|
||||
|
||||
DWORD CHashThread::ThreadFunc(LPVOID pThis)
|
||||
{
|
||||
((CHashThread*)pThis)->Loop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
char* toHex(unsigned char* buffer, unsigned int len)
|
||||
{
|
||||
char* hex = new char[len * 2 + 1];
|
||||
hex[len * 2] = 0;
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
unsigned char l = buffer[i] >> 4;
|
||||
unsigned char r = buffer[i] & 0x0F;
|
||||
|
||||
if (l > 9)
|
||||
hex[i * 2] = 'a' + l - 10;
|
||||
else
|
||||
hex[i * 2] = '0' + l;
|
||||
|
||||
if (r > 9)
|
||||
hex[i * 2 + 1] = 'a' + r - 10;
|
||||
else
|
||||
hex[i * 2 + 1] = '0' + r;
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
}
|
||||
|
||||
void CHashThread::DoHash()
|
||||
{
|
||||
if (!m_filename)
|
||||
return;
|
||||
|
||||
LPCTSTR file = m_filename;
|
||||
m_filename = 0;
|
||||
|
||||
m_sync.Unlock();
|
||||
|
||||
int shareMode = FILE_SHARE_READ;
|
||||
HANDLE hFile = CreateFile(file, GENERIC_READ, shareMode, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||
delete [] file;
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
m_sync.Lock();
|
||||
m_result = FAILURE_OPEN;
|
||||
if (m_server_thread)
|
||||
m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
|
||||
return;
|
||||
}
|
||||
|
||||
const enum _algorithm alg = m_algorithm;
|
||||
|
||||
void* data;
|
||||
switch (alg)
|
||||
{
|
||||
case MD5:
|
||||
data = new ::MD5;
|
||||
break;
|
||||
case SHA512:
|
||||
data = new SHA512_State;
|
||||
SHA512_Init((SHA512_State*)data);
|
||||
break;
|
||||
case SHA1:
|
||||
data = new SHA_State;
|
||||
SHA_Init((SHA_State*)data);
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned char buffer[262144];
|
||||
DWORD read = 0;
|
||||
BOOL res = 0;
|
||||
while ((res = ReadFile(hFile, buffer, 262144, &read, 0) != 0) && read > 0)
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
case MD5:
|
||||
((::MD5*)data)->update(buffer, read);
|
||||
break;
|
||||
case SHA512:
|
||||
SHA512_Bytes((SHA512_State*)data, buffer, read);
|
||||
break;
|
||||
case SHA1:
|
||||
SHA_Bytes((SHA_State*)data, buffer, read);
|
||||
break;
|
||||
}
|
||||
|
||||
m_sync.Lock();
|
||||
if (!m_server_thread)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
m_sync.Unlock();
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
|
||||
if (!res)
|
||||
{
|
||||
m_sync.Lock();
|
||||
m_result = FAILURE_READ;
|
||||
if (m_server_thread)
|
||||
m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
|
||||
return;
|
||||
}
|
||||
|
||||
m_sync.Lock();
|
||||
|
||||
switch (alg)
|
||||
{
|
||||
case MD5:
|
||||
((::MD5*)data)->finalize();
|
||||
m_hash = ((::MD5*)data)->hex_digest();
|
||||
break;
|
||||
case SHA512:
|
||||
{
|
||||
unsigned char digest[64];
|
||||
SHA512_Final((SHA512_State*)data, digest);
|
||||
m_hash = toHex(digest, 64);
|
||||
}
|
||||
break;
|
||||
case SHA1:
|
||||
{
|
||||
unsigned char digest[20];
|
||||
SHA_Final((SHA_State*)data, digest);
|
||||
m_hash = toHex(digest, 20);
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_result = m_hash ? OK : FAILURE_READ;
|
||||
if (m_server_thread)
|
||||
m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
|
||||
}
|
||||
|
||||
void CHashThread::Loop()
|
||||
{
|
||||
m_sync.Lock();
|
||||
while (!m_quit)
|
||||
{
|
||||
DoHash();
|
||||
m_sync.Unlock();
|
||||
Sleep(100);
|
||||
m_sync.Lock();
|
||||
}
|
||||
}
|
||||
|
||||
enum CHashThread::_result CHashThread::Hash(LPCTSTR file, enum _algorithm algorithm, int& id, CServerThread* server_thread)
|
||||
{
|
||||
m_sync.Lock();
|
||||
if (m_active_id)
|
||||
{
|
||||
m_sync.Unlock();
|
||||
return BUSY;
|
||||
}
|
||||
|
||||
++m_id;
|
||||
if (m_id > 1000000)
|
||||
m_id = 1;
|
||||
id = m_id;
|
||||
m_active_id = id;
|
||||
|
||||
delete [] m_hash;
|
||||
m_hash = 0;
|
||||
|
||||
delete [] m_filename;
|
||||
m_filename = new TCHAR[_tcslen(file) + 1];
|
||||
_tcscpy(m_filename, file);
|
||||
|
||||
m_server_thread = server_thread;
|
||||
m_algorithm = algorithm;
|
||||
|
||||
m_result = PENDING;
|
||||
|
||||
m_sync.Unlock();
|
||||
|
||||
return PENDING;
|
||||
}
|
||||
|
||||
enum CHashThread::_result CHashThread::GetResult(int id, CHashThread::_algorithm& alg, CStdString& hash, CStdString& file)
|
||||
{
|
||||
if (id <= 0)
|
||||
return FAILURE_MASK;
|
||||
|
||||
m_sync.Lock();
|
||||
|
||||
if (id != m_active_id)
|
||||
{
|
||||
m_sync.Unlock();
|
||||
return BUSY;
|
||||
}
|
||||
|
||||
if (m_result == PENDING)
|
||||
{
|
||||
m_sync.Unlock();
|
||||
return PENDING;
|
||||
}
|
||||
|
||||
alg = m_algorithm;
|
||||
file = m_filename;
|
||||
|
||||
delete [] m_filename;
|
||||
m_filename = 0;
|
||||
|
||||
m_active_id = 0;
|
||||
|
||||
if (m_result == OK)
|
||||
{
|
||||
hash = m_hash;
|
||||
delete [] m_hash;
|
||||
m_hash = 0;
|
||||
m_sync.Unlock();
|
||||
return OK;
|
||||
}
|
||||
|
||||
m_sync.Unlock();
|
||||
|
||||
return m_result;
|
||||
}
|
||||
|
||||
void CHashThread::Stop(CServerThread* server_thread)
|
||||
{
|
||||
m_sync.Lock();
|
||||
if (m_server_thread == server_thread)
|
||||
m_server_thread = 0;
|
||||
m_sync.Unlock();
|
||||
}
|
||||
Reference in New Issue
Block a user