mirror of
https://github.com/reactos/reactos.git
synced 2024-11-02 21:09:15 +00:00
480 lines
15 KiB
C
480 lines
15 KiB
C
/*
|
|
* PROJECT: ReactOS Applications
|
|
* LICENSE: LGPL - See COPYING in the top level directory
|
|
* FILE: base/applications/msconfig_new/msconfig.c
|
|
* PURPOSE: MSConfig main dialog
|
|
* COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#include "fileutils.h"
|
|
#include "utils.h"
|
|
|
|
#include "generalpage.h"
|
|
#include "systempage.h"
|
|
#include "freeldrpage.h"
|
|
#include "srvpage.h"
|
|
// #include "startuppage.h"
|
|
#include "toolspage.h"
|
|
|
|
/* Allow only for a single instance of MSConfig */
|
|
#ifdef _MSC_VER
|
|
#pragma data_seg("MSConfigInstance")
|
|
HWND hSingleWnd = NULL;
|
|
#pragma data_seg()
|
|
#pragma comment(linker, "/SECTION:MSConfigInstance,RWS")
|
|
#else
|
|
HWND hSingleWnd __attribute__((section ("MSConfigInstance"), shared)) = NULL;
|
|
#endif
|
|
|
|
/* Defaults for ReactOS */
|
|
BOOL bIsWindows = FALSE;
|
|
BOOL bIsPreVistaOSVersion = TRUE;
|
|
|
|
/* Language-independent Vendor strings */
|
|
const LPCWSTR IDS_REACTOS = L"ReactOS";
|
|
const LPCWSTR IDS_MICROSOFT = L"Microsoft";
|
|
const LPCWSTR IDS_WINDOWS = L"Windows";
|
|
|
|
HINSTANCE hInst = NULL;
|
|
LPWSTR szAppName = NULL;
|
|
HWND hMainWnd; /* Main Window */
|
|
|
|
HWND hTabWnd; /* Tab Control Window */
|
|
HICON hIcon = NULL, hIconSm = NULL;
|
|
WNDPROC wpOrigEditProc = NULL;
|
|
|
|
|
|
/* About Box dialog */
|
|
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
return (INT_PTR)TRUE;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
|
|
{
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
return (INT_PTR)TRUE;
|
|
}
|
|
break;
|
|
}
|
|
return (INT_PTR)FALSE;
|
|
}
|
|
|
|
|
|
/* Message handler for dialog box */
|
|
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMessage)
|
|
{
|
|
case WM_SYSCOMMAND:
|
|
{
|
|
switch (LOWORD(wParam) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
|
|
{
|
|
case IDM_ABOUT:
|
|
DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, About);
|
|
// break;
|
|
return TRUE;
|
|
}
|
|
|
|
// break;
|
|
return FALSE;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
|
|
{
|
|
case IDM_ABOUT:
|
|
DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, About);
|
|
// break;
|
|
return TRUE;
|
|
}
|
|
|
|
break;
|
|
// return FALSE;
|
|
}
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
if (wpOrigEditProc)
|
|
SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LONG_PTR)wpOrigEditProc);
|
|
|
|
if (hIcon) DestroyIcon(hIcon);
|
|
if (hIconSm) DestroyIcon(hIconSm);
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Return */
|
|
if (wpOrigEditProc)
|
|
return CallWindowProc(wpOrigEditProc, hWnd, uMessage, wParam, lParam);
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#include <pshpack1.h>
|
|
typedef struct DLGTEMPLATEEX
|
|
{
|
|
WORD dlgVer;
|
|
WORD signature;
|
|
DWORD helpID;
|
|
DWORD exStyle;
|
|
DWORD style;
|
|
WORD cDlgItems;
|
|
short x;
|
|
short y;
|
|
short cx;
|
|
short cy;
|
|
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
|
|
#include <poppack.h>
|
|
|
|
int CALLBACK PropSheetCallback(HWND hDlg, UINT message, LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case PSCB_PRECREATE:
|
|
{
|
|
LPDLGTEMPLATE dlgTemplate = (LPDLGTEMPLATE)lParam;
|
|
LPDLGTEMPLATEEX dlgTemplateEx = (LPDLGTEMPLATEEX)lParam;
|
|
|
|
// MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION;
|
|
DWORD style = DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
|
|
// DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
|
|
DWORD exStyle = WS_EX_CONTROLPARENT | WS_EX_APPWINDOW;
|
|
|
|
/* Hide the dialog by default; we will center it on screen later, and then show it */
|
|
style &= ~WS_VISIBLE;
|
|
|
|
/* Set the styles of the property sheet dialog */
|
|
if (dlgTemplateEx->signature == 0xFFFF)
|
|
{
|
|
dlgTemplateEx->style = style;
|
|
dlgTemplateEx->exStyle = exStyle;
|
|
}
|
|
else
|
|
{
|
|
dlgTemplate->style = style;
|
|
dlgTemplate->dwExtendedStyle = exStyle;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PSCB_INITIALIZED:
|
|
{
|
|
/* Customize the window's system menu, add items before the "Close" item */
|
|
LPWSTR szMenuString;
|
|
HMENU hSysMenu = GetSystemMenu(hDlg, FALSE);
|
|
assert(hSysMenu);
|
|
|
|
szMenuString = LoadResourceString(hInst, IDS_ABOUT);
|
|
if (szMenuString)
|
|
{
|
|
/* "About" menu */
|
|
InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED | MF_STRING, IDM_ABOUT, szMenuString);
|
|
/* Separator */
|
|
InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_SEPARATOR , 0 , NULL);
|
|
|
|
MemFree(szMenuString);
|
|
}
|
|
DrawMenuBar(hDlg);
|
|
|
|
/* Set the dialog icons */
|
|
hIcon = (HICON)LoadImageW(hInst, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
|
|
hIconSm = (HICON)CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE);
|
|
SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
|
SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
|
|
|
|
/* Sub-class the property sheet window procedure */
|
|
wpOrigEditProc = (WNDPROC)SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LONG_PTR)MainWndProc);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
HWND CreatePropSheet(HINSTANCE hInstance, HWND hwndOwner, LPCTSTR lpszTitle)
|
|
{
|
|
HWND hPropSheet;
|
|
PROPSHEETHEADERW psh;
|
|
PROPSHEETPAGEW psp[7];
|
|
unsigned int nPages = 0;
|
|
|
|
/* Header */
|
|
psh.dwSize = sizeof(psh);
|
|
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | /*PSH_USEICONID |*/ PSH_HASHELP | /*PSH_NOCONTEXTHELP |*/ PSH_USECALLBACK;
|
|
psh.hInstance = hInstance;
|
|
psh.hwndParent = hwndOwner;
|
|
// psh.pszIcon = MAKEINTRESOURCEW(IDI_APPICON); // Disabled because it only sets the small icon; the big icon is a stretched version of the small one.
|
|
psh.pszCaption = lpszTitle;
|
|
psh.nStartPage = 0;
|
|
psh.ppsp = psp;
|
|
psh.pfnCallback = PropSheetCallback;
|
|
|
|
/* General page */
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_GENERAL_PAGE);
|
|
psp[nPages].pfnDlgProc = GeneralPageWndProc;
|
|
++nPages;
|
|
|
|
// if (bIsPreVistaOSVersion)
|
|
{
|
|
/* SYSTEM.INI page */
|
|
if (MyFileExists(lpszSystemIni, NULL))
|
|
{
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTitle = MAKEINTRESOURCEW(IDS_TAB_SYSTEM);
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SYSTEM_PAGE);
|
|
psp[nPages].pfnDlgProc = SystemPageWndProc;
|
|
psp[nPages].lParam = (LPARAM)lpszSystemIni;
|
|
++nPages;
|
|
|
|
BackupIniFile(lpszSystemIni);
|
|
}
|
|
|
|
/* WIN.INI page */
|
|
if (MyFileExists(lpszWinIni, NULL))
|
|
{
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTitle = MAKEINTRESOURCEW(IDS_TAB_WIN);
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SYSTEM_PAGE);
|
|
psp[nPages].pfnDlgProc = WinPageWndProc;
|
|
psp[nPages].lParam = (LPARAM)lpszWinIni;
|
|
++nPages;
|
|
|
|
BackupIniFile(lpszWinIni);
|
|
}
|
|
}
|
|
|
|
/* FreeLdr page */
|
|
// TODO: Program the interface for Vista: "light" BCD editor...
|
|
if (!bIsWindows || (bIsWindows && bIsPreVistaOSVersion))
|
|
{
|
|
LPCWSTR lpszLoaderIniFile = NULL;
|
|
DWORD dwTabNameId = 0;
|
|
if (bIsWindows)
|
|
{
|
|
lpszLoaderIniFile = lpszBootIni;
|
|
dwTabNameId = IDS_TAB_BOOT;
|
|
}
|
|
else
|
|
{
|
|
lpszLoaderIniFile = lpszFreeLdrIni;
|
|
dwTabNameId = IDS_TAB_FREELDR;
|
|
}
|
|
|
|
if (MyFileExists(lpszLoaderIniFile, NULL))
|
|
{
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTitle = MAKEINTRESOURCEW(dwTabNameId);
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_FREELDR_PAGE);
|
|
psp[nPages].pfnDlgProc = FreeLdrPageWndProc;
|
|
psp[nPages].lParam = (LPARAM)lpszLoaderIniFile;
|
|
++nPages;
|
|
|
|
BackupIniFile(lpszLoaderIniFile);
|
|
}
|
|
}
|
|
|
|
/* Services page */
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SERVICES_PAGE);
|
|
psp[nPages].pfnDlgProc = ServicesPageWndProc;
|
|
++nPages;
|
|
|
|
#if 0
|
|
/* Startup page */
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_STARTUP_PAGE);
|
|
psp[nPages].pfnDlgProc = StartupPageWndProc;
|
|
++nPages;
|
|
#endif
|
|
|
|
/* Tools page */
|
|
psp[nPages].dwSize = sizeof(PROPSHEETPAGEW);
|
|
psp[nPages].dwFlags = PSP_HASHELP;
|
|
psp[nPages].hInstance = hInstance;
|
|
psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_TOOLS_PAGE);
|
|
psp[nPages].pfnDlgProc = ToolsPageWndProc;
|
|
++nPages;
|
|
|
|
/* Set the total number of created pages */
|
|
psh.nPages = nPages;
|
|
|
|
/* Create the property sheet */
|
|
hPropSheet = (HWND)PropertySheetW(&psh);
|
|
if (hPropSheet)
|
|
{
|
|
/* Center the property sheet on the desktop and show it */
|
|
ClipOrCenterWindowToMonitor(hPropSheet, MONITOR_WORKAREA | MONITOR_CENTER);
|
|
ShowWindow(hPropSheet, SW_SHOWNORMAL);
|
|
}
|
|
|
|
return hPropSheet;
|
|
}
|
|
|
|
BOOL Initialize(HINSTANCE hInstance)
|
|
{
|
|
BOOL Success = TRUE;
|
|
LPWSTR lpszVistaAppName = NULL;
|
|
HANDLE hSemaphore;
|
|
INITCOMMONCONTROLSEX InitControls;
|
|
|
|
/* Initialize our global version flags */
|
|
bIsWindows = IsWindowsOS();
|
|
bIsPreVistaOSVersion = IsPreVistaOSVersion();
|
|
|
|
/* Initialize global strings */
|
|
szAppName = LoadResourceString(hInstance, IDS_MSCONFIG);
|
|
if (!bIsPreVistaOSVersion)
|
|
lpszVistaAppName = LoadResourceString(hInstance, IDS_MSCONFIG_2);
|
|
|
|
/* We use a semaphore in order to have a single-instance application */
|
|
hSemaphore = CreateSemaphoreW(NULL, 0, 1, L"MSConfigRunning");
|
|
if (!hSemaphore || GetLastError() == ERROR_ALREADY_EXISTS)
|
|
{
|
|
CloseHandle(hSemaphore);
|
|
|
|
/*
|
|
* A semaphore with the same name already exist. It should have been
|
|
* created by another instance of MSConfig. Try to find its window
|
|
* and bring it to front.
|
|
*/
|
|
if ( (hSingleWnd && IsWindow(hSingleWnd)) ||
|
|
( (hSingleWnd = FindWindowW(L"#32770", szAppName)) != NULL ) ||
|
|
(!bIsPreVistaOSVersion ? ( (hSingleWnd = FindWindowW(L"#32770", lpszVistaAppName)) != NULL ) : FALSE) )
|
|
{
|
|
/* Found it. Show the window. */
|
|
ShowWindow(hSingleWnd, SW_SHOWNORMAL);
|
|
SetForegroundWindow(hSingleWnd);
|
|
}
|
|
|
|
/* Quit this instance of MSConfig */
|
|
Success = FALSE;
|
|
}
|
|
if (!bIsPreVistaOSVersion) MemFree(lpszVistaAppName);
|
|
|
|
/* Quit now if we failed */
|
|
if (!Success)
|
|
{
|
|
MemFree(szAppName);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Initialize the common controls */
|
|
InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
InitControls.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS /* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/;
|
|
InitCommonControlsEx(&InitControls);
|
|
|
|
hInst = hInstance;
|
|
|
|
return Success;
|
|
}
|
|
|
|
VOID Cleanup(VOID)
|
|
{
|
|
MemFree(szAppName);
|
|
|
|
// // Close the sentry semaphore.
|
|
// CloseHandle(hSemaphore);
|
|
}
|
|
|
|
int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPTSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
HACCEL hAccelTable;
|
|
|
|
UNREFERENCED_PARAMETER(hPrevInstance);
|
|
UNREFERENCED_PARAMETER(lpCmdLine);
|
|
UNREFERENCED_PARAMETER(nCmdShow);
|
|
|
|
/*
|
|
* Initialize this instance of MSConfig. Quit if we have
|
|
* another instance already running.
|
|
*/
|
|
if (!Initialize(hInstance))
|
|
return -1;
|
|
|
|
// hInst = hInstance;
|
|
|
|
hMainWnd = CreatePropSheet(hInstance, NULL, szAppName);
|
|
if (!hMainWnd)
|
|
{
|
|
/* We failed, cleanup and bail out */
|
|
Cleanup();
|
|
return -1;
|
|
}
|
|
|
|
hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_MSCONFIG));
|
|
|
|
/* Message loop */
|
|
while (IsWindow(hMainWnd) && GetMessageW(&msg, NULL, 0, 0))
|
|
{
|
|
/*
|
|
* PropSheet_GetCurrentPageHwnd returns NULL when the user clicks the OK or Cancel button
|
|
* and after all of the pages have been notified. Apply button doesn't cause this to happen.
|
|
* We can then use the DestroyWindow function to destroy the property sheet.
|
|
*/
|
|
if (PropSheet_GetCurrentPageHwnd(hMainWnd) == NULL)
|
|
break;
|
|
|
|
/* Process the accelerator table */
|
|
if (!TranslateAcceleratorW(hMainWnd, hAccelTable, &msg))
|
|
{
|
|
/*
|
|
* If e.g. an item on the tree view is being edited,
|
|
* we cannot pass the event to PropSheet_IsDialogMessage.
|
|
* Doing so causes the property sheet to be closed at Enter press
|
|
* (instead of completing edit operation).
|
|
*/
|
|
if (/*g_bDisableDialogDispatch ||*/ !PropSheet_IsDialogMessage(hMainWnd, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessageW(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// FIXME: Process the results of MSConfig !!
|
|
|
|
/* Destroy the accelerator table and the window */
|
|
if (hAccelTable != NULL)
|
|
DestroyAcceleratorTable(hAccelTable);
|
|
|
|
DestroyWindow(hMainWnd);
|
|
|
|
/* Finish cleanup and return */
|
|
Cleanup();
|
|
return (int)msg.wParam;
|
|
}
|
|
|
|
/* EOF */
|