reactos/base/applications/msconfig_new/msconfig.c

479 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 */