xref: /reactos/dll/cpl/sysdm/sysdm.c (revision ccef43f3)
1 /*
2  * PROJECT:     ReactOS System Control Panel Applet
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/cpl/sysdm/sysdm.c
5  * PURPOSE:     dll entry file
6  * COPYRIGHT:   Copyright Thomas Weidenmueller <w3seek@reactos.org>
7  *
8  */
9 
10 #include "precomp.h"
11 
12 #include <regstr.h>
13 
14 static LONG APIENTRY SystemApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
15 HINSTANCE hApplet = 0;
16 
17 /* Applets */
18 APPLET Applets[NUM_APPLETS] =
19 {
20     {IDI_CPLSYSTEM, IDS_CPLSYSTEMNAME, IDS_CPLSYSTEMDESCRIPTION, SystemApplet}
21 };
22 
23 #define MAX_SYSTEM_PAGES    32
24 
25 
26 INT __cdecl
27 ResourceMessageBox(
28     _In_opt_ HINSTANCE hInstance,
29     _In_opt_ HWND hwnd,
30     _In_ UINT uType,
31     _In_ UINT uCaption,
32     _In_ UINT uText,
33     ...)
34 {
35     va_list args;
36     WCHAR szCaption[MAX_STR_LENGTH];
37     WCHAR szText[MAX_STR_LENGTH];
38     WCHAR szCookedText[2*MAX_STR_LENGTH];
39 
40     LoadStringW(hInstance, uCaption, szCaption, _countof(szCaption));
41     LoadStringW(hInstance, uText, szText, _countof(szText));
42 
43     va_start(args, uText);
44     StringCchVPrintfW(szCookedText, _countof(szCookedText),
45                       szText, args);
46     va_end(args);
47 
48     return MessageBoxW(hwnd,
49                        szCookedText,
50                        szCaption,
51                        uType);
52 }
53 
54 
55 static BOOL CALLBACK
56 PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
57 {
58     PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
59     if (ppsh != NULL && ppsh->nPages < MAX_SYSTEM_PAGES)
60     {
61         ppsh->phpage[ppsh->nPages++] = hpage;
62         return TRUE;
63     }
64 
65     return FALSE;
66 }
67 
68 static BOOL
69 InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc)
70 {
71     HPROPSHEETPAGE hPage;
72     PROPSHEETPAGE psp;
73 
74     if (ppsh->nPages < MAX_SYSTEM_PAGES)
75     {
76         ZeroMemory(&psp, sizeof(psp));
77         psp.dwSize = sizeof(psp);
78         psp.dwFlags = PSP_DEFAULT;
79         psp.hInstance = hApplet;
80         psp.pszTemplate = MAKEINTRESOURCE(idDlg);
81         psp.pfnDlgProc = DlgProc;
82 
83         hPage = CreatePropertySheetPage(&psp);
84         if (hPage != NULL)
85         {
86             return PropSheetAddPage(hPage, (LPARAM)ppsh);
87         }
88     }
89 
90     return FALSE;
91 }
92 
93 typedef HPROPSHEETPAGE (WINAPI *PCreateNetIDPropertyPage)(VOID);
94 
95 static HMODULE
96 AddNetIdPage(PROPSHEETHEADER *ppsh)
97 {
98     HPROPSHEETPAGE hPage;
99     HMODULE hMod;
100     PCreateNetIDPropertyPage pCreateNetIdPage;
101 
102     hMod = LoadLibrary(TEXT("netid.dll"));
103     if (hMod != NULL)
104     {
105         pCreateNetIdPage = (PCreateNetIDPropertyPage)GetProcAddress(hMod,
106                                                                     "CreateNetIDPropertyPage");
107         if (pCreateNetIdPage != NULL)
108         {
109             hPage = pCreateNetIdPage();
110             if (hPage == NULL)
111                 goto Fail;
112 
113             if (!PropSheetAddPage(hPage, (LPARAM)ppsh))
114             {
115                 DestroyPropertySheetPage(hPage);
116                 goto Fail;
117             }
118         }
119         else
120         {
121 Fail:
122             FreeLibrary(hMod);
123             hMod = NULL;
124         }
125     }
126 
127     return hMod;
128 }
129 
130 static int CALLBACK
131 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
132 {
133     // NOTE: This callback is needed to set large icon correctly.
134     HICON hIcon;
135     switch (uMsg)
136     {
137         case PSCB_INITIALIZED:
138         {
139             hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLSYSTEM));
140             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
141             break;
142         }
143     }
144     return 0;
145 }
146 
147 /* First Applet */
148 LONG CALLBACK
149 SystemApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
150 {
151     HPROPSHEETPAGE hpsp[MAX_SYSTEM_PAGES];
152     PROPSHEETHEADER psh;
153     HMODULE hNetIdDll;
154     HPSXA hpsxa = NULL;
155     INT nPage = 0;
156     LONG Ret;
157     static INITCOMMONCONTROLSEX icc = {sizeof(INITCOMMONCONTROLSEX), ICC_LINK_CLASS};
158 
159     if (!InitCommonControlsEx(&icc))
160         return 0;
161 
162     if (uMsg == CPL_STARTWPARMSW && lParam != 0)
163     {
164         nPage = _wtoi((PWSTR)lParam);
165     }
166 
167     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
168     psh.dwSize = sizeof(PROPSHEETHEADER);
169     psh.dwFlags =  PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
170     psh.hwndParent = hwnd;
171     psh.hInstance = hApplet;
172     psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLSYSTEM);
173     psh.pszCaption = MAKEINTRESOURCE(IDS_CPLSYSTEMNAME);
174     psh.nPages = 0;
175     psh.nStartPage = 0;
176     psh.phpage = hpsp;
177     psh.pfnCallback = PropSheetProc;
178 
179     InitPropSheetPage(&psh, IDD_PROPPAGEGENERAL, GeneralPageProc);
180     hNetIdDll = AddNetIdPage(&psh);
181     InitPropSheetPage(&psh, IDD_PROPPAGEHARDWARE, HardwarePageProc);
182     InitPropSheetPage(&psh, IDD_PROPPAGEADVANCED, AdvancedPageProc);
183 
184     /* Load additional pages provided by shell extensions */
185     hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\System"), MAX_SYSTEM_PAGES - psh.nPages);
186     if (hpsxa != NULL)
187     {
188         SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
189     }
190 
191     if (nPage != 0 && nPage <= psh.nPages)
192         psh.nStartPage = nPage;
193 
194     Ret = (LONG)(PropertySheet(&psh) != -1);
195 
196     if (hpsxa != NULL)
197     {
198         SHDestroyPropSheetExtArray(hpsxa);
199     }
200 
201     if (hNetIdDll != NULL)
202         FreeLibrary(hNetIdDll);
203 
204     return Ret;
205 }
206 
207 /* Control Panel Callback */
208 LONG CALLBACK
209 CPlApplet(HWND hwndCPl,
210           UINT uMsg,
211           LPARAM lParam1,
212           LPARAM lParam2)
213 {
214     UINT i = (UINT)lParam1;
215 
216     UNREFERENCED_PARAMETER(hwndCPl);
217 
218     switch (uMsg)
219     {
220         case CPL_INIT:
221             return TRUE;
222 
223         case CPL_GETCOUNT:
224             return NUM_APPLETS;
225 
226         case CPL_INQUIRE:
227             if (i < NUM_APPLETS)
228             {
229                  CPLINFO *CPlInfo = (CPLINFO*)lParam2;
230                  CPlInfo->lData = 0;
231                  CPlInfo->idIcon = Applets[i].idIcon;
232                  CPlInfo->idName = Applets[i].idName;
233                  CPlInfo->idInfo = Applets[i].idDescription;
234             }
235             else
236             {
237                 return TRUE;
238             }
239             break;
240 
241         case CPL_DBLCLK:
242             if (i < NUM_APPLETS)
243                 Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
244             else
245                 return TRUE;
246             break;
247 
248         case CPL_STARTWPARMSW:
249             if (i < NUM_APPLETS)
250                 return Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
251             break;
252     }
253 
254     return FALSE;
255 }
256 
257 
258 BOOL WINAPI
259 DllMain(HINSTANCE hinstDLL,
260         DWORD dwReason,
261         LPVOID lpvReserved)
262 {
263     UNREFERENCED_PARAMETER(lpvReserved);
264 
265     switch (dwReason)
266     {
267         case DLL_PROCESS_ATTACH:
268         case DLL_THREAD_ATTACH:
269             hApplet = hinstDLL;
270             break;
271     }
272 
273     return TRUE;
274 }
275