224 lines
6.1 KiB
C
224 lines
6.1 KiB
C
// md5_1.c
|
|
// Copyright : 2021-05-14 Yutaka Sawada
|
|
// License : GPL
|
|
|
|
#include <windows.h>
|
|
|
|
#include "common1.h"
|
|
#include "phmd5.h"
|
|
#include "md5_1.h"
|
|
|
|
|
|
// バイト配列の MD5 ハッシュ値を求める
|
|
void data_md5(
|
|
unsigned char *data_in, // ハッシュ値を求めるバイト配列
|
|
unsigned int data_len, // 入力バイト数
|
|
unsigned char *hash) // ハッシュ値 16バイト
|
|
{
|
|
PHMD5 ctx;
|
|
|
|
Phmd5Begin(&ctx);
|
|
Phmd5Process(&ctx, data_in, data_len);
|
|
Phmd5End(&ctx);
|
|
memcpy(hash, ctx.hash, 16);
|
|
}
|
|
|
|
// ファイルの MD5 ハッシュ値を求める
|
|
int file_md5(
|
|
wchar_t *file_name, // 表示するファイル名
|
|
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
|
|
unsigned __int64 file_size,
|
|
unsigned char *hash) // ハッシュ値 (16バイト)
|
|
{
|
|
unsigned char buf[IO_SIZE];
|
|
unsigned int rv, len;
|
|
unsigned int time_last;
|
|
unsigned __int64 file_left;
|
|
PHMD5 hash_ctx;
|
|
|
|
// ファイルの先頭に戻す
|
|
file_left = 0;
|
|
if (!SetFilePointerEx(hFileRead, *((PLARGE_INTEGER)&file_left), NULL, FILE_BEGIN))
|
|
return 1;
|
|
|
|
prog_last = -1; // 検証中のファイル名を毎回表示する
|
|
time_last = GetTickCount();
|
|
file_left = file_size;
|
|
Phmd5Begin(&hash_ctx); // 初期化
|
|
|
|
while (file_left > 0){
|
|
if (file_left < IO_SIZE){
|
|
len = (unsigned int)file_left;
|
|
} else {
|
|
len = IO_SIZE;
|
|
}
|
|
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
|
|
return 1;
|
|
file_left -= len;
|
|
|
|
// MD5 計算
|
|
Phmd5Process(&hash_ctx, buf, len);
|
|
|
|
// 経過表示
|
|
if (GetTickCount() - time_last >= UPDATE_TIME){
|
|
if (print_progress_file((int)(((file_size - file_left) * 1000) / file_size), file_name))
|
|
return 2;
|
|
time_last = GetTickCount();
|
|
}
|
|
}
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash, hash_ctx.hash, 16);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ファイルの MD5 ハッシュ値を求めて、全体的な経過を表示する
|
|
int file_md5_total(
|
|
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
|
|
unsigned __int64 file_size,
|
|
unsigned char *hash, // ハッシュ値 (16バイト)
|
|
unsigned char *hash16, // 先頭 16KB 分のハッシュ値
|
|
__int64 total_file_size,
|
|
__int64 *prog_now) // 経過表示での現在位置
|
|
{
|
|
unsigned char buf[IO_SIZE];
|
|
unsigned int rv, len;
|
|
unsigned int time_last;
|
|
unsigned __int64 file_left;
|
|
PHMD5 hash_ctx;
|
|
|
|
// ファイルの先頭に戻す
|
|
file_left = 0;
|
|
if (!SetFilePointerEx(hFileRead, *((PLARGE_INTEGER)&file_left), NULL, FILE_BEGIN))
|
|
return 1;
|
|
|
|
time_last = GetTickCount() / UPDATE_TIME; // 時刻の変化時に経過を表示する
|
|
file_left = file_size;
|
|
Phmd5Begin(&hash_ctx); // 初期化
|
|
|
|
while (file_left > 0){
|
|
if (file_left < IO_SIZE){
|
|
len = (unsigned int)file_left;
|
|
} else {
|
|
len = IO_SIZE;
|
|
}
|
|
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
|
|
return 2;
|
|
(*prog_now) += len;
|
|
if (file_left == file_size){ // 最初だけ先頭 16KB 分のハッシュ値を計算する
|
|
if (len > 16384){
|
|
Phmd5Process(&hash_ctx, buf, 16384);
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash16, hash_ctx.hash, 16);
|
|
Phmd5Begin(&hash_ctx); // 初期化しなおす
|
|
} else { // ファイル・サイズが 16KB 以下なら
|
|
Phmd5Process(&hash_ctx, buf, len);
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash, hash_ctx.hash, 16);
|
|
return 0;
|
|
}
|
|
}
|
|
file_left -= len;
|
|
|
|
// MD5 計算
|
|
Phmd5Process(&hash_ctx, buf, len);
|
|
|
|
// 経過表示
|
|
if (GetTickCount() / UPDATE_TIME != time_last){
|
|
if (print_progress((int)(((*prog_now) * 1000) / total_file_size)))
|
|
return -2;
|
|
time_last = GetTickCount() / UPDATE_TIME;
|
|
}
|
|
}
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash, hash_ctx.hash, 16);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ファイルの先頭 16KB 分の MD5 ハッシュ値を求める
|
|
int file_md5_16k(
|
|
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
|
|
unsigned __int64 file_size,
|
|
unsigned char *hash) // ハッシュ値 (16バイト)
|
|
{
|
|
unsigned char buf[16384];
|
|
unsigned int len;
|
|
LARGE_INTEGER qwi; // Quad Word Integer
|
|
PHMD5 hash_ctx;
|
|
|
|
// ファイルの先頭に戻す
|
|
qwi.QuadPart = 0;
|
|
if (!SetFilePointerEx(hFileRead, qwi, NULL, FILE_BEGIN))
|
|
return 1;
|
|
|
|
Phmd5Begin(&hash_ctx); // 初期化
|
|
|
|
if (!ReadFile(hFileRead, buf, 16384, &len, NULL))
|
|
return 2;
|
|
if ((unsigned __int64)len > file_size)
|
|
len = (unsigned int)file_size;
|
|
|
|
// MD5 計算
|
|
Phmd5Process(&hash_ctx, buf, len);
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash, hash_ctx.hash, 16);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ファイルの先頭 32バイト目からの MD5 ハッシュ値を求める
|
|
int file_md5_from32(
|
|
wchar_t *file_name, // 表示するファイル名
|
|
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
|
|
unsigned char *hash) // ハッシュ値 (16バイト)
|
|
{
|
|
unsigned char buf[IO_SIZE];
|
|
unsigned int rv, len;
|
|
unsigned int time_last;
|
|
unsigned __int64 file_size, file_left;
|
|
LARGE_INTEGER qwi; // Quad Word Integer
|
|
PHMD5 hash_ctx;
|
|
|
|
// ファイル・サイズを取得する
|
|
if (!GetFileSizeEx(hFileRead, (PLARGE_INTEGER)&file_size))
|
|
return 1;
|
|
if (file_size <= 32)
|
|
return 1;
|
|
|
|
// ファイルの開始位置を 32バイト目にする
|
|
qwi.QuadPart = 32;
|
|
if (!SetFilePointerEx(hFileRead, qwi, NULL, FILE_BEGIN))
|
|
return 1;
|
|
|
|
prog_last = -1; // 検証中のファイル名を毎回表示する
|
|
time_last = GetTickCount();
|
|
file_left = file_size - 32;
|
|
Phmd5Begin(&hash_ctx); // 初期化
|
|
|
|
while (file_left > 0){
|
|
if (file_left < IO_SIZE){
|
|
len = (unsigned int)file_left;
|
|
} else {
|
|
len = IO_SIZE;
|
|
}
|
|
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
|
|
return 1;
|
|
file_left -= len;
|
|
|
|
// MD5 計算
|
|
Phmd5Process(&hash_ctx, buf, len);
|
|
|
|
// 経過表示
|
|
if (GetTickCount() - time_last >= UPDATE_TIME){
|
|
if (print_progress_file((int)(((file_size - file_left) * 1000) / file_size), file_name))
|
|
return 2;
|
|
time_last = GetTickCount();
|
|
}
|
|
}
|
|
Phmd5End(&hash_ctx); // 最終処理
|
|
memcpy(hash, hash_ctx.hash, 16);
|
|
|
|
return 0;
|
|
}
|