2 * Copyright 2000, International Business Machines Corporation and others.
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
11 * INCLUDES _________________________________________________________________
19 #include <afs/param.h>
27 #include "get_cur_config.h"
28 #include "partition_utils.h"
30 #include <afs\dirpath.h>
31 #include <afs\afs_clientAdmin.h>
33 #include <afs\lanahelper.h>
37 * DEFINITIONS _________________________________________________________________
43 * PROTOTYPES _________________________________________________________________
46 static void SetConfigDefaults();
47 static void RunCfgTool();
48 static void RunWizard();
49 static void CloseLibHandles(BOOL bExiting
= FALSE
);
51 void RegisterWizardHelp();
52 void RegisterConfigToolHelp();
54 // These are the prototypes for the dialog procs of each wizard page.
55 BOOL CALLBACK
IntroPageDlgProc(HWND hRHS
, UINT msg
, WPARAM wp
, LPARAM lp
);
56 BOOL CALLBACK
InfoPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
57 BOOL CALLBACK
InfoPage2DlgProc(HWND hRHS
, UINT msg
, WPARAM wp
, LPARAM lp
);
58 BOOL CALLBACK
FileServerPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
59 BOOL CALLBACK
DBServerPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
60 BOOL CALLBACK
BackupPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
61 BOOL CALLBACK
PartitionPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
62 BOOL CALLBACK
RootAfsPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
63 BOOL CALLBACK
ReplicationPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
64 BOOL CALLBACK
SysControlPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
65 BOOL CALLBACK
ConfigServerPageDlgProc(HWND hwndDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
68 static WIZARD_STATE g_aStates
[] = {
69 { sidSTEP_ONE
, IDD_INTRO_PAGE
, (DLGPROC
)IntroPageDlgProc
, 0 },
70 { sidSTEP_TWO
, IDD_INFO_PAGE
, (DLGPROC
)InfoPageDlgProc
, 0 },
71 { sidSTEP_THREE
, IDD_INFO_PAGE2_FIRST_SERVER
, (DLGPROC
)InfoPage2DlgProc
, 0 },
72 { sidSTEP_FOUR
, IDD_INFO_PAGE2_NOT_FIRST_SERVER
,(DLGPROC
)InfoPage2DlgProc
, 0 },
73 { sidSTEP_FIVE
, IDD_FILE_SERVER_PAGE
, (DLGPROC
)FileServerPageDlgProc
, 0 },
74 { sidSTEP_SIX
, IDD_DB_SERVER_PAGE
, (DLGPROC
)DBServerPageDlgProc
, 0 },
75 { sidSTEP_SEVEN
, IDD_BACKUP_SERVER_PAGE
, (DLGPROC
)BackupPageDlgProc
, 0 },
76 { sidSTEP_EIGHT
, IDD_PARTITION_PAGE
, (DLGPROC
)PartitionPageDlgProc
, 0 },
77 { sidSTEP_NINE
, IDD_ROOT_VOLUMES_PAGE
, (DLGPROC
)RootAfsPageDlgProc
, 0 },
78 { sidSTEP_TEN
, IDD_REPLICATION_PAGE
, (DLGPROC
)ReplicationPageDlgProc
, 0 },
79 { sidSTEP_ELEVEN
, IDD_SYS_CONTROL_PAGE
, (DLGPROC
)SysControlPageDlgProc
, 0 },
80 { sidSTEP_TWELVE
, IDD_CONFIG_SERVER_PAGE
, (DLGPROC
)ConfigServerPageDlgProc
, 0 }
83 size_t g_nNumStates
= sizeof(g_aStates
) / sizeof(g_aStates
[0]);
86 // Res ID's of text descriptions of each state
87 UINT g_StateDesc
[] = {
105 * EXPORTED VARIABLES _________________________________________________________________
108 LPWIZARD g_pWiz
= NULL
;
109 LPPROPSHEET g_pSheet
= NULL
;
118 static void *hClientCell
= 0;
125 * EXPORTED FUNCTIONS _________________________________________________________________
128 extern "C" int WINAPI
WinMain (HINSTANCE hInst
, HINSTANCE hPrev
, LPSTR pszCmdLineA
, int nCmdShow
)
130 afs_status_t nStatus
;
132 TaLocale_LoadCorrespondingModule (hInst
);
134 // Tell the applib our application's name
135 TCHAR szAppName
[cchRESOURCE
];
136 AfsAppLib_SetAppName(GetResString(GetAppTitleID(), szAppName
));
138 // Open the admin libraries
139 int nResult
= afsclient_Init(&nStatus
);
141 ShowError(0, nStatus
, IDS_CANT_INIT_ADMIN_LIBS
);
146 char szLogPath
[MAX_PATH
];
147 sprintf(szLogPath
, "%s\\%s", AFSDIR_SERVER_LOGS_DIRPATH
, LOG_FILE_NAME
);
148 if (!g_LogFile
.Open(szLogPath
))
149 ShowError(0, 0, IDS_CANT_OPEN_LOG_FILE
);
151 // Register the help file with the applib's help system
152 AfsAppLib_RegisterHelpFile(TEXT("TaAfsCfg.hlp"));
154 /* Start up sockets */
156 WSAStartup(0x0101, &WSAjunk
);
158 memset(&g_CfgData
, 0, sizeof(CFG_DATA
));
160 // Get this machine's local name
161 char szLocalName
[sizeof(g_CfgData
.szLocalName
) / sizeof(TCHAR
)];
162 if (gethostname(szLocalName
, sizeof(szLocalName
)) != 0) {
163 ShowError(GetFocus(), WSAGetLastError(), IDS_ERROR_LOCAL_HOST_NAME
);
166 CopyAnsiToString(g_CfgData
.szLocalName
, szLocalName
);
168 // Turn the local name into a host name
169 struct hostent
*pHostEnt
= gethostbyname(szLocalName
);
171 ShowError(GetFocus(), WSAGetLastError(), IDS_ERROR_HOST_NAME
);
174 CopyAnsiToString(g_CfgData
.szHostname
, pHostEnt
->h_name
, sizeof(g_CfgData
.szHostname
));
176 RegisterFastListClass();
178 // Get current config status
179 BOOL bCanceled
= FALSE
;
180 DWORD dwStatus
= GetCurrentConfig(NULL
, bCanceled
);
181 if (dwStatus
|| bCanceled
) {
183 ShowError(GetFocus(), dwStatus
, IDS_CONFIG_CHECK_FAILED
);
187 // Run the appropriate interface
188 if ((strstr(_strlwr(pszCmdLineA
), "wizard") != 0))
193 FreePartitionTable();
195 // Disconnect from the config and admin libraries
196 CloseLibHandles(TRUE
);
202 * This is a dialog proc that is shared by all of the wizard pages. It
203 * handles things that are common to all of them. Each page also has its
206 BOOL CALLBACK
WizStep_Common_DlgProc(HWND hRHS
, UINT msg
, WPARAM wp
, LPARAM lp
)
208 // Get the dialog's resource ID
209 int nIDD
= GetWindowLong(hRHS
, GWL_ID
);
211 if (AfsAppLib_HandleHelp(nIDD
, hRHS
, msg
, wp
, lp
))
215 case WM_INITDIALOG
: MakeBold(hRHS
, IDC_TITLE
);
220 switch (LOWORD(wp
)) {
231 BOOL
QueryCancelWiz()
233 int nChoice
= Message(MB_YESNO
, IDS_WIZARD_APP_TITLE
, IDS_CANCEL_DESC
);
234 if (nChoice
== IDYES
) {
235 g_LogFile
.Write("User has chosen to cancel the program.\r\n");
246 * Accessor functions for the g_CfgData variable. There are versions
247 * for both TCHARs and char *'s.
249 TCHAR
GetDeviceName() { return g_CfgData
.chDeviceName
; }
250 LPTSTR
GetPartitionName() { return g_CfgData
.szPartitionName
; }
251 LPTSTR
GetHostName() { return g_CfgData
.szHostname
; }
252 LPTSTR
GetSysControlMachine() { return g_CfgData
.szSysControlMachine
; }
253 LPTSTR
GetCellName() { return g_CfgData
.szCellName
; }
254 LPTSTR
GetServerPW() { return g_CfgData
.szServerPW
; }
255 LPTSTR
GetAdminName() { return g_CfgData
.szAdminName
; }
256 LPTSTR
GetAdminPW() { return g_CfgData
.szAdminPW
; }
257 LPTSTR
GetAdminUID() { return g_CfgData
.szAdminUID
; }
258 LPTSTR
GetLocalName() { return g_CfgData
.szLocalName
; }
259 LPTSTR
GetHostname() { return g_CfgData
.szHostname
; }
260 LPTSTR
GetCellServDbHostname() { return g_CfgData
.szCellServDbHostname
; }
261 LPTSTR
GetClientCellName() { return g_CfgData
.szClientCellName
; }
262 LPTSTR
GetSalvageLogFileName() { return g_CfgData
.szSalvageLogFileName
; }
264 LPTSTR
GetClientNetbiosName()
266 static TCHAR szValue
[MAX_MACHINE_NAME_LEN
+ 1] = "";
268 if ( szValue
[0] == 0 )
269 CopyAnsiToString(GetClientNetbiosNameA(), szValue
);
274 char GetDeviceNameA()
276 static char szValueA
[2];
278 TCHAR devName
[2] = TEXT("X");
279 devName
[0] = g_CfgData
.chDeviceName
;
281 CopyStringToAnsi(szValueA
, devName
);
286 char *GetPartitionNameA()
288 static char szValueA
[MAX_PARTITION_NAME_LEN
+ 1];
290 CopyStringToAnsi(szValueA
, g_CfgData
.szPartitionName
);
295 char *GetSysControlMachineA()
297 static char szValueA
[MAX_MACHINE_NAME_LEN
+ 1];
299 CopyStringToAnsi(szValueA
, g_CfgData
.szSysControlMachine
);
306 static char szValueA
[MAX_CELL_NAME_LEN
+ 1];
308 CopyStringToAnsi(szValueA
, g_CfgData
.szCellName
);
315 static char szValueA
[MAX_SERVER_PW_LEN
+ 1];
317 CopyStringToAnsi(szValueA
, g_CfgData
.szServerPW
);
322 char *GetAdminNameA()
324 static char szValueA
[MAX_ADMIN_NAME_LEN
+ 1];
326 CopyStringToAnsi(szValueA
, g_CfgData
.szAdminName
);
333 static char szValueA
[MAX_ADMIN_PW_LEN
+ 1];
335 CopyStringToAnsi(szValueA
, g_CfgData
.szAdminPW
);
342 static char szValueA
[MAX_UID_LEN
+ 1];
344 CopyStringToAnsi(szValueA
, g_CfgData
.szAdminUID
);
349 char *GetLocalNameA()
351 static char szValueA
[MAX_MACHINE_NAME_LEN
+ 1];
353 CopyStringToAnsi(szValueA
, g_CfgData
.szLocalName
);
360 static char szValueA
[MAX_MACHINE_NAME_LEN
+ 1];
362 CopyStringToAnsi(szValueA
, g_CfgData
.szHostname
);
367 char *GetCellServDbHostnameA()
369 static char szValueA
[MAX_MACHINE_NAME_LEN
+ 1];
371 CopyStringToAnsi(szValueA
, g_CfgData
.szCellServDbHostname
);
376 char *GetClientCellNameA()
378 static char szValueA
[MAX_CELL_NAME_LEN
+ 1];
380 CopyStringToAnsi(szValueA
, g_CfgData
.szClientCellName
);
385 char *GetClientNetbiosNameA()
387 static char szValueA
[MAX_MACHINE_NAME_LEN
+ 1]="";
389 if ( szValueA
[0] == 0 )
390 lana_GetNetbiosName(szValueA
, LANA_NETBIOS_NAME_FULL
);
395 char *GetSalvageLogFileNameA()
397 static char szValueA
[_MAX_PATH
];
399 CopyStringToAnsi(szValueA
, g_CfgData
.szSalvageLogFileName
);
405 BOOL
GetLibHandles(afs_status_t
*pStatus
)
407 ASSERT(g_CfgData
.szHostname
[0]);
411 // ************************* NOTE ********************************
412 // * You MUST have already determined whether or not the host
413 // * and client config info is valid before calling this function.
414 // ***************************************************************
416 // This function can be called at any time to get handles to the cell and
417 // the config library. It will try to get the most powerful handle to the
418 // cell that it can, and then use that to open the config library. If the
419 // libraries are already open, it will close them first. Two handles to
420 // the config library will be opened, one to the server to be configured,
421 // and one to the client machine we are configuring from.
423 // There are two types of cell handles, NULL and Standard. A null handle
424 // can make calls to any server except DB servers. We need this primarily
425 // to talk to the bos server to determine the machine's current configuration,
426 // and to configure the client information if it is not already. A standard
427 // handle can talk to any server. Standard handles can be either authenticated
428 // or unauthenticated.
430 // Close all current handles
433 g_LogFile
.Write("Getting handles to the cell and the config library.\r\n");
436 // Start by getting a null cell handle and using it to open the client
437 // connection to the config library.
438 g_LogFile
.Write("Opening a NULL cell handle to use with the client config library handle.\r\n");
439 nResult
= afsclient_NullCellOpen(&hClientCell
, pStatus
);
441 g_LogFile
.Write("Failed to open a NULL cell handle: %lx.\r\n", (unsigned long)*pStatus
);
445 // Get the client handle. We never need a better handle than this
446 // for the client, and so this handle will never be upgraded.
447 g_LogFile
.Write("Getting config handle for the client.\r\n");
448 if (!cfg_HostOpen(hClientCell
, GetHostnameA(), &g_hClient
, pStatus
)) {
449 g_LogFile
.Write("Failed to get config handle: %lx.\r\n", (unsigned long)*pStatus
);
454 // Now we need to get the most powerful cell handle that we can and use it
455 // to open the config library for the server.
457 // If the client info is valid and we know what cell the server should be in,
458 // and the client has that cell in its CellServDB, then we can get a Standard cell
459 // handle. However there is an exception: if this is the first server in the
460 // cell then there may not yet be an authentication server to talk to. In that
461 // case we use a null cell handle.
462 if (g_CfgData
.bValidClientInfo
&& // Client config is valid
463 g_CfgData
.szCellName
[0] && // We have a cell name
464 (!g_CfgData
.bFirstServer
|| g_CfgData
.bAuthServerRunning
)) // Auth server is running
466 g_LogFile
.Write("Opening a non-NULL cell handle to use with the server config library handle.\r\n");
468 // Do we have the user info necessary to authenticate?
469 BOOL bHaveUserInfo
= g_CfgData
.szAdminName
[0] && g_CfgData
.szAdminPW
[0];
471 // Open a standard cell handle. szAdminName and szAdminPW will either be NULL, or
472 // if they have been entered by the user, will be the admin name and password strings.
473 if ((!g_CfgData
.bFirstServer
|| g_CfgData
.bAdminPrincipalCreated
) && bHaveUserInfo
) {
474 g_LogFile
.Write("Getting tokens in cell %s for user '%s'.\r\n", GetCellNameA(), GetAdminNameA());
475 nResult
= afsclient_TokenGetNew(GetCellNameA(), GetAdminNameA(), GetAdminPWA(), &g_hToken
, pStatus
);
477 g_LogFile
.Write("Getting unauthenticated tokens for cell '%s'.\r\n", GetCellNameA());
478 nResult
= afsclient_TokenGetNew(GetCellNameA(), "", "", &g_hToken
, pStatus
);
482 g_LogFile
.Write("Failed to get tokens for the specified cell: %lx.\r\n", (unsigned long)*pStatus
);
486 // If the admin name and password are NULL, then this will be an unauthenticated
487 // connection to the cell.
488 g_LogFile
.Write("Getting cell handle for cell %s.\r\n", GetCellNameA());
489 nResult
= afsclient_CellOpen(GetCellNameA(), g_hToken
, &g_hCell
, pStatus
);
491 g_LogFile
.Write("Failed to open the cell: %lx.\r\n", (unsigned long)*pStatus
);
495 g_LogFile
.Write("Opening a NULL cell handle to use with the server config library handle.\r\n");
496 nResult
= afsclient_NullCellOpen(&g_hCell
, pStatus
);
498 g_LogFile
.Write("Failed to open a NULL cell handle: %lx.\r\n", (unsigned long)*pStatus
);
503 // Get the server handle
504 g_LogFile
.Write("Getting config library handle for the server.\r\n");
505 if (!cfg_HostOpen(g_hCell
, GetHostnameA(), &g_hServer
, pStatus
)) {
506 g_LogFile
.Write("Failed to get config library handle for the server: %lx.\r\n", (unsigned long)*pStatus
);
513 BOOL
GetHandles(HWND hParentDlg
)
515 afs_status_t nStatus
;
517 if (!GetLibHandles(&nStatus
)) {
518 ShowError(hParentDlg
, nStatus
, IDS_GET_TOKENS_ERROR
);
519 g_CfgData
.szAdminPW
[0] = 0;
528 * Static FUNCTIONS _________________________________________________________________
531 static void CloseLibHandles(BOOL bExiting
)
533 afs_status_t nStatus
;
535 // We will close them in the reverse order of their creation.
537 cfg_HostClose(g_hServer
, &nStatus
);
542 afsclient_CellClose(g_hCell
, &nStatus
);
547 afsclient_TokenClose(g_hToken
, &nStatus
);
551 // Only close the client cfg and cell handles if we are exiting.
554 cfg_HostClose(g_hClient
, &nStatus
);
559 afsclient_CellClose(hClientCell
, &nStatus
);
565 static void SetConfigDefaults()
567 if (g_CfgData
.bWizard
) {
568 if (g_CfgData
.configFS
== CS_NULL
)
569 g_CfgData
.configFS
= CS_CONFIGURE
;
571 if (g_CfgData
.configDB
== CS_NULL
)
572 g_CfgData
.configDB
= CS_CONFIGURE
;
574 if (g_CfgData
.configBak
== CS_NULL
)
575 g_CfgData
.configBak
= CS_CONFIGURE
;
577 if (g_CfgData
.configPartition
== CS_NULL
)
578 g_CfgData
.configPartition
= CS_CONFIGURE
;
580 if (g_CfgData
.configRootVolumes
== CS_NULL
)
581 g_CfgData
.configRootVolumes
= CS_CONFIGURE
;
583 if (g_CfgData
.configRep
== CS_NULL
)
584 g_CfgData
.configRep
= CS_CONFIGURE
;
586 if (g_CfgData
.configSCS
== CS_NULL
)
587 g_CfgData
.configSCS
= CS_DONT_CONFIGURE
;
589 if (g_CfgData
.configSCC
== CS_NULL
)
590 g_CfgData
.configSCC
= CS_DONT_CONFIGURE
;
593 lstrcpy(g_CfgData
.szAdminName
, TEXT("admin"));
594 lstrcpy(g_CfgData
.szAdminUID
, TEXT("0"));
596 g_CfgData
.bUseNextUid
= TRUE
;
600 // Prototypes for each property page's dialog proc
601 BOOL CALLBACK
PartitionsPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
602 BOOL CALLBACK
ServicesPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
604 static void RunCfgTool()
606 // If the client info is invalid, then the config tool cannot run. Inform the user and
607 // ask if they want to run the wizard instead.
608 if (!g_CfgData
.bValidClientInfo
) {
609 int nChoice
= MsgBox(0, IDS_NEED_CLIENT_INFO
, GetAppTitleID(), MB_YESNO
| MB_ICONSTOP
);
610 if (nChoice
== IDYES
)
615 // If the server info is invalid, then the config tool cannot run. The Wizard must be run
616 // to initially configure the server. Inform the user and ask if they want to run the wizard instead.
617 if (!g_CfgData
.bValidServerInfo
) {
618 int nChoice
= MsgBox(0, IDS_NEED_SERVER_INFO
, GetAppTitleID(), MB_OKCANCEL
| MB_ICONEXCLAMATION
);
624 g_CfgData
.bWizard
= FALSE
;
628 RegisterConfigToolHelp();
630 // Create the prop sheet
631 g_pSheet
= PropSheet_Create(IDS_CFG_TOOL_APP_TITLE
, TRUE
);
634 PropSheet_AddTab(g_pSheet
, IDS_PARTITIONS_PAGE_TITLE
, IDD_PARTITIONS_PAGE
, (DLGPROC
)PartitionsPageDlgProc
, 0, TRUE
, TRUE
);
635 PropSheet_AddTab(g_pSheet
, IDS_SERVICES_PAGE_TITLE
, IDD_SERVICES_PAGE
, (DLGPROC
)ServicesPageDlgProc
, 0, TRUE
);
637 // Let the user see it
638 PropSheet_ShowModal(g_pSheet
);
641 static void RunWizard()
643 g_CfgData
.bWizard
= TRUE
;
647 RegisterWizardHelp();
650 g_pWiz
->SetDialogTemplate(IDD_WIZARD
, IDC_WIZARD_LEFTPANE
, IDC_WIZARD_RIGHTPANE
, IDBACK
, IDNEXT
);
651 g_pWiz
->SetGraphic(IDB_GRAPHIC_16
, IDB_GRAPHIC_256
);
652 g_pWiz
->SetStates(g_aStates
, g_nNumStates
);
653 g_pWiz
->SetGraphicCallback(PaintPageGraphic
);
655 g_pWiz
->SetState(sidSTEP_ONE
);