diff --git a/reactos/base/applications/mmc/console.c b/reactos/base/applications/mmc/console.c new file mode 100644 index 00000000000..f189a6c4165 --- /dev/null +++ b/reactos/base/applications/mmc/console.c @@ -0,0 +1,311 @@ +/* + * ReactOS Management Console + * Copyright (C) 2006 - 2007 Thomas Weidenmueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "precomp.h" + +static const TCHAR szMMCMainFrame[] = TEXT("MMCMainFrame"); +static const TCHAR szMMCChildFrm[] = TEXT("MMCChildFrm"); + +static LONG MainFrameWndCount = 0; +static ULONG NewConsoleCount = 0; + +static LPTSTR +CreateNewConsoleTitle(VOID) +{ + LPTSTR lpTitle; + + if (LoadAndFormatString(hAppInstance, + IDS_CONSOLETITLE, + &lpTitle, + ++NewConsoleCount) == 0) + { + lpTitle = NULL; + } + + return lpTitle; +} + +typedef struct _CONSOLE_MAINFRAME_WND +{ + HWND hwnd; + LPCTSTR lpConsoleTitle; + HMENU hMenuConsoleRoot; + union + { + DWORD Flags; + struct + { + DWORD AppAuthorMode : 1; + }; + }; +} CONSOLE_MAINFRAME_WND, *PCONSOLE_MAINFRAME_WND; + +static LRESULT CALLBACK +ConsoleMainFrameWndProc(IN HWND hwnd, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + PCONSOLE_MAINFRAME_WND Info; + LRESULT Ret = FALSE; + + Info = (PCONSOLE_MAINFRAME_WND)GetWindowLongPtr(hwnd, + 0); + + if (Info != NULL || uMsg == WM_NCCREATE) + { + switch (uMsg) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_FILE_EXIT: + PostMessage(hwnd, + WM_CLOSE, + 0, + 0); + break; + } + break; + } + + case WM_NCCREATE: + { + MainFrameWndCount++; + + Info = HeapAlloc(hAppHeap, + 0, + sizeof(*Info)); + if (Info != NULL) + { + ZeroMemory(Info, + sizeof(*Info)); + + Info->hwnd = hwnd; + + SetWindowLongPtr(hwnd, + 0, + (LONG_PTR)Info); + + Info->hMenuConsoleRoot = LoadMenu(hAppInstance, + MAKEINTRESOURCE(IDM_CONSOLEROOT)); + Ret = TRUE; + } + break; + } + + case WM_CREATE: + { + LPCTSTR lpFileName = (LPCTSTR)(((LPCREATESTRUCT)lParam)->lpCreateParams); + + if (lpFileName != NULL) + { + /* FIXME */ + } + else + { + Info->AppAuthorMode = TRUE; + Info->lpConsoleTitle = CreateNewConsoleTitle(); + } + + SetWindowText(Info->hwnd, + Info->lpConsoleTitle); + break; + } + + case WM_NCDESTROY: + SetMenu(Info->hwnd, + NULL); + + if (Info->hMenuConsoleRoot != NULL) + { + DestroyMenu(Info->hMenuConsoleRoot); + Info->hMenuConsoleRoot = NULL; + } + + HeapFree(hAppHeap, + 0, + Info); + + if (--MainFrameWndCount == 0) + PostQuitMessage(0); + break; + + + case WM_CLOSE: + DestroyWindow(hwnd); + break; + + default: + goto HandleDefaultMsg; + } + } + else + { +HandleDefaultMsg: + Ret = DefWindowProc(hwnd, + uMsg, + wParam, + lParam); + } + + return Ret; +} + +typedef struct _CONSOLE_CHILDFRM_WND +{ + HWND hwnd; + PCONSOLE_MAINFRAME_WND MainFrame; +} CONSOLE_CHILDFRM_WND, *PCONSOLE_CHILDFRM_WND; + +static LRESULT CALLBACK +ConsoleChildFrmProc(IN HWND hwnd, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + PCONSOLE_CHILDFRM_WND Info; + LRESULT Ret = FALSE; + + Info = (PCONSOLE_CHILDFRM_WND)GetWindowLongPtr(hwnd, + 0); + + if (Info != NULL || uMsg == WM_NCCREATE) + { + switch (uMsg) + { + case WM_NCCREATE: + Info = HeapAlloc(hAppHeap, + 0, + sizeof(*Info)); + if (Info != NULL) + { + ZeroMemory(Info, + sizeof(*Info)); + + Info->hwnd = hwnd; + + SetWindowLongPtr(hwnd, + 0, + (LONG_PTR)Info); + + Ret = TRUE; + } + break; + + + case WM_NCDESTROY: + HeapFree(hAppHeap, + 0, + Info); + break; + + default: + goto HandleDefaultMsg; + } + } + else + { +HandleDefaultMsg: + Ret = DefWindowProc(hwnd, + uMsg, + wParam, + lParam); + } + + return Ret; + +} + +BOOL +RegisterMMCWndClasses(VOID) +{ + WNDCLASS wc; + BOOL Ret; + + /* Register the MMCMainFrame window class */ + wc.style = 0; + wc.lpfnWndProc = ConsoleMainFrameWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(PCONSOLE_MAINFRAME_WND); + wc.hInstance = hAppInstance; + wc.hIcon = LoadIcon(hAppInstance, + MAKEINTRESOURCE(IDI_MAINAPP)); + wc.hCursor = LoadCursor(NULL, + MAKEINTRESOURCE(IDC_ARROW)); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szMMCMainFrame; + + Ret = (RegisterClass(&wc) != (ATOM)0); + if (Ret) + { + /* Register the MMCChildFrm window class */ + wc.lpfnWndProc = ConsoleChildFrmProc; + wc.cbWndExtra = sizeof(PCONSOLE_CHILDFRM_WND); + wc.lpszClassName = szMMCChildFrm; + + Ret = (RegisterClass(&wc) != (ATOM)0); + if (!Ret) + { + UnregisterClass(szMMCMainFrame, + hAppInstance); + } + } + + return Ret; +} + +VOID +UnregisterMMCWndClasses(VOID) +{ + UnregisterClass(szMMCChildFrm, + hAppInstance); + UnregisterClass(szMMCMainFrame, + hAppInstance); +} + +HWND +CreateConsoleWindow(IN LPCTSTR lpFileName OPTIONAL) +{ + HWND hWndConsole; + LONG_PTR FileName = (LONG_PTR)lpFileName; + + hWndConsole = CreateWindowEx(WS_EX_WINDOWEDGE, + szMMCMainFrame, + NULL, + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hAppInstance, + (PVOID)FileName); + + if (hWndConsole != NULL) + { + ShowWindow(hWndConsole, + SW_SHOWDEFAULT); + } + + return hWndConsole; +} diff --git a/reactos/base/applications/mmc/lang/en-US.rc b/reactos/base/applications/mmc/lang/en-US.rc new file mode 100644 index 00000000000..3d0052fd31a --- /dev/null +++ b/reactos/base/applications/mmc/lang/en-US.rc @@ -0,0 +1,21 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +IDM_CONSOLEROOT MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", ID_FILE_EXIT + END + + POPUP "&Help" + BEGIN + MENUITEM "&About ReactOS Management Console...", ID_HELP_ABOUT + END +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPTITLE "ReactOS Management Console" + IDS_CONSOLETITLE "Console%1!u!" +END diff --git a/reactos/base/applications/mmc/manifest.xml b/reactos/base/applications/mmc/manifest.xml new file mode 100644 index 00000000000..d19e587942d --- /dev/null +++ b/reactos/base/applications/mmc/manifest.xml @@ -0,0 +1,24 @@ + + + + ReactOS System Management Console + + + + + + + + diff --git a/reactos/base/applications/mmc/misc.c b/reactos/base/applications/mmc/misc.c new file mode 100644 index 00000000000..82ed116cf63 --- /dev/null +++ b/reactos/base/applications/mmc/misc.c @@ -0,0 +1,115 @@ +/* + * ReactOS Management Console + * Copyright (C) 2006 - 2007 Thomas Weidenmueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "precomp.h" + +INT +LengthOfStrResource(IN HINSTANCE hInst, + IN UINT uID) +{ + HRSRC hrSrc; + HGLOBAL hRes; + LPWSTR lpName, lpStr; + + if (hInst == NULL) + { + return -1; + } + + /* There are always blocks of 16 strings */ + lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); + + /* Find the string table block */ + if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && + (hRes = LoadResource(hInst, hrSrc)) && + (lpStr = LockResource(hRes))) + { + UINT x; + + /* Find the string we're looking for */ + uID &= 0xF; /* position in the block, same as % 16 */ + for (x = 0; x < uID; x++) + { + lpStr += (*lpStr) + 1; + } + + /* Found the string */ + return (int)(*lpStr); + } + return -1; +} + + +static INT +AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID) +{ + INT ln; + + ln = LengthOfStrResource(hInst, + uID); + if (ln++ > 0) + { + (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, + ln * sizeof(TCHAR)); + if ((*lpTarget) != NULL) + { + INT Ret; + if (!(Ret = LoadString(hInst, uID, *lpTarget, ln))) + { + LocalFree((HLOCAL)(*lpTarget)); + } + return Ret; + } + } + return 0; +} + +DWORD +LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...) +{ + DWORD Ret = 0; + LPWSTR lpFormat; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) != 0) + { + va_start(lArgs, lpTarget); + /* let's use FormatMessage to format it because it has the ability to allocate + memory automatically */ + Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, + lpFormat, + 0, + 0, + (LPTSTR)lpTarget, + 0, + &lArgs); + va_end(lArgs); + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} diff --git a/reactos/base/applications/mmc/mmc.c b/reactos/base/applications/mmc/mmc.c new file mode 100644 index 00000000000..fadffa92c6c --- /dev/null +++ b/reactos/base/applications/mmc/mmc.c @@ -0,0 +1,65 @@ +/* + * ReactOS Management Console + * Copyright (C) 2006 - 2007 Thomas Weidenmueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "precomp.h" + +HINSTANCE hAppInstance; +HANDLE hAppHeap; + +int +_tmain(IN int argc, + IN const TCHAR *argv[]) +{ + HWND hMainConsole; + MSG Msg; + BOOL bRet; + + hAppInstance = GetModuleHandle(NULL); + hAppHeap = GetProcessHeap(); + + InitCommonControls(); + + if (!RegisterMMCWndClasses()) + { + /* FIXME - Display error */ + return 1; + } + + hMainConsole = CreateConsoleWindow(argc > 1 ? argv[1] : NULL); + if (hMainConsole != NULL) + { + for (;;) + { + bRet = GetMessage(&Msg, + NULL, + 0, + 0); + if (bRet != 0 && bRet != -1) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + else if (bRet == 0) + break; + } + } + + UnregisterMMCWndClasses(); + return 0; +} diff --git a/reactos/base/applications/mmc/mmc.rbuild b/reactos/base/applications/mmc/mmc.rbuild new file mode 100644 index 00000000000..8c71e01cff5 --- /dev/null +++ b/reactos/base/applications/mmc/mmc.rbuild @@ -0,0 +1,21 @@ + + + + . + + 0x0600 + 0x0501 + kernel32 + user32 + gdi32 + comdlg32 + advapi32 + shell32 + comctl32 + console.c + misc.c + mmc.c + mmc.rc + precomp.h + + \ No newline at end of file diff --git a/reactos/base/applications/mmc/mmc.rc b/reactos/base/applications/mmc/mmc.rc new file mode 100644 index 00000000000..d1f7931ca7d --- /dev/null +++ b/reactos/base/applications/mmc/mmc.rc @@ -0,0 +1,17 @@ +/* $Id: sndvol32.rc 23239 2006-07-23 09:59:30Z janderwald $ */ + +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Management Console\0" +#define REACTOS_STR_INTERNAL_NAME "mmc\0" +#define REACTOS_STR_ORIGINAL_FILENAME "mmc.exe\0" +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +1 24 DISCARDABLE "manifest.xml" + +IDI_MAINAPP ICON DISCARDABLE resources/mmc.ico + +#include "lang/en-US.rc" diff --git a/reactos/base/applications/mmc/precomp.h b/reactos/base/applications/mmc/precomp.h new file mode 100644 index 00000000000..460b8aef130 --- /dev/null +++ b/reactos/base/applications/mmc/precomp.h @@ -0,0 +1,38 @@ +#ifndef __PRECOMP_H +#define __PRECOMP_H + +#include +#include +#include +#include +#include "resource.h" + +/* console.c */ + +BOOL +RegisterMMCWndClasses(VOID); + +VOID +UnregisterMMCWndClasses(VOID); + +HWND +CreateConsoleWindow(IN LPCTSTR lpFileName OPTIONAL); + +/* misc.c */ + +INT +LengthOfStrResource(IN HINSTANCE hInst, + IN UINT uID); + +DWORD +LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...); + +/* mmc.c */ + +extern HINSTANCE hAppInstance; +extern HANDLE hAppHeap; + +#endif /* __PRECOMP_H */ diff --git a/reactos/base/applications/mmc/resource.h b/reactos/base/applications/mmc/resource.h new file mode 100644 index 00000000000..37f42f5af71 --- /dev/null +++ b/reactos/base/applications/mmc/resource.h @@ -0,0 +1,14 @@ +#ifndef __RESOURCE_H +#define __RESOURCE_H + +#define IDS_APPTITLE 101 +#define IDS_CONSOLETITLE 102 + +#define IDI_MAINAPP 101 + +#define IDM_CONSOLEROOT 101 + +#define ID_FILE_EXIT 1001 +#define ID_HELP_ABOUT 9001 + +#endif /* __RESOURCE_H */ diff --git a/reactos/base/applications/mmc/resources/mmc.ico b/reactos/base/applications/mmc/resources/mmc.ico new file mode 100644 index 00000000000..e95d3607365 Binary files /dev/null and b/reactos/base/applications/mmc/resources/mmc.ico differ