diff --git a/reactos/base/applications/devmgmt/En.rc b/reactos/base/applications/devmgmt/En.rc new file mode 100644 index 00000000000..aee0a8fd9d7 --- /dev/null +++ b/reactos/base/applications/devmgmt/En.rc @@ -0,0 +1,72 @@ +IDR_MAINMENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDC_EXIT + END + POPUP "Action" + BEGIN + MENUITEM "Print", IDC_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Properties...", IDC_PROP + MENUITEM SEPARATOR + MENUITEM "Help", IDC_PROGHELP, GRAYED + END + POPUP "Help" + BEGIN + MENUITEM "Help", IDC_PROGHELP + MENUITEM "About", IDC_ABOUT + END +END + +IDR_POPUP MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "Properties...", IDC_PROP, GRAYED + MENUITEM SEPARATOR + MENUITEM "Help", IDC_PROGHELP + END +END + +IDD_ABOUTBOX DIALOGEX 22,16,190,182 +CAPTION "About Device Manager" +FONT 8,"Tahoma",0,0 +STYLE WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +BEGIN + LTEXT "Device Manager v0.1\nCopyright (C) 2006\nby Ged Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 130, 26 + PUSHBUTTON "Close", IDOK, 75, 162, 44, 15 + ICON IDI_MAIN_ICON, IDC_STATIC, 10, 10, 7, 30 + EDITTEXT IDC_LICENSE_EDIT, 8, 44, 174, 107, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_PROP "Properties" + IDS_TOOLTIP_REFRESH "Refresh" + IDS_TOOLTIP_HELP "Help" + IDS_TOOLTIP_EXIT "Exit" +END + +/* Hints */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_HINT_BLANK " " + IDS_HINT_EXIT " Exits the program." + IDS_HINT_REFRESH " Refresh the service list." + IDS_HINT_PROP " Open property sheet for the current selection." + IDS_HINT_HELP " Display help window." + IDS_HINT_ABOUT " About ReactOS Device Manager." + + IDS_HINT_SYS_RESTORE " Restores this window to normal size." + IDS_HINT_SYS_MOVE " Moves this window." + IDS_HINT_SYS_SIZE " Resizes this window." + IDS_HINT_SYS_MINIMIZE " Collapses this window to an icon." + IDS_HINT_SYS_MAXIMIZE " Expands this window to fill this screen." + IDS_HINT_SYS_CLOSE " Closes this window." +END diff --git a/reactos/base/applications/devmgmt/about.c b/reactos/base/applications/devmgmt/about.c new file mode 100644 index 00000000000..b7766d2efb5 --- /dev/null +++ b/reactos/base/applications/devmgmt/about.c @@ -0,0 +1,62 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/about.c + * PURPOSE: About dialog box message handler + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +BOOL CALLBACK +AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND hLicenseEditWnd; + HICON hIcon = NULL; + TCHAR strLicense[700]; + + switch (message) + { + case WM_INITDIALOG: + + hIcon = LoadImage(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON), + IMAGE_ICON, + 16, + 16, + 0); + + SendMessage(hDlg, + WM_SETICON, + ICON_SMALL, + (LPARAM)hIcon); + + hLicenseEditWnd = GetDlgItem(hDlg, + IDC_LICENSE_EDIT); + + LoadString(hInstance, + IDS_LICENSE, + strLicense, + sizeof(strLicense) / sizeof(TCHAR)); + + SetWindowText(hLicenseEditWnd, + strLicense); + + return TRUE; + + case WM_COMMAND: + + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + DestroyIcon(hIcon); + EndDialog(hDlg, + LOWORD(wParam)); + return TRUE; + } + + break; + } + + return FALSE; +} diff --git a/reactos/base/applications/devmgmt/devmgmt.c b/reactos/base/applications/devmgmt/devmgmt.c new file mode 100644 index 00000000000..afb233b6176 --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.c @@ -0,0 +1,67 @@ +/* + * PROJECT: ReactOS Device Managment + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/devmgmt.c + * PURPOSE: Program HQ + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +HINSTANCE hInstance; +HANDLE ProcessHeap; + +int WINAPI +WinMain(HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + LPTSTR lpAppName; + HWND hMainWnd; + MSG Msg; + int Ret = 1; + INITCOMMONCONTROLSEX icex; + + hInstance = hThisInstance; + ProcessHeap = GetProcessHeap(); + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&icex); + + if (!AllocAndLoadString(&lpAppName, + hInstance, + IDS_APPNAME)) + { + return 1; + } + + if (InitMainWindowImpl()) + { + hMainWnd = CreateMainWindow(lpAppName, + nCmdShow); + if (hMainWnd != NULL) + { + /* pump the message queue */ + while( GetMessage( &Msg, NULL, 0, 0 ) ) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + + } + + Ret = 0; + } + + UninitMainWindowImpl(); + } + + LocalFree((HLOCAL)lpAppName); + + return Ret; +} + + + diff --git a/reactos/base/applications/devmgmt/devmgmt.rbuild b/reactos/base/applications/devmgmt/devmgmt.rbuild new file mode 100644 index 00000000000..8448678cf78 --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.rbuild @@ -0,0 +1,28 @@ + + + + . + + + + + 0x600 + 0x501 + ntdll + setupapi + gdi32 + kernel32 + user32 + comctl32 + advapi32 + + about.c + devmgmt.c + enumdevices.c + mainwnd.c + misc.c + + devmgmt.rc + precomp.h + + diff --git a/reactos/base/applications/devmgmt/devmgmt.rc b/reactos/base/applications/devmgmt/devmgmt.rc new file mode 100644 index 00000000000..79667eed93c --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.rc @@ -0,0 +1,29 @@ +#include +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Device Manager\0" +#define REACTOS_STR_INTERNAL_NAME "devmgmt\0" +#define REACTOS_STR_ORIGINAL_FILENAME "devmgmt.exe\0" +//#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +//1 24 DISCARDABLE "manifest.xml" + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPNAME "ReactOS Device Manager" +END + +IDI_MAIN_ICON ICON "res/computer.ico" +IDB_ROOT_IMAGE BITMAP "res/root.bmp" + +/* main toolbar icons */ +IDB_PROP BITMAP DISCARDABLE "res/properties.bmp" +IDB_REFRESH BITMAP DISCARDABLE "res/refresh.bmp" +IDB_HELP BITMAP DISCARDABLE "res/help.bmp" +IDB_EXIT BITMAP DISCARDABLE "res/exit.bmp" + + +#include "En.rc" diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c new file mode 100644 index 00000000000..e48d5a25480 --- /dev/null +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -0,0 +1,356 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/enumdevices.c + * PURPOSE: Enumerates all devices on the local machine + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +SP_CLASSIMAGELIST_DATA ImageListData; + + +static HTREEITEM +InsertIntoTreeView(HWND hTV, + HTREEITEM hRoot, + LPTSTR lpLabel, + INT DevImage) +{ + TV_ITEM tvi; + TV_INSERTSTRUCT tvins; + + ZeroMemory(&tvi, sizeof(tvi)); + ZeroMemory(&tvins, sizeof(tvins)); + + tvi.mask = TVIF_TEXT | TVIF_IMAGE; + tvi.pszText = lpLabel; + tvi.cchTextMax = lstrlen(lpLabel); + tvi.iImage = DevImage; + tvi.iSelectedImage = DevImage; + + tvins.item = tvi; + tvins.hInsertAfter = hRoot; + + return TreeView_InsertItem(hTV, &tvins); +} + + +static INT +EnumDeviceClasses(INT ClassIndex, + TCHAR *DeviceClassName, + TCHAR *DeviceClassDesc, + BOOL *DevicePresent, + INT *ClassImage) +{ + GUID ClassGuid; + HKEY KeyClass; + HDEVINFO hDevInfo; + TCHAR ClassName[MAX_CLASS_NAME_LEN]; + DWORD RequiredSize = MAX_CLASS_NAME_LEN; + UINT Ret; + + *DevicePresent = FALSE; + + Ret = CM_Enumerate_Classes(ClassIndex, + &ClassGuid, + 0); + if (Ret != CR_SUCCESS) + { + /* all classes enumerated */ + if(Ret == CR_NO_SUCH_VALUE) + return -1; + + if (Ret == CR_INVALID_DATA) + ; /*FIXME: what should we do here? */ + + /* handle other errors... */ + } + + if (SetupDiClassNameFromGuid(&ClassGuid, + ClassName, + RequiredSize, + &RequiredSize)) + { + lstrcpy(DeviceClassName, ClassName); + } + else + { + *DeviceClassName = _T('\0'); + } + + if (!SetupDiGetClassImageIndex(&ImageListData, + &ClassGuid, + ClassImage)) + { + /* set the blank icon */ + *ClassImage = 41; + } + + /* FIXME: why are we calling this here? */ + hDevInfo = SetupDiGetClassDevs(&ClassGuid, + 0, + NULL, + DIGCF_PRESENT); + if (hDevInfo == INVALID_HANDLE_VALUE) + return -2; + + KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, + MAXIMUM_ALLOWED, + DIOCR_INSTALLER, + NULL, + 0); + if (KeyClass != INVALID_HANDLE_VALUE) + { + DWORD dwSize = MAX_CLASS_NAME_LEN; + + if (RegQueryValue(KeyClass, + NULL, + DeviceClassDesc, + &dwSize) != ERROR_SUCCESS) + { + *DeviceClassDesc = _T('\0'); + } + } + else + { + return -3; + } + + /* FIXME: Can we call this earlier, or see above? */ + SetupDiDestroyDeviceInfoList(hDevInfo); + + *DevicePresent = TRUE; + + RegCloseKey(KeyClass); + + return 0; +} + + +static INT +EnumDevices(INT index, + TCHAR* DeviceClassName, + TCHAR* DeviceName) +{ + HDEVINFO hDevInfo; + SP_DEVINFO_DATA DeviceInfoData; + DWORD RequiredSize = 0; + GUID *guids = NULL; + BOOL bRet; + + *DeviceName = _T('\0'); + + bRet = SetupDiClassGuidsFromName(DeviceClassName, + NULL, + RequiredSize, + &RequiredSize); + if (RequiredSize == 0) + return -2; + + if (!bRet) + { + guids = HeapAlloc(GetProcessHeap(), 0, RequiredSize); + if (guids == NULL) + return -1; + + bRet = SetupDiClassGuidsFromName(DeviceClassName, + guids, + RequiredSize, + &RequiredSize); + + if (!bRet || RequiredSize == 0) + { + /* incorrect class name */ + HeapFree(GetProcessHeap(), 0, guids); + return -3; + } + } + + /* get device info set for our device class */ + hDevInfo = SetupDiGetClassDevs(guids, + 0, + NULL, + DIGCF_PRESENT); + + HeapFree(GetProcessHeap(), 0, guids); + if(hDevInfo == INVALID_HANDLE_VALUE) + { + if(!bRet) + { + /* device info is unavailable */ + return -4; + } + } + + ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + bRet = SetupDiEnumDeviceInfo(hDevInfo, + index, + &DeviceInfoData); + + if (!bRet) + { + //no such device: + SetupDiDestroyDeviceInfoList(hDevInfo); + return -1; + } + + /* get the device's friendly name */ + if (!SetupDiGetDeviceRegistryProperty(hDevInfo, + &DeviceInfoData, + SPDRP_FRIENDLYNAME, + 0, + (BYTE*)DeviceName, + MAX_DEV_LEN, + NULL)) + { + /* if the friendly name fails, try the description instead */ + bRet = SetupDiGetDeviceRegistryProperty(hDevInfo, + &DeviceInfoData, + SPDRP_DEVICEDESC, + 0, + (BYTE*)DeviceName, + MAX_DEV_LEN, + NULL); + if (!bRet) + { + /* if the description fails, just give up! */ + SetupDiDestroyDeviceInfoList(hDevInfo); + return -5; + } + } + + return 0; +} + + +VOID +ListDevicesByType(PMAIN_WND_INFO Info, + HTREEITEM hRoot) +{ + HTREEITEM hDevItem; + TCHAR DevName[MAX_DEV_LEN]; + TCHAR DevDesc[MAX_DEV_LEN]; + BOOL DevExist = FALSE; + INT ClassRet; + INT index = 0; + INT DevImage; + + do + { + ClassRet = EnumDeviceClasses(index, + DevName, + DevDesc, + &DevExist, + &DevImage); + + if ((ClassRet != -1) && (DevExist)) + { + TCHAR DeviceName[MAX_DEV_LEN]; + INT Ret, DevIndex = 0; + + if (DevDesc[0] != _T('\0')) + { + hDevItem = InsertIntoTreeView(Info->hTreeView, + hRoot, + DevDesc, + DevImage); + } + else + { + hDevItem = InsertIntoTreeView(Info->hTreeView, + hRoot, + DevName, + DevImage); + } + + do + { + Ret = EnumDevices(DevIndex, + DevName, + DeviceName); + if (Ret == 0) + { + InsertIntoTreeView(Info->hTreeView, + hDevItem, + DeviceName, + DevImage); + } + + DevIndex++; + + } while (Ret != -1); + + if (!TreeView_GetChild(Info->hTreeView, + hDevItem)) + { + TreeView_DeleteItem(Info->hTreeView, + hDevItem); + } + else + { + TreeView_SortChildren(Info->hTreeView, + hDevItem, + 0); + } + } + + index++; + + } while (ClassRet != -1); + + TreeView_Expand(Info->hTreeView, + hRoot, + TVE_EXPAND); + + TreeView_SortChildren(Info->hTreeView, + hRoot, + 0); +} + + +HTREEITEM +InitTreeView(PMAIN_WND_INFO Info) +{ + HTREEITEM hRoot; + HBITMAP hComp; + TCHAR ComputerName[MAX_PATH]; + DWORD dwSize = MAX_PATH; + INT RootImage; + //COLORREF Mask = RGB(255, 0, 128); + + TreeView_DeleteAllItems(Info->hTreeView); + + /* get the device image List */ + ImageListData.cbSize = sizeof(ImageListData); + SetupDiGetClassImageList(&ImageListData); + + hComp = LoadBitmap(hInstance, + MAKEINTRESOURCE(IDB_ROOT_IMAGE)); + + ImageList_Add(ImageListData.ImageList, + hComp, + NULL); + + TreeView_SetImageList(Info->hTreeView, + &ImageListData.ImageList, + TVSIL_NORMAL); + + if (!GetComputerName(ComputerName, + &dwSize)) + { + ComputerName[0] = _T('\0'); + } + + RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; + + hRoot = InsertIntoTreeView(Info->hTreeView, + NULL, + ComputerName, + RootImage); + + return hRoot; +} diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c new file mode 100644 index 00000000000..a62540c95f4 --- /dev/null +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -0,0 +1,590 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/mainwnd.c + * PURPOSE: Main window message handler + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +static const TCHAR szMainWndClass[] = TEXT("DevMgmtWndClass"); + +/* Toolbar buttons */ +TBBUTTON Buttons [] = +{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ + {TBICON_PROP, IDC_PROP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* properties */ + {TBICON_REFRESH, IDC_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */ + + /* Note: First item for a seperator is its width in pixels */ + {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ + + {TBICON_HELP, IDC_PROGHELP,TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* help */ + {TBICON_EXIT, IDC_EXIT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* exit */ + +}; + + +/* menu hints */ +static const MENU_HINT MainMenuHintTable[] = { + /* File Menu */ + {IDC_EXIT, IDS_HINT_EXIT}, + + /* Action Menu */ + {IDC_REFRESH, IDS_HINT_REFRESH}, + {IDC_PROP, IDS_HINT_PROP}, + + /* Help Menu */ + {IDC_PROGHELP, IDS_HINT_HELP}, + {IDC_ABOUT, IDS_HINT_ABOUT} +}; +/* system menu hints */ +static const MENU_HINT SystemMenuHintTable[] = { + {SC_RESTORE, IDS_HINT_SYS_RESTORE}, + {SC_MOVE, IDS_HINT_SYS_MOVE}, + {SC_SIZE, IDS_HINT_SYS_SIZE}, + {SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE}, + {SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE}, + {SC_CLOSE, IDS_HINT_SYS_CLOSE}, +}; + + +static BOOL +MainWndMenuHint(PMAIN_WND_INFO Info, + WORD CmdId, + const MENU_HINT *HintArray, + DWORD HintsCount, + UINT DefHintId) +{ + BOOL Found = FALSE; + const MENU_HINT *LastHint; + UINT HintId = DefHintId; + + LastHint = HintArray + HintsCount; + while (HintArray != LastHint) + { + if (HintArray->CmdId == CmdId) + { + HintId = HintArray->HintId; + Found = TRUE; + break; + } + HintArray++; + } + + StatusBarLoadString(Info->hStatus, + SB_SIMPLEID, + hInstance, + HintId); + + return Found; +} + + +static VOID +UpdateMainStatusBar(PMAIN_WND_INFO Info) +{ + if (Info->hStatus != NULL) + { + SendMessage(Info->hStatus, + SB_SIMPLE, + (WPARAM)Info->InMenuLoop, + 0); + } +} + + +static BOOL +CreateToolbar(PMAIN_WND_INFO Info) +{ + INT NumButtons = sizeof(Buttons) / sizeof(Buttons[0]); + + Info->hTool = CreateWindowEx(0, + TOOLBARCLASSNAME, + NULL, + WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU)IDC_TOOLBAR, + hInstance, + NULL); + if(Info->hTool != NULL) + { + HIMAGELIST hImageList; + + SendMessage(Info->hTool, + TB_SETEXTENDEDSTYLE, + 0, + TBSTYLE_EX_HIDECLIPPEDBUTTONS); + + SendMessage(Info->hTool, + TB_BUTTONSTRUCTSIZE, + sizeof(Buttons[0]), + 0); + + hImageList = InitImageList(IDB_PROP, + IDB_EXIT, + 16, + 16); + if (hImageList == NULL) + return FALSE; + + ImageList_Destroy((HIMAGELIST)SendMessage(Info->hTool, + TB_SETIMAGELIST, + 0, + (LPARAM)hImageList)); + + SendMessage(Info->hTool, + TB_ADDBUTTONS, + NumButtons, + (LPARAM)Buttons); + + return TRUE; + } + + return FALSE; +} + + +static BOOL +CreateTreeView(PMAIN_WND_INFO Info) +{ + Info->hTreeView = CreateWindowEx(0, + WC_TREEVIEW, + NULL, + WS_CHILD | WS_VISIBLE | WS_BORDER | + TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU) IDC_TREEVIEW, + hInstance, + NULL); + if (Info->hTreeView == NULL) + { + DisplayString(_T("Could not create TreeView.")); + return FALSE; + } + + return TRUE; +} + +static BOOL +CreateStatusBar(PMAIN_WND_INFO Info) +{ + INT StatWidths[] = {110, -1}; /* widths of status bar */ + + Info->hStatus = CreateWindowEx(0, + STATUSCLASSNAME, + NULL, + WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU)IDC_STATUSBAR, + hInstance, + NULL); + if(Info->hStatus == NULL) + return FALSE; + + + SendMessage(Info->hStatus, + SB_SETPARTS, + sizeof(StatWidths) / sizeof(INT), + (LPARAM)StatWidths); + + return TRUE; +} + + + +static VOID +InitMainWnd(PMAIN_WND_INFO Info) +{ + HTREEITEM hRoot; + + if (!CreateToolbar(Info)) + DisplayString(_T("error creating toolbar")); + + if (!CreateTreeView(Info)) + { + DisplayString(_T("error creating list view")); + return; + } + + if (!CreateStatusBar(Info)) + DisplayString(_T("error creating status bar")); + + /* Create Popup Menu */ + Info->hShortcutMenu = LoadMenu(hInstance, + MAKEINTRESOURCE(IDR_POPUP)); + Info->hShortcutMenu = GetSubMenu(Info->hShortcutMenu, + 0); + + hRoot = InitTreeView(Info); + if (hRoot) + ListDevicesByType(Info, hRoot); +} + + +static VOID +MainWndCommand(PMAIN_WND_INFO Info, + WORD CmdId, + HWND hControl) +{ + UNREFERENCED_PARAMETER(hControl); + + switch (CmdId) + { + case IDC_PROP: + { + // call builtin driver prop sheet + } + break; + + case IDC_REFRESH: + { + // refresh treeview + } + break; + + case IDC_PROGHELP: + DisplayString(_T("Help is not yet implemented\n")); + SetFocus(Info->hTreeView); + break; + + case IDC_EXIT: + PostMessage(Info->hMainWnd, + WM_CLOSE, + 0, + 0); + break; + + case IDC_ABOUT: + DialogBox(hInstance, + MAKEINTRESOURCE(IDD_ABOUTBOX), + Info->hMainWnd, + (DLGPROC)AboutDialogProc); + SetFocus(Info->hTreeView); + break; + + } +} + + +static VOID CALLBACK +MainWndResize(PMAIN_WND_INFO Info, + WORD cx, + WORD cy) +{ + RECT rcClient, rcTool, rcStatus; + int lvHeight, iToolHeight, iStatusHeight; + + /* Size toolbar and get height */ + SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0); + GetWindowRect(Info->hTool, &rcTool); + iToolHeight = rcTool.bottom - rcTool.top; + + /* Size status bar and get height */ + SendMessage(Info->hStatus, WM_SIZE, 0, 0); + GetWindowRect(Info->hStatus, &rcStatus); + iStatusHeight = rcStatus.bottom - rcStatus.top; + + /* Calculate remaining height and size list view */ + GetClientRect(Info->hMainWnd, &rcClient); + lvHeight = rcClient.bottom - iToolHeight - iStatusHeight; + SetWindowPos(Info->hTreeView, + NULL, + 0, + iToolHeight, + rcClient.right, + lvHeight, + SWP_NOZORDER); +} + + +static LRESULT CALLBACK +MainWndProc(HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + PMAIN_WND_INFO Info; + LRESULT Ret = 0; + + /* Get the window context */ + Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd, + GWLP_USERDATA); + if (Info == NULL && msg != WM_CREATE) + { + goto HandleDefaultMessage; + } + + switch(msg) + { + case WM_CREATE: + { + Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams); + + /* Initialize the main window context */ + Info->hMainWnd = hwnd; + + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + (LONG_PTR)Info); + + InitMainWnd(Info); + + /* Show the window */ + ShowWindow(hwnd, + Info->nCmdShow); + + } + break; + + case WM_SIZE: + { + MainWndResize(Info, + LOWORD(lParam), + HIWORD(lParam)); + } + break; + + case WM_NOTIFY: + { + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case NM_DBLCLK: + { + POINT pt; + RECT rect; + + GetCursorPos(&pt); + GetWindowRect(Info->hTreeView, &rect); + + if (PtInRect(&rect, pt)) + { + SendMessage(hwnd, + WM_COMMAND, + //ID_PROP, + MAKEWPARAM((WORD)IDC_PROP, (WORD)0), + 0); + } + + //OpenPropSheet(Info); + } + break; + + case TTN_GETDISPINFO: + { + LPTOOLTIPTEXT lpttt; + UINT idButton; + + lpttt = (LPTOOLTIPTEXT)lParam; + + /* Specify the resource identifier of the descriptive + * text for the given button. */ + idButton = (UINT)lpttt->hdr.idFrom; + switch (idButton) + { + case IDC_PROP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); + break; + + case IDC_REFRESH: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); + break; + + case IDC_PROGHELP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP); + break; + + case IDC_EXIT: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT); + break; + + } + } + break; + } + } + break; + + case WM_CONTEXTMENU: + { + POINT pt; + RECT lvRect; + + INT xPos = GET_X_LPARAM(lParam); + INT yPos = GET_Y_LPARAM(lParam); + + GetCursorPos(&pt); + + /* display popup when cursor is in the list view */ + GetWindowRect(Info->hTreeView, &lvRect); + if (PtInRect(&lvRect, pt)) + { + TrackPopupMenuEx(Info->hShortcutMenu, + TPM_RIGHTBUTTON, + xPos, + yPos, + Info->hMainWnd, + NULL); + } + } + break; + + case WM_COMMAND: + { + MainWndCommand(Info, + LOWORD(wParam), + (HWND)lParam); + goto HandleDefaultMessage; + } + + case WM_MENUSELECT: + { + if (Info->hStatus != NULL) + { + if (!MainWndMenuHint(Info, + LOWORD(wParam), + MainMenuHintTable, + sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]), + IDS_HINT_BLANK)) + { + MainWndMenuHint(Info, + LOWORD(wParam), + SystemMenuHintTable, + sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]), + IDS_HINT_BLANK); + } + } + } + break; + + case WM_ENTERMENULOOP: + { + Info->InMenuLoop = TRUE; + UpdateMainStatusBar(Info); + break; + } + + case WM_EXITMENULOOP: + { + Info->InMenuLoop = FALSE; + UpdateMainStatusBar(Info); + break; + } + + case WM_CLOSE: + { + DestroyMenu(Info->hShortcutMenu); + DestroyWindow(hwnd); + } + break; + + case WM_DESTROY: + { + //DestroyMainWnd(Info); + + HeapFree(ProcessHeap, + 0, + Info); + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + 0); + + /* Break the message queue loop */ + PostQuitMessage(0); + } + break; + + default: + { +HandleDefaultMessage: + + Ret = DefWindowProc(hwnd, + msg, + wParam, + lParam); + } + break; + } + return Ret; +} + + + +HWND +CreateMainWindow(LPCTSTR lpCaption, + int nCmdShow) +{ + PMAIN_WND_INFO Info; + HWND hMainWnd = NULL; + + Info = HeapAlloc(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(MAIN_WND_INFO)); + + if (Info != NULL) + { + Info->nCmdShow = nCmdShow; + + hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE, + szMainWndClass, + lpCaption, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + CW_USEDEFAULT, + CW_USEDEFAULT, + 650, + 450, + NULL, + NULL, + hInstance, + Info); + if (hMainWnd == NULL) + { + GetError(); + HeapFree(ProcessHeap, + 0, + Info); + } + } + + return hMainWnd; +} + +BOOL +InitMainWindowImpl(VOID) +{ + WNDCLASSEX wc = {0}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = MainWndProc; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON)); + wc.hCursor = LoadCursor(NULL, + IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = szMainWndClass; + wc.hIconSm = (HICON)LoadImage(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON), + IMAGE_ICON, + 16, + 16, + LR_SHARED); + + return RegisterClassEx(&wc) != (ATOM)0; +} + + +VOID +UninitMainWindowImpl(VOID) +{ + UnregisterClass(szMainWndClass, + hInstance); +} + diff --git a/reactos/base/applications/devmgmt/manifest.xml b/reactos/base/applications/devmgmt/manifest.xml new file mode 100644 index 00000000000..4df22534fca --- /dev/null +++ b/reactos/base/applications/devmgmt/manifest.xml @@ -0,0 +1,23 @@ + + + +ReactOS Service Manager + + + + + + diff --git a/reactos/base/applications/devmgmt/misc.c b/reactos/base/applications/devmgmt/misc.c new file mode 100644 index 00000000000..3a24fe720bd --- /dev/null +++ b/reactos/base/applications/devmgmt/misc.c @@ -0,0 +1,261 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/misc.c + * PURPOSE: miscallanous functions + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +static 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; +} + +INT +AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID) +{ + INT ln; + + ln = LengthOfStrResource(hInst, + uID); + if (ln++ > 0) + { + (*lpTarget) = (LPTSTR)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; + LPTSTR 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; +} + +BOOL +StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...) +{ + BOOL Ret = FALSE; + LPTSTR lpFormat, lpStr; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) > 0) + { + va_start(lArgs, uID); + /* 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)&lpStr, + 0, + &lArgs); + va_end(lArgs); + + if (lpStr != NULL) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} + +BOOL +StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID) +{ + BOOL Ret = FALSE; + LPTSTR lpStr; + + if (AllocAndLoadString(&lpStr, + hInstance, + uID) > 0) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + return Ret; +} + + +INT +GetTextFromEdit(OUT LPTSTR lpString, + IN HWND hDlg, + IN UINT Res) +{ + INT len = GetWindowTextLength(GetDlgItem(hDlg, Res)); + if(len > 0) + { + GetDlgItemText(hDlg, + Res, + lpString, + len + 1); + } + else + lpString = NULL; + + return len; +} + + +HIMAGELIST +InitImageList(UINT StartResource, + UINT EndResource, + UINT Width, + UINT Height) +{ + HBITMAP hBitmap; + HIMAGELIST hImageList; + UINT i; + INT Ret; + + /* Create the toolbar icon image list */ + hImageList = ImageList_Create(Width, + Height, + ILC_MASK | ILC_COLOR24, + EndResource - StartResource, + 0); + if (hImageList == NULL) + return NULL; + + /* Add all icons to the image list */ + for (i = StartResource; i <= EndResource; i++) + { + hBitmap = LoadImage(hInstance, + MAKEINTRESOURCE(i), + IMAGE_BITMAP, + Width, + Height, + LR_LOADTRANSPARENT); + if (hBitmap == NULL) + return NULL; + + Ret = ImageList_AddMasked(hImageList, + hBitmap, + RGB(255, 0, 128)); + if (Ret == -1) + return NULL; + + DeleteObject(hBitmap); + } + + return hImageList; +} + + +VOID GetError(VOID) +{ + LPVOID lpMsgBuf; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + MessageBox(NULL, lpMsgBuf, _T("Error!"), MB_OK | MB_ICONERROR); + + LocalFree(lpMsgBuf); +} + + +VOID DisplayString(PTCHAR Msg) +{ + MessageBox(NULL, Msg, _T("Note!"), MB_ICONEXCLAMATION|MB_OK); +} + diff --git a/reactos/base/applications/devmgmt/precomp.h b/reactos/base/applications/devmgmt/precomp.h new file mode 100644 index 00000000000..52c6c82c602 --- /dev/null +++ b/reactos/base/applications/devmgmt/precomp.h @@ -0,0 +1,102 @@ +#ifndef __DEVMGMT_PRECOMP_H +#define __DEVMGMT_PRECOMP_H + +//#define WIN32_LEAN_AND_MEAN +#include +#include /* GET_X/Y_LPARAM */ +#include +#include +#include +#include +#include +#include "resource.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4100) +#endif + +#ifndef SB_SIMPLEID +#define SB_SIMPLEID 0xFF +#endif + +#define NO_ITEM_SELECTED -1 +#define MAX_KEY_LENGTH 256 +#define MAX_DEV_LEN 1000 + + +typedef struct _MAIN_WND_INFO +{ + HWND hMainWnd; + HWND hTreeView; + HWND hStatus; + HWND hTool; + HWND hProgDlg; + HMENU hShortcutMenu; + int nCmdShow; + + /* status flags */ + BOOL InMenuLoop : 1; + +} MAIN_WND_INFO, *PMAIN_WND_INFO; + + +BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + + +/* servman.c */ +extern HINSTANCE hInstance; +extern HANDLE ProcessHeap; + +/* mainwnd.c */ +typedef struct _MENU_HINT +{ + WORD CmdId; + UINT HintId; +} MENU_HINT, *PMENU_HINT; + +BOOL InitMainWindowImpl(VOID); +VOID UninitMainWindowImpl(VOID); +HWND CreateMainWindow(LPCTSTR lpCaption, int nCmdShow); + + +/* enumdevices.c */ +HTREEITEM InitTreeView(PMAIN_WND_INFO Info); +VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot); + + +/* misc.c */ +INT AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID); + +DWORD LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...); + +BOOL StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...); + +BOOL StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID); + +INT GetTextFromEdit(OUT LPTSTR lpString, + IN HWND hDlg, + IN UINT Res); + +VOID GetError(VOID); + +VOID DisplayString(PTCHAR); + +HIMAGELIST InitImageList(UINT NumButtons, + UINT StartResource, + UINT Width, + UINT Height); + + +#endif /* __DEVMGMT_PRECOMP_H */ diff --git a/reactos/base/applications/devmgmt/res/computer.ico b/reactos/base/applications/devmgmt/res/computer.ico new file mode 100644 index 00000000000..deb7f520f20 Binary files /dev/null and b/reactos/base/applications/devmgmt/res/computer.ico differ diff --git a/reactos/base/applications/devmgmt/res/exit.bmp b/reactos/base/applications/devmgmt/res/exit.bmp new file mode 100644 index 00000000000..97381f1f6f7 Binary files /dev/null and b/reactos/base/applications/devmgmt/res/exit.bmp differ diff --git a/reactos/base/applications/devmgmt/res/help.bmp b/reactos/base/applications/devmgmt/res/help.bmp new file mode 100644 index 00000000000..4c958c2e9a0 Binary files /dev/null and b/reactos/base/applications/devmgmt/res/help.bmp differ diff --git a/reactos/base/applications/devmgmt/res/properties.bmp b/reactos/base/applications/devmgmt/res/properties.bmp new file mode 100644 index 00000000000..15e080ec923 Binary files /dev/null and b/reactos/base/applications/devmgmt/res/properties.bmp differ diff --git a/reactos/base/applications/devmgmt/res/refresh.bmp b/reactos/base/applications/devmgmt/res/refresh.bmp new file mode 100644 index 00000000000..e7c12bbd302 Binary files /dev/null and b/reactos/base/applications/devmgmt/res/refresh.bmp differ diff --git a/reactos/base/applications/devmgmt/res/root.bmp b/reactos/base/applications/devmgmt/res/root.bmp new file mode 100644 index 00000000000..e2734fb590b Binary files /dev/null and b/reactos/base/applications/devmgmt/res/root.bmp differ diff --git a/reactos/base/applications/devmgmt/resource.h b/reactos/base/applications/devmgmt/resource.h new file mode 100644 index 00000000000..2097e147753 --- /dev/null +++ b/reactos/base/applications/devmgmt/resource.h @@ -0,0 +1,63 @@ +#define IDC_STATIC -1 + + +#define IDI_MAIN_ICON 50 +#define IDB_ROOT_IMAGE 51 + +/* windows */ +#define IDC_TREEVIEW 1000 +#define IDC_TOOLBAR 1001 +#define IDC_STATUSBAR 1002 + +/* commands */ +#define IDC_PROP 2000 +#define IDC_REFRESH 2001 +#define IDC_PRINT 2002 +#define IDC_PROGHELP 2003 +#define IDC_EXIT 2004 +#define IDC_ABOUT 4031 + +/* menus */ +#define IDR_MAINMENU 102 +#define IDR_POPUP 103 + +/* tooltips */ +#define IDS_TOOLTIP_PROP 6000 +#define IDS_TOOLTIP_REFRESH 6001 +#define IDS_TOOLTIP_HELP 6002 +#define IDS_TOOLTIP_EXIT 6003 + +/* button bitmaps */ +#define IDB_PROP 10000 +#define IDB_REFRESH 10001 +#define IDB_HELP 10002 +#define IDB_EXIT 10003 + +/* toolbar buttons */ +#define TBICON_PROP 0 +#define TBICON_REFRESH 1 +#define TBICON_HELP 2 +#define TBICON_EXIT 3 + +/* about box info */ +#define IDD_ABOUTBOX 200 +#define IDC_LICENSE_EDIT 201 +#define IDS_APPNAME 202 +#define IDS_LICENSE 203 + + +/* menu hints */ +#define IDS_HINT_BLANK 20000 +#define IDS_HINT_REFRESH 20002 +#define IDS_HINT_PROP 20003 +#define IDS_HINT_HELP 20004 +#define IDS_HINT_ABOUT 20005 +#define IDS_HINT_EXIT 20006 + +/* system menu hints */ +#define IDS_HINT_SYS_RESTORE 21001 +#define IDS_HINT_SYS_MOVE 21002 +#define IDS_HINT_SYS_SIZE 21003 +#define IDS_HINT_SYS_MINIMIZE 21004 +#define IDS_HINT_SYS_MAXIMIZE 21005 +#define IDS_HINT_SYS_CLOSE 21006