[SERVMAN]

- Avoid a potential race whereby the current service selection can change before the propsheet thread starts up
- Cleanup the depends data, it doesn't need to be passed around the propsheet
This commit is contained in:
Ged Murphy 2017-12-05 22:13:02 +00:00 committed by GitHub
parent 4296826c58
commit e36b89addb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 95 deletions

View file

@ -10,8 +10,7 @@
#include "precomp.h"
LPWSTR
TV1_GetDependants(PSERVICEPROPSHEET pDlgInfo,
SC_HANDLE hService)
TV1_GetDependants(SC_HANDLE hService)
{
LPQUERY_SERVICE_CONFIG lpServiceConfig;
LPWSTR lpStr = NULL;
@ -80,7 +79,7 @@ TV1_GetDependants(PSERVICEPROPSHEET pDlgInfo,
}
VOID
TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
TV1_AddDependantsToTree(PDEPENDDATA pDependData,
HTREEITEM hParent,
LPWSTR lpServiceName)
{
@ -103,7 +102,7 @@ TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
if (hService)
{
/* Get a list of service dependents */
lpDependants = TV1_GetDependants(pDlgInfo, hService);
lpDependants = TV1_GetDependants(hService);
if (lpDependants)
{
lpStr = lpDependants;
@ -127,7 +126,7 @@ TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
}
/* Add it */
AddItemToTreeView(pDlgInfo->hDependsTreeView1,
AddItemToTreeView(pDependData->hDependsTreeView1,
hParent,
lpServiceConfig->lpDisplayName,
lpStr,
@ -156,7 +155,7 @@ TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
/* Load the 'No dependencies' string */
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
AddItemToTreeView(pDlgInfo->hDependsTreeView1,
AddItemToTreeView(pDependData->hDependsTreeView1,
NULL,
lpNoDepends,
NULL,
@ -166,7 +165,7 @@ TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
LocalFree(lpNoDepends);
/* Disable the window */
EnableWindow(pDlgInfo->hDependsTreeView1, FALSE);
EnableWindow(pDependData->hDependsTreeView1, FALSE);
}
}
@ -178,25 +177,25 @@ TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
}
BOOL
TV1_Initialize(PSERVICEPROPSHEET pDlgInfo,
TV1_Initialize(PDEPENDDATA pDependData,
LPWSTR lpServiceName)
{
BOOL bRet = FALSE;
/* Associate the imagelist with TV1 */
pDlgInfo->hDependsTreeView1 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE1);
if (!pDlgInfo->hDependsTreeView1)
pDependData->hDependsTreeView1 = GetDlgItem(pDependData->hDependsWnd, IDC_DEPEND_TREE1);
if (!pDependData->hDependsTreeView1)
{
ImageList_Destroy(pDlgInfo->hDependsImageList);
pDlgInfo->hDependsImageList = NULL;
ImageList_Destroy(pDependData->hDependsImageList);
pDependData->hDependsImageList = NULL;
return FALSE;
}
(void)TreeView_SetImageList(pDlgInfo->hDependsTreeView1,
pDlgInfo->hDependsImageList,
(void)TreeView_SetImageList(pDependData->hDependsTreeView1,
pDependData->hDependsImageList,
TVSIL_NORMAL);
/* Set the first items in the control */
TV1_AddDependantsToTree(pDlgInfo, NULL, lpServiceName);
TV1_AddDependantsToTree(pDependData, NULL, lpServiceName);
return bRet;
}

View file

@ -118,7 +118,7 @@ TV2_GetDependants(LPWSTR lpServiceName,
}
VOID
TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
TV2_AddDependantsToTree(PDEPENDDATA pDependData,
HTREEITEM hParent,
LPWSTR lpServiceName)
{
@ -138,7 +138,7 @@ TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
/* Add it */
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
AddItemToTreeView(pDependData->hDependsTreeView2,
hParent,
lpServiceStatus[i].lpDisplayName,
lpServiceStatus[i].lpServiceName,
@ -158,7 +158,7 @@ TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
/* Load the 'No dependencies' string */
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
AddItemToTreeView(pDependData->hDependsTreeView2,
NULL,
lpNoDepends,
NULL,
@ -168,31 +168,31 @@ TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
LocalFree(lpNoDepends);
/* Disable the window */
EnableWindow(pDlgInfo->hDependsTreeView2, FALSE);
EnableWindow(pDependData->hDependsTreeView2, FALSE);
}
}
}
BOOL
TV2_Initialize(PSERVICEPROPSHEET pDlgInfo,
TV2_Initialize(PDEPENDDATA pDependData,
LPWSTR lpServiceName)
{
BOOL bRet = FALSE;
/* Associate the imagelist with TV2 */
pDlgInfo->hDependsTreeView2 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE2);
if (!pDlgInfo->hDependsTreeView2)
pDependData->hDependsTreeView2 = GetDlgItem(pDependData->hDependsWnd, IDC_DEPEND_TREE2);
if (!pDependData->hDependsTreeView2)
{
ImageList_Destroy(pDlgInfo->hDependsImageList);
pDlgInfo->hDependsImageList = NULL;
ImageList_Destroy(pDependData->hDependsImageList);
pDependData->hDependsImageList = NULL;
return FALSE;
}
(void)TreeView_SetImageList(pDlgInfo->hDependsTreeView2,
pDlgInfo->hDependsImageList,
(void)TreeView_SetImageList(pDependData->hDependsTreeView2,
pDependData->hDependsImageList,
TVSIL_NORMAL);
/* Set the first items in the control */
TV2_AddDependantsToTree(pDlgInfo, NULL, lpServiceName);
TV2_AddDependantsToTree(pDependData, NULL, lpServiceName);
return bRet;
}

View file

@ -128,11 +128,18 @@ typedef struct _SERVICEPROPSHEET
{
PMAIN_WND_INFO Info;
ENUM_SERVICE_STATUS_PROCESS *pService;
} SERVICEPROPSHEET, *PSERVICEPROPSHEET;
typedef struct _DEPENDDATA
{
PSERVICEPROPSHEET pDlgInfo;
HIMAGELIST hDependsImageList;
HWND hDependsWnd;
HWND hDependsTreeView1;
HWND hDependsTreeView2;
} SERVICEPROPSHEET, *PSERVICEPROPSHEET;
} DEPENDDATA, *PDEPENDDATA;
HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPWSTR lpDisplayName, LPWSTR lpServiceName, ULONG serviceType, BOOL bHasChildren);
@ -147,12 +154,12 @@ LPWSTR DisplayName,
LPWSTR ServiceList);
/* tv1_dependencies */
BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName);
VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName);
BOOL TV1_Initialize(PDEPENDDATA pDependData, LPWSTR lpServiceName);
VOID TV1_AddDependantsToTree(PDEPENDDATA pDependData, HTREEITEM hParent, LPWSTR lpServiceName);
/* tv2_dependencies */
BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName);
VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName);
BOOL TV2_Initialize(PDEPENDDATA pDependData, LPWSTR lpServiceName);
VOID TV2_AddDependantsToTree(PDEPENDDATA pDependData, HTREEITEM hParent, LPWSTR lpServiceName);
BOOL TV2_HasDependantServices(LPWSTR lpServiceName);
LPENUM_SERVICE_STATUS TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount);

View file

@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/propsheet.c
* PURPOSE: Property dialog box message handler
* COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-2017 Ged Murphy <gedmurphy@reactos.org>
*
*/
@ -29,8 +29,20 @@ InitPropSheetPage(PROPSHEETPAGE *psp,
VOID
OpenPropSheet(PMAIN_WND_INFO Info)
{
PSERVICEPROPSHEET pServicePropSheet;
HANDLE hThread;
hThread = (HANDLE)_beginthreadex(NULL, 0, &PropSheetThread, Info, 0, NULL);
pServicePropSheet = HeapAlloc(ProcessHeap,
0,
sizeof(*pServicePropSheet));
if (!pServicePropSheet) return;
/* Set the current service in this calling thread to avoid
* it being updated before the thread is up */
pServicePropSheet->pService = Info->pCurrentService;
pServicePropSheet->Info = Info;
hThread = (HANDLE)_beginthreadex(NULL, 0, &PropSheetThread, pServicePropSheet, 0, NULL);
if (hThread)
{
CloseHandle(hThread);
@ -40,65 +52,54 @@ OpenPropSheet(PMAIN_WND_INFO Info)
unsigned int __stdcall PropSheetThread(void* Param)
{
PSERVICEPROPSHEET pServicePropSheet;
PROPSHEETHEADER psh;
PROPSHEETPAGE psp[4];
PSERVICEPROPSHEET pServicePropSheet;
HWND hDlg = NULL;
MSG Msg;
PMAIN_WND_INFO Info = (PMAIN_WND_INFO)Param;
pServicePropSheet = (PSERVICEPROPSHEET)Param;
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_MODELESS;
psh.hwndParent = Info->hMainWnd;
psh.hwndParent = pServicePropSheet->Info->hMainWnd;
psh.hInstance = hInstance;
psh.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SM_ICON));
psh.pszCaption = Info->pCurrentService->lpDisplayName;
psh.pszCaption = pServicePropSheet->Info->pCurrentService->lpDisplayName;
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = psp;
/* Initialize the tabs */
InitPropSheetPage(&psp[0], pServicePropSheet, IDD_DLG_GENERAL, GeneralPageProc);
InitPropSheetPage(&psp[1], pServicePropSheet, IDD_LOGON, LogonPageProc);
InitPropSheetPage(&psp[2], pServicePropSheet, IDD_RECOVERY, RecoveryPageProc);
InitPropSheetPage(&psp[3], pServicePropSheet, IDD_DLG_DEPEND, DependenciesPageProc);
pServicePropSheet = HeapAlloc(ProcessHeap,
0,
sizeof(*pServicePropSheet));
if (pServicePropSheet)
hDlg = (HWND)PropertySheetW(&psh);
if (hDlg)
{
/* Save current service, as it could change while the dialog is open */
pServicePropSheet->pService = Info->pCurrentService;
pServicePropSheet->Info = Info;
InitPropSheetPage(&psp[0], pServicePropSheet, IDD_DLG_GENERAL, GeneralPageProc);
InitPropSheetPage(&psp[1], pServicePropSheet, IDD_LOGON, LogonPageProc);
InitPropSheetPage(&psp[2], pServicePropSheet, IDD_RECOVERY, RecoveryPageProc);
InitPropSheetPage(&psp[3], pServicePropSheet, IDD_DLG_DEPEND, DependenciesPageProc);
hDlg = (HWND)PropertySheetW(&psh);
if (hDlg)
/* Pump the message queue */
while (GetMessageW(&Msg, NULL, 0, 0))
{
/* Pump the message queue */
while (GetMessageW(&Msg, NULL, 0, 0))
if (PropSheet_GetCurrentPageHwnd(hDlg) == NULL)
{
/* The user hit the ok / cancel button, pull it down */
EnableWindow(pServicePropSheet->Info->hMainWnd, TRUE);
DestroyWindow(hDlg);
}
if (PropSheet_GetCurrentPageHwnd(hDlg) == NULL)
{
/* The user hit the ok / cancel button, pull it down */
EnableWindow(Info->hMainWnd, TRUE);
DestroyWindow(hDlg);
}
if (PropSheet_IsDialogMessage(hDlg, &Msg) != 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
if (PropSheet_IsDialogMessage(hDlg, &Msg) != 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
HeapFree(GetProcessHeap(), 0, pServicePropSheet);
}
HeapFree(GetProcessHeap(), 0, pServicePropSheet);
return (hDlg != NULL);
}

View file

@ -159,20 +159,20 @@ TreeView_GetItemText(HWND hTreeView,
*/
static VOID
InitDependPage(PSERVICEPROPSHEET pDlgInfo)
InitDependPage(PDEPENDDATA pDependData)
{
/* Initialize the image list */
pDlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS,
IDI_DRIVER,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CXSMICON),
IMAGE_ICON);
pDependData->hDependsImageList = InitImageList(IDI_NODEPENDS,
IDI_DRIVER,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CXSMICON),
IMAGE_ICON);
/* Set the first tree view */
TV1_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
TV1_Initialize(pDependData, pDependData->pDlgInfo->pService->lpServiceName);
/* Set the second tree view */
TV2_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
TV2_Initialize(pDependData, pDependData->pDlgInfo->pService->lpServiceName);
}
/*
@ -185,12 +185,13 @@ DependenciesPageProc(HWND hwndDlg,
WPARAM wParam,
LPARAM lParam)
{
PSERVICEPROPSHEET pDlgInfo;
PDEPENDDATA pDependData;
/* Get the window context */
pDlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg,
GWLP_USERDATA);
if (pDlgInfo == NULL && uMsg != WM_INITDIALOG)
pDependData = (PDEPENDDATA)GetWindowLongPtr(hwndDlg,
GWLP_USERDATA);
if (pDependData == NULL && uMsg != WM_INITDIALOG)
{
return FALSE;
}
@ -199,16 +200,17 @@ DependenciesPageProc(HWND hwndDlg,
{
case WM_INITDIALOG:
{
pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
if (pDlgInfo != NULL)
pDependData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEPENDDATA));
if (pDependData != NULL)
{
SetWindowLongPtr(hwndDlg,
GWLP_USERDATA,
(LONG_PTR)pDlgInfo);
(LONG_PTR)pDependData);
pDlgInfo->hDependsWnd = hwndDlg;
pDependData->pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
pDependData->hDependsWnd = hwndDlg;
InitDependPage(pDlgInfo);
InitDependPage(pDependData);
}
}
break;
@ -226,19 +228,19 @@ DependenciesPageProc(HWND hwndDlg,
if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE1)
{
/* Has this node been expanded before */
if (!TreeView_GetChild(pDlgInfo->hDependsTreeView1, lpnmtv->itemNew.hItem))
if (!TreeView_GetChild(pDependData->hDependsTreeView1, lpnmtv->itemNew.hItem))
{
/* It's not, add the children */
TV1_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
TV1_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
}
}
else if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE2)
{
/* Has this node been expanded before */
if (!TreeView_GetChild(pDlgInfo->hDependsTreeView2, lpnmtv->itemNew.hItem))
if (!TreeView_GetChild(pDependData->hDependsTreeView2, lpnmtv->itemNew.hItem))
{
/* It's not, add the children */
TV2_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
TV2_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
}
}
}
@ -256,11 +258,13 @@ DependenciesPageProc(HWND hwndDlg,
break;
case WM_DESTROY:
DestroyTreeView(pDlgInfo->hDependsTreeView1);
DestroyTreeView(pDlgInfo->hDependsTreeView2);
DestroyTreeView(pDependData->hDependsTreeView1);
DestroyTreeView(pDependData->hDependsTreeView2);
if (pDlgInfo->hDependsImageList)
ImageList_Destroy(pDlgInfo->hDependsImageList);
if (pDependData->hDependsImageList)
ImageList_Destroy(pDependData->hDependsImageList);
HeapFree(GetProcessHeap(), 0, pDependData);
}
return FALSE;

View file

@ -170,7 +170,8 @@ ShowFailureActions(
{
WCHAR szBuffer[256];
PWSTR startPtr, endPtr;
INT i, index, id, length;
INT index, id, length;
DWORD i;
for (i = 0; i < min(pRecoveryData->pServiceFailure->cActions, 3); i++)
{