1.主要功能
a.可以存储注册的账号密码,方便下次登录
b.有多个不同的的界面切换
c.带一个磁盘查看器的小功能
2.功能展示
下图是一个登录的主界面
注册时的界面
账号密码登录成功后的一个下功能界面
添加过程如下
根据自己的选择在上面添加 开发工具我用的是VS2022
3.部分代码讲解(整体代码在4)
这个是三个窗口之间的切换的主体逻辑 具体功能在他内部实现,每个界面里面用switch case判断空间消息,然后在内部的switch用来判断控件ID,以下图为例右键属性就能查看,用三个不同的回调函数来处三个窗口之间的消息
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); // 第一个窗口
INT_PTR CALLBACK OneWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); // 第二个窗口
INT_PTR CALLBACK TwoWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); // 第三个窗口
// 主窗口逻辑
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_EDIT1:
{
}break;
case IDC_EDIT2:
{
}break;
case IDC_BUTTON1:
{
}break;
case IDC_BUTTON2:
{
} break;
case WM_CLOSE:
{
EndDialog(hwnd, 0);
} break;
}
return 0;
}
// 注册栏
INT_PTR CALLBACK OneWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_EDIT1:{}break;
case IDC_EDIT2:{}break;
case IDC_EDIT3:{}break;
case IDOK:
{
}break;
case IDCANCEL:
{
DestroyWindow(hwnd);
}break;
}
}break;
case WM_CLOSE:
{
DestroyWindow(hwnd);
} break;
}
return 0;
}
// 功能栏
INT_PTR CALLBACK TwoWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_INITDIALOG:
{
}break;
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_BUTTON2:
{
}break;
case IDC_BUTTON3:
{
}
}
}break;
case WM_CLOSE:
{
DestroyWindow(hwnd);
} break;
}
return 0;
}
注册栏逻辑,先获取三次输入的句柄,和输入的长度,通过对比输入两次的密码是否相同,来判断是否注册成功,成功的化将账号密码存在1.txt内,通过fwite wb二进制写入写入的时候通过,和换行分割 ,numAccounts是存储的数量 定义的为int类型的全局变量
HWND hwndTextbox = GetDlgItem(hwnd, IDC_EDIT1);
HWND hwndTextbox2 = GetDlgItem(hwnd, IDC_EDIT2);
HWND hwndTextbox3 = GetDlgItem(hwnd, IDC_EDIT3);
int len = GetWindowTextLength(hwndTextbox);
int len2 = GetWindowTextLength(hwndTextbox2);
int len3 = GetWindowTextLength(hwndTextbox3);
// 账号
CHAR* account1 = new CHAR[len + 1];
GetWindowTextA(hwndTextbox, account1, len + 1);
// 第一次输入密码
CHAR* password1 = new CHAR[len2 + 1];
GetWindowTextA(hwndTextbox2, password1, len2 + 1);
// 第二次输入密码
CHAR* password2 = new CHAR[len3 + 1];
GetWindowTextA(hwndTextbox3, password2, len3 + 1);
// 对你两次输入的密码
if (strcmp(password1, password2) == 0)
{
// 存储账号和密码到数组中
strcpy_s(accounts[numAccounts].username,300, account1);
strcpy_s(accounts[numAccounts].password,300, password2);
numAccounts++;
FILE* file = {};
fopen_s(&file, "1.txt", "wb");
// 将所有注册账号和密码写入文件
for (int i = 0; i < numAccounts; i++)
{
fwrite(accounts[i].username, sizeof(CHAR), strlen(accounts[i].username), file);
fputc(',', file);
fwrite(accounts[i].password, sizeof(CHAR), strlen(accounts[i].password), file);
fputc('\n', file);
}
fclose(file);
MessageBox(NULL, _T("注册成功"), _T("提示"), MB_OK);
}
else
{
MessageBox(NULL, _T("两次输入的密码不同"), _T("提示"), MB_OK);
}
登录栏逻辑,跟注册类似,通过strcmp对比文件夹内是不是有这个账号密码,成功的话进入小功能界面,定义的结构体数组来区分账号密码
HWND hwndTextbox = GetDlgItem(hwnd, IDC_EDIT1);
HWND hwndTextbox2 = GetDlgItem(hwnd, IDC_EDIT2);
int len = GetWindowTextLength(hwndTextbox);
int len2 = GetWindowTextLength(hwndTextbox2);
// 登录框账号
CHAR* account = new CHAR[len + 1];
GetWindowTextA(hwndTextbox, account, len + 1);
// 登录框密码
CHAR* password = new CHAR[len2 + 1];
GetWindowTextA(hwndTextbox2, password, len2 + 1);
bool found = false;
// 检查登录账号和密码是否匹配
for (int i = 0; i < numAccounts; i++)
{
if ((strcmp(account, accounts[i].username) == 0) && (strcmp(password, accounts[i].password) == 0))
{
found = true;
break;
}
}
if (found)
{
HWND TwoHwnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG3), hwnd, TwoWindowProc);
if (TwoHwnd != NULL)
{
ShowWindow(TwoHwnd, SW_SHOW);
UpdateWindow(TwoHwnd);
}
ShowWindow(hwnd, SW_HIDE);
}
else
{
MessageBox(NULL, _T("账户或密码错误"), _T("提示"), MB_OK);
}
}break;
case IDC_BUTTON2:
{
HWND oneHwnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, OneWindowProc);
if (oneHwnd != NULL)
{
ShowWindow(oneHwnd, SW_SHOW);
UpdateWindow(oneHwnd);
}
} break;
}
功能栏代码如下
// 读取磁盘信息
void choseCD(HWND hwnd)
{
TCHAR buffer[512] = {};
// 获取盘符类型
int type = GetDriveType(text);
// 根据类型 以下都是拷贝到btxet
switch (type)
{
case DRIVE_UNKNOWN:
{
_tcscpy_s(buffer, 512, _T("未知"));
}
break;
case DRIVE_NO_ROOT_DIR:
{
_tcscpy_s(buffer, 512, _T("无效"));
}
break;
case DRIVE_REMOVABLE:
{
_tcscpy_s(buffer, 512, _T("可移动的磁盘"));
}
break;
case DRIVE_FIXED:
{
_tcscpy_s(buffer, 512, _T("硬盘"));
}
break;
case DRIVE_REMOTE:
{
_tcscpy_s(buffer, 512, _T("网络驱动器"));
}
break;
case DRIVE_CDROM:
{
_tcscpy_s(buffer, 512, _T("CD_ROM驱动器"));
}
break;
case DRIVE_RAMDISK:
{
_tcscpy_s(buffer, 512, _T("RAM驱动器"));
}
break;
default:
break;
}
// 获取盘符空间信息
DWORD sectorsPerCluster = 0;
DWORD bytesPerSector = 0;
DWORD freeClusters = 0;
DWORD totalClusters = 0;
if (GetDiskFreeSpace(text, §orsPerCluster, &bytesPerSector, &freeClusters, &totalClusters))
{
double totalCapacity = static_cast<double>(totalClusters) * sectorsPerCluster * bytesPerSector / (1024 * 1024 * 1024); // 总容量,单位GB
double freeSpace = static_cast<double>(freeClusters) * sectorsPerCluster * bytesPerSector / (1024 * 1024 * 1024); // 空闲容量,单位GB
// 存储到text
_stprintf_s(buffer, 512, _T("总容量:%.2f GB,空闲容量:%.2f GB"), totalCapacity, freeSpace);
}
SetWindowText(hwnd, buffer);
}
4.整体代码
// (注:在使用下述代码过程中注意按键ID是否修改为自己创建的,代码中如有不理解的可评论区留言)
#include <Windows.h>
#include <tchar.h>
#include <CommCtrl.h>
#include "resource.h"
#include <stdio.h>
#include <Windowsx.h>
#include <string.h>
#include <cstring>
#define MAX_ACCOUNTS 300 // 最大注册账号数量
int numAccounts = 0; // 当前注册账号数量
HINSTANCE g_hInstance = 0;
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); // 第一个窗口
INT_PTR CALLBACK OneWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); // 第二个窗口
INT_PTR CALLBACK TwoWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); // 第三个窗口
TCHAR text[512] = {}; // 传是那个盘
struct Account
{
CHAR username[100];
CHAR password[100];
};
Account accounts[MAX_ACCOUNTS]; // 注册账号数组
void choseCD(HWND hwnd);
void LoadAccountsFromFile();
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPTSTR lpCmdLine,int nCmdShow)
{
g_hInstance = hInstance;
LoadAccountsFromFile();
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
return 0;
}
// 主窗口逻辑
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_EDIT1:
{
}break;
case IDC_EDIT2:
{
}break;
case IDC_BUTTON1:
{
HWND hwndTextbox = GetDlgItem(hwnd, IDC_EDIT1);
HWND hwndTextbox2 = GetDlgItem(hwnd, IDC_EDIT2);
int len = GetWindowTextLength(hwndTextbox);
int len2 = GetWindowTextLength(hwndTextbox2);
// 登录框账号
CHAR* account = new CHAR[len + 1];
GetWindowTextA(hwndTextbox, account, len + 1);
// 登录框密码
CHAR* password = new CHAR[len2 + 1];
GetWindowTextA(hwndTextbox2, password, len2 + 1);
bool found = false;
// 检查登录账号和密码是否匹配
for (int i = 0; i < numAccounts; i++)
{
if ((strcmp(account, accounts[i].username) == 0) && (strcmp(password, accounts[i].password) == 0))
{
found = true;
break;
}
}
if (found)
{
HWND TwoHwnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG3), hwnd, TwoWindowProc);
if (TwoHwnd != NULL)
{
ShowWindow(TwoHwnd, SW_SHOW);
UpdateWindow(TwoHwnd);
}
ShowWindow(hwnd, SW_HIDE);
}
else
{
MessageBox(NULL, _T("账户或密码错误"), _T("提示"), MB_OK);
}
}break;
case IDC_BUTTON2:
{
HWND oneHwnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, OneWindowProc);
if (oneHwnd != NULL)
{
ShowWindow(oneHwnd, SW_SHOW);
UpdateWindow(oneHwnd);
}
} break;
}
} break;
case WM_CLOSE:
{
EndDialog(hwnd, 0);
} break;
}
return 0;
}
// 注册栏
INT_PTR CALLBACK OneWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_EDIT1:{}break;
case IDC_EDIT2:{}break;
case IDC_EDIT3:{}break;
case IDOK:
{
HWND hwndTextbox = GetDlgItem(hwnd, IDC_EDIT1);
HWND hwndTextbox2 = GetDlgItem(hwnd, IDC_EDIT2);
HWND hwndTextbox3 = GetDlgItem(hwnd, IDC_EDIT3);
int len = GetWindowTextLength(hwndTextbox);
int len2 = GetWindowTextLength(hwndTextbox2);
int len3 = GetWindowTextLength(hwndTextbox3);
// 账号
CHAR* account1 = new CHAR[len + 1];
GetWindowTextA(hwndTextbox, account1, len + 1);
// 第一次输入密码
CHAR* password1 = new CHAR[len2 + 1];
GetWindowTextA(hwndTextbox2, password1, len2 + 1);
// 第二次输入密码
CHAR* password2 = new CHAR[len3 + 1];
GetWindowTextA(hwndTextbox3, password2, len3 + 1);
// 对你两次输入的密码
if (strcmp(password1, password2) == 0)
{
// 存储账号和密码到数组中
strcpy_s(accounts[numAccounts].username,300, account1);
strcpy_s(accounts[numAccounts].password,300, password2);
numAccounts++;
FILE* file = {};
fopen_s(&file, "1.txt", "wb");
// 将所有注册账号和密码写入文件
for (int i = 0; i < numAccounts; i++)
{
fwrite(accounts[i].username, sizeof(CHAR), strlen(accounts[i].username), file);
fputc(',', file);
fwrite(accounts[i].password, sizeof(CHAR), strlen(accounts[i].password), file);
fputc('\n', file);
}
fclose(file);
MessageBox(NULL, _T("注册成功"), _T("提示"), MB_OK);
}
else
{
MessageBox(NULL, _T("两次输入的密码不同"), _T("提示"), MB_OK);
}
}break;
case IDCANCEL:
{
DestroyWindow(hwnd);
}break;
}
}break;
case WM_CLOSE:
{
DestroyWindow(hwnd);
} break;
}
return 0;
}
// 功能栏
INT_PTR CALLBACK TwoWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_INITDIALOG:
{
// 获取ComboBox句柄
HWND hComboBox = GetDlgItem(hwnd, IDC_COMBO1);
// 添加下拉列表项
SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"C:\\");
SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"D:\\");
return TRUE;
}break;
case WM_COMMAND:
{
WORD id = LOWORD(wparam);
switch (id)
{
case IDC_BUTTON2:
{
// 输出磁盘信息
HWND hit = GetDlgItem(hwnd, IDC_COMBO1);
GetWindowText(hit, text, 512);
HWND hEdit = GetDlgItem(hwnd, IDC_EDIT1);
choseCD(hEdit);
}break;
case IDC_BUTTON3:
{
// 用空格当清屏
HWND clear = GetDlgItem(hwnd, IDC_EDIT1);
SetWindowText(clear, _T(" "));
}
}
}break;
case WM_CLOSE:
{
DestroyWindow(hwnd);
} break;
}
return 0;
}
// 读取磁盘信息
void choseCD(HWND hwnd)
{
TCHAR buffer[512] = {};
// 获取盘符类型
int type = GetDriveType(text);
// 根据类型 以下都是拷贝到btxet
switch (type)
{
case DRIVE_UNKNOWN:
{
_tcscpy_s(buffer, 512, _T("未知"));
}
break;
case DRIVE_NO_ROOT_DIR:
{
_tcscpy_s(buffer, 512, _T("无效"));
}
break;
case DRIVE_REMOVABLE:
{
_tcscpy_s(buffer, 512, _T("可移动的磁盘"));
}
break;
case DRIVE_FIXED:
{
_tcscpy_s(buffer, 512, _T("硬盘"));
}
break;
case DRIVE_REMOTE:
{
_tcscpy_s(buffer, 512, _T("网络驱动器"));
}
break;
case DRIVE_CDROM:
{
_tcscpy_s(buffer, 512, _T("CD_ROM驱动器"));
}
break;
case DRIVE_RAMDISK:
{
_tcscpy_s(buffer, 512, _T("RAM驱动器"));
}
break;
default:
break;
}
// 获取盘符空间信息
DWORD sectorsPerCluster = 0;
DWORD bytesPerSector = 0;
DWORD freeClusters = 0;
DWORD totalClusters = 0;
if (GetDiskFreeSpace(text, §orsPerCluster, &bytesPerSector, &freeClusters, &totalClusters))
{
double totalCapacity = static_cast<double>(totalClusters) * sectorsPerCluster * bytesPerSector / (1024 * 1024 * 1024); // 总容量,单位GB
double freeSpace = static_cast<double>(freeClusters) * sectorsPerCluster * bytesPerSector / (1024 * 1024 * 1024); // 空闲容量,单位GB
// 存储到text
_stprintf_s(buffer, 512, _T("总容量:%.2f GB,空闲容量:%.2f GB"), totalCapacity, freeSpace);
}
SetWindowText(hwnd, buffer);
}
// 加载账号密码
void LoadAccountsFromFile()
{
FILE* file = nullptr;
fopen_s(&file, "1.txt", "rb");
if (file != nullptr)
{
char line[200]; // 假设每行最多包含 200 个字符
// 按行读取账号和密码
while (fgets(line, sizeof(line), file))
{
if (strlen(line) > 0 && line[strlen(line) - 1] == '\n') {
line[strlen(line) - 1] = '\0'; // 去掉换行符
}
// 解析账号和密码
char* context = nullptr; // 上下文指针
char* username = nullptr;
char* password = nullptr;
username = strtok_s(line, ",", &context);
password = strtok_s(nullptr, ",", &context);
// 存储到账号数组中
if (username != nullptr && password != nullptr) {
strcpy_s(accounts[numAccounts].username, sizeof(accounts[numAccounts].username), username);
strcpy_s(accounts[numAccounts].password, sizeof(accounts[numAccounts].password), password);
numAccounts++;
}
}
fclose(file);
}
}
略有不足 还望理解 本定时更新
如想了解实时漏洞的poc可关注猫蛋儿安全公众号,或者github搜索:MDPOCS