ticket-2618-patches-20031207
[openafs.git] / src / WINNT / afssvrmgr / action.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "svrmgr.h"
16 #include "action.h"
17 #include "window.h"
18 #include "messages.h"
19 #include "display.h"
20
21
22 /*
23  * DEFINITIONS ________________________________________________________________
24  *
25  */
26
27 #define cREALLOC_ACTIONLIST  4
28
29 typedef enum
30    {
31    actcolOPERATION,
32    actcolELAPSED,
33    } ACTIONCOLUMN;
34
35 static struct
36    {
37    int idsColumn;
38    int cxWidth;
39    }
40 ACTIONCOLUMNS[] =
41    {
42       { IDS_ACTCOL_OPERATION, 100 }, // actcolOPERATIONS
43       { IDS_ACTCOL_ELAPSED,   100 }, // actcolELAPSED
44    };
45
46 #define nACTIONCOLUMNS  (sizeof(ACTIONCOLUMNS)/sizeof(ACTIONCOLUMNS[0]))
47
48 #define cxMIN_ACTION  75
49 #define cyMIN_ACTION  50
50
51
52 /*
53  * ACTION TYPES _______________________________________________________________
54  *
55  */
56
57 typedef enum
58    {
59    atUNUSED = 0,
60    atOPENCELL,
61    atSCOUT,
62    atTIMEOUT,
63    atREFRESH,
64    atGETSERVERLOGFILE,
65    atSETSERVERAUTH,
66    atSTARTSERVICE,
67    atSTOPSERVICE,
68    atRESTARTSERVICE,
69    atCREATEFILESET,
70    atDELETEFILESET,
71    atMOVEFILESET,
72    atSETFILESETQUOTA,
73    atSYNCVLDB,
74    atSALVAGE,
75    atSETFILESETREPPARAMS,
76    atCREATEREPLICA,
77    atPRUNEFILES,
78    atINSTALLFILE,
79    atUNINSTALLFILE,
80    atRENAMEFILESET,
81    atCREATESERVICE,
82    atDELETESERVICE,
83    atRELEASEFILESET,
84    atGETFILEDATES,
85    atEXECUTECOMMAND,
86    atADMINLIST_LOAD,
87    atADMINLIST_SAVE,
88    atHOSTLIST_LOAD,
89    atHOSTLIST_SAVE,
90    atCLONE,
91    atCLONESYS,
92    atDUMP,
93    atRESTORE,
94    atSETRESTART,
95    atCHANGEADDR,
96    } ACTIONTYPE;
97
98 typedef struct
99    {
100    ACTIONTYPE Type;
101    NOTIFYPARAMS Params;
102    DWORD dwTickStart;
103    HWND hDlg;
104    } ACTION, *PACTION;
105
106
107 /*
108  * VARIABLES __________________________________________________________________
109  *
110  */
111
112 static struct l
113    {
114    PACTION *aActions;
115    size_t cActions;
116    size_t cActionsInUse;
117    BOOL fShowConfirmations;
118    } l;
119
120 rwWindowData awdActions[] = {
121     { IDC_ACTION_DESC,     raSizeX | raRepaint, 0,                                      0 },
122     { IDC_ACTION_LIST,     raSizeX | raSizeY,   MAKELONG(cxMIN_ACTION,cyMIN_ACTION),    0 },
123     { idENDLIST,           0,                   0,                                      0 }
124  };
125
126
127 /*
128  * PROTOTYPES _________________________________________________________________
129  *
130  */
131
132 void TicksToElapsedTime (LPSYSTEMTIME pst, DWORD dwTicks);
133 void CopyFirstWord (LPTSTR pszTarget, LPTSTR pszSource);
134
135 BOOL CALLBACK Action_Window_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
136 void Action_Window_Refresh (void);
137 LPTSTR Action_GetDescription (size_t ii);
138
139 BOOL Action_CompareNotifyParams (PNOTIFYPARAMS pParams1, PNOTIFYPARAMS pParams2);
140 PACTION Action_Begin (ACTIONTYPE Type, PNOTIFYPARAMS pParams);
141 PACTION Action_Find (ACTIONTYPE Type, PNOTIFYPARAMS pParams);
142 void Action_OnDestroy (HWND hDlg);
143 void Action_SpecifyWindow (PACTION pParams, HWND hDlg);
144 void Action_End (PACTION pParams, DWORD dwStatus);
145
146 void Action_GetServerLogFile_Begin (PNOTIFYPARAMS pParams);
147 void Action_GetServerLogFile_End (PNOTIFYPARAMS pParams);
148 void Action_SetServerAuth_Begin (PNOTIFYPARAMS pParams);
149 void Action_SetServerAuth_End (PNOTIFYPARAMS pParams);
150 void Action_InstallFile_Begin (PNOTIFYPARAMS pParams);
151 void Action_InstallFile_End (PNOTIFYPARAMS pParams);
152 void Action_UninstallFile_Begin (PNOTIFYPARAMS pParams);
153 void Action_UninstallFile_End (PNOTIFYPARAMS pParams);
154 void Action_PruneFiles_Begin (PNOTIFYPARAMS pParams);
155 void Action_PruneFiles_End (PNOTIFYPARAMS pParams);
156 void Action_StartService_Begin (PNOTIFYPARAMS pParams);
157 void Action_StartService_End (PNOTIFYPARAMS pParams);
158 void Action_StopService_Begin (PNOTIFYPARAMS pParams);
159 void Action_StopService_End (PNOTIFYPARAMS pParams);
160 void Action_RestartService_Begin (PNOTIFYPARAMS pParams);
161 void Action_RestartService_End (PNOTIFYPARAMS pParams);
162 void Action_CreateFileset_Begin (PNOTIFYPARAMS pParams);
163 void Action_CreateFileset_End (PNOTIFYPARAMS pParams);
164 void Action_DeleteFileset_Begin (PNOTIFYPARAMS pParams);
165 void Action_DeleteFileset_End (PNOTIFYPARAMS pParams);
166 void Action_SetFilesetQuota_Begin (PNOTIFYPARAMS pParams);
167 void Action_SetFilesetQuota_End (PNOTIFYPARAMS pParams);
168 void Action_SyncVLDB_Begin (PNOTIFYPARAMS pParams);
169 void Action_SyncVLDB_End (PNOTIFYPARAMS pParams);
170 void Action_Salvage_Begin (PNOTIFYPARAMS pParams);
171 void Action_Salvage_End (PNOTIFYPARAMS pParams);
172 void Action_Scout_Begin (PNOTIFYPARAMS pParams);
173 void Action_Scout_End (PNOTIFYPARAMS pParams);
174 void Action_SetFilesetRepParams_Begin (PNOTIFYPARAMS pParams);
175 void Action_SetFilesetRepParams_End (PNOTIFYPARAMS pParams);
176 void Action_CreateReplica_Begin (PNOTIFYPARAMS pParams);
177 void Action_CreateReplica_End (PNOTIFYPARAMS pParams);
178 void Action_RenameFileset_Begin (PNOTIFYPARAMS pParams);
179 void Action_RenameFileset_End (PNOTIFYPARAMS pParams);
180 void Action_CreateService_Begin (PNOTIFYPARAMS pParams);
181 void Action_CreateService_End (PNOTIFYPARAMS pParams);
182 void Action_DeleteService_Begin (PNOTIFYPARAMS pParams);
183 void Action_DeleteService_End (PNOTIFYPARAMS pParams);
184 void Action_ReleaseFileset_Begin (PNOTIFYPARAMS pParams);
185 void Action_ReleaseFileset_End (PNOTIFYPARAMS pParams);
186 void Action_GetFileDates_Begin (PNOTIFYPARAMS pParams);
187 void Action_GetFileDates_End (PNOTIFYPARAMS pParams);
188 void Action_ExecuteCommand_Begin (PNOTIFYPARAMS pParams);
189 void Action_ExecuteCommand_End (PNOTIFYPARAMS pParams);
190 void Action_AdminListLoad_Begin (PNOTIFYPARAMS pParams);
191 void Action_AdminListLoad_End (PNOTIFYPARAMS pParams);
192 void Action_AdminListSave_Begin (PNOTIFYPARAMS pParams);
193 void Action_AdminListSave_End (PNOTIFYPARAMS pParams);
194 void Action_HostListLoad_Begin (PNOTIFYPARAMS pParams);
195 void Action_HostListLoad_End (PNOTIFYPARAMS pParams);
196 void Action_HostListSave_Begin (PNOTIFYPARAMS pParams);
197 void Action_HostListSave_End (PNOTIFYPARAMS pParams);
198 void Action_Clone_Begin (PNOTIFYPARAMS pParams);
199 void Action_Clone_End (PNOTIFYPARAMS pParams);
200 void Action_Clonesys_Begin (PNOTIFYPARAMS pParams);
201 void Action_Clonesys_End (PNOTIFYPARAMS pParams);
202 void Action_SetRestart_Begin (PNOTIFYPARAMS pParams);
203 void Action_SetRestart_End (PNOTIFYPARAMS pParams);
204 void Action_ChangeAddr_Begin (PNOTIFYPARAMS pParams);
205 void Action_ChangeAddr_End (PNOTIFYPARAMS pParams);
206
207 void Action_Refresh_Begin (PNOTIFYPARAMS pParams);
208 void Action_Refresh_Update (PNOTIFYPARAMS pParams);
209 void Action_Refresh_SectionStart (PNOTIFYPARAMS pParams);
210 void Action_Refresh_SectionEnd (PNOTIFYPARAMS pParams);
211 void Action_Refresh_End (PNOTIFYPARAMS pParams);
212 void Action_Refresh_UpdateText (HWND hDlg, LPIDENT lpi, DWORD dwPerComplete);
213 void Action_Refresh_SetSection (HWND hDlg, BOOL fStart, int idSection);
214 void Action_Refresh_SkipSection (HWND hDlg);
215 BOOL CALLBACK Action_Refresh_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
216
217 void Action_MoveFileset_Begin (PNOTIFYPARAMS pParams);
218 void Action_MoveFileset_End (PNOTIFYPARAMS pParams);
219 BOOL CALLBACK Action_MoveFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
220
221 void Action_DumpFileset_Begin (PNOTIFYPARAMS pParams);
222 void Action_DumpFileset_End (PNOTIFYPARAMS pParams);
223 BOOL CALLBACK Action_DumpFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
224
225 void Action_RestoreFileset_Begin (PNOTIFYPARAMS pParams);
226 void Action_RestoreFileset_End (PNOTIFYPARAMS pParams);
227 BOOL CALLBACK Action_RestoreFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
228
229 void Action_OpenCell_Begin (PNOTIFYPARAMS pParams);
230 void Action_OpenCell_End (PNOTIFYPARAMS pParams);
231 BOOL CALLBACK Action_OpenCell_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
232
233
234 /*
235  * ROUTINES ___________________________________________________________________
236  *
237  */
238
239 void ActionNotification_MainThread (NOTIFYEVENT evt, PNOTIFYPARAMS pParams)
240 {
241    BOOL fRefresh = TRUE;
242
243    switch (evt)
244       {
245
246       // When Scout starts and stops checking a server, it'll notify us.
247       //
248       case evtScoutBegin:                Action_Scout_Begin (pParams);                  break;
249       case evtScoutEnd:                  Action_Scout_End (pParams);                    break;
250
251       // If AFSClass is going to perform a lengthy refresh, it will send
252       // us notifications for when it starts, when it's done, and periodic
253       // updates about how far along it is.  Use that information to present
254       // a dialog to the user...
255       //
256       case evtRefreshAllBegin:           Action_Refresh_Begin (pParams);                break;
257       case evtRefreshAllUpdate:          Action_Refresh_Update (pParams);               break;
258       case evtRefreshAllSectionStart:    Action_Refresh_SectionStart (pParams);         break;
259       case evtRefreshAllSectionEnd:      Action_Refresh_SectionEnd (pParams);           break;
260       case evtRefreshAllEnd:             Action_Refresh_End(pParams);                   break;
261
262       case evtGetServerLogFileBegin:     Action_GetServerLogFile_Begin (pParams);       break;
263       case evtGetServerLogFileEnd:       Action_GetServerLogFile_End (pParams);         break;
264       case evtSetServerAuthBegin:        Action_SetServerAuth_Begin (pParams);          break;
265       case evtSetServerAuthEnd:          Action_SetServerAuth_End (pParams);            break;
266       case evtInstallFileBegin:          Action_InstallFile_Begin (pParams);            break;
267       case evtInstallFileEnd:            Action_InstallFile_End (pParams);              break;
268       case evtUninstallFileBegin:        Action_UninstallFile_Begin (pParams);          break;
269       case evtUninstallFileEnd:          Action_UninstallFile_End (pParams);            break;
270       case evtPruneFilesBegin:           Action_PruneFiles_Begin (pParams);             break;
271       case evtPruneFilesEnd:             Action_PruneFiles_End (pParams);               break;
272       case evtStartServiceBegin:         Action_StartService_Begin (pParams);           break;
273       case evtStartServiceEnd:           Action_StartService_End (pParams);             break;
274       case evtStopServiceBegin:          Action_StopService_Begin (pParams);            break;
275       case evtStopServiceEnd:            Action_StopService_End (pParams);              break;
276       case evtRestartServiceBegin:       Action_RestartService_Begin (pParams);         break;
277       case evtRestartServiceEnd:         Action_RestartService_End (pParams);           break;
278       case evtCreateFilesetBegin:        Action_CreateFileset_Begin (pParams);          break;
279       case evtCreateFilesetEnd:          Action_CreateFileset_End (pParams);            break;
280       case evtDeleteFilesetBegin:        Action_DeleteFileset_Begin (pParams);          break;
281       case evtDeleteFilesetEnd:          Action_DeleteFileset_End (pParams);            break;
282       case evtMoveFilesetBegin:          Action_MoveFileset_Begin (pParams);            break;
283       case evtMoveFilesetEnd:            Action_MoveFileset_End (pParams);              break;
284       case evtSetFilesetQuotaBegin:      Action_SetFilesetQuota_Begin (pParams);        break;
285       case evtSetFilesetQuotaEnd:        Action_SetFilesetQuota_End (pParams);          break;
286       case evtSyncVLDBBegin:             Action_SyncVLDB_Begin (pParams);               break;
287       case evtSyncVLDBEnd:               Action_SyncVLDB_End (pParams);                 break;
288       case evtSalvageBegin:              Action_Salvage_Begin (pParams);                break;
289       case evtSalvageEnd:                Action_Salvage_End (pParams);                  break;
290       case evtSetFilesetRepParamsBegin:  Action_SetFilesetRepParams_Begin (pParams);    break;
291       case evtSetFilesetRepParamsEnd:    Action_SetFilesetRepParams_End (pParams);      break;
292       case evtCreateReplicaBegin:        Action_CreateReplica_Begin (pParams);          break;
293       case evtCreateReplicaEnd:          Action_CreateReplica_End (pParams);            break;
294       case evtRenameFilesetBegin:        Action_RenameFileset_Begin (pParams);          break;
295       case evtRenameFilesetEnd:          Action_RenameFileset_End (pParams);            break;
296       case evtCreateServiceBegin:        Action_CreateService_Begin (pParams);          break;
297       case evtCreateServiceEnd:          Action_CreateService_End (pParams);            break;
298       case evtDeleteServiceBegin:        Action_DeleteService_Begin (pParams);          break;
299       case evtDeleteServiceEnd:          Action_DeleteService_End (pParams);            break;
300       case evtReleaseFilesetBegin:       Action_ReleaseFileset_Begin (pParams);         break;
301       case evtReleaseFilesetEnd:         Action_ReleaseFileset_End (pParams);           break;
302       case evtGetFileDatesBegin:         Action_GetFileDates_Begin (pParams);           break;
303       case evtGetFileDatesEnd:           Action_GetFileDates_End (pParams);             break;
304       case evtExecuteCommandBegin:       Action_ExecuteCommand_Begin (pParams);         break;
305       case evtExecuteCommandEnd:         Action_ExecuteCommand_End (pParams);           break;
306       case evtAdminListLoadBegin:        Action_AdminListLoad_Begin (pParams);          break;
307       case evtAdminListLoadEnd:          Action_AdminListLoad_End (pParams);            break;
308       case evtAdminListSaveBegin:        Action_AdminListSave_Begin (pParams);          break;
309       case evtAdminListSaveEnd:          Action_AdminListSave_End (pParams);            break;
310       case evtHostListLoadBegin:         Action_HostListLoad_Begin (pParams);           break;
311       case evtHostListLoadEnd:           Action_HostListLoad_End (pParams);             break;
312       case evtHostListSaveBegin:         Action_HostListSave_Begin (pParams);           break;
313       case evtHostListSaveEnd:           Action_HostListSave_End (pParams);             break;
314       case evtCloneBegin:                Action_Clone_Begin (pParams);                  break;
315       case evtCloneEnd:                  Action_Clone_End (pParams);                    break;
316       case evtCloneMultipleBegin:        Action_Clonesys_Begin (pParams);               break;
317       case evtCloneMultipleEnd:          Action_Clonesys_End (pParams);                 break;
318       case evtDumpFilesetBegin:          Action_DumpFileset_Begin (pParams);            break;
319       case evtDumpFilesetEnd:            Action_DumpFileset_End (pParams);              break;
320       case evtRestoreFilesetBegin:       Action_RestoreFileset_Begin (pParams);         break;
321       case evtRestoreFilesetEnd:         Action_RestoreFileset_End (pParams);           break;
322       case evtSetRestartTimesBegin:      Action_SetRestart_Begin (pParams);             break;
323       case evtSetRestartTimesEnd:        Action_SetRestart_End (pParams);               break;
324       case evtChangeAddressBegin:        Action_ChangeAddr_Begin (pParams);             break;
325       case evtChangeAddressEnd:          Action_ChangeAddr_End (pParams);               break;
326       case evtOpenCellBegin:             Action_OpenCell_Begin (pParams);               break;
327       case evtOpenCellEnd:               Action_OpenCell_End (pParams);                 break;
328
329       default:
330          fRefresh = FALSE;
331       }
332
333    if (fRefresh)
334       Action_Window_Refresh();
335 }
336
337
338 void TicksToElapsedTime (LPSYSTEMTIME pst, DWORD dwTicks)
339 {
340 #define msecSECOND  (1000L)
341 #define msecMINUTE  (1000L * 60L)
342 #define msecHOUR    (1000L * 60L * 60L)
343 #define msecDAY     (1000L * 60L * 60L * 24L)
344
345    memset (pst, 0x00, sizeof(SYSTEMTIME));
346
347    pst->wDay = (int)( dwTicks / msecDAY );
348    dwTicks %= msecDAY;
349    pst->wHour = (int)( dwTicks / msecHOUR );
350    dwTicks %= msecHOUR;
351    pst->wMinute = (int)( dwTicks / msecMINUTE );
352    dwTicks %= msecMINUTE;
353    pst->wSecond = (int)( dwTicks / msecSECOND );
354    dwTicks %= msecSECOND;
355    pst->wMilliseconds = (int)( dwTicks );
356 }
357
358
359 void CopyFirstWord (LPTSTR pszTarget, LPTSTR pszSource)
360 {
361    lstrcpy (pszTarget, pszSource);
362
363    LPTSTR pch;
364    if ((pch = (LPTSTR)lstrchr (pszTarget, TEXT(' '))) != NULL)
365       *pch = TEXT('\0');
366    if ((pch = (LPTSTR)lstrchr (pszTarget, TEXT('\t'))) != NULL)
367       *pch = TEXT('\0');
368 }
369
370
371 void Action_OpenWindow (void)
372 {
373    if (!g.hAction || !IsWindow (g.hAction))
374       {
375       g.hAction = ModelessDialog (IDD_ACTIONS, NULL, (DLGPROC)Action_Window_DlgProc);
376       ShowWindow (g.hAction, SW_SHOW);
377       }
378 }
379
380
381 void Action_CloseWindow (void)
382 {
383    if (g.hAction && IsWindow (g.hAction))
384       {
385       DestroyWindow (g.hAction);
386       }
387 }
388
389
390 BOOL CALLBACK Action_Window_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
391 {
392    if (HandleColumnNotify (hDlg, msg, wp, lp, &gr.viewAct))
393       return FALSE;
394
395    switch (msg)
396       {
397       case WM_INITDIALOG:
398          g.hAction = hDlg;
399          HWND hList;
400          hList = GetDlgItem (hDlg, IDC_ACTION_LIST);
401          FL_RestoreView (hList, &gr.viewAct);
402
403          if (gr.rActions.right == 0)
404             GetWindowRect (hDlg, &gr.rActions);
405          ResizeWindow (hDlg, awdActions, rwaMoveToHere, &gr.rActions);
406
407          Action_Window_Refresh();
408          SetTimer (hDlg, ID_ACTION_TIMER, 1000, NULL);  // timer message every sec
409
410          SetWindowPos (g.hAction, HWND_TOPMOST, 0, 0, 0, 0,
411                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
412          break;
413
414       case WM_DESTROY:
415          gr.fActions = FALSE;
416          g.hAction = NULL;
417          Main_SetActionMenus();
418          FL_StoreView (GetDlgItem (hDlg, IDC_ACTION_LIST), &gr.viewAct);
419          KillTimer (hDlg, ID_ACTION_TIMER);
420          break;
421
422       case WM_TIMER:
423          if (FastList_GetItemCount (GetDlgItem (hDlg, IDC_ACTION_LIST)))
424             Action_Window_Refresh();
425          break;
426
427       case WM_SIZE:
428          // if (lp==0), we're minimizing--don't call ResizeWindow().
429          //
430          if (lp != 0)
431             {
432             ResizeWindow (hDlg, awdActions, rwaFixupGuts);
433             GetWindowRect (hDlg, &gr.rActions);
434             }
435          break;
436
437       case WM_MOVE:
438          GetWindowRect (hDlg, &gr.rActions);
439          break;
440
441       case WM_COMMAND:
442          switch (LOWORD(wp))
443             {
444             case IDOK:
445             case IDCANCEL:
446                DestroyWindow (hDlg);
447                break;
448             }
449          break;
450       }
451
452    return FALSE;
453 }
454
455
456 void Action_WindowToTop (BOOL fTop)
457 {
458    if (g.hAction && IsWindow(g.hAction))
459       {
460       if (fTop)
461          {
462          SetWindowPos (g.hAction, HWND_TOPMOST, 0, 0, 0, 0,
463                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
464          }
465       else //(!fTop)
466          {
467          SetWindowPos (g.hAction, g.hMain, 0, 0, 0, 0,
468                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
469          }
470       }
471 }
472
473
474 void Action_Window_Refresh (void)
475 {
476    size_t nItems = 0;
477    TCHAR szText[ cchRESOURCE ];
478
479    HWND hList = GetDlgItem (g.hAction, IDC_ACTION_LIST);
480    if (hList != NULL)
481       {
482       LPARAM lpOld = FL_StartChange (hList, TRUE);
483
484       for (size_t ii = 0; ii < l.cActions; ++ii)
485          {
486          LPTSTR pszDesc;
487          if ((pszDesc = Action_GetDescription (ii)) != NULL)
488             {
489             SYSTEMTIME st;
490             TicksToElapsedTime (&st, GetTickCount() - l.aActions[ ii ]->dwTickStart);
491             FormatElapsed (szText, TEXT("%s"), &st);
492             FL_AddItem (hList, &gr.viewAct, (LPARAM)ii, IMAGE_NOIMAGE, pszDesc, szText);
493             ++nItems;
494
495             FreeString (pszDesc);
496             }
497          }
498
499       FL_EndChange (hList, lpOld);
500       }
501
502    if (nItems == 0)
503       GetString (szText, IDS_ACTION_DESC_NONE);
504    else if (nItems == 1)
505       GetString (szText, IDS_ACTION_DESC_ONE);
506    else // (nItems >= 2)
507       GetString (szText, IDS_ACTION_DESC_MULT);
508    SetDlgItemText (g.hAction, IDC_ACTION_DESC, szText);
509 }
510
511
512 LPTSTR Action_GetDescription (size_t ii)
513 {
514    TCHAR szText[ cchRESOURCE ];
515    TCHAR szText2[ cchRESOURCE ];
516    TCHAR szText3[ cchRESOURCE ];
517    LPTSTR pszDesc = NULL;
518
519    if (!l.aActions[ ii ])
520       return NULL;
521
522    switch (l.aActions[ ii ]->Type)
523       {
524       case atSCOUT:
525          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
526          pszDesc = FormatString (IDS_ACTION_SCOUT, TEXT("%s"), szText);
527          break;
528
529       case atREFRESH:
530          pszDesc = FormatString (IDS_ACTION_REFRESH);
531          break;
532
533       case atGETSERVERLOGFILE:
534          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
535          pszDesc = FormatString (IDS_ACTION_GETSERVERLOGFILE, TEXT("%s%s"), szText, l.aActions[ ii ]->Params.sz1);
536          break;
537
538       case atSETSERVERAUTH:
539          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
540          pszDesc = FormatString (IDS_ACTION_SETSERVERAUTH, TEXT("%s"), szText);
541          break;
542
543       case atINSTALLFILE:
544          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
545          CopyBaseFileName (szText2, l.aActions[ ii ]->Params.sz1);
546          pszDesc = FormatString (IDS_ACTION_INSTALLFILE, TEXT("%s%s"), szText, szText2);
547          break;
548
549       case atUNINSTALLFILE:
550          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
551          CopyBaseFileName (szText2, l.aActions[ ii ]->Params.sz1);
552          pszDesc = FormatString (IDS_ACTION_UNINSTALLFILE, TEXT("%s%s"), szText, szText2);
553          break;
554
555       case atPRUNEFILES:
556          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
557          pszDesc = FormatString (IDS_ACTION_PRUNEFILES, TEXT("%s"), szText);
558          break;
559
560       case atSTARTSERVICE:
561          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
562          l.aActions[ ii ]->Params.lpi1->GetServiceName (szText2);
563          pszDesc = FormatString (IDS_ACTION_STARTSERVICE, TEXT("%s%s"), szText, szText2);
564          break;
565
566       case atSTOPSERVICE:
567          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
568          l.aActions[ ii ]->Params.lpi1->GetServiceName (szText2);
569          pszDesc = FormatString (IDS_ACTION_STOPSERVICE, TEXT("%s%s"), szText, szText2);
570          break;
571
572       case atRESTARTSERVICE:
573          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
574          l.aActions[ ii ]->Params.lpi1->GetServiceName (szText2);
575          pszDesc = FormatString (IDS_ACTION_RESTARTSERVICE, TEXT("%s%s"), szText, szText2);
576          break;
577
578       case atCREATEFILESET:
579          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
580          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
581          pszDesc = FormatString (IDS_ACTION_CREATEFILESET, TEXT("%s%s%s"), szText, szText2, l.aActions[ ii ]->Params.sz1);
582          break;
583
584       case atDELETEFILESET:
585          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
586          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
587          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
588          pszDesc = FormatString (IDS_ACTION_DELETEFILESET, TEXT("%s%s%s"), szText, szText2, szText3);
589          break;
590
591       case atMOVEFILESET:
592          l.aActions[ ii ]->Params.lpi2->GetServerName (szText);
593          l.aActions[ ii ]->Params.lpi2->GetAggregateName (szText2);
594          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
595          pszDesc = FormatString (IDS_ACTION_MOVEFILESET, TEXT("%s%s%s"), szText, szText2, szText3);
596          break;
597
598       case atSETFILESETQUOTA:
599          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
600          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
601          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
602          pszDesc = FormatString (IDS_ACTION_SETFILESETQUOTA, TEXT("%s%s%s"), szText, szText2, szText3);
603          break;
604
605       case atSETFILESETREPPARAMS:
606          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
607          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
608          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
609          pszDesc = FormatString (IDS_ACTION_SETREPPARAMS, TEXT("%s%s%s"), szText, szText2, szText3);
610          break;
611
612       case atCREATEREPLICA:
613          l.aActions[ ii ]->Params.lpi2->GetServerName (szText);
614          l.aActions[ ii ]->Params.lpi2->GetAggregateName (szText2);
615          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
616          pszDesc = FormatString (IDS_ACTION_CREATEREPLICA, TEXT("%s%s%s"), szText, szText2, szText3);
617          break;
618
619       case atSYNCVLDB:
620          if (l.aActions[ ii ]->Params.lpi1->fIsServer())
621             {
622             l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
623             pszDesc = FormatString (IDS_ACTION_SYNCVLDB_SVR, TEXT("%s"), szText);
624             }
625          else
626             {
627             l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
628             l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
629             pszDesc = FormatString (IDS_ACTION_SYNCVLDB_AGG, TEXT("%s%s"), szText, szText2);
630             }
631          break;
632
633       case atSALVAGE:
634          if (l.aActions[ ii ]->Params.lpi1->fIsServer())
635             {
636             l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
637             pszDesc = FormatString (IDS_ACTION_SALVAGE_SVR, TEXT("%s"), szText);
638             }
639          else if (l.aActions[ ii ]->Params.lpi1->fIsAggregate())
640             {
641             l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
642             l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
643             pszDesc = FormatString (IDS_ACTION_SALVAGE_AGG, TEXT("%s%s"), szText, szText2);
644             }
645          else // (l.aActions[ ii ]->Params.lpi1->fIsFileset())
646             {
647             l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
648             l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
649             l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
650             pszDesc = FormatString (IDS_ACTION_SALVAGE_VOL, TEXT("%s%s%s"), szText, szText2, szText3);
651             }
652          break;
653
654       case atRENAMEFILESET:
655          pszDesc = FormatString (IDS_ACTION_RENAMEFILESET, TEXT("%s%s"), l.aActions[ ii ]->Params.sz1, l.aActions[ ii ]->Params.sz2);
656          break;
657
658       case atCREATESERVICE:
659          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
660          pszDesc = FormatString (IDS_ACTION_CREATESERVICE, TEXT("%s%s"), szText, l.aActions[ ii ]->Params.sz1);
661          break;
662
663       case atDELETESERVICE:
664          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
665          l.aActions[ ii ]->Params.lpi1->GetServiceName (szText2);
666          pszDesc = FormatString (IDS_ACTION_DELETESERVICE, TEXT("%s%s"), szText, szText2);
667          break;
668
669       case atRELEASEFILESET:
670          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
671          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
672          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
673          pszDesc = FormatString (IDS_ACTION_RELEASEFILESET, TEXT("%s%s%s"), szText, szText2, szText3);
674          break;
675
676       case atGETFILEDATES:
677          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
678          CopyBaseFileName (szText2, l.aActions[ ii ]->Params.sz1);
679          pszDesc = FormatString (IDS_ACTION_GETDATES, TEXT("%s%s"), szText, szText2);
680          break;
681
682       case atEXECUTECOMMAND:
683          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
684          CopyFirstWord (szText2, l.aActions[ ii ]->Params.sz1);
685          pszDesc = FormatString (IDS_ACTION_EXECUTE, TEXT("%s%s"), szText, szText2);
686          break;
687
688       case atADMINLIST_LOAD:
689          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
690          pszDesc = FormatString (IDS_ACTION_ADMINLIST_LOAD, TEXT("%s"), szText);
691          break;
692
693       case atADMINLIST_SAVE:
694          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
695          pszDesc = FormatString (IDS_ACTION_ADMINLIST_SAVE, TEXT("%s"), szText);
696          break;
697
698       case atHOSTLIST_LOAD:
699          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
700          pszDesc = FormatString (IDS_ACTION_HOSTLIST_LOAD, TEXT("%s"), szText);
701          break;
702
703       case atHOSTLIST_SAVE:
704          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
705          pszDesc = FormatString (IDS_ACTION_HOSTLIST_SAVE, TEXT("%s"), szText);
706          break;
707
708       case atCLONE:
709          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
710          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
711          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
712          pszDesc = FormatString (IDS_ACTION_CLONE, TEXT("%s%s%s"), szText, szText2, szText3);
713          break;
714
715       case atCLONESYS:
716          pszDesc = FormatString (IDS_ACTION_CLONESYS);
717          break;
718
719       case atDUMP:
720          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
721          l.aActions[ ii ]->Params.lpi1->GetAggregateName (szText2);
722          l.aActions[ ii ]->Params.lpi1->GetFilesetName (szText3);
723          pszDesc = FormatString (IDS_ACTION_DUMP, TEXT("%s%s%s%s"), szText, szText2, szText3, FindBaseFileName(l.aActions[ ii ]->Params.sz1));
724          break;
725
726       case atRESTORE:
727          pszDesc = FormatString (IDS_ACTION_RESTORE, TEXT("%s%s"), l.aActions[ ii ]->Params.sz1, FindBaseFileName(l.aActions[ ii ]->Params.sz2));
728          break;
729
730       case atSETRESTART:
731          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
732          pszDesc = FormatString (IDS_ACTION_SETRESTART, TEXT("%s"), szText);
733          break;
734
735       case atCHANGEADDR:
736          l.aActions[ ii ]->Params.lpi1->GetServerName (szText);
737          pszDesc = FormatString (IDS_ACTION_CHANGEADDR, TEXT("%s"), szText);
738          break;
739
740       case atOPENCELL:
741          pszDesc = FormatString (IDS_ACTION_OPENCELL, TEXT("%s"), l.aActions[ ii ]->Params.sz1);
742          break;
743       }
744
745    return pszDesc;
746 }
747
748
749 void Action_SetDefaultView (LPVIEWINFO lpvi)
750 {
751    lpvi->lvsView = FLS_VIEW_LIST;
752    lpvi->nColsAvail = nACTIONCOLUMNS;
753
754    for (size_t iCol = 0; iCol < nACTIONCOLUMNS; ++iCol)
755       {
756       lpvi->cxColumns[ iCol ]  = ACTIONCOLUMNS[ iCol ].cxWidth;
757       lpvi->idsColumns[ iCol ] = ACTIONCOLUMNS[ iCol ].idsColumn;
758       }
759
760    lpvi->iSort = actcolELAPSED | COLUMN_SORTREV;
761
762    lpvi->nColsShown = 2;
763    lpvi->aColumns[0] = (int)actcolOPERATION;
764    lpvi->aColumns[1] = (int)actcolELAPSED;
765 }
766
767
768 void Action_ShowConfirmations (BOOL fShow)
769 {
770    l.fShowConfirmations = fShow;
771 }
772
773
774 BOOL Action_CompareNotifyParams (PNOTIFYPARAMS pParams1, PNOTIFYPARAMS pParams2)
775 {
776    if (!pParams1 || !pParams2)
777       return FALSE;
778
779    if (pParams1->lpi1 != pParams2->lpi1)
780       return FALSE;
781    if (pParams1->lpi2 != pParams2->lpi2)
782       return FALSE;
783    if (lstrcmp (pParams1->sz1, pParams2->sz1))
784       return FALSE;
785    if (lstrcmp (pParams1->sz2, pParams2->sz2))
786       return FALSE;
787    if (pParams1->dw1 != pParams2->dw1)
788       return FALSE;
789
790    return TRUE;
791 }
792
793
794 PACTION Action_Begin (ACTIONTYPE Type, PNOTIFYPARAMS pParams)
795 {
796    for (size_t ii = 0; ii < l.cActions; ++ii)
797       {
798       if (!l.aActions[ii])
799          break;
800       }
801    if (!REALLOC (l.aActions, l.cActions, 1+ii, cREALLOC_ACTIONLIST))
802       return NULL;
803
804    PACTION pAction = New (ACTION);
805    memcpy (&pAction->Params, pParams, sizeof(NOTIFYPARAMS));
806    pAction->Type = Type;
807    pAction->dwTickStart = GetTickCount();
808    pAction->hDlg = NULL;
809
810    l.aActions[ii] = pAction;
811
812    if (Type != atREFRESH)
813       l.cActionsInUse++;
814
815    return l.aActions[ii];
816 }
817
818
819 void Action_SpecifyWindow (PACTION pAction, HWND hDlg)
820 {
821    pAction->hDlg = hDlg;
822    ShowWindow (hDlg, SW_SHOW);
823 }
824
825
826 PACTION Action_Find (ACTIONTYPE Type, PNOTIFYPARAMS pParams)
827 {
828    for (size_t ii = 0; ii < l.cActions; ++ii)
829       {
830       if (!l.aActions[ ii ])
831          continue;
832
833       if (l.aActions[ ii ]->Type != Type)
834          continue;
835
836       if (Action_CompareNotifyParams (&l.aActions[ ii ]->Params, pParams))
837          return l.aActions[ ii ];
838       }
839
840    return NULL;
841 }
842
843
844 void Action_End (PACTION pParams, DWORD dwStatus)
845 {
846    if (!pParams)
847       return;
848
849    ACTIONTYPE TypeClosed = atUNUSED;
850
851    for (size_t ii = 0; ii < l.cActions; ++ii)
852       {
853       if (l.aActions[ ii ] == pParams)
854          {
855          if (l.fShowConfirmations && !dwStatus)
856             {
857             switch (l.aActions[ ii ]->Type)
858                {
859                case atUNUSED:
860                case atSCOUT:
861                case atTIMEOUT:
862                case atREFRESH:
863                   // don't show confirmation messages for these operations
864                   break;
865
866                default:
867                   LPTSTR pszDesc;
868                   if ((pszDesc = Action_GetDescription (ii)) != NULL)
869                      {
870                      Message (MB_OK | MB_ICONINFORMATION | MB_MODELESS, IDS_CONFIRMATION_TITLE, TEXT("%1"), TEXT("%s"), pszDesc);
871                      FreeString (pszDesc);
872                      }
873                   break;
874                }
875             }
876
877          TypeClosed = l.aActions[ ii ]->Type;
878
879          if (IsWindow (l.aActions[ ii ]->hDlg))
880             PostMessage (l.aActions[ ii ]->hDlg, WM_COMMAND, IDCANCEL, 0);
881
882          Delete (l.aActions[ii]);
883          l.aActions[ii] = NULL;
884          }
885       }
886
887    // If we've finished all operations in progress, and if the user has
888    // already closed the app (well, tried to--we would've just hidden the
889    // window), close for real.
890    //
891    if ((TypeClosed != atUNUSED) && (TypeClosed != atREFRESH))
892       {
893       if ((--l.cActionsInUse) == 0)
894          {
895          if (g.lpiCell && !IsWindowVisible (g.hMain))
896             {
897             Quit (0);
898             }
899          }
900       }
901 }
902
903
904 BOOL Action_fAnyActive (void)
905 {
906    return (l.cActionsInUse >= 1) ? TRUE : FALSE;
907 }
908
909
910 void Action_OnDestroy (HWND hDlg)
911 {
912    for (size_t ii = 0; ii < l.cActions; ++ii)
913       {
914       if (!l.aActions[ ii ])
915          continue;
916       if (l.aActions[ ii ]->hDlg == hDlg)
917          l.aActions[ ii ]->hDlg = NULL;
918       }
919 }
920
921
922 /*
923  * NO-DIALOG OPERATIONS
924  *
925  */
926
927 void Action_Scout_Begin (PNOTIFYPARAMS pParams)
928 {
929    Action_Begin (atSCOUT, pParams);
930 }
931
932 void Action_Scout_End (PNOTIFYPARAMS pParams)
933 {
934    Action_End (Action_Find (atSCOUT, pParams), pParams->status);
935 }
936
937 void Action_GetServerLogFile_Begin (PNOTIFYPARAMS pParams)
938 {
939    Action_Begin (atGETSERVERLOGFILE, pParams);
940 }
941
942 void Action_GetServerLogFile_End (PNOTIFYPARAMS pParams)
943 {
944    Action_End (Action_Find (atGETSERVERLOGFILE, pParams), pParams->status);
945 }
946
947 void Action_SetServerAuth_Begin (PNOTIFYPARAMS pParams)
948 {
949    Action_Begin (atSETSERVERAUTH, pParams);
950 }
951
952 void Action_SetServerAuth_End (PNOTIFYPARAMS pParams)
953 {
954    Action_End (Action_Find (atSETSERVERAUTH, pParams), pParams->status);
955 }
956
957 void Action_InstallFile_Begin (PNOTIFYPARAMS pParams)
958 {
959    Action_Begin (atINSTALLFILE, pParams);
960 }
961
962 void Action_InstallFile_End (PNOTIFYPARAMS pParams)
963 {
964    Action_End (Action_Find (atINSTALLFILE, pParams), pParams->status);
965 }
966
967 void Action_UninstallFile_Begin (PNOTIFYPARAMS pParams)
968 {
969    Action_Begin (atUNINSTALLFILE, pParams);
970 }
971
972 void Action_UninstallFile_End (PNOTIFYPARAMS pParams)
973 {
974    Action_End (Action_Find (atUNINSTALLFILE, pParams), pParams->status);
975 }
976
977 void Action_PruneFiles_Begin (PNOTIFYPARAMS pParams)
978 {
979    Action_Begin (atPRUNEFILES, pParams);
980 }
981
982 void Action_PruneFiles_End (PNOTIFYPARAMS pParams)
983 {
984    Action_End (Action_Find (atPRUNEFILES, pParams), pParams->status);
985 }
986
987 void Action_StartService_Begin (PNOTIFYPARAMS pParams)
988 {
989    Action_Begin (atSTARTSERVICE, pParams);
990 }
991
992 void Action_StartService_End (PNOTIFYPARAMS pParams)
993 {
994    Action_End (Action_Find (atSTARTSERVICE, pParams), pParams->status);
995 }
996
997 void Action_StopService_Begin (PNOTIFYPARAMS pParams)
998 {
999    Action_Begin (atSTOPSERVICE, pParams);
1000 }
1001
1002 void Action_StopService_End (PNOTIFYPARAMS pParams)
1003 {
1004    Action_End (Action_Find (atSTOPSERVICE, pParams), pParams->status);
1005 }
1006
1007 void Action_RestartService_Begin (PNOTIFYPARAMS pParams)
1008 {
1009    Action_Begin (atRESTARTSERVICE, pParams);
1010 }
1011
1012 void Action_RestartService_End (PNOTIFYPARAMS pParams)
1013 {
1014    Action_End (Action_Find (atRESTARTSERVICE, pParams), pParams->status);
1015 }
1016
1017 void Action_CreateFileset_Begin (PNOTIFYPARAMS pParams)
1018 {
1019    Action_Begin (atCREATEFILESET, pParams);
1020 }
1021
1022 void Action_CreateFileset_End (PNOTIFYPARAMS pParams)
1023 {
1024    Action_End (Action_Find (atCREATEFILESET, pParams), pParams->status);
1025 }
1026
1027 void Action_DeleteFileset_Begin (PNOTIFYPARAMS pParams)
1028 {
1029    Action_Begin (atDELETEFILESET, pParams);
1030 }
1031
1032 void Action_DeleteFileset_End (PNOTIFYPARAMS pParams)
1033 {
1034    Action_End (Action_Find (atDELETEFILESET, pParams), pParams->status);
1035 }
1036
1037 void Action_SetFilesetQuota_Begin (PNOTIFYPARAMS pParams)
1038 {
1039    Action_Begin (atSETFILESETQUOTA, pParams);
1040 }
1041
1042 void Action_SetFilesetQuota_End (PNOTIFYPARAMS pParams)
1043 {
1044    Action_End (Action_Find (atSETFILESETQUOTA, pParams), pParams->status);
1045 }
1046
1047 void Action_SyncVLDB_Begin (PNOTIFYPARAMS pParams)
1048 {
1049    Action_Begin (atSYNCVLDB, pParams);
1050 }
1051
1052 void Action_SyncVLDB_End (PNOTIFYPARAMS pParams)
1053 {
1054    Action_End (Action_Find (atSYNCVLDB, pParams), pParams->status);
1055 }
1056
1057 void Action_Salvage_Begin (PNOTIFYPARAMS pParams)
1058 {
1059    Action_Begin (atSALVAGE, pParams);
1060 }
1061
1062 void Action_Salvage_End (PNOTIFYPARAMS pParams)
1063 {
1064    Action_End (Action_Find (atSALVAGE, pParams), pParams->status);
1065 }
1066
1067 void Action_SetFilesetRepParams_Begin (PNOTIFYPARAMS pParams)
1068 {
1069    Action_Begin (atSETFILESETREPPARAMS, pParams);
1070 }
1071
1072 void Action_SetFilesetRepParams_End (PNOTIFYPARAMS pParams)
1073 {
1074    Action_End (Action_Find (atSETFILESETREPPARAMS, pParams), pParams->status);
1075 }
1076
1077 void Action_CreateReplica_Begin (PNOTIFYPARAMS pParams)
1078 {
1079    Action_Begin (atCREATEREPLICA, pParams);
1080 }
1081
1082 void Action_CreateReplica_End (PNOTIFYPARAMS pParams)
1083 {
1084    Action_End (Action_Find (atCREATEREPLICA, pParams), pParams->status);
1085 }
1086
1087 void Action_RenameFileset_Begin (PNOTIFYPARAMS pParams)
1088 {
1089    Action_Begin (atRENAMEFILESET, pParams);
1090 }
1091
1092 void Action_RenameFileset_End (PNOTIFYPARAMS pParams)
1093 {
1094    Action_End (Action_Find (atRENAMEFILESET, pParams), pParams->status);
1095 }
1096
1097 void Action_CreateService_Begin (PNOTIFYPARAMS pParams)
1098 {
1099    Action_Begin (atCREATESERVICE, pParams);
1100 }
1101
1102 void Action_CreateService_End (PNOTIFYPARAMS pParams)
1103 {
1104    Action_End (Action_Find (atCREATESERVICE, pParams), pParams->status);
1105 }
1106
1107 void Action_DeleteService_Begin (PNOTIFYPARAMS pParams)
1108 {
1109    Action_Begin (atDELETESERVICE, pParams);
1110 }
1111
1112 void Action_DeleteService_End (PNOTIFYPARAMS pParams)
1113 {
1114    Action_End (Action_Find (atDELETESERVICE, pParams), pParams->status);
1115 }
1116
1117 void Action_ReleaseFileset_Begin (PNOTIFYPARAMS pParams)
1118 {
1119    Action_Begin (atRELEASEFILESET, pParams);
1120 }
1121
1122 void Action_ReleaseFileset_End (PNOTIFYPARAMS pParams)
1123 {
1124    Action_End (Action_Find (atRELEASEFILESET, pParams), pParams->status);
1125 }
1126
1127 void Action_GetFileDates_Begin (PNOTIFYPARAMS pParams)
1128 {
1129    Action_Begin (atGETFILEDATES, pParams);
1130 }
1131
1132 void Action_GetFileDates_End (PNOTIFYPARAMS pParams)
1133 {
1134    Action_End (Action_Find (atGETFILEDATES, pParams), pParams->status);
1135 }
1136
1137 void Action_ExecuteCommand_Begin (PNOTIFYPARAMS pParams)
1138 {
1139    Action_Begin (atEXECUTECOMMAND, pParams);
1140 }
1141
1142 void Action_ExecuteCommand_End (PNOTIFYPARAMS pParams)
1143 {
1144    Action_End (Action_Find (atEXECUTECOMMAND, pParams), pParams->status);
1145 }
1146
1147 void Action_AdminListLoad_Begin (PNOTIFYPARAMS pParams)
1148 {
1149    Action_Begin (atADMINLIST_LOAD, pParams);
1150 }
1151
1152 void Action_AdminListLoad_End (PNOTIFYPARAMS pParams)
1153 {
1154    Action_End (Action_Find (atADMINLIST_LOAD, pParams), pParams->status);
1155 }
1156
1157 void Action_AdminListSave_Begin (PNOTIFYPARAMS pParams)
1158 {
1159    Action_Begin (atADMINLIST_SAVE, pParams);
1160 }
1161
1162 void Action_AdminListSave_End (PNOTIFYPARAMS pParams)
1163 {
1164    Action_End (Action_Find (atADMINLIST_SAVE, pParams), pParams->status);
1165 }
1166
1167 void Action_HostListLoad_Begin (PNOTIFYPARAMS pParams)
1168 {
1169    Action_Begin (atHOSTLIST_LOAD, pParams);
1170 }
1171
1172 void Action_HostListLoad_End (PNOTIFYPARAMS pParams)
1173 {
1174    Action_End (Action_Find (atHOSTLIST_LOAD, pParams), pParams->status);
1175 }
1176
1177 void Action_HostListSave_Begin (PNOTIFYPARAMS pParams)
1178 {
1179    Action_Begin (atHOSTLIST_SAVE, pParams);
1180 }
1181
1182 void Action_HostListSave_End (PNOTIFYPARAMS pParams)
1183 {
1184    Action_End (Action_Find (atHOSTLIST_SAVE, pParams), pParams->status);
1185 }
1186
1187 void Action_Clone_Begin (PNOTIFYPARAMS pParams)
1188 {
1189    Action_Begin (atCLONE, pParams);
1190 }
1191
1192 void Action_Clone_End (PNOTIFYPARAMS pParams)
1193 {
1194    Action_End (Action_Find (atCLONE, pParams), pParams->status);
1195 }
1196
1197 void Action_Clonesys_Begin (PNOTIFYPARAMS pParams)
1198 {
1199    Action_Begin (atCLONESYS, pParams);
1200 }
1201
1202 void Action_Clonesys_End (PNOTIFYPARAMS pParams)
1203 {
1204    Action_End (Action_Find (atCLONESYS, pParams), pParams->status);
1205 }
1206
1207 void Action_SetRestart_Begin (PNOTIFYPARAMS pParams)
1208 {
1209    Action_Begin (atSETRESTART, pParams);
1210 }
1211
1212 void Action_SetRestart_End (PNOTIFYPARAMS pParams)
1213 {
1214    Action_End (Action_Find (atSETRESTART, pParams), pParams->status);
1215 }
1216
1217 void Action_ChangeAddr_Begin (PNOTIFYPARAMS pParams)
1218 {
1219    Action_Begin (atCHANGEADDR, pParams);
1220 }
1221
1222 void Action_ChangeAddr_End (PNOTIFYPARAMS pParams)
1223 {
1224    Action_End (Action_Find (atCHANGEADDR, pParams), pParams->status);
1225 }
1226
1227
1228 /*
1229  * REFRESHALL DIALOGS
1230  *
1231  */
1232
1233 void Action_Refresh_Begin (PNOTIFYPARAMS pParams)
1234 {
1235    NOTIFYPARAMS ZeroParams;
1236    memset (&ZeroParams, 0x00, sizeof(NOTIFYPARAMS));
1237
1238    PACTION pAction;
1239    if ((pAction = Action_Find (atREFRESH, &ZeroParams)) == NULL)
1240       {
1241       if ((pAction = Action_Begin (atREFRESH, &ZeroParams)) != NULL)
1242          {
1243          HWND hDlg = ModelessDialogParam (IDD_REFRESHALL, NULL, (DLGPROC)Action_Refresh_DlgProc, (LPARAM)(pParams->lpi1));
1244
1245          if (hDlg == NULL)
1246             Action_End (pAction, pParams->status);
1247          else
1248             Action_SpecifyWindow (pAction, hDlg);
1249          }
1250       }
1251 }
1252
1253
1254 void Action_Refresh_Update (PNOTIFYPARAMS pParams)
1255 {
1256    NOTIFYPARAMS ZeroParams;
1257    memset (&ZeroParams, 0x00, sizeof(NOTIFYPARAMS));
1258
1259    PACTION pAction;
1260    if ((pAction = Action_Find (atREFRESH, &ZeroParams)) != NULL)
1261       {
1262       if (pAction->hDlg && IsWindow(pAction->hDlg))
1263          PostMessage (pAction->hDlg, WM_REFRESH_UPDATE, (WPARAM)pParams->dw1, (LPARAM)pParams->lpi1);
1264       }
1265 }
1266
1267
1268 void Action_Refresh_SectionStart (PNOTIFYPARAMS pParams)
1269 {
1270    NOTIFYPARAMS ZeroParams;
1271    memset (&ZeroParams, 0x00, sizeof(NOTIFYPARAMS));
1272
1273    PACTION pAction;
1274    if ((pAction = Action_Find (atREFRESH, &ZeroParams)) != NULL)
1275       {
1276       if (pAction->hDlg && IsWindow(pAction->hDlg))
1277          PostMessage (pAction->hDlg, WM_REFRESH_SETSECTION, (WPARAM)TRUE, (LPARAM)pParams->dw1);
1278       }
1279 }
1280
1281
1282 void Action_Refresh_SectionEnd (PNOTIFYPARAMS pParams)
1283 {
1284    NOTIFYPARAMS ZeroParams;
1285    memset (&ZeroParams, 0x00, sizeof(NOTIFYPARAMS));
1286
1287    PACTION pAction;
1288    if ((pAction = Action_Find (atREFRESH, &ZeroParams)) != NULL)
1289       {
1290       if (pAction->hDlg && IsWindow(pAction->hDlg))
1291          PostMessage (pAction->hDlg, WM_REFRESH_SETSECTION, (WPARAM)FALSE, (LPARAM)pParams->dw1);
1292       }
1293 }
1294
1295
1296 void Action_Refresh_End (PNOTIFYPARAMS pParams)
1297 {
1298    NOTIFYPARAMS ZeroParams;
1299    memset (&ZeroParams, 0x00, sizeof(NOTIFYPARAMS));
1300
1301    Action_End (Action_Find (atREFRESH, &ZeroParams), pParams->status);
1302 }
1303
1304
1305 BOOL CALLBACK Action_Refresh_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
1306 {
1307    switch (msg)
1308       {
1309       case WM_INITDIALOG:
1310          LPIDENT lpi;
1311          if ((lpi = (LPIDENT)lp) != NULL)
1312             {
1313             LPTSTR pszDesc = NULL;
1314             TCHAR szName[ cchRESOURCE ];
1315
1316             if (lpi->fIsCell())
1317                {
1318                lpi->GetCellName (szName);
1319                pszDesc = FormatString (IDS_REFRESH_DESC_CELL, TEXT("%s"), szName);
1320                }
1321             else
1322                {
1323                lpi->GetServerName (szName);
1324                pszDesc = FormatString (IDS_REFRESH_DESC_SERVER, TEXT("%s"), szName);
1325                }
1326             if (pszDesc != NULL)
1327                {
1328                SetDlgItemText (hDlg, IDC_REFRESH_DESC, pszDesc);
1329                FreeString (pszDesc);
1330                }
1331             }
1332
1333          SendDlgItemMessage (hDlg, IDC_REFRESH_PERCENTBAR, PBM_SETRANGE, 0, MAKELPARAM(0,100));
1334          Action_Refresh_UpdateText (hDlg, lpi, 0);
1335          Action_Refresh_SetSection (hDlg, TRUE, -1);
1336          break;
1337
1338       case WM_REFRESH_UPDATE:
1339          Action_Refresh_UpdateText (hDlg, (LPIDENT)lp, (DWORD)wp);
1340          break;
1341
1342       case WM_REFRESH_SETSECTION:
1343          Action_Refresh_SetSection (hDlg, (BOOL)wp, (int)lp);
1344          break;
1345
1346       case WM_DESTROY:
1347          Action_OnDestroy (hDlg);
1348          break;
1349
1350       case WM_COMMAND:
1351          switch (LOWORD(wp))
1352             {
1353             case IDOK:
1354             case IDCANCEL:
1355                DestroyWindow (hDlg);
1356                break;
1357
1358             case IDC_REFRESH_SKIP:
1359                Action_Refresh_SkipSection (hDlg);
1360                break;
1361             }
1362          break;
1363       }
1364
1365    return FALSE;
1366 }
1367
1368
1369 void Action_Refresh_UpdateText (HWND hDlg, LPIDENT lpi, DWORD dwPerComplete)
1370 {
1371    dwPerComplete = limit (0, dwPerComplete, 100);
1372
1373    SendDlgItemMessage (hDlg, IDC_REFRESH_PERCENTBAR, PBM_SETPOS, (WPARAM)dwPerComplete, 0);
1374
1375    LPTSTR pszComplete = FormatString (IDS_REFRESH_PERCENT, TEXT("%lu"), dwPerComplete);
1376    SetDlgItemText (hDlg, IDC_REFRESH_PERCENT, pszComplete);
1377    FreeString (pszComplete);
1378
1379    if (lpi == NULL)
1380       {
1381       TCHAR szText[ cchRESOURCE ];
1382       GetString (szText, IDS_REFRESH_CURRENT_VLDB);
1383       SetDlgItemText (hDlg, IDC_REFRESH_CURRENT, szText);
1384       }
1385    else
1386       {
1387       TCHAR szCell[ cchNAME ];
1388       TCHAR szServer[ cchNAME ];
1389       TCHAR szAggregate[ cchNAME ];
1390       TCHAR szFileset[ cchNAME ];
1391       TCHAR szService[ cchNAME ];
1392
1393       lpi->GetCellName (szCell);
1394       if (!lpi->fIsCell())
1395          lpi->GetServerName (szServer);
1396       if (lpi->fIsAggregate() || lpi->fIsFileset())
1397          lpi->GetAggregateName (szAggregate);
1398       if (lpi->fIsFileset())
1399          lpi->GetFilesetName (szFileset);
1400       if (lpi->fIsService())
1401          lpi->GetServiceName (szService);
1402
1403       LPTSTR pszCurrent = NULL;
1404       if (lpi->fIsCell())
1405          pszCurrent = FormatString (IDS_REFRESH_CURRENT_CELL, TEXT("%s"), szCell);
1406       if (lpi->fIsServer())
1407          pszCurrent = FormatString (IDS_REFRESH_CURRENT_SERVER, TEXT("%s%s"), szCell, szServer);
1408       else if (lpi->fIsAggregate())
1409          pszCurrent = FormatString (IDS_REFRESH_CURRENT_AGGREGATE, TEXT("%s%s%s"), szCell, szServer, szAggregate);
1410       else if (lpi->fIsFileset())
1411          pszCurrent = FormatString (IDS_REFRESH_CURRENT_FILESET, TEXT("%s%s%s%s"), szCell, szServer, szAggregate, szFileset);
1412       else if (lpi->fIsService())
1413          pszCurrent = FormatString (IDS_REFRESH_CURRENT_SERVICE, TEXT("%s%s%s"), szCell, szServer, szService);
1414
1415       if (pszCurrent != NULL)
1416          {
1417          SetDlgItemText (hDlg, IDC_REFRESH_CURRENT, pszCurrent);
1418          FreeString (pszCurrent);
1419          }
1420       }
1421 }
1422
1423
1424 void Action_Refresh_SetSection (HWND hDlg, BOOL fStart, int idSection)
1425 {
1426    // Are we ending a section that we don't care about?
1427    //
1428    if ((!fStart) && (idSection != (int)GetWindowLong (hDlg, DWL_USER)))
1429       return;
1430
1431    if (!fStart)
1432       idSection = -1;  // ending a section means new section = -1 (invalid)
1433
1434    SetWindowLong (hDlg, DWL_USER, idSection);
1435    EnableWindow (GetDlgItem (hDlg, IDC_REFRESH_SKIP), (idSection == -1) ? FALSE : TRUE);
1436 }
1437
1438
1439 void Action_Refresh_SkipSection (HWND hDlg)
1440 {
1441    int idSection;
1442    if ((idSection = (int)GetWindowLong (hDlg, DWL_USER)) != -1)
1443       {
1444       AfsClass_SkipRefresh (idSection);
1445       Action_Refresh_SetSection (hDlg, FALSE, idSection);
1446       }
1447 }
1448
1449
1450 /*
1451  * MOVE-FILESET DIALOGS
1452  *
1453  */
1454
1455 void Action_MoveFileset_Begin (PNOTIFYPARAMS pParams)
1456 {
1457    PACTION pAction;
1458    if ((pAction = Action_Begin (atMOVEFILESET, pParams)) != NULL)
1459       {
1460       HWND hDlg = ModelessDialogParam (IDD_SET_MOVING, NULL, (DLGPROC)Action_MoveFileset_DlgProc, (LPARAM)pAction);
1461
1462       if (hDlg == NULL)
1463          Action_End (pAction, pParams->status);
1464       else
1465          Action_SpecifyWindow (pAction, hDlg);
1466       }
1467 }
1468
1469
1470 void Action_MoveFileset_End (PNOTIFYPARAMS pParams)
1471 {
1472    Action_End (Action_Find (atMOVEFILESET, pParams), pParams->status);
1473 }
1474
1475
1476 BOOL CALLBACK Action_MoveFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
1477 {
1478    HWND hAnimate = GetDlgItem (hDlg, IDC_ANIMATE);
1479
1480    switch (msg)
1481       {
1482       case WM_INITDIALOG:
1483          Animate_Open (hAnimate, MAKEINTRESOURCE( AVI_SETMOVE ));
1484          Animate_Play (hAnimate, 0, -1, -1);
1485
1486          PACTION pAction;
1487          if ((pAction = (PACTION)lp) != NULL)
1488             {
1489             TCHAR szServerSource[ cchNAME ];
1490             TCHAR szServerTarget[ cchNAME ];
1491             TCHAR szAggregateSource[ cchNAME ];
1492             TCHAR szAggregateTarget[ cchNAME ];
1493             TCHAR szFileset[ cchNAME ];
1494             pAction->Params.lpi1->GetServerName (szServerSource);
1495             pAction->Params.lpi1->GetAggregateName (szAggregateSource);
1496             pAction->Params.lpi1->GetFilesetName (szFileset);
1497             pAction->Params.lpi2->GetServerName (szServerTarget);
1498             pAction->Params.lpi2->GetAggregateName (szAggregateTarget);
1499
1500             TCHAR szText[ cchRESOURCE ];
1501             GetDlgItemText (hDlg, IDC_MOVESET_DESC, szText, cchRESOURCE);
1502
1503             LPTSTR pszText;
1504             pszText = FormatString (szText, TEXT("%s%s%s%s%s"), szServerSource, szAggregateSource, szFileset, szServerTarget, szAggregateTarget);
1505             SetDlgItemText (hDlg, IDC_MOVESET_DESC, pszText);
1506             FreeString (pszText);
1507             }
1508          break;
1509
1510       case WM_DESTROY:
1511          Animate_Stop (hAnimate);
1512          Animate_Close (hAnimate);
1513          Action_OnDestroy (hDlg);
1514          break;
1515
1516       case WM_COMMAND:
1517          switch (LOWORD(wp))
1518             {
1519             case IDOK:
1520             case IDCANCEL:
1521                DestroyWindow (hDlg);
1522                break;
1523             }
1524          break;
1525       }
1526
1527    return FALSE;
1528 }
1529
1530
1531 /*
1532  * DUMP-FILESET DIALOGS
1533  *
1534  */
1535
1536 void Action_DumpFileset_Begin (PNOTIFYPARAMS pParams)
1537 {
1538    PACTION pAction;
1539    if ((pAction = Action_Begin (atDUMP, pParams)) != NULL)
1540       {
1541       HWND hDlg = ModelessDialogParam (IDD_SET_DUMPING, NULL, (DLGPROC)Action_DumpFileset_DlgProc, (LPARAM)pAction);
1542
1543       if (hDlg == NULL)
1544          Action_End (pAction, pParams->status);
1545       else
1546          Action_SpecifyWindow (pAction, hDlg);
1547       }
1548 }
1549
1550 void Action_DumpFileset_End (PNOTIFYPARAMS pParams)
1551 {
1552    Action_End (Action_Find (atDUMP, pParams), pParams->status);
1553 }
1554
1555 BOOL CALLBACK Action_DumpFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
1556 {
1557    HWND hAnimate = GetDlgItem (hDlg, IDC_ANIMATE);
1558
1559    switch (msg)
1560       {
1561       case WM_INITDIALOG:
1562          Animate_Open (hAnimate, MAKEINTRESOURCE( AVI_SETMOVE ));
1563          Animate_Play (hAnimate, 0, -1, -1);
1564
1565          PACTION pAction;
1566          if ((pAction = (PACTION)lp) != NULL)
1567             {
1568             TCHAR szServer[ cchNAME ];
1569             TCHAR szAggregate[ cchNAME ];
1570             TCHAR szFileset[ cchNAME ];
1571             pAction->Params.lpi1->GetServerName (szServer);
1572             pAction->Params.lpi1->GetAggregateName (szAggregate);
1573             pAction->Params.lpi1->GetFilesetName (szFileset);
1574
1575             TCHAR szText[ cchRESOURCE ];
1576             GetDlgItemText (hDlg, IDC_DUMPSET_DESC, szText, cchRESOURCE);
1577
1578             LPTSTR pszText;
1579             pszText = FormatString (szText, TEXT("%s%s%s%s"), szServer, szAggregate, szFileset, FindBaseFileName(pAction->Params.sz1));
1580             SetDlgItemText (hDlg, IDC_DUMPSET_DESC, pszText);
1581             FreeString (pszText);
1582             }
1583          break;
1584
1585       case WM_DESTROY:
1586          Animate_Stop (hAnimate);
1587          Animate_Close (hAnimate);
1588          Action_OnDestroy (hDlg);
1589          break;
1590
1591       case WM_COMMAND:
1592          switch (LOWORD(wp))
1593             {
1594             case IDOK:
1595             case IDCANCEL:
1596                DestroyWindow (hDlg);
1597                break;
1598             }
1599          break;
1600       }
1601
1602    return FALSE;
1603 }
1604
1605
1606 /*
1607  * RESTORE-FILESET DIALOGS
1608  *
1609  */
1610
1611 void Action_RestoreFileset_Begin (PNOTIFYPARAMS pParams)
1612 {
1613    PACTION pAction;
1614    if ((pAction = Action_Begin (atRESTORE, pParams)) != NULL)
1615       {
1616       HWND hDlg = ModelessDialogParam (IDD_SET_RESTORING, NULL, (DLGPROC)Action_RestoreFileset_DlgProc, (LPARAM)pAction);
1617
1618       if (hDlg == NULL)
1619          Action_End (pAction, pParams->status);
1620       else
1621          Action_SpecifyWindow (pAction, hDlg);
1622       }
1623 }
1624
1625 void Action_RestoreFileset_End (PNOTIFYPARAMS pParams)
1626 {
1627    Action_End (Action_Find (atRESTORE, pParams), pParams->status);
1628 }
1629
1630 BOOL CALLBACK Action_RestoreFileset_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
1631 {
1632    HWND hAnimate = GetDlgItem (hDlg, IDC_ANIMATE);
1633
1634    switch (msg)
1635       {
1636       case WM_INITDIALOG:
1637          Animate_Open (hAnimate, MAKEINTRESOURCE( AVI_SETMOVE ));
1638          Animate_Play (hAnimate, 0, -1, -1);
1639
1640          PACTION pAction;
1641          if ((pAction = (PACTION)lp) != NULL)
1642             {
1643             TCHAR szText[ cchRESOURCE ];
1644             GetDlgItemText (hDlg, IDC_RESTORESET_DESC, szText, cchRESOURCE);
1645
1646             LPTSTR pszText;
1647             pszText = FormatString (szText, TEXT("%s%s"), ((LPTSTR)pAction->Params.sz1), FindBaseFileName(pAction->Params.sz2));
1648             SetDlgItemText (hDlg, IDC_RESTORESET_DESC, pszText);
1649             FreeString (pszText);
1650             }
1651          break;
1652
1653       case WM_DESTROY:
1654          Animate_Stop (hAnimate);
1655          Animate_Close (hAnimate);
1656          Action_OnDestroy (hDlg);
1657          break;
1658
1659       case WM_COMMAND:
1660          switch (LOWORD(wp))
1661             {
1662             case IDOK:
1663             case IDCANCEL:
1664                DestroyWindow (hDlg);
1665                break;
1666             }
1667          break;
1668       }
1669
1670    return FALSE;
1671 }
1672
1673
1674 /*
1675  * OPEN-CELL DIALOGS
1676  *
1677  */
1678
1679 void Action_OpenCell_Begin (PNOTIFYPARAMS pParams)
1680 {
1681    PACTION pAction;
1682    if ((pAction = Action_Begin (atOPENCELL, pParams)) != NULL)
1683       {
1684       if (!IsWindow (g.hMain) || !IsWindowVisible (g.hMain))
1685          {
1686          HWND hDlg = ModelessDialogParam (IDD_OPENINGCELL, NULL, (DLGPROC)Action_OpenCell_DlgProc, (LPARAM)pAction);
1687
1688          if (hDlg == NULL)
1689             Action_End (pAction, pParams->status);
1690          else
1691             Action_SpecifyWindow (pAction, hDlg);
1692          }
1693       }
1694 }
1695
1696 void Action_OpenCell_End (PNOTIFYPARAMS pParams)
1697 {
1698    Action_End (Action_Find (atOPENCELL, pParams), pParams->status);
1699 }
1700
1701 BOOL CALLBACK Action_OpenCell_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
1702 {
1703    static int iFrameLast = 0;
1704
1705    if (msg == WM_INITDIALOG)
1706       SetWindowLong (hDlg, DWL_USER, lp);
1707
1708    switch (msg)
1709       {
1710       case WM_INITDIALOG:
1711          AfsAppLib_StartAnimation (GetDlgItem (hDlg, IDC_ANIMATE));
1712
1713          PACTION pAction;
1714          if ((pAction = (PACTION)lp) != NULL)
1715             {
1716             TCHAR szText[ cchRESOURCE ];
1717             GetDlgItemText (hDlg, IDC_OPENCELL_DESC, szText, cchRESOURCE);
1718
1719             LPTSTR pszText;
1720             pszText = FormatString (szText, TEXT("%s"), pAction->Params.sz1);
1721             SetDlgItemText (hDlg, IDC_OPENCELL_DESC, pszText);
1722             FreeString (pszText);
1723             }
1724          break;
1725
1726       case WM_DESTROY:
1727          Action_OnDestroy (hDlg);
1728          break;
1729
1730       case WM_COMMAND:
1731          switch (LOWORD(wp))
1732             {
1733             case IDOK:
1734             case IDCANCEL:
1735                DestroyWindow (hDlg);
1736                break;
1737             }
1738          break;
1739       }
1740
1741    return FALSE;
1742 }
1743