MFC 注册表编程

记录点滴。

对话框部分程序:

 1 // RegeditDlg.h : 头文件
 2 //
 3 
 4 #pragma once
 5 #include "afxwin.h"
 6 
 7 // 注册表监控线程函数
 8 static DWORD WINAPI ThreadFunc();
 9 
10 // CRegeditDlg 对话框
11 class CRegeditDlg : public CDialogEx
12 {
13 // 构造
14 public:
15     CRegeditDlg(CWnd* pParent = NULL);    // 标准构造函数
16 
17 // 对话框数据
18     enum { IDD = IDD_REGEDIT_DIALOG };
19 
20     protected:
21     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
22 
23 
24 // 实现
25 protected:
26     HICON m_hIcon;
27 
28     // 生成的消息映射函数
29     virtual BOOL OnInitDialog();
30     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
31     afx_msg void OnPaint();
32     afx_msg HCURSOR OnQueryDragIcon();
33     DECLARE_MESSAGE_MAP()
34 public:
35     CString Reg_add;
36 //    CString Reg_change;
37     afx_msg void OnBnClickedButton1();
38     afx_msg void OnBnClickedButton2();
39     afx_msg void OnBnClickedButton3();
40     afx_msg void OnLbnSelchangeList1();
41     afx_msg void OnCbnSelchangeCombo1();
42     afx_msg void OnBnClickedButton4();
43     CString ValueName;
44     CString ValueData;
45     CComboBox m_COMBOX;
46     CString ValueSearch;
47     afx_msg void OnBnClickedButton5();
48     CString MainPage;
49     afx_msg void OnBnClickedButton7();
50     afx_msg void OnBnClickedButton6();
51     afx_msg void OnBnClickedButton9();
52     afx_msg void OnBnClickedButton10();
53 };
  1 /*
  2 2015.5    HT
  3 注册表编程
  4 
  5 基于:
  6 HKEY_CURRENT_CONFIGRegedit
  7 
  8 */
  9 
 10 // RegeditDlg.cpp : 实现文件
 11 //
 12 
 13 #include "stdafx.h"
 14 #include "Regedit.h"
 15 #include "RegeditDlg.h"
 16 #include "afxdialogex.h"
 17 
 18 #ifdef _DEBUG
 19 #define new DEBUG_NEW
 20 #endif
 21 
 22 
 23 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
 24 
 25 class CAboutDlg : public CDialogEx
 26 {
 27 public:
 28     CAboutDlg();
 29 
 30 // 对话框数据
 31     enum { IDD = IDD_ABOUTBOX };
 32 
 33     protected:
 34     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 35 
 36 // 实现
 37 protected:
 38     DECLARE_MESSAGE_MAP()
 39 };
 40 
 41 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
 42 {
 43 }
 44 
 45 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
 46 {
 47     CDialogEx::DoDataExchange(pDX);
 48 }
 49 
 50 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
 51 END_MESSAGE_MAP()
 52 
 53 
 54 // CRegeditDlg 对话框
 55 
 56 
 57 
 58 CRegeditDlg::CRegeditDlg(CWnd* pParent /*=NULL*/)
 59     : CDialogEx(CRegeditDlg::IDD, pParent)
 60     , Reg_add(_T(""))
 61     , ValueName(_T(""))
 62     , ValueData(_T(""))
 63     , ValueSearch(_T(""))
 64     , MainPage(_T(""))
 65 {
 66     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 67 }
 68 
 69 void CRegeditDlg::DoDataExchange(CDataExchange* pDX)
 70 {
 71     CDialogEx::DoDataExchange(pDX);
 72     DDX_Text(pDX, IDC_EDIT1, Reg_add);
 73     //  DDX_Text(pDX, IDC_EDIT2, Reg_change);
 74     DDX_Text(pDX, IDC_EDIT3, ValueName);
 75     DDX_Text(pDX, IDC_EDIT4, ValueData);
 76     DDX_Control(pDX, IDC_COMBO1, m_COMBOX);
 77     DDX_Text(pDX, IDC_EDIT2, ValueSearch);
 78     DDX_Text(pDX, IDC_EDIT5, MainPage);
 79 }
 80 
 81 BEGIN_MESSAGE_MAP(CRegeditDlg, CDialogEx)
 82     ON_WM_SYSCOMMAND()
 83     ON_WM_PAINT()
 84     ON_WM_QUERYDRAGICON()
 85     ON_BN_CLICKED(IDC_BUTTON1, &CRegeditDlg::OnBnClickedButton1)
 86     ON_BN_CLICKED(IDC_BUTTON2, &CRegeditDlg::OnBnClickedButton2)
 87     ON_BN_CLICKED(IDC_BUTTON3, &CRegeditDlg::OnBnClickedButton3)
 88     ON_CBN_SELCHANGE(IDC_COMBO1, &CRegeditDlg::OnCbnSelchangeCombo1)
 89     ON_BN_CLICKED(IDC_BUTTON4, &CRegeditDlg::OnBnClickedButton4)
 90     ON_BN_CLICKED(IDC_BUTTON5, &CRegeditDlg::OnBnClickedButton5)
 91     ON_BN_CLICKED(IDC_BUTTON7, &CRegeditDlg::OnBnClickedButton7)
 92     ON_BN_CLICKED(IDC_BUTTON6, &CRegeditDlg::OnBnClickedButton6)
 93     ON_BN_CLICKED(IDC_BUTTON9, &CRegeditDlg::OnBnClickedButton9)
 94     ON_BN_CLICKED(IDC_BUTTON10, &CRegeditDlg::OnBnClickedButton10)
 95 END_MESSAGE_MAP()
 96 
 97 
 98 // CRegeditDlg 消息处理程序
 99 
100 BOOL CRegeditDlg::OnInitDialog()
101 {
102     CDialogEx::OnInitDialog();
103 
104     // 将“关于...”菜单项添加到系统菜单中。
105 
106     // IDM_ABOUTBOX 必须在系统命令范围内。
107     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
108     ASSERT(IDM_ABOUTBOX < 0xF000);
109 
110     CMenu* pSysMenu = GetSystemMenu(FALSE);
111     if (pSysMenu != NULL)
112     {
113         BOOL bNameValid;
114         CString strAboutMenu;
115         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
116         ASSERT(bNameValid);
117         if (!strAboutMenu.IsEmpty())
118         {
119             pSysMenu->AppendMenu(MF_SEPARATOR);
120             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
121         }
122     }
123 
124     // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
125     //  执行此操作
126     SetIcon(m_hIcon, TRUE);            // 设置大图标
127     SetIcon(m_hIcon, FALSE);        // 设置小图标
128 
129     // TODO:  在此添加额外的初始化代码
130 
131     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
132 }
133 
134 void CRegeditDlg::OnSysCommand(UINT nID, LPARAM lParam)
135 {
136     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
137     {
138         CAboutDlg dlgAbout;
139         dlgAbout.DoModal();
140     }
141     else
142     {
143         CDialogEx::OnSysCommand(nID, lParam);
144     }
145 }
146 
147 // 如果向对话框添加最小化按钮,则需要下面的代码
148 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
149 //  这将由框架自动完成。
150 
151 void CRegeditDlg::OnPaint()
152 {
153     if (IsIconic())
154     {
155         CPaintDC dc(this); // 用于绘制的设备上下文
156 
157         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
158 
159         // 使图标在工作区矩形中居中
160         int cxIcon = GetSystemMetrics(SM_CXICON);
161         int cyIcon = GetSystemMetrics(SM_CYICON);
162         CRect rect;
163         GetClientRect(&rect);
164         int x = (rect.Width() - cxIcon + 1) / 2;
165         int y = (rect.Height() - cyIcon + 1) / 2;
166 
167         // 绘制图标
168         dc.DrawIcon(x, y, m_hIcon);
169     }
170     else
171     {
172         CDialogEx::OnPaint();
173     }
174 }
175 
176 //当用户拖动最小化窗口时系统调用此函数取得光标
177 //显示。
178 HCURSOR CRegeditDlg::OnQueryDragIcon()
179 {
180     return static_cast<HCURSOR>(m_hIcon);
181 }
182 
183 
184 
185 void CRegeditDlg::OnBnClickedButton1()
186 {
187     // 添加项
188 
189     UpdateData(TRUE);
190 
191     HKEY KEY = NULL;
192     DWORD dw;
193     CString data_add = TEXT("Regedit\");
194     if (Reg_add.GetLength() == 0)
195     {
196         MessageBox(_T("不能空,输入项名"));
197         return;
198     }
199     data_add += Reg_add;
200 
201     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,
202         data_add, 0, KEY_ALL_ACCESS, &KEY))
203     {
204         MessageBox(_T("该项已存在!"));
205         return;
206     }
207 
208     if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG, data_add, 0, NULL, REG_OPTION_NON_VOLATILE,
209         KEY_ALL_ACCESS, NULL, &KEY, &dw))
210     {
211         MessageBox(_T("添加项成功!"));
212     }
213     else
214     {
215         MessageBox(_T("添加项失败!"));
216     }
217 
218     UpdateData(FALSE);
219 }
220 
221 void CRegeditDlg::OnBnClickedButton3()
222 {
223     // 删除项
224     UpdateData(TRUE);
225 
226     CString data_add = TEXT("Regedit\");
227     if (Reg_add.GetLength() == 0)
228     {
229         MessageBox(_T("不能空,输入项名"));
230         return;
231     }
232     data_add += Reg_add;
233 
234     if (ERROR_SUCCESS == RegDeleteKey(HKEY_CURRENT_CONFIG, data_add))
235         MessageBox(_T("删除项成功!"));
236 
237     UpdateData(FALSE);
238 }
239 
240 void CRegeditDlg::OnBnClickedButton4()
241 {
242     //新建键值
243     UpdateData(TRUE);
244 
245     HKEY KEY;
246     unsigned char *pData = (unsigned char*)ValueData.GetBuffer(ValueData.GetLength());
247     /*
248     类型:
249     DWORD            REG_DWORD
250     QWORD            REG_QWORD
251     多字符串值        REG_MULTI_SZ
252     二进制值            REG_BINARY
253     可扩充字符串值        REG_EXPAND_SZ
254     字符串值(默认)        REG_SZ
255     */
256     DWORD nType = REG_SZ;
257     int TypeSelect;
258     TypeSelect = m_COMBOX.GetCurSel();
259     /*测试用
260     CString STemp;
261     STemp.Format(_T("%d"), TypeSelect);
262     MessageBox(STemp);*/
263 
264     switch (TypeSelect)
265     {
266     case 0: nType = REG_DWORD;        break;
267     case 1: nType = REG_QWORD;        break;
268     case 2: nType = REG_MULTI_SZ;    break;
269     case 3: nType = REG_BINARY;        break;
270     case 4: nType = REG_EXPAND_SZ;    break;
271     case 5: nType = REG_SZ;            break;
272     default:
273         break;
274     }
275     CString data_add = TEXT("Regedit\");
276     if (Reg_add.GetLength() == 0)
277     {
278         MessageBox(_T("先选择项名"));
279         return;
280     }
281     data_add += Reg_add;
282 
283     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,
284         data_add, 0, KEY_ALL_ACCESS, &KEY))
285     {
286         if (ERROR_SUCCESS == RegSetValueEx(KEY, ValueName, 0, nType,
287             pData, (DWORD)ValueData.GetLength()*2))
288         {
289             MessageBox(_T("新建键值成功!"));
290         }
291     }
292     RegCloseKey(KEY);
293 
294     UpdateData(FALSE);
295 }
296 
297 void CRegeditDlg::OnBnClickedButton2()
298 {
299     // 删除键值
300     UpdateData(TRUE);
301 
302     HKEY KEY;
303     CString data_add = TEXT("Regedit\");
304     if (Reg_add.GetLength() == 0)
305     {
306         MessageBox(_T("先选择项名"));
307         return;
308     }
309     data_add += Reg_add;
310 
311     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,
312         data_add, 0, KEY_ALL_ACCESS, &KEY))
313     {
314         if (ERROR_SUCCESS == RegDeleteValue(KEY, (LPCTSTR)ValueName))
315         {
316             MessageBox(_T("删除键值成功!"));
317         }
318         else
319         {
320             MessageBox(_T("删除失败,该值可能不存在"));
321         }
322     }
323     RegCloseKey(KEY);
324 
325     UpdateData(FALSE);
326 }
327 
328 void CRegeditDlg::OnBnClickedButton5()
329 {
330     // 键值查询
331     UpdateData(TRUE);
332 
333     HKEY KEY;
334     unsigned char pValue[100];
335     DWORD len = 100;
336     CString data_add = TEXT("Regedit\");
337     if (Reg_add.GetLength() == 0)
338     {
339         MessageBox(_T("先选择项名"));
340         return;
341     }
342     data_add += Reg_add;
343 
344     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,
345         data_add, 0, KEY_ALL_ACCESS, &KEY))
346     {
347         // 不关心值项类型,设为NULL
348         if (ERROR_SUCCESS == RegQueryValueEx(KEY, (LPCTSTR)ValueSearch, 0, NULL,
349             (LPBYTE)pValue, &len))
350         {
351             MessageBox(_T("OK,该键值存在"));
352         }
353         else
354         {
355             MessageBox(_T("键值不存在"));
356         }
357     }
358     RegCloseKey(KEY);
359 
360 }
361 
362 
363 void CRegeditDlg::OnBnClickedButton7()
364 {
365     // 修改IE主页
366     UpdateData(TRUE);
367     HKEY KEY;
368     unsigned char* pData = (unsigned char*)MainPage.GetBuffer();
369 
370     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\Microsoft\Internet Explorer\Main\"),
371         0, KEY_ALL_ACCESS, &KEY))
372     {
373         RegSetValueEx(KEY, TEXT("Search Page"), 0, REG_SZ,
374             (const BYTE*)pData, MainPage.GetLength() * 2);
375         RegSetValueEx(KEY, TEXT("Start Page"), 0, REG_SZ,
376             (const BYTE*)pData, MainPage.GetLength()*2);
377         RegSetValueEx(KEY, TEXT("Start Page Redirect Cache"), 0, REG_SZ,
378             (const BYTE*)pData, MainPage.GetLength() * 2);
379     }
380     else
381     {
382         MessageBox(_T("修改IE主页失败!"));
383         return;
384     }
385 
386     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\Microsoft\Internet Explorer\Main\"),
387         0, KEY_ALL_ACCESS, &KEY))
388     {
389         RegSetValueEx(KEY, TEXT("Search Page"), 0, REG_SZ,
390             (const BYTE*)pData, MainPage.GetLength() * 2);
391         RegSetValueEx(KEY, TEXT("Start Page"), 0, REG_SZ,
392             (const BYTE*)pData, MainPage.GetLength() * 2);
393     }
394     else
395     {
396         MessageBox(_T("修改IE主页失败!"));
397         return;
398     }
399     RegCloseKey(KEY);
400 
401     MessageBox(_T("修改IE主页成功!"));
402 
403 }
404 
405 void CRegeditDlg::OnCbnSelchangeCombo1()
406 {
407     // TODO:  在此添加控件通知处理程序代码
408 }
409 
410 void CRegeditDlg::OnBnClickedButton6()
411 {
412     // 注册表禁止访问
413     HKEY KEY;
414     DWORD Value = 1;
415     //HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesSystem
416     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 
417         TEXT("Software\Microsoft\Windows\CurrentVersion\Policies\System\"),
418         0, KEY_ALL_ACCESS, &KEY))
419     {
420         RegSetValueEx(KEY, TEXT("Disableregistrytools"), 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD));
421         MessageBox(_T("禁用注册表成功!"));
422     }
423 
424 }
425 
426 
427 void CRegeditDlg::OnBnClickedButton9()
428 {
429     // 注册表允许访问
430     HKEY KEY;
431     DWORD Value = 0;
432     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
433         TEXT("Software\Microsoft\Windows\CurrentVersion\Policies\System\"),
434         0, KEY_ALL_ACCESS, &KEY))
435     {
436         RegSetValueEx(KEY, TEXT("Disableregistrytools"), 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD));
437         MessageBox(_T("启用注册表成功!"));
438     }
439 }
440 
441 /*
442 线程函数不能退出
443 不能独占cpu
444 */
445 // 注册表监控线程函数
446 // 经过测试还不是很完善,有些 HKEY 项无法受到监控
447 static DWORD WINAPI ThreadFunc()
448 {
449     HANDLE hNotify[5];
450     HKEY hKEY1, hKEY2, hKEY3, hKEY4, hKEY5;
451     DWORD ret;
452 
453     if (ERROR_SUCCESS ==
454         (RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL,
455         0, KEY_NOTIFY, &hKEY1) ||
456         RegOpenKeyEx(HKEY_CURRENT_USER, NULL,
457         0, KEY_NOTIFY, &hKEY2) ||
458         RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL,
459         0, KEY_NOTIFY, &hKEY3) ||
460         RegOpenKeyEx(HKEY_USERS, NULL,
461         0, KEY_NOTIFY, &hKEY4) ||
462         RegOpenKeyEx(HKEY_CURRENT_CONFIG, NULL,
463         0, KEY_NOTIFY, &hKEY5))
464         );
465     else
466     {
467         AfxMessageBox(_T("RegOpenKeyEx 失败"));
468         return 0;
469     }
470     
471 
472     // 安全属性    是否手动重置    初始化状态    名称
473     hNotify[0] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify"));
474     hNotify[1] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify"));
475     hNotify[2] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify"));
476     hNotify[3] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify"));
477     hNotify[4] = CreateEvent(NULL, FALSE, FALSE, TEXT("RegistryNotify"));
478     if (hNotify[4] == 0)
479     {
480         AfxMessageBox(_T("CreateEvent 失败"));
481         return 0;
482     }
483 
484     while (1)
485     {
486         /*
487         监听到指定注册表项变化,hEvent参数指定的事件会被触发为有信号状态
488         监听到变化该函数则自动结束退出
489         */
490         RegNotifyChangeKeyValue(hKEY1, TRUE,
491             REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[0], TRUE);
492         RegNotifyChangeKeyValue(hKEY2, TRUE,
493             REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[1], TRUE);    
494         RegNotifyChangeKeyValue(hKEY3, TRUE,
495             REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[2], TRUE);
496         RegNotifyChangeKeyValue(hKEY4, TRUE,
497             REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[3], TRUE);
498         RegNotifyChangeKeyValue(hKEY5, TRUE,
499             REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hNotify[4], TRUE);
500 
501         ret = WaitForMultipleObjects(5, hNotify, NULL, INFINITE);
502         if (ret == WAIT_OBJECT_0 || (WAIT_OBJECT_0 + 1) || (WAIT_OBJECT_0 + 2)
503             || (WAIT_OBJECT_0 + 3) || (WAIT_OBJECT_0 + 4))
504         {
505             AfxMessageBox(_T("!!有程序正在修改注册表"));
506         }
507 
508         //// 监听单个事件
509         //if (WaitForSingleObject(hNotify1, INFINITE) == WAIT_OBJECT_0 || 
510         //    WaitForSingleObject(hNotify2, INFINITE) == WAIT_OBJECT_0 ||
511         //    WaitForSingleObject(hNotify3, INFINITE) == WAIT_OBJECT_0 ||
512         //    WaitForSingleObject(hNotify4, INFINITE) == WAIT_OBJECT_0 ||
513         //    WaitForSingleObject(hNotify5, INFINITE) == WAIT_OBJECT_0 
514         //    )
515         //{
516         //    AfxMessageBox(_T("!!有程序正在修改注册表"));
517         //}
518     }
519     
520     CloseHandle(hNotify[0]);
521     CloseHandle(hNotify[1]);
522     CloseHandle(hNotify[2]);
523     CloseHandle(hNotify[3]);
524     CloseHandle(hNotify[4]);
525     RegCloseKey(hKEY1);
526     RegCloseKey(hKEY2);
527     RegCloseKey(hKEY3);
528     RegCloseKey(hKEY4);
529     RegCloseKey(hKEY5);
530     return 0;
531 }
532 
533 void CRegeditDlg::OnBnClickedButton10()
534 {
535     // 注册表监控进程
536 
537     /*
538     第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置
539     第二个参数表示线程栈空间大小,传入0表示使用默认大小(1MB)
540     第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址
541     第四个参数是传给线程函数的参数
542     第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,
543         如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()
544     第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号
545     函数返回值:
546         成功返回新线程的句柄,失败返回NULL
547 
548     线程函数需要静态成员函数或全局函数
549     */
550     HANDLE hThread = CreateThread(NULL, 0,
551         (LPTHREAD_START_ROUTINE)ThreadFunc,
552         NULL, 0, NULL);
553     MessageBox(_T("注册表监控已打开!"));
554 
555     CloseHandle(hThread);
556 }
原文地址:https://www.cnblogs.com/ht-beyond/p/4547578.html