KOR세상

파일 해시섬 프로그램 소스코드

작성자

카테고리:

파일 해시섬 프로그램 소개 페이지

WndProcs.h

#ifndef _WNDPROCS_H_
#define _WNDPROCS_H_
#include <Windows.h>
#include <gdiplus.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <wincrypt.h>
#include <bcrypt.h>
#include <iostream>
#include <vector>
#pragma comment(lib, "Gdiplus.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "bcrypt.lib")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#define IDC_PROGRESSBAR 100
#define IDC_FILEPATHBT 101
#define IDC_CRC32BT 102
#define IDC_MD5BT 103
#define IDC_SHA1BT 104
#define IDC_SHA256BT 105
#define IDC_SHA512BT 106
#define IDC_CHECKBT 107
#define IDC_HASHCOMPAREBT 108
#define MD5BUFSIZE 1024
#define MD5LEN 16
#define SHA1BUFSIZE 32768
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define SHA256BUFSIZE 65536
#define SHA512BUFSIZE 65536

using namespace Gdiplus;

extern HINSTANCE g_hInstance;
extern ULONG_PTR gdiplusToken;
extern Image* pImage;

extern HWND hFilePathLabelWnd, hFilePathEditWnd, hFilePathButtonWnd;
extern HWND hHashInputLabelWnd, hHashCompareInputWnd, hHashCheckButtonWnd;
extern HWND hCrc32LabelWnd, hCrc32CopyButtonWnd, hCrc32TextEditWnd;
extern HWND hMd5LabelWnd, hMd5CopyButtonWnd, hMd5TextEditWnd;
extern HWND hSha1LabelWnd, hSha1CopyButtonWnd, hSha1TextEditWnd;
extern HWND hSha256LabelWnd, hSha256CopyButtonWnd, hSha256TextEditWnd;
extern HWND hSha512LabelWnd, hSha512CopyButtonWnd, hSha512TextEditWnd;
extern HWND hOkButtonWnd;
extern HWND hProgressbarWnd;

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
#endif

WinMain.cpp

#include "WndProcs.h"

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);

LPCTSTR lpszWndClass = TEXT("파일 해시섬 프로그램 Ver 2.0 - 공식배포처 https://korworld.kr");
HINSTANCE g_hInstance;
ULONG_PTR gdiplusToken;
Image* pImage = NULL;

int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
	GdiplusStartupInput gdiplusStartupInput;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	HWND hWnd;
	MSG Message;
	WNDCLASSEX WndClassEx;

	g_hInstance = hInstance;

	WndClassEx.cbSize = sizeof(WndClassEx); // 구조체 크기를 RegisterClass로 전달하기 위한 멤버이며 보통 값은 자기 자신의 크기를 넘겨주면 됨
	WndClassEx.cbClsExtra = 0; // 윈도우 클래스 레벨에서 추가적인 여분 메모리 할당용. 보안상 이슈로 거의 사용되지 않고 0으로 두는 경우가 많음
	WndClassEx.cbWndExtra = 0; // 윈도우 인스턴스마다 추가적으로 할당할 여분의 메모리 할당용. 각 윈도우별로 별도 할당되고 윈도우별로 특별한 데이터를 저정하기 위한 예약된 메모리 공간. 이쪽도 그렇게 잘 사용되지는 않음. 프로젝트 규모가 크거나 할때는 어느정도 쓰이나 규모가 작거나 복잡도가 낮은경우에는 거의 쓰일 일이 없음
	WndClassEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
	WndClassEx.hIcon = LoadIcon(NULL, NULL);
	WndClassEx.hIconSm = LoadIcon(NULL, NULL);
	WndClassEx.hInstance = hInstance;
	WndClassEx.lpfnWndProc = WndProc;
	WndClassEx.lpszClassName = lpszWndClass;
	WndClassEx.lpszMenuName = NULL;
	WndClassEx.style = CS_VREDRAW | CS_HREDRAW;
	RegisterClassEx(&WndClassEx);

	hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME, lpszWndClass, lpszWndClass, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, 
		NULL, (HMENU)NULL, g_hInstance, NULL);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	while (TRUE)
	{
		if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
		{
			if (Message.message == WM_QUIT)
			{
				break;
			}
			else
			{
				TranslateMessage(&Message);
				DispatchMessage(&Message);
			}
		}
		else
		{
			WaitMessage();
		}
	}

	GdiplusShutdown(gdiplusToken);

	return (int)Message.wParam;
}

WndProc.cpp

#include "WndProcs.h"

/// CRC32를 포함 각종 파일 해시섬 로직들은 AI(구글 제미나이)에 의해 작성되어진 코드 입니다
/// 일부 AI에 의한 오류나 윈도우 UI환경에 맞추는 부분정도만 직접 진행하였으므로
/// 제가 전부 이해하고 있는 상태가 아닙니다
/// 따라서 파일 해시섬 로직에 대한 궁금증에 대해서는 아쉽지만 AI에 문의해 주시기 바랍니다

/// CRC32 파일 해시섬 함수들 형선언 시작
void makeCRCtable(unsigned long *, unsigned long);
unsigned long calcCRC(const unsigned char *, signed long, unsigned long, unsigned long *);
LPCWSTR getFileCrc(FILE* s);
/// CRC32 파일 해시섬 함수들 형선언 끝

// 윈도우 핸들러
HWND hFilePathLabelWnd, hFilePathEditWnd, hFilePathButtonWnd;
HWND hHashInputLabelWnd, hHashCompareInputWnd, hHashCheckButtonWnd;
HWND hCrc32LabelWnd, hCrc32CopyButtonWnd, hCrc32TextEditWnd;
HWND hMd5LabelWnd, hMd5CopyButtonWnd, hMd5TextEditWnd;
HWND hSha1LabelWnd, hSha1CopyButtonWnd, hSha1TextEditWnd;
HWND hSha256LabelWnd, hSha256CopyButtonWnd, hSha256TextEditWnd;
HWND hSha512LabelWnd, hSha512CopyButtonWnd, hSha512TextEditWnd;
HWND hOkButtonWnd;
HWND hProgressbarWnd;

// 파일 처리
OPENFILENAME OpenFileName;

// 프로그레스바 윈도우 진행도 0 ~ 100
int progressStatus = 0;

// 파일 경로 및 파일 이름+확장자
TCHAR lpstrFile[MAX_PATH] = TEXT("");
TCHAR lpstrFileTitle[MAX_PATH] = TEXT("");

// 파일 해시섬 문자열 전역 변수
wchar_t hashBuffer[256] = L"";
wchar_t crc32ResultBuffer[256] = L"";
wchar_t md5ResultBuffer[256] = L"";
wchar_t sha1ResultBuffer[256] = L"";
wchar_t sha256ResultBuffer[256] = L"";
wchar_t sha512ResultBuffer[256] = L"";

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT PaintStruct;

	HDC hdc;

	HDROP hDropFile = (HDROP)wParam;

	wchar_t dragFileName[MAX_PATH];
	wchar_t dragFileExt[MAX_PATH];
	
	// CRC32 해시 관련 변수
	FILE *in;
	char tempFilePath[256];
	errno_t err;
	

	// MD5 해시 관련 변수
	HANDLE hFile = INVALID_HANDLE_VALUE;
	HCRYPTPROV hCryptProv = 0;
	HCRYPTHASH hMd5Hash = 0;
	BYTE rgbMd5File[MD5BUFSIZE];
	DWORD cbRead = 0;
	BYTE rgbMd5Hash[MD5LEN];
	DWORD cbHash = 0;

	// SHA-1 해시 관련 변수
	NTSTATUS functionStatus = NULL;
	BCRYPT_ALG_HANDLE hAlg = NULL;
	BCRYPT_HASH_HANDLE hSha1Hash = NULL;
	DWORD cbData = 0, cbSha1Hash = 0, cbSha1HashObject = 0;
	PBYTE pbHashObject = NULL;
	PBYTE pbHash = NULL;

	// SHA-256 해시 관련 변수
	BCRYPT_HASH_HANDLE hSha256Hash = NULL;
	DWORD cbSha256Hash = 0, cbSha256HashObject = 0;
	BYTE sha256Buffer[SHA256BUFSIZE];

	// SHA-512 해시 관련 변수
	BCRYPT_HASH_HANDLE hSha512Hash = NULL;
	DWORD cbSha512Hash = 0, cbSha512HashObject = 0;
	BYTE sha512Buffer[SHA512BUFSIZE];

	switch (iMessage)
	{
		case WM_CREATE: // 프로그램 실행시 윈도우 생성과 동시에 처리되는 로직
		{
			DragAcceptFiles(hWnd, TRUE); // 드래그앤 드롭 파일 입력 허용
			OpenFileName.lStructSize = sizeof(OpenFileName);
			OpenFileName.hwndOwner = hWnd;
			OpenFileName.lpstrFilter = TEXT("모든 파일\0*.*\0");
			OpenFileName.nMaxFile = MAX_PATH;
			OpenFileName.nMaxFileTitle = MAX_PATH;

			// GDI+로 불러올 이미지 파일 위치
			pImage = new Image(L"bg.png");

			INITCOMMONCONTROLSEX icex;
			icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
			icex.dwICC = ICC_PROGRESS_CLASS;
			InitCommonControlsEx(&icex);

			// 자식 윈도우 컨트롤들 그리기 및 배치
			hFilePathLabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("파일 경로"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 5, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hFilePathEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), TEXT("파일을 드래그앤 드롭으로 프로그램에 올려놓아도 자동으로 경로를 입력받습니다"), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | SS_CENTER,
				10, 35, 1130, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hFilePathButtonWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("BUTTON"), TEXT("파일선택"), WS_CHILD | WS_VISIBLE | WS_BORDER,
				1150, 35, 100, 25, hWnd, (HMENU)IDC_FILEPATHBT, g_hInstance, NULL);

			hHashInputLabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("비교할 해시값을 아래에 입력해주세요"), WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE,
				10, 100, 300, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hHashCompareInputWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
				10, 130, 1130, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hHashCheckButtonWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("BUTTON"), TEXT("해시 값 비교"), WS_CHILD | WS_VISIBLE | WS_BORDER | WS_DISABLED,
				1150, 130, 100, 25, hWnd, (HMENU)IDC_HASHCOMPAREBT, g_hInstance, NULL);

			hCrc32LabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("CRC32"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 180, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hCrc32CopyButtonWnd = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT("CRC32 해시 값 복사"), WS_CHILD | WS_VISIBLE | SS_CENTER | WS_DISABLED,
				130, 180, 175, 25, hWnd, (HMENU)IDC_CRC32BT, g_hInstance, NULL);
			hCrc32TextEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,
				10, 210, 1240, 25, hWnd, (HMENU)-1, g_hInstance, NULL);

			hMd5LabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("MD5"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 260, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hMd5CopyButtonWnd = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT("MD5 해시 값 복사"), WS_CHILD | WS_VISIBLE | SS_CENTER | WS_DISABLED,
				130, 260, 175, 25, hWnd, (HMENU)IDC_MD5BT, g_hInstance, NULL);
			hMd5TextEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,
				10, 290, 1240, 25, hWnd, (HMENU)-1, g_hInstance, NULL);

			hSha1LabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("SHA-1"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 340, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hSha1CopyButtonWnd = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT("SHA-1 해시 값 복사"), WS_CHILD | WS_VISIBLE | SS_CENTER | WS_DISABLED,
				130, 340, 175, 25, hWnd, (HMENU)IDC_SHA1BT, g_hInstance, NULL);
			hSha1TextEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,
				10, 370, 1240, 25, hWnd, (HMENU)-1, g_hInstance, NULL);

			hSha256LabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("SHA-256"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 420, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hSha256CopyButtonWnd = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT("SHA-256 해시 값 복사"), WS_CHILD | WS_VISIBLE | SS_CENTER | WS_DISABLED,
				130, 420, 175, 25, hWnd, (HMENU)IDC_SHA256BT, g_hInstance, NULL);
			hSha256TextEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,
				10, 450, 1240, 25, hWnd, (HMENU)-1, g_hInstance, NULL);

			hSha512LabelWnd = CreateWindowEx(NULL, TEXT("STATIC"), TEXT("SHA-512"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE,
				10, 500, 100, 25, hWnd, (HMENU)-1, g_hInstance, NULL);
			hSha512CopyButtonWnd = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT("SHA-512 해시 값 복사"), WS_CHILD | WS_VISIBLE | SS_CENTER | WS_DISABLED,
				130, 500, 175, 25, hWnd, (HMENU)IDC_SHA512BT, g_hInstance, NULL);
			hSha512TextEditWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY,
				10, 530, 1240, 25, hWnd, (HMENU)-1, g_hInstance, NULL);

			hOkButtonWnd = CreateWindowEx(WS_EX_STATICEDGE, TEXT("BUTTON"), TEXT("파일 해시섬 확인"), WS_CHILD | WS_VISIBLE | WS_BORDER | WS_DISABLED,
				1050, 640, 200, 25, hWnd, (HMENU)IDC_CHECKBT, g_hInstance, NULL);

			hProgressbarWnd = CreateWindowEx(NULL, PROGRESS_CLASS, (LPCWSTR)NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
				0, 670, 1280, 15, hWnd, (HMENU)IDC_PROGRESSBAR, g_hInstance, NULL);

			SendMessage(hProgressbarWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
			SendMessage(hProgressbarWnd, PBM_SETPOS, 0, 0);
			SendMessage(hProgressbarWnd, PBM_SETSTEP, (WPARAM)1, 0);
			return 0;
		}
		case WM_PAINT: // 윈도우 그리기 처리 로직
		{
			hdc = BeginPaint(hWnd, &PaintStruct);
			Graphics graphics(hdc);
			graphics.DrawImage(pImage, 0, 0, 1280, 720);
			EndPaint(hWnd, &PaintStruct);
			return 0;
		}
		case WM_DROPFILES: // 파일 드래그 온 드롭시 실행될 로직
		{
			DragQueryFile(hDropFile, 0, lpstrFile, MAX_PATH);
			_wsplitpath_s(lpstrFile, NULL, NULL, NULL, NULL, dragFileName, MAX_PATH, dragFileExt, MAX_PATH);
			wcscat_s(dragFileName, MAX_PATH, dragFileExt);
			ZeroMemory(lpstrFileTitle, sizeof(lpstrFileTitle));
			wcscat_s(lpstrFileTitle, MAX_PATH, dragFileName);
			SetWindowText(hFilePathEditWnd, lpstrFile);
			EnableWindow(hOkButtonWnd, TRUE);
			EnableWindow(hCrc32CopyButtonWnd, FALSE);
			EnableWindow(hMd5CopyButtonWnd, FALSE);
			EnableWindow(hSha1CopyButtonWnd, FALSE);
			EnableWindow(hSha256CopyButtonWnd, FALSE);
			EnableWindow(hSha512CopyButtonWnd, FALSE);
			EnableWindow(hHashCheckButtonWnd, FALSE);
			DragFinish(hDropFile);
			SetForegroundWindow(hWnd);
			return 0;
		}
		case WM_COMMAND: // 컨트롤 입력 처리 로직
		{
			switch (LOWORD(wParam))
			{
			case IDC_FILEPATHBT: // 파일 열기 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					memset(&OpenFileName, 0, sizeof(OPENFILENAME));
					OpenFileName.lStructSize = sizeof(OPENFILENAME);
					OpenFileName.hwndOwner = hWnd;
					OpenFileName.lpstrFilter = TEXT("모든 파일\0*.*\0");
					OpenFileName.nMaxFile = MAX_PATH;
					OpenFileName.lpstrFile = lpstrFile;
					OpenFileName.nMaxFileTitle = MAX_PATH;
					OpenFileName.lpstrFileTitle = lpstrFileTitle;
					if (GetOpenFileName(&OpenFileName) != 0)
					{
						SetWindowText(hFilePathEditWnd, lpstrFile);
						EnableWindow(hOkButtonWnd, TRUE);
						EnableWindow(hCrc32CopyButtonWnd, FALSE);
						EnableWindow(hMd5CopyButtonWnd, FALSE);
						EnableWindow(hSha1CopyButtonWnd, FALSE);
						EnableWindow(hSha256CopyButtonWnd, FALSE);
						EnableWindow(hSha512CopyButtonWnd, FALSE);
						EnableWindow(hHashCheckButtonWnd, FALSE);
					}
				}
				break;
			case IDC_CRC32BT: // CRC32 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hCrc32TextEditWnd, EM_SETSEL, 0, -1);
					SendMessage(hCrc32TextEditWnd, WM_COPY, 0, 0);
					MessageBox(hWnd, TEXT("CRC32 해시 값이 클립보드에 복사되었습니다\n복사된 값을 붙여 넣으려면 Ctrl + V키를 누르거나 마우스 오른쪽으로 메뉴를 호출 한뒤에 \'붙여넣기\'로 값을 붙여넣기 할수 있습니다"), TEXT("알림"), MB_OK);
				}
				break;
			case IDC_MD5BT: // MD5 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hMd5TextEditWnd, EM_SETSEL, 0, -1);
					SendMessage(hMd5TextEditWnd, WM_COPY, 0, 0);
					MessageBox(hWnd, TEXT("MD5 해시 값이 클립보드에 복사되었습니다\n복사된 값을 붙여 넣으려면 Ctrl + V키를 누르거나 마우스 오른쪽으로 메뉴를 호출 한뒤에 \'붙여넣기\'로 값을 붙여넣기 할수 있습니다"), TEXT("알림"), MB_OK);
				}
				break;
			case IDC_SHA1BT: // SHA-1 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hSha1TextEditWnd, EM_SETSEL, 0, -1);
					SendMessage(hSha1TextEditWnd, WM_COPY, 0, 0);
					MessageBox(hWnd, TEXT("SHA-1 해시 값이 클립보드에 복사되었습니다\n복사된 값을 붙여 넣으려면 Ctrl + V키를 누르거나 마우스 오른쪽으로 메뉴를 호출 한뒤에 \'붙여넣기\'로 값을 붙여넣기 할수 있습니다"), TEXT("알림"), MB_OK);
				}
				break;
			case IDC_SHA256BT: // SHA-256 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hSha256TextEditWnd, EM_SETSEL, 0, -1);
					SendMessage(hSha256TextEditWnd, WM_COPY, 0, 0);
					MessageBox(hWnd, TEXT("SHA-256 해시 값이 클립보드에 복사되었습니다\n복사된 값을 붙여 넣으려면 Ctrl + V키를 누르거나 마우스 오른쪽으로 메뉴를 호출 한뒤에 \'붙여넣기\'로 값을 붙여넣기 할수 있습니다"), TEXT("알림"), MB_OK);
				}
				break;
			case IDC_SHA512BT: // SHA-256 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hSha512TextEditWnd, EM_SETSEL, 0, -1);
					SendMessage(hSha512TextEditWnd, WM_COPY, 0, 0);
					MessageBox(hWnd, TEXT("SHA-512 해시 값이 클립보드에 복사되었습니다\n복사된 값을 붙여 넣으려면 Ctrl + V키를 누르거나 마우스 오른쪽으로 메뉴를 호출 한뒤에 \'붙여넣기\'로 값을 붙여넣기 할수 있습니다"), TEXT("알림"), MB_OK);
				}
				break;
			case IDC_CHECKBT: // SHA-512 해시 값 복사 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					SendMessage(hProgressbarWnd, PBM_SETPOS, 0, 0);
					progressStatus = 0;
					// CRC32 처리 로직 시작
					WideCharToMultiByte(CP_ACP, 0, lpstrFile, -1, tempFilePath, sizeof(tempFilePath), NULL, NULL);
					err = fopen_s(&in, tempFilePath, "rb");
					if (err != 0)
					{
						MessageBox(hWnd, TEXT("지정된 파일이 없습니다. 파일을 선택 한후에 해시섬 확인을 진행해 주세요"), TEXT("경고"), MB_OK | MB_ICONWARNING);
						break;
					}
					if (progressStatus < 20)
					{
						for (int i = 0; i < 20; i++)
						{
							SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
							progressStatus++;
						}
					}
					wcscpy_s(crc32ResultBuffer, getFileCrc(in));
					SetWindowText(hCrc32TextEditWnd, crc32ResultBuffer);
					// MD5 처리 로직 시작
					hFile = CreateFile(lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
					functionStatus = CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
					functionStatus = CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hMd5Hash);
					while (ReadFile(hFile, rgbMd5File, MD5BUFSIZE, &cbRead, NULL) && cbRead > 0)
					{
						if (!CryptHashData(hMd5Hash, rgbMd5File, cbRead, 0))
						{
							CryptDestroyHash(hMd5Hash);
							CryptReleaseContext(hCryptProv, 0);
							CloseHandle(hFile);
						}
					}
					cbHash = MD5LEN;
					if (CryptGetHashParam(hMd5Hash, HP_HASHVAL, rgbMd5Hash, &cbHash, 0))
					{
						for (DWORD i = 0; i < cbHash; i++)
						{
							swprintf_s(md5ResultBuffer, 256, L"%s%02x", md5ResultBuffer, rgbMd5Hash[i]);
							if (progressStatus < 40)
							{
								SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
								progressStatus++;
							}
						}
					}
					CryptDestroyHash(hMd5Hash);
					CryptReleaseContext(hCryptProv, 0);
					CloseHandle(hFile);
					SetWindowText(hMd5TextEditWnd, md5ResultBuffer);
					// SHA-1 처리 로직 시작
					functionStatus = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, NULL, 0);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbSha1HashObject, sizeof(DWORD), &cbData, 0);
					pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha1HashObject);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbSha1Hash, sizeof(DWORD), &cbData, 0);
					pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha1Hash);
					functionStatus = BCryptCreateHash(hAlg, &hSha1Hash, pbHashObject, cbSha1HashObject, NULL, 0, 0);
					hFile = CreateFile(lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					BYTE sha1Buffer[1024 * 4];
					DWORD byteRead = 0;
					while (ReadFile(hFile, sha1Buffer, sizeof(sha1Buffer), &byteRead, NULL) && byteRead > 0)
					{
						functionStatus = BCryptHashData(hSha1Hash, sha1Buffer, byteRead, 0);
					}
					functionStatus = BCryptFinishHash(hSha1Hash, pbHash, cbSha1Hash, 0);
					for (DWORD i = 0; i < cbSha1Hash; i++)
					{
						swprintf_s(sha1ResultBuffer, 256, L"%s%02x", sha1ResultBuffer, pbHash[i]);
						if (progressStatus < 60)
						{
							SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
							progressStatus++;
						}
					}
					CloseHandle(hFile);
					SetWindowText(hSha1TextEditWnd, sha1ResultBuffer);
					// SHA-256 처리 로직 시작
					hAlg = NULL;
					cbData = 0;
					pbHashObject = NULL;
					pbHash = NULL;
					functionStatus = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbSha256HashObject, sizeof(DWORD), &cbData, 0);
					pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha256HashObject);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbSha256Hash, sizeof(DWORD), &cbData, 0);
					pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha256Hash);
					functionStatus = BCryptCreateHash(hAlg, &hSha256Hash, pbHashObject, cbSha256HashObject, NULL, 0, 0);
					hFile = CreateFile(lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					byteRead = 0;
					while (ReadFile(hFile, sha256Buffer, SHA256BUFSIZE, &byteRead, NULL) && byteRead > 0)
					{
						functionStatus = BCryptHashData(hSha256Hash, sha256Buffer, byteRead, 0);
					}
					functionStatus = BCryptFinishHash(hSha256Hash, pbHash, cbSha256Hash, 0);
					for (DWORD i = 0; i < cbSha256Hash; i++)
					{
						swprintf_s(sha256ResultBuffer, 256, L"%s%02x", sha256ResultBuffer, pbHash[i]);
						if (progressStatus < 80)
						{
							SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
							progressStatus++;
						}
					}
					CloseHandle(hFile);
					SetWindowText(hSha256TextEditWnd, sha256ResultBuffer);
					// SHA-512 처리 로직 시작
					hAlg = NULL;
					cbData = 0;
					pbHashObject = NULL;
					pbHash = NULL;
					functionStatus = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA512_ALGORITHM, NULL, 0);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbSha512HashObject, sizeof(DWORD), &cbData, 0);
					pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha512HashObject);
					functionStatus = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbSha512Hash, sizeof(DWORD), &cbData, 0);
					pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSha512Hash);
					functionStatus = BCryptCreateHash(hAlg, &hSha512Hash, pbHashObject, cbSha512HashObject, NULL, 0, 0);
					hFile = CreateFile(lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					byteRead = 0;
					while (ReadFile(hFile, sha512Buffer, SHA512BUFSIZE, &byteRead, NULL) && byteRead > 0)
					{
						functionStatus = BCryptHashData(hSha512Hash, sha512Buffer, byteRead, 0);
					}
					functionStatus = BCryptFinishHash(hSha512Hash, pbHash, cbSha512Hash, 0);
					for (DWORD i = 0; i < cbSha512Hash; i++)
					{
						swprintf_s(sha512ResultBuffer, 256, L"%s%02x", sha512ResultBuffer, pbHash[i]);
						if (progressStatus < 100)
						{
							SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
							progressStatus++;
						}
					}
					CloseHandle(hFile);
					SetWindowText(hSha512TextEditWnd, sha512ResultBuffer);
					// 해시 값 출력 처리 완료 후 처리
					if (progressStatus < 100)
					{
						for (int i = 0; i < (100 - progressStatus); i++)
						{
							SendMessage(hProgressbarWnd, PBM_STEPIT, 0, 0);
						}
					}
					SendMessage(hProgressbarWnd, PBM_SETPOS, 100, 0);
					wmemset(crc32ResultBuffer, 0, 256);
					wmemset(md5ResultBuffer, 0, 256);
					wmemset(sha1ResultBuffer, 0, 256);
					wmemset(sha256ResultBuffer, 0, 256);
					wmemset(sha512ResultBuffer, 0, 256);
					EnableWindow(hCrc32CopyButtonWnd, TRUE);
					EnableWindow(hMd5CopyButtonWnd, TRUE);
					EnableWindow(hSha1CopyButtonWnd, TRUE);
					EnableWindow(hSha256CopyButtonWnd, TRUE);
					EnableWindow(hSha512CopyButtonWnd, TRUE);
					EnableWindow(hHashCheckButtonWnd, TRUE);
				}
				break;
			case IDC_HASHCOMPAREBT: // 해시 값 비교 버튼 로직
				if (HIWORD(wParam) == BN_CLICKED)
				{
					TCHAR messageText[MAX_PATH];
					int hashTextLength = GetWindowTextLength(hHashCompareInputWnd) + 1;
					int crc32TextLength = GetWindowTextLength(hCrc32TextEditWnd) + 1;
					int md5TextLength = GetWindowTextLength(hMd5TextEditWnd) + 1;
					int sha1TextLength = GetWindowTextLength(hSha1TextEditWnd) + 1;
					int sha256TextLength = GetWindowTextLength(hSha256TextEditWnd) + 1;
					int sha512TextLength = GetWindowTextLength(hSha512TextEditWnd) + 1;
					GetWindowText(hHashCompareInputWnd, hashBuffer, hashTextLength);
					GetWindowText(hCrc32TextEditWnd, crc32ResultBuffer, crc32TextLength);
					GetWindowText(hMd5TextEditWnd, md5ResultBuffer, md5TextLength);
					GetWindowText(hSha1TextEditWnd, sha1ResultBuffer, sha1TextLength);
					GetWindowText(hSha256TextEditWnd, sha256ResultBuffer, sha256TextLength);
					GetWindowText(hSha512TextEditWnd, sha512ResultBuffer, sha512TextLength);

					if (wcscmp(hashBuffer, crc32ResultBuffer) == 0)
					{
						wsprintf(messageText, TEXT("%s 파일에 CRC32해시 값 %ls 와 일치합니다"), lpstrFileTitle, crc32ResultBuffer);
						MessageBox(hWnd, messageText, TEXT("일치하는 해시 값이 있습니다"), MB_OK);
					}
					else if (wcscmp(hashBuffer, md5ResultBuffer) == 0)
					{
						wsprintf(messageText, TEXT("%s 파일에 MD5해시 값 %s 와 일치합니다"), lpstrFileTitle, md5ResultBuffer);
						MessageBox(hWnd, messageText, TEXT("일치하는 해시 값이 있습니다"), MB_OK);
					}
					else if (wcscmp(hashBuffer, sha1ResultBuffer) == 0)
					{
						wsprintf(messageText, TEXT("%s 파일에 SHA-1해시 값 %s 와 일치합니다"), lpstrFileTitle, sha1ResultBuffer);
						MessageBox(hWnd, messageText, TEXT("일치하는 해시 값이 있습니다"), MB_OK);
					}
					else if (wcscmp(hashBuffer, sha256ResultBuffer) == 0)
					{
						wsprintf(messageText, TEXT("%s 파일에 SHA-256해시 값 %s 와 일치합니다"), lpstrFileTitle, sha256ResultBuffer);
						MessageBox(hWnd, messageText, TEXT("일치하는 해시 값이 있습니다"), MB_OK);
					}
					else if (wcscmp(hashBuffer, sha512ResultBuffer) == 0)
					{
						wsprintf(messageText, TEXT("%s 파일에 SHA-512해시 값 %s 와 일치합니다"), lpstrFileTitle, sha512ResultBuffer);
						MessageBox(hWnd, messageText, TEXT("일치하는 해시 값이 있습니다"), MB_OK);
					}
					else
					{
						MessageBox(hWnd, TEXT("일치하는 해시값이 없습니다"), TEXT("일치하는 해시값이 없습니다"), MB_OK);
					}
					wmemset(hashBuffer, 0, 256);
					wmemset(crc32ResultBuffer, 0, 256);
					wmemset(md5ResultBuffer, 0, 256);
					wmemset(sha1ResultBuffer, 0, 256);
					wmemset(sha256ResultBuffer, 0, 256);
					wmemset(sha512ResultBuffer, 0, 256);
				}
				break;
			}
			return 0;
		}
		case WM_DESTROY: // 윈도우 종료시 실행될 로직
		{// !!!메모리 누수 방지를 위해 메모리 릴리즈 처리를 반드시 해줄것
			delete pImage;
			PostQuitMessage(0);
			return 0;
		}
	}

	return DefWindowProc(hWnd, iMessage, wParam, lParam);
}

/// CRC32 파일 해시섬 함수들 시작
void Crc32Table(unsigned long* table, unsigned long id)
{
	unsigned long i, j, k;

	for (i = 0; i < 256; ++i)
	{
		k = i;
		for (j = 0; j < 8; ++j)
		{
			if (k & 1) k = (k >> 1) ^ id;
			else k >>= 1;
		}
		table[i] = k;
	}
}

unsigned long calcCrc(const unsigned char* mem, signed long size, unsigned long CRC, unsigned long* table)
{
	CRC = ~CRC;

	while (size--)
	{
		CRC = table[(CRC ^ *(mem++)) & 0xff] ^ (CRC >> 8);
	}

	return ~CRC;
}

LPCWSTR getFileCrc(FILE* s)
{
	unsigned char buf[32768];
	unsigned long CRC = 0;
	unsigned long table[256];
	size_t len;
	wchar_t buffer[256];

	Crc32Table(table, 0xEDB88320);

	while ((len = fread(buf, 1, sizeof(buf), s)) != NULL)
	{
		CRC = calcCrc(buf, (unsigned long)len, CRC, table);
	}
	_ultow_s(CRC, buffer, sizeof(buffer) / sizeof(wchar_t), 16);

	return buffer;
}
/// CRC32 파일 해시섬 함수들 끝

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다