概述:控制面板相关注册表,以及控制面板程序开发

0x01 控制面板项目

image-20240221100622711

对应的注册表位置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace

说明:

用于存储和控制控制面板(Control Panel)中的项目。具体来说,ControlPanel\NameSpace键下通常包含了一系列的子键,每个子键都代表控制面板中的一个特定的文件夹或项目。这些子键通常有一个名为{GUID}的名称,其中GUID是一个全局唯一标识符,用于唯一标识该文件夹或项目。

例如,如果你想在控制面板中添加或删除一个项目,你可能需要修改这个键或其下的子键。通过添加或删除子键,你可以改变控制面板的外观和行为。

0x02 控制面板项目

控制面板项本身通常存储在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Control Panel\CputsHKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Control Panel\Cputs(对于 32 位程序在 64 位系统上的情况)中。每个控制面板项都有一个对应的 GUID,并指向其可执行文件或 DLL。

不过,ControlPanel\NameSpace 通常用于自定义桌面上的“控制面板”文件夹内容,而不是直接控制控制面板项本身。

对于 ControlPanel\NameSpace 下的 GUID,它们通常与桌面上的文件夹快捷方式相关联,而不是直接与控制面板项。例如,一个 GUID 可能指向一个包含多个控制面板项的文件夹,这些项在桌面上以单个图标的形式显示。

要获取特定 GUID 与其对应的项目或文件夹之间的确切关系,你需要查看注册表中的具体条目,并可能需要参考 Windows 内部文档或在线资源。但是,通常不建议直接修改这些条目,除非你确切知道自己在做什么,并且有备份或恢复计划,以防出现问题。

0x03 新建一个控制面板项目

通常如果需要新建一个控制面板项目,则需要在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Control Panel\Cputs 路径下添加一个注册表项,并且注册表项需要指向 cpl 文件,如下图所示:

0x04 编写一个控制面板程序

参考项目:gtrubach/MyCPLApplet: Example of creating control panel applets in Windows.

cpl 文件类似 dll 文件,入口函数不同,加载逻辑基本一致:

若口函数如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
extern "C" LONG APIENTRY CPlApplet(
HWND hwndCPL, // handle of Control Panel window
UINT uMsg, // message
LONG_PTR lParam1, // first message parameter
LONG_PTR lParam2 // second message parameter
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

LPCPLINFO lpCPlInfo;
LONG retCode = 0;

switch (uMsg)
{
case CPL_INIT: // first message, sent once
return TRUE;

case CPL_GETCOUNT: // second message, sent once
return 1L; // (LONG)NUM_APPLETS;

case CPL_INQUIRE: // third message, sent once per app
lpCPlInfo = (LPCPLINFO)lParam2;

lpCPlInfo->idIcon = IDI_SAMPLE_CPL;
lpCPlInfo->idName = IDS_SAMPLE_CPL_NAME;
lpCPlInfo->idInfo = IDS_SAMPLE_CPL_DESCRIPTION;
lpCPlInfo->lData = 0L;
break;

case CPL_DBLCLK: // application icon double-clicked
{
CWnd wndCPL;
BOOL b = wndCPL.Attach(hwndCPL);
CMyPropertySheet propSheet(IDS_SAMPLE_CPL_NAME, &wndCPL);

// This is where you would retrieve information from the property
// sheet if propSheet.DoModal() returned IDOK. We aren't doing
// anything for simplicity.

propSheet.DoModal();
wndCPL.Detach();
}
break;
}
return retCode;
}