windows-updates-20010819
authorJames Peterson <jimpeter@us.ibm.com>
Sun, 19 Aug 2001 15:44:41 +0000 (15:44 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sun, 19 Aug 2001 15:44:41 +0000 (15:44 +0000)
1. Version control (Win9x & Windows NT/2000)
 NTMakefile.i386_win95 and NTMakefile.i386_nt40 added AFSPRODUCT_VERSION
 variable, setting this will propagate through the software by setting
 the product version for the installation and client dialog boxes.  In
 particular it will provide correct notification if Win2K installation is
 being upgraded, reinstall or downgraded.

 Version information shows up in the following ways:
   Welcome dialog during installation
   Properities page for Install.exe (Windows Installation routine)
   Windows Add/Remove Dialogs application list
   AFS Control Center and Client dialog boxes

 See README-WIN9X.TXT or README-NT.TXT for further information on how to set thi
s
 variable.

2. CellServDB  (Win9x & Windows NT/2000)
 The installer can choose between various sources for CellServDB:
 a) Previous installed file, afsdcell.ini(WinNT/2000) or CellServDB(Win9x).
 b) File that comes with the installation package (recent copy from grand.centra
l.org)
 c) Download a the file from the Web (default http://grand.central.org/dl/cellse
rvdb/CellServDB).
 d) Browse for a file

3. Drive Mapping (Win9x & Windows NT/2000)
 The installer can choose up to two drive mappings during the installation
 process.  Default is map Z: to AFS root and U: to user home directory

4. Silent Running (Win9x & Windows NT/2000)
 Setup.exe is capable of running silently (-s option); that is, it will use a pr
e-made
 response script to drive its responses.  You can also do a normal installation
with
 the record option (-r) to build a sample response file.

 The installation routine has been improved to accept a modified response file s
o the
 administrator can setup up additional drive mappings including substituting the
 user's
 loggin name into the path.  By using a text editor an administrator can setup a
 variable
 path name that includes %LOGINNAME% in a path statement.  This variable will be

 substituted for the current user's login name.  (Only at installation time.)

 For example: if an administrator wanted to install AFS client on a machine that
 had the
 following mappings:
 Z:=/
 U:=/afs/afscell.org/u/username
 Q:=/afs/afscell.org/general

 Then follow these steps:
 a) run setup with -r option and specify install to record responses into file s
etup.iss
  setup.exe -r -f1setup.iss
 b) Follow normal installation responses
 c) Edit the setup.iss response file by modifying the "DRIVEPATH section".

 This response file could start off looking like this:

 [DLG_DRIVEPATH-1]
 Result=1
 Drive_0=Z:
 Path_0=/
 Share_0=all
 Drive_1=U:
 Path_1=/afs/afscell.org/u/administrator
 Share_1=home
 Count=2

 This section map would be changed to look like this:

 [DLG_DRIVEPATH-1]
 Result=1
 Drive_0=Z:
 Path_0=/
 Share_0=all
 Drive_1=U:
 Path_1=/afs/afscell.org/u/%LOGINNAME%
 Share_1=home
 Drive_2=Q:
 Path_2=/afs/afscell.org/general
 Share_2=genrl
 Count=3

 d) Use the silent mode to install AFS (must log to windows as your user name e.
g. Frank)
  setup.exe -s -f1setup.iss

HINT: Share name should be limited to 12 characters.
    The response file terminate if the installation is in any way different; for
 example,
    the response is recorded on a clean machine and it is run on a system where
AFS
    is already installed.
    The execution is truly silent, except for a log file.
    The last response is BootOption and if set to 1 it will reboot your machine!

 Refer to additional documentation on silent/record in you Install Shield User's
 Guide.

5. Fixed the Un-Installation bug that damaged the NetBT parameter registration. (Win2k/NT only)

6. Change Default selection for Win2000 to Client and Documentation only.  (Win2
K/NT only)
 The default installation is with Server and Control Center NOT selected.

7. Win9x Client Operation (Win9x only)

 Win9x client has been changed to allow "connection" with out forcing
 authentication.  Previous implementation of the Win9x client had three steps to
 the
 connection process: 1) start client 2) obtain tokens 3) Map drives

 The updated Win9x client can leave the username blank and select to Connect.  T
herefore, only
 the client will be started (without obtaining tokens).  The user can still map
drives
 (those that don't require authentication).  This is particularity useful if you
 want to
 use a different routine to obtain authentication tokens or additional drive map
pings.

 A command line option has also been added (-noid).  This option Prevent selecti
on of
 (Gray out) username/password. This will cause the client to start up without au
thentication.
 By using both -noid and -connect allows the user to run the AFS client in login
 script
 that could provide Kerbos 5 authentication and addition drive mapping.

8. Installation (Win9x only)
 Fix installation into paths that have space, e.g. \Program Files\Afscli

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

complete list in first message

44 files changed:
src/NTMake9x
src/README-NT
src/README-WIN9X
src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.cpp [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.def [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.dep [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.h [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.rc [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/GetWebDllFun.h [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/Resource.h [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/StdAfx.h [new file with mode: 0644]
src/WINNT/afs_setup_utils/GetWebDll/ntmakefile [new file with mode: 0644]
src/WINNT/afs_setup_utils/NTMakefile
src/WINNT/afs_setup_utils/_isuser/_IsUser.RC [new file with mode: 0644]
src/WINNT/afs_setup_utils/_isuser/_IsUser.dep [new file with mode: 0644]
src/WINNT/afs_setup_utils/_isuser/_isuser.c [new file with mode: 0644]
src/WINNT/afs_setup_utils/_isuser/ntmakefile [new file with mode: 0644]
src/WINNT/afs_setup_utils/_isuser/resource.h [new file with mode: 0644]
src/WINNT/afs_setup_utils/afs_setup_utils.cpp
src/WINNT/install/InstallShield5/Default.shl
src/WINNT/install/InstallShield5/Default.txt [moved from src/WINNT/install/InstallShield5/Default.rge with 87% similarity]
src/WINNT/install/InstallShield5/GatherFiles.bat
src/WINNT/install/InstallShield5/HowToSetTheVersion.txt
src/WINNT/install/InstallShield5/NTMakefile
src/WINNT/install/InstallShield5/ScatterFiles.bat
src/WINNT/install/InstallShield5/lang/en_US/value.txt [moved from src/WINNT/install/InstallShield5/lang/en_US/value.shl with 91% similarity]
src/WINNT/install/InstallShield5/setup.rul
src/WINNT/install/Win9x/NTMakeFile
src/WINNT/install/Win9x/setup.iss [new file with mode: 0644]
src/WINNT/win9xpanel/CAfs.cpp
src/WINNT/win9xpanel/Change.cpp
src/WINNT/win9xpanel/NTMakefile
src/WINNT/win9xpanel/WinAfsLoad.cpp
src/WINNT/win9xpanel/WinAfsLoad.h
src/WINNT/win9xpanel/WinAfsLoad.rc
src/WINNT/win9xpanel/WinAfsLoadDlg.cpp
src/WINNT/win9xpanel/WinAfsLoadDlg.h
src/WINNT/win9xpanel/cafs.h
src/config/NTMakefile
src/config/NTMakefile.i386_nt40
src/config/NTMakefile.i386_win95
src/config/afsconfig-windows.h [new file with mode: 0644]
src/config/util_cr.c
src/tviced/NTMakefile

index 8b84b89..42c7693 100644 (file)
@@ -307,9 +307,9 @@ clean: start
        $(CD) $(OBJ)\WINNT\install\Win9x
        nmake /nologo /f NTMakefile clean
        $(CD) ..\..\..\..
-       .\src\rmbat $(DESTDIR)\include\*.* $(DESTDIR)\include\afs\*.* $(DESTDIR)\include\WINNT\*.* $(DESTDIR)\include\rx\*.*
-       .\src\rmbat $(DESTDIR)\LIB\*.LIB $(DESTDIR)\LIB\*.DLL $(DESTDIR)\LIB\AFS\*.LIB
-       .\src\RMBAT $(DESTDIR)\root.client\usr\vice\etc\*.*
+       $(DESTDIR)\BIN\rmbat $(DESTDIR)\include\*.* $(DESTDIR)\include\afs\*.* $(DESTDIR)\include\WINNT\*.* $(DESTDIR)\include\rx\*.*
+       $(DESTDIR)\BIN\rmbat $(DESTDIR)\LIB\*.LIB $(DESTDIR)\LIB\*.DLL $(DESTDIR)\LIB\AFS\*.LIB
+       $(DESTDIR)\BIN\rmbat $(DESTDIR)\root.client\usr\vice\etc\*.*
        $(CD) $(OBJ)\config
        nmake /nologo /f ntmakefile clean_version
        $(CD) ..\..
index 9973d5f..d998720 100644 (file)
@@ -3,7 +3,7 @@ All Rights Reserved.
 
 This software has been released under the terms of the IBM Public
 License.  For details, see the LICENSE file in the top-level source
-directory or online at http://www.openafs.org/dl/license10.html
+directory or on-line at http://www.openafs.org/dl/license10.html
 
 Building OpenAFS on Windows NT
 ------------------------------
@@ -53,9 +53,17 @@ C. Optional: Install Installshield 5.x
       2. build of the product plus an installer package
 
    In order to do the build that includes the installer package, a
-   copy of InstallShield 5.x must be installed. NOTE: InstallShield
+   copy of Installshield 5.x must be installed. NOTE: Installshield
    versions 6 and higher WILL NOT WORK.
 
+   Optional DLL's missing for Install Script
+   Two Microsoft DLL's must be included at DEST\WinInstall\Config\.
+       SHLWAPI.DLL
+       WININET.DLL  
+
+       These files are only used for the Install, they will not be left 
+       on the target machine.
+
 D. Optional: Install flex and bison
 
    There are two files in the source tree that are processed with lex
@@ -94,7 +102,7 @@ E. Configure the OpenAFS build environment
    set MSVCDIR=<path to vc directory of MS Visual C++>
    Ex: set MSVCDIR=c:\progra~1\DevStudio\vc
 
-      This is the path to the compiler directory of the Microsot Visual
+      This is the path to the compiler directory of the Microsoft Visual
       C++ installation.
 
    set AFSDEV_INCLUDE=<default include directories>
@@ -122,12 +130,12 @@ E. Configure the OpenAFS build environment
       This is the root directory of OpenAFS, which is the parent
       directory of the src directory.
 
-   set IS5ROOT=<root directory of the InstallShield5 program files>
+   set IS5ROOT=<root directory of the Installshield5 program files>
    Ex: set IS5ROOT=d:\progra~1\instal~1\instal~1.1pr
 
-      This is the path to the InstallShield5 program directory. You
-      should only define this if you have InstallShield installed on
-      your computer and want to create the install package as part of
+      This is the path to the Installshield5 program directory. You
+      should only define this if you have Installshield installed on
+      your computer and want to create the install script as part of
       the build.
 
    set BISON_SIMPLE=<path to bison.simple>
@@ -147,7 +155,40 @@ E. Configure the OpenAFS build environment
    As can be seen in the examples above, all paths in ntbuild.bat must
    be in the old MSDOS 8.3 format.
 
-F. Begin the build
+F. Set version and installation options
+
+       Modify .\src\config\NTMakefile.i386_nt40
+               AFSPRODUCT_VERSION  - Product version
+               CELLNAME_DEFAULT - The default AFS cell name
+               CELLSERVDB_INSTALL - The default name for the CellServDB included in the install script
+               CELLSERVDB_WEB  - The default web address to obtain CellServDB
+
+For Example:
+
+ .\src\config\NTMakefile.i386_nt40
+
+   AFSPRODUCT_VERSION=1.1.1a
+   CELLNAME_DEFAULT=openafs.org
+   CELLSERVDB_INSTALL=CellServDB.GrandCentral
+   CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
+
+NOTE: If CELLNAME_DEFAULT has a '.' in cell name, then the name is assumed to be 
+a valid cell name and when the user installs AFS the AFS Control Center 
+will default to NOT installed!
+
+Version level may be specified in different formats, for example the following
+forms all have the same version level; however will be displayed differently:
+
+AFSPRODUCT_VERSION=1.1.1a
+AFSPRODUCT_VERSION=1.1.1 a
+AFSPRODUCT_VERSION=1.1.1.1
+AFSPRODUCT_VERSION=1.1.101
+
+Add CellServDB file to install area.
+        For the previous example you would add file:
+                DEST\Winistall\Config\CellServDB.GrandCentral
+
+G. Begin the build
 
  1. Make sure you are running the default NT command shell, cmd.exe.
     Other shells may work, but many do not.
@@ -167,7 +208,7 @@ F. Begin the build
     You only need to do this once.
 
  4. Begin the build. You can choose to build just the product bits,
-    or, if InstallShield is installed, the product bits and the
+    or, if Installshield is installed, the product bits and the
     install package.
 
     To build just the product bits, run:
index a19ba59..dae84fb 100644 (file)
@@ -124,6 +124,34 @@ or         nmake -f ntmake9x clean
       VC6RedistSetup_enu.exe
    This is located at:
       http://support.microsoft.com/support/kb/articles/Q259/4/03.ASP
+       Two Microsoft DLL's must be included at DEST\WinInstall\Config\.
+          SHLWAPI.DLL
+          WININET.DLL  
+       These DLL's will not be left on the target machine, there are only
+       used for installation and removed after installation is complete.
+
+6) Required changes to configuration file .\src\config\NTMakefile.i386_win95
+
+AFSPRODUCT_VERSION  - Product version
+CELLNAME_DEFAULT - The default AFS cell name
+CELLSERVDB_INSTALL - The default name for the CellServDB included in the install script
+CELLSERVDB_WEB  - The default web address to obtain CellServDB
+                 
+For Example:
+
+ .\src\config\NTMakefile.i386_win95  
+   AFSPRODUCT_VERSION=1.1.1a
+   CELLNAME_DEFAULT=openafs.org
+   CELLSERVDB_INSTALL=CellServDB.GrandCentral
+   CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
+
+Version level may be specified in different formats, for example the following
+forms all have the same version level; however will be displayed differently:
+
+AFSPRODUCT_VERSION=1.1.1a
+AFSPRODUCT_VERSION=1.1.1 a
+AFSPRODUCT_VERSION=1.1.1.1
+AFSPRODUCT_VERSION=1.1.101
 
 6) Installation
 
@@ -163,3 +191,5 @@ or  nmake -f ntmake9x clean
    5. Reboot the target machine.
    6. You can now start the client by executing the program WinAfsLoad.exe
       from the install directory.
+
+
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.cpp b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.cpp
new file mode 100644 (file)
index 0000000..50ce00f
--- /dev/null
@@ -0,0 +1,409 @@
+// GetWebDll.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "stdafx.h"
+#include "GetWebDll.h"
+#include "getwebdllfun.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//
+//     Note!
+//
+//             If this DLL is dynamically linked against the MFC
+//             DLLs, any functions exported from this DLL which
+//             call into MFC must have the AFX_MANAGE_STATE macro
+//             added at the very beginning of the function.
+//
+//             For example:
+//
+//             extern "C" BOOL PASCAL EXPORT ExportedFunction()
+//             {
+//                     AFX_MANAGE_STATE(AfxGetStaticModuleState());
+//                     // normal function body here
+//             }
+//
+//             It is very important that this macro appear in each
+//             function, prior to any calls into MFC.  This means that
+//             it must appear as the first statement within the 
+//             function, even before any object variable declarations
+//             as their constructors may generate calls into the MFC
+//             DLL.
+//
+//             Please see MFC Technical Notes 33 and 58 for additional
+//             details.
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CGetWebDllApp
+
+BEGIN_MESSAGE_MAP(CGetWebDllApp, CWinApp)
+       //{{AFX_MSG_MAP(CGetWebDllApp)
+               // NOTE - the ClassWizard will add and remove mapping macros here.
+               //    DO NOT EDIT what you see in these blocks of generated code!
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CGetWebDllApp construction
+
+CGetWebDllApp::CGetWebDllApp()
+{
+       // TODO: add construction code here,
+       // Place all significant initialization in InitInstance
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CGetWebDllApp object
+
+CGetWebDllApp theApp;
+
+
+LPCTSTR pszURL = NULL;
+BOOL    bStripMode = FALSE;
+BOOL    bProgressMode = FALSE;
+DWORD   dwAccessType = PRE_CONFIG_INTERNET_ACCESS;
+
+DWORD dwHttpRequestFlags =
+       INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;
+//
+//GET /updateCellServDB.jsp?type=bunk HTTP/1.1
+//Accept: */*
+//Accept -Language: en -us
+//Accept -Encoding: gzip , deflate
+//User-Agent: ufilerNativeClient/1.0 (1.0; Windows NT)
+//Host: 192.168.0.1
+//Connection: Keep -Alive
+
+const TCHAR szVersion[] =
+       _T("HTTP/1.1");
+
+const TCHAR szHeaders[] =
+       _T("\
+Accept: */*\r\n\
+Accept -Language: en -us\r\n\
+Accept -Encoding: gzip , deflate\r\n\
+User-Agent: ufilerNativeClient/1.0 (1.0; Windows NT)\r\n\
+Host: 192.168.0.1\r\n\
+Connection: Keep -Alive\r\n");
+
+CTearSession::CTearSession(LPCTSTR pszAppName, int nMethod)
+       : CInternetSession(pszAppName, 1, nMethod)
+{
+}
+
+void CTearSession::OnStatusCallback(DWORD /* dwContext */, DWORD dwInternetStatus,
+       LPVOID /* lpvStatusInfomration */, DWORD /* dwStatusInformationLen */)
+{
+       if (!bProgressMode)
+               return;
+
+       if (dwInternetStatus != INTERNET_STATUS_CONNECTED_TO_SERVER)
+               AfxMessageBox("Connection Not Made",MB_ICONERROR | MB_OK);
+       return;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CTearException -- used if something goes wrong for us
+
+// TEAR will throw its own exception type to handle problems it might
+// encounter while fulfilling the user's request.
+
+IMPLEMENT_DYNCREATE(CTearException, CException)
+
+CTearException::CTearException(int nCode)
+       : m_nErrorCode(nCode)
+{
+}
+
+void ThrowTearException(int nCode)
+{
+       CTearException* pEx = new CTearException(nCode);
+       throw pEx;
+}
+
+// StripTags() rips through a buffer and removes HTML tags from it.
+// The function uses a static variable to remember its state in case
+// a HTML tag spans a buffer boundary.
+
+void StripTags(LPTSTR pszBuffer)
+{
+       static BOOL bInTag = FALSE;
+       LPTSTR pszSource = pszBuffer;
+       LPTSTR pszDest = pszBuffer;
+
+       while (*pszSource != '\0')
+       {
+               if (bInTag)
+               {
+                       if (*pszSource == '>')
+                               bInTag = FALSE;
+                       pszSource++;
+               }
+               else
+               {
+                       if (*pszSource == '<')
+                               bInTag = TRUE;
+                       else
+                       {
+                               *pszDest = *pszSource;
+                               pszDest++;
+                       }
+                       pszSource++;
+               }
+       }
+       *pszDest = '\0';
+}
+
+
+extern "C" 
+__declspec(dllexport) INT GetWebPage(LPSTR lpErrMsg,LPSTR lpFile,LPSTR lpCmdLine)
+{
+       CString emsg;
+//     emsg.Format("p1=[%s],p2=[%s]",lpFile,lpCmdLine);
+//     AfxMessageBox(emsg,MB_ICONERROR | MB_OK);
+       if ((strlen(lpCmdLine)==0) || (strlen(lpFile)==0))
+       {
+               emsg="Parameter Error";
+               return 1;
+       }
+
+       int nRetCode = 0;
+
+       CTearSession session(_T("TEAR - MFC Sample App"), dwAccessType);
+       CHttpConnection* pServer = NULL;
+       CHttpFile* pFile = NULL;
+       char *szParm=strstr(lpCmdLine,"?");
+       try
+       {
+               // check to see if this is a reasonable URL
+               CFile ofile(lpFile,CFile::modeCreate|CFile::modeWrite);
+
+               CString strServerName;
+               CString strObject;
+               INTERNET_PORT nPort;
+               DWORD dwServiceType;
+
+               if (!AfxParseURL(lpCmdLine, dwServiceType, strServerName, strObject, nPort) ||
+                       dwServiceType != INTERNET_SERVICE_HTTP)
+               {
+                       emsg="Error: can only use URLs beginning with http://";
+                       ThrowTearException(1);
+               }
+
+               if (bProgressMode)
+               {
+                       VERIFY(session.EnableStatusCallback(TRUE));
+               }
+
+               pServer = session.GetHttpConnection(strServerName, nPort);
+               pFile = pServer->OpenRequest(
+                       CHttpConnection::HTTP_VERB_GET,
+                       strObject,              //updateCellServDB.jsp
+                       NULL,                   // URL of document
+                       1,                              // context
+                       NULL,
+                       szVersion,
+                       dwHttpRequestFlags);
+               pFile->AddRequestHeaders(szHeaders);
+               pFile->SendRequest();
+
+               DWORD dwRet;
+               pFile->QueryInfoStatusCode(dwRet);
+
+               // if access was denied, prompt the user for the password
+
+               if (dwRet == HTTP_STATUS_DENIED)
+               {
+                       DWORD dwPrompt;
+                       dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
+                               FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);
+
+                       // if the user cancelled the dialog, bail out
+
+                       if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
+                       {
+                               emsg="Access denied: Invalid password";
+                               ThrowTearException(1);
+                       }
+
+                       pFile->SendRequest();
+                       pFile->QueryInfoStatusCode(dwRet);
+               }
+
+               CString strNewLocation;
+               pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);
+
+               // were we redirected?
+               // these response status codes come from WININET.H
+
+               if (dwRet == HTTP_STATUS_MOVED ||
+                       dwRet == HTTP_STATUS_REDIRECT ||
+                       dwRet == HTTP_STATUS_REDIRECT_METHOD)
+               {
+                       CString strNewLocation;
+                       pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);
+
+                       int nPlace = strNewLocation.Find(_T("Location: "));
+                       if (nPlace == -1)
+                       {
+                               emsg="Error: Site redirects with no new location";
+                               ThrowTearException(2);
+                       }
+
+                       strNewLocation = strNewLocation.Mid(nPlace + 10);
+                       nPlace = strNewLocation.Find('\n');
+                       if (nPlace > 0)
+                               strNewLocation = strNewLocation.Left(nPlace);
+
+                       // close up the redirected site
+
+                       pFile->Close();
+                       delete pFile;
+                       pServer->Close();
+                       delete pServer;
+
+                       if (bProgressMode)
+                       {
+                               emsg.Format("Caution: redirected to %s",(LPCTSTR) strNewLocation);
+                       }
+
+                       // figure out what the old place was
+                       if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort))
+                       {
+                               emsg="Error: the redirected URL could not be parsed.";
+                               ThrowTearException(2);
+                       }
+
+                       if (dwServiceType != INTERNET_SERVICE_HTTP)
+                       {
+                               emsg="Error: the redirected URL does not reference a HTTP resource.";
+                               ThrowTearException(2);
+                       }
+
+                       // try again at the new location
+                       pServer = session.GetHttpConnection(strServerName, nPort);
+                       pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
+                               strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
+                       pFile->AddRequestHeaders(szHeaders);
+                       pFile->SendRequest();
+
+                       pFile->QueryInfoStatusCode(dwRet);
+                       if (dwRet != HTTP_STATUS_OK)
+                       {
+                               emsg.Format("Error: Got status code %d",dwRet);
+                               ThrowTearException(2);
+                       }
+               }
+
+
+               TCHAR sz[1024];
+               while (pFile->ReadString(sz, 1023))
+               {
+                       if (bStripMode)
+                               StripTags(sz);
+                       ofile.Write(sz,strlen(sz));
+               }
+
+               pFile->Close();
+               pServer->Close();
+               ofile.Close();
+       }
+       catch (CInternetException* pEx)
+       {
+               // catch errors from WinINet
+
+               TCHAR szErr[1024];
+               pEx->GetErrorMessage(szErr, 1024);
+
+               CString emsg;
+               emsg.Format("Error: (%s)",szErr);
+               nRetCode = 2;
+               pEx->Delete();
+       }
+       catch (CFileException* pEx)
+       {
+               TCHAR szErr[1024];
+               pEx->GetErrorMessage(szErr, 1024);
+
+               emsg.Format("File Error: (%s)",szErr);
+               nRetCode = 2;
+               pEx->Delete();
+       }
+       catch (CTearException* pEx)
+       {
+               // catch things wrong with parameters, etc
+
+               nRetCode = pEx->m_nErrorCode;
+               pEx->Delete();
+       }
+
+       if (pFile != NULL)
+               delete pFile;
+       if (pServer != NULL)
+               delete pServer;
+       session.Close();
+       int len=strlen(lpErrMsg);
+       strncpy(lpErrMsg,emsg,len);
+       lpErrMsg[len]=0;
+       return nRetCode;
+}
+
+extern "C" 
+__declspec(dllexport) INT GetUserLogon(LPSTR lpUserName)
+{
+       int nRetCode = 1;
+       ULONG nSize=strlen(lpUserName);
+       if (!GetUserName(lpUserName,&nSize)) nRetCode=0;
+       return nRetCode;
+}
+
+extern "C" 
+__declspec(dllexport) INT BrowseFile(HWND hwndOwner,LPSTR lpstrTitle,LPSTR lpFileName,INT size)
+{
+       char *xptr;
+//     char msg[256];
+       char *ptr=strrchr(lpFileName,'\\');
+       int nFileOffset=0;
+       int nFileExtension=0;
+       if (ptr)
+               nFileOffset=ptr-lpFileName+1;
+       else {
+               ptr=strrchr(lpFileName,':');
+               if (ptr)
+                       nFileOffset=ptr-lpFileName;
+       }
+       if (ptr==NULL)
+               ptr=lpFileName;
+       if (xptr=strrchr(ptr,'.'))
+               nFileExtension=nFileOffset+(xptr-ptr);
+//     sprintf(msg,"Title: [%s] filename=[%s], %i,%i,%i",lpstrTitle,lpFileName,nFileOffset,nFileExtension,size);
+//     AfxMessageBox(msg,MB_OK);
+       OPENFILENAME data={
+               sizeof(OPENFILENAME)    //lStructSize
+               ,hwndOwner                              //hwndOwner
+               ,NULL                                   //
+               ,"*.*"                                  //lpstrFilter
+               ,NULL                                   //lpstrCustomFilter
+               ,NULL                                   //nMaxCustFilter
+               ,0                                              //nFilterIndex
+               ,lpFileName                     //lpstrFile
+               ,size                                   //nMaxFile - at least 256 characters
+               ,NULL                                   //lpstrFileTitle
+               ,0                                              //nMaxFileTitle
+               ,NULL                                   //lpstrInitialDir
+               ,lpstrTitle                             //lpstrTitle
+               ,OFN_HIDEREADONLY|OFN_PATHMUSTEXIST             //Flags
+               ,nFileOffset                    //nFileOffset
+               ,nFileExtension                 //nFileExtension
+               ,NULL                                   //lpstrDefExt
+               ,NULL                                   //lCustData
+               ,NULL                                   //lpfnHook
+               ,NULL                                   //lpTemplateName
+       };
+       return GetOpenFileName(&data);
+}
\ No newline at end of file
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.def b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.def
new file mode 100644 (file)
index 0000000..4288460
--- /dev/null
@@ -0,0 +1,7 @@
+; GetWebDll.def : Declares the module parameters for the DLL.
+
+LIBRARY      "GetWebDll"
+DESCRIPTION  'GetWebDll Windows Dynamic Link Library'
+
+EXPORTS
+    ; Explicit exports can go here
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.dep b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.dep
new file mode 100644 (file)
index 0000000..7101cbd
--- /dev/null
@@ -0,0 +1,11 @@
+# Microsoft Developer Studio Generated Dependency File, included by GetWebDll.mak
+
+.\GetWebDll.cpp : \
+       ".\GetWebDll.h"\
+       ".\GetWebDllFun.h"\
+       
+
+.\StdAfx.cpp : \
+       ".\StdAfx.h"\
+       "c:\program files\microsoft visual studio\vc98\include\basetsd.h"\
+       
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.h b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.h
new file mode 100644 (file)
index 0000000..3148447
--- /dev/null
@@ -0,0 +1,67 @@
+// GetWebDll.h : main header file for the GETWEBDLL DLL
+//
+
+#if !defined(AFX_GETWEBDLL_H__470FBE70_389E_11D5_A375_00105A6BCA62__INCLUDED_)
+#define AFX_GETWEBDLL_H__470FBE70_389E_11D5_A375_00105A6BCA62__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef __AFXWIN_H__
+       #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h"          // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CGetWebDllApp
+// See GetWebDll.cpp for the implementation of this class
+//
+
+class CGetWebDllApp : public CWinApp
+{
+public:
+       CGetWebDllApp();
+
+// Overrides
+       // ClassWizard generated virtual function overrides
+       //{{AFX_VIRTUAL(CGetWebDllApp)
+       //}}AFX_VIRTUAL
+
+       //{{AFX_MSG(CGetWebDllApp)
+               // NOTE - the ClassWizard will add and remove member functions here.
+               //    DO NOT EDIT what you see in these blocks of generated code !
+       //}}AFX_MSG
+       DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+class CTearSession : public CInternetSession
+{
+public:
+       CTearSession(LPCTSTR pszAppName, int nMethod);
+       virtual void OnStatusCallback(DWORD dwContext, DWORD dwInternetStatus,
+               LPVOID lpvStatusInfomration, DWORD dwStatusInformationLen);
+};
+
+
+class CTearException : public CException
+{
+       DECLARE_DYNCREATE(CTearException)
+
+public:
+       CTearException(int nCode = 0);
+       ~CTearException() { }
+
+       int m_nErrorCode;
+};
+
+#endif // !defined(AFX_GETWEBDLL_H__470FBE70_389E_11D5_A375_00105A6BCA62__INCLUDED_)
+
+
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.rc b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDll.rc
new file mode 100644 (file)
index 0000000..7c5b0b0
--- /dev/null
@@ -0,0 +1,122 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+       "\r\n"
+       "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+       "#ifdef _WIN32\r\n"
+       "LANGUAGE 9, 1\r\n"
+       "#pragma code_page(1252)\r\n"
+       "#endif //_WIN32\r\n"
+       "#include ""afxres.rc""         // Standard components\r\n"
+       "#endif\r\n"
+    "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // APSTUDIO_INVOKED
+
+
+
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO     VERSIONINFO
+  FILEVERSION       1,0,0,1
+  PRODUCTVERSION    1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+       BLOCK "StringFileInfo"
+       BEGIN
+        BLOCK "040904B0"
+               BEGIN 
+                       VALUE "CompanyName",     "\0"
+                       VALUE "FileDescription", "GetWebDll DLL\0"
+                       VALUE "FileVersion",     "1, 0, 0, 1\0"
+                       VALUE "InternalName",    "GetWebDll\0"
+                       VALUE "LegalCopyright",  "Copyright (C) 2001\0"
+                       VALUE "LegalTrademarks", "\0"
+                       VALUE "OriginalFilename","GetWebDll.DLL\0"
+                       VALUE "ProductName",     "GetWebDll Dynamic Link Library\0"
+                       VALUE "ProductVersion",  "1, 0, 0, 1\0"
+               END
+       END
+       BLOCK "VarFileInfo" 
+       BEGIN 
+               VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "afxres.rc"   // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/GetWebDllFun.h b/src/WINNT/afs_setup_utils/GetWebDll/GetWebDllFun.h
new file mode 100644 (file)
index 0000000..db3d10c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef __cplusplus
+extern "C" {
+#endif  /* __cplusplus */
+
+__declspec(dllexport) INT GetWebPage(LPSTR lpErrMsg,LPSTR lpFile,LPSTR lpCmdLine);
+
+__declspec(dllexport) INT GetUserLogon(LPSTR lpUserName);
+
+__declspec(dllexport) INT BrowseFile(HWND hwndOwner,LPSTR lpstrTitle,LPSTR lpFileFullName,INT fullsize);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/Resource.h b/src/WINNT/afs_setup_utils/GetWebDll/Resource.h
new file mode 100644 (file)
index 0000000..7f9b9e4
--- /dev/null
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by GETWEBDLL.RC
+//
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE       18000
+#define _APS_NEXT_CONTROL_VALUE                18000
+#define _APS_NEXT_SYMED_VALUE          18000
+#define _APS_NEXT_COMMAND_VALUE                32771
+#endif
+#endif
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/StdAfx.h b/src/WINNT/afs_setup_utils/GetWebDll/StdAfx.h
new file mode 100644 (file)
index 0000000..866a939
--- /dev/null
@@ -0,0 +1,44 @@
+// stdafx.h : include file for standard system include files,
+//  or project specific include files that are used frequently, but
+//      are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__470FBE72_389E_11D5_A375_00105A6BCA62__INCLUDED_)
+#define AFX_STDAFX_H__470FBE72_389E_11D5_A375_00105A6BCA62__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN           // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h>         // MFC OLE classes
+#include <afxodlgs.h>       // MFC OLE dialog classes
+#include <afxdisp.h>        // MFC Automation classes
+#endif // _AFX_NO_OLE_SUPPORT
+
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h>                     // MFC ODBC database classes
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h>                    // MFC DAO database classes
+#endif // _AFX_NO_DAO_SUPPORT
+
+#include <afxdtctl.h>          // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>                    // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#include <afxinet.h>
+
+#endif // !defined(AFX_STDAFX_H__470FBE72_389E_11D5_A375_00105A6BCA62__INCLUDED_)
diff --git a/src/WINNT/afs_setup_utils/GetWebDll/ntmakefile b/src/WINNT/afs_setup_utils/GetWebDll/ntmakefile
new file mode 100644 (file)
index 0000000..f5b9cc6
--- /dev/null
@@ -0,0 +1,115 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on GetWebDll.dsp
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF 
+
+OUTDIR=.
+INTDIR=.
+# Begin Custom Macros
+OutDir=.
+# End Custom Macros
+
+ALL : "$(OUTDIR)\GetWebDll.dll"
+
+
+CLEAN :
+       -@erase "$(INTDIR)\GetWebDll.pch"
+       -@erase "$(INTDIR)\GetWebDll.res"
+       -@erase "$(INTDIR)\*.obj"
+       -@erase "$(INTDIR)\vc60.idb"
+       -@erase "$(OUTDIR)\GetWebDll.dll"
+       -@erase "$(OUTDIR)\GetWebDll.exp"
+       -@erase "$(OUTDIR)\GetWebDll.lib"
+       -@erase "$(OUTDIR)\GetWebDll.sbl"
+       -@erase "$(OUTDIR)\GetWebDll.pjt"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GetWebDll.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
+
+.c{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.c{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\GetWebDll.res" /d "NDEBUG" 
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\GetWebDll.bsc" 
+BSC32_SBRS= \
+       
+LINK32=link.exe
+LINK32_FLAGS=/nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\GetWebDll.pdb" /machine:I386 /def:".\GetWebDll.def" /out:"$(OUTDIR)\GetWebDll.dll" /implib:"$(OUTDIR)\GetWebDll.lib" 
+DEF_FILE= \
+       ".\GetWebDll.def"
+LINK32_OBJS= \
+       "$(INTDIR)\GetWebDll.obj" \
+       "$(INTDIR)\StdAfx.obj" \
+       "$(INTDIR)\GetWebDll.res"
+
+"$(OUTDIR)\GetWebDll.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("GetWebDll.dep")
+!INCLUDE "GetWebDll.dep"
+!ELSE 
+!MESSAGE Warning: cannot find "GetWebDll.dep"
+!ENDIF 
+!ENDIF 
+
+
+SOURCE=.\GetWebDll.cpp
+
+"$(INTDIR)\GetWebDll.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GetWebDll.pch"
+
+
+SOURCE=.\GetWebDll.rc
+
+"$(INTDIR)\GetWebDll.res" : $(SOURCE) "$(INTDIR)"
+       $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+SOURCE=.\StdAfx.cpp
+
+CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GetWebDll.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
+
+"$(INTDIR)\StdAfx.obj" "$(INTDIR)\GetWebDll.pch" : $(SOURCE) "$(INTDIR)"
+       $(CPP) @<<
+  $(CPP_SWITCHES) $(SOURCE)
+<<
+
index dc4d0a2..f5eed59 100644 (file)
@@ -89,11 +89,19 @@ $(AFSRM_EXEFILE): $(AFSRM_EXEOBJS) $(AFSRM_EXELIBS)
 install : $(INSTALL_UTILS_DLLFILE) $(SERVER_UNINST_DLLFILE) $(CLIENT_UNINST_DLLFILE) \
           $(CC_UNINST_DLLFILE) $(LIGHT_CLIENT_UNINST_DLLFILE) $(DOCS_UNINST_DLLFILE) \
           $(AFSRM_EXEFILE) lang
+                 cd _isuser
+                 nmake -fntmakefile
+          $(CD) ..
+                 cd getwebdll
+                 nmake -fntmakefile
+          $(CD) ..
+                 echo 
 
 lang ::
        $(CD) lang
        for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile install
        $(CD) ..
+   echo done lang
 
 ############################################################################
 # How to build the shared source file for each uninstall dll
@@ -156,7 +164,13 @@ $(DOCS_UNINST_DLLFILE) : d_afs_setup_utils.obj $(DLLOBJS) $(DLLLIBS)
 ############################################################################
 
 clean::
-
+   $(CD) _isuser
+   nmake -fntmakefile clean
+   $(CD) ..
+   $(CD) getwebdll
+   nmake -fntmakefile clean
+   $(CD) ..
+   echo done clean
 
 ############################################################################
 #
diff --git a/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC b/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC
new file mode 100644 (file)
index 0000000..3f3c650
--- /dev/null
@@ -0,0 +1,188 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "sdrc.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+DLG_DRIVEPATH DIALOGEX 0, 0, 332, 218
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Select Local Drive Mapping"
+FONT 8, "MS Sans Serif"
+BEGIN
+    LTEXT           "",52,0,0,332,36
+    LTEXT           "Enable Assignment, choose drive letter and define AFS mount point path.",
+                    901,17,41,289,19,SS_NOPREFIX
+    LTEXT           "Map local drive letter to AFS mount point.",50,10,3,220,
+                    8,0,WS_EX_TRANSPARENT
+    LTEXT           "AFS service can map drive letters to AFS mount points.\nBoth Letters and mounts points can be configured!",
+                    51,17,12,273,22,0,WS_EX_TRANSPARENT
+    CONTROL         "",1301,"Static",SS_ETCHEDHORZ | WS_GROUP,0,36,332,1
+    DEFPUSHBUTTON   "&Next >",SD_PBUT_CONTINUE,215,196,50,14
+    PUSHBUTTON      "Cancel",SD_PBUT_CANCEL,272,196,50,14
+    PUSHBUTTON      "< &Back",SD_PBUT_BACK,166,196,50,14
+    CONTROL         "",SD_STA_IMAGE_2,"Static",SS_BLACKFRAME,54,185,268,1
+    LTEXT           "",7,10,182,40,10,NOT WS_VISIBLE
+    COMBOBOX        IDC_HOMEDRIVELIST,17,151,41,76,CBS_DROPDOWNLIST | 
+                    WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    GROUPBOX        "Root Drive Assignment",IDC_STATIC,2,62,323,52,WS_GROUP
+    EDITTEXT        IDC_HOMEPATH,66,151,258,12,ES_AUTOHSCROLL | 
+                    ES_OEMCONVERT | WS_GROUP
+    LTEXT           "Drive",IDC_STATIC,17,139,17,8
+    LTEXT           "Path",IDC_STATIC,66,139,15,8
+    COMBOBOX        IDC_ROOTDRIVELIST,17,94,40,76,CBS_DROPDOWNLIST | 
+                    WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    GROUPBOX        "Home Drive Assignment",IDC_STATIC,5,117,323,56,WS_GROUP
+    EDITTEXT        IDC_ROOTPATH,66,94,254,12,ES_AUTOHSCROLL | ES_OEMCONVERT | 
+                    WS_GROUP
+    LTEXT           "Drive",IDC_STATIC,17,84,17,8
+    LTEXT           "Path",IDC_STATIC,66,84,15,8
+    LTEXT           "@10550,10551;1;0;;0,128,128   ",1200,0,0,332,36,NOT 
+                    WS_VISIBLE,WS_EX_TRANSPARENT
+    PUSHBUTTON      "C",3,21,200,25,12,NOT WS_VISIBLE | WS_GROUP | NOT 
+                    WS_TABSTOP
+    CONTROL         "Enable Assigment",IDC_ENABLEROOT,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,5,72,71,10
+    CONTROL         "Enable Assigment",IDC_ENABLEHOME,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,9,128,71,10
+END
+
+DLG_CELLSERVDB DIALOGEX 0, 0, 336, 228
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Select AFS Cell Data Base (afsdcell.ini)"
+FONT 8, "MS Sans Serif"
+BEGIN
+    LTEXT           "",52,0,0,336,36
+    LTEXT           "Select the data base from one of the following source locations.",
+                    901,17,41,289,15,SS_NOPREFIX
+    LTEXT           "Choose Source location:",50,10,3,220,8,0,
+                    WS_EX_TRANSPARENT
+    LTEXT           "AFS Cell Data Base contains the list of available AFS cells and their IP addresses.",
+                    51,17,15,275,19,0,WS_EX_TRANSPARENT
+    CONTROL         "",1301,"Static",SS_ETCHEDHORZ | WS_GROUP,0,36,336,1
+    DEFPUSHBUTTON   "&Next >",SD_PBUT_CONTINUE,215,196,50,14
+    PUSHBUTTON      "Cancel",SD_PBUT_CANCEL,272,196,50,14
+    PUSHBUTTON      "< &Back",SD_PBUT_BACK,166,196,50,14
+    CONTROL         "",SD_STA_IMAGE_2,"Static",SS_BLACKFRAME,54,185,268,1
+    LTEXT           "",7,10,182,40,10,NOT WS_VISIBLE
+    LTEXT           "@10550,10551;1;0;;0,128,128   ",1200,0,0,336,36,NOT 
+                    WS_VISIBLE,WS_EX_TRANSPARENT
+    PUSHBUTTON      "C",3,21,200,25,12,NOT WS_VISIBLE | WS_GROUP | NOT 
+                    WS_TABSTOP
+    PUSHBUTTON      "B&rowse...",IDC_BROWSE,262,160,46,14
+    GROUPBOX        "Download from Web Address",IDC_STATIC,108,115,205,31
+    GROUPBOX        "Select File",IDC_STATIC,108,150,205,31
+    EDITTEXT        IDC_WEB,115,126,180,12,ES_AUTOHSCROLL | ES_OEMCONVERT | 
+                    WS_GROUP
+    GROUPBOX        "Packaged Installation File",IDC_STATIC,108,87,205,23,
+                    WS_GROUP
+    LTEXT           "General.org",IDC_INSTALL,114,96,187,10
+    GROUPBOX        "",IDC_STATIC,90,58,15,124,NOT WS_VISIBLE | WS_GROUP
+    CONTROL         "",IDC_CHECK_INSTALL,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,94,96,8,10
+    CONTROL         "",IDC_CHECK_WEB,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+                    94,125,8,10
+    CONTROL         "",IDC_CHECK_BROWSEFILE,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,94,160,8,10
+    CONTROL         "",IDC_CHECK_PREVIOUSFILE,"Button",BS_AUTORADIOBUTTON | 
+                    WS_GROUP,94,70,8,10
+    LTEXT           "",IDC_PREVIOUSFILE,114,71,189,8
+    GROUPBOX        "Previous Installation",IDC_STATIC,108,58,205,26,
+                    WS_GROUP
+    EDITTEXT        IDC_BROWSEFILE,113,161,142,12,ES_AUTOHSCROLL
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""sdrc.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+//10000                   ICON    DISCARDABLE     "icon1.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    DLG_CELLSERVDB, DIALOG
+    BEGIN
+        RIGHTMARGIN, 332
+        BOTTOMMARGIN, 218
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep b/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep
new file mode 100644 (file)
index 0000000..b4a4083
--- /dev/null
@@ -0,0 +1,9 @@
+# Microsoft Developer Studio Generated Dependency File, included by _IsUser.mak
+
+.\_isuser.c : \
+       "c:\program files\microsoft visual studio\vc98\include\basetsd.h"\
+       
+
+.\_Isuser.RC : \
+       ".\SDRC.H"\
+       
diff --git a/src/WINNT/afs_setup_utils/_isuser/_isuser.c b/src/WINNT/afs_setup_utils/_isuser/_isuser.c
new file mode 100644 (file)
index 0000000..0c10074
--- /dev/null
@@ -0,0 +1,21 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            
+//  IIIIIII SSSSSS                                                            
+//    II    SS                          InstallShield (R)                     
+//    II    SSSSSS      (c) 1996-2000, InstallShield Software Corporation     
+//    II        SS      (c) 1990-1996, InstallShield Corporation              
+//  IIIIIII SSSSSS                     All Rights Reserved.                   
+//                                                                            
+//                                                                            
+////////////////////////////////////////////////////////////////////////////////
+
+#define NOCOMM
+#include <windows.h>
+
+
+BOOL WINAPI DllMain( PVOID hmod, ULONG ulReason, PCONTEXT pctx )
+{
+        return TRUE;
+}
+
diff --git a/src/WINNT/afs_setup_utils/_isuser/ntmakefile b/src/WINNT/afs_setup_utils/_isuser/ntmakefile
new file mode 100644 (file)
index 0000000..4bde69c
--- /dev/null
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on _IsUser.dsp
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF 
+
+OUTDIR=.
+INTDIR=.
+# Begin Custom Macros
+OutDir=.
+# End Custom Macros
+
+ALL : "$(OUTDIR)\_IsUser.dll"
+
+
+CLEAN :
+       -@erase "$(INTDIR)\_isuser.obj"
+       -@erase "$(INTDIR)\_Isuser.res"
+       -@erase "$(INTDIR)\vc60.idb"
+       -@erase "$(OUTDIR)\_IsUser.dll"
+       -@erase "$(OUTDIR)\_IsUser.exp"
+       -@erase "$(OUTDIR)\_IsUser.lib"
+       -@erase "$(OUTDIR)\*.pch"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ISUSER_EXPORTS" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
+
+.c{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx{$(INTDIR)}.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.c{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx{$(INTDIR)}.sbr::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\_Isuser.res" /d "NDEBUG" 
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\_IsUser.bsc" 
+BSC32_SBRS= \
+       
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\_IsUser.pdb" /machine:I386 /out:"$(OUTDIR)\_IsUser.dll" /implib:"$(OUTDIR)\_IsUser.lib" 
+LINK32_OBJS= \
+       "$(INTDIR)\_isuser.obj" \
+       "$(INTDIR)\_Isuser.res"
+
+"$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("_IsUser.dep")
+!INCLUDE "_IsUser.dep"
+!ELSE 
+!MESSAGE Warning: cannot find "_IsUser.dep"
+!ENDIF 
+!ENDIF 
+
+
+SOURCE=.\_isuser.c
+
+"$(INTDIR)\_isuser.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\_Isuser.RC
+
+"$(INTDIR)\_Isuser.res" : $(SOURCE) "$(INTDIR)"
+       $(RSC) $(RSC_PROJ) $(SOURCE)
+
diff --git a/src/WINNT/afs_setup_utils/_isuser/resource.h b/src/WINNT/afs_setup_utils/_isuser/resource.h
new file mode 100644 (file)
index 0000000..6f5440c
--- /dev/null
@@ -0,0 +1,38 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by _IsUser.RC
+//
+#define IDC_HOMEPATH                    301
+#define IDC_ROOTPATH                    302
+#define IDC_HOMEDRIVELIST               1007
+#define IDC_ROOTDRIVELIST               1008
+#define IDC_ENABLEROOT                  1010
+#define IDC_ENABLEHOME                  1011
+#define IDC_INSTALL                     1011
+#define IDC_WEB                         1016
+#define IDC_CHECK_INSTALL               1018
+#define IDC_CHECK_WEB                   1019
+#define IDC_CHECK_FILE                  1020
+#define IDC_CHECK_BROWSEFILE            1020
+#define IDC_CHECK_DEFAULT               1021
+#define IDC_CHECK_PREVIOUSFILE          1021
+#define IDC_PREVIOUSFILE                1024
+#define IDC_BROWSE                      1025
+#define IDC_BROWSEFILE                  1026
+#define DLG_TEMPLATE                    13029
+#define DLG_DRIVEPATH                   13030
+#define DLG_CELLSERVDB                  13031
+#define IDC_PATH                        13032
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        104
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1028
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
index 363adc7..c391342 100644 (file)
  */
 
 /*
- * INCLUDES _________________________________________________________________\r
- *\r
- */\r
-\r
-extern "C" {\r
-#include <afs/param.h>\r
-#include <afs/stds.h>\r
-#include <afs/fileutil.h>\r
-}\r
-\r
-#include <windows.h>\r
-#include <stdio.h>\r
-#include <time.h>\r
-#include <assert.h>\r
-#include <stdlib.h>\r
-#include <io.h>\r
-#include <string.h>\r
-#include <SYS\STAT.H>\r
-#include <shellapi.h>\r
-\r
-#include <WINNT/afsreg.h>\r
-#include <WINNT/afssw.h>\r
-#include <WINNT/talocale.h>\r
-\r
-#include "resource.h"\r
-#include "progress_dlg.h"\r
-#include "sutil.h"\r
-#include "forceremove.h"\r
-\r
-\r
-/*\r
- * PROTOTYPES _________________________________________________________________\r
- *\r
- */\r
-static char *GetAppInstallDir(struct APPINFO *pApp, BOOL bRemembered);\r
-BOOL UninstallCredsTool();\r
-BOOL ServerSpecificUninstall();\r
-BOOL ClientSpecificUninstall();\r
-\r
-\r
-\r
-/*\r
- * DEFINITIONS _________________________________________________________________\r
- *\r
- */\r
-#define SUCALLCONV  WINAPI\r
-\r
-#define UNINSTALL_TEMP_INFO_KEY     "HKEY_LOCAL_MACHINE\\Software\\AfsUninstallTempInfo"\r
-#define INSTALL_DIR_VALUE_NAME      "InstallDir"\r
-\r
-#define AFS_PRESERVED_CFG_INFO_KEY  "HKEY_LOCAL_MACHINE\\Software\\AfsPreservedConfigInfo"\r
-\r
-#define MS_SHARED_FILES_KEY         "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs"\r
-\r
-// Log file to use when running in silent mode\r
-#define UNINSTALL_ERROR_LOG_NAME    "\\AfsUninstallErrorLog.txt"\r
-#define INSTALL_ERROR_LOG_NAME      "\\AfsInstallErrorLog.txt"\r
-\r
-#define TARGETDIR                   "<TARGETDIR>"\r
-#define WINDIR                      "<WINDIR>"\r
-#define WINSYSDIR                   "<WINSYSDIR>"\r
-\r
-#define WIN9X_START_MENU_REG_KEY    "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"\r
-#define WIN9X_START_MENU_REG_VALUE  "Programs"\r
-    \r
-#define WINNT_START_MENU_REG_KEY    "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"\r
-#define WINNT_START_MENU_REG_VALUE  "Common Programs"\r
-\r
-#define LOCALE_ID_LEN               4\r
-\r
-struct REGVALUE {\r
-    char *pszKey;\r
-    char *pszValue;\r
-};\r
-\r
-\r
-typedef BOOL (APP_UNINSTALL_FUNC)();\r
-\r
-\r
-\r
-struct APPINFO {\r
-    char *pszAppName;\r
-\r
-    // Service Info\r
-    char *pszSvcName;\r
-    char *pszSvcKey;\r
-    char *pszSvcDependOn;\r
-    char *pszSvcDisplayName;\r
-\r
-    char *pszNetworkProviderOrder;\r
-\r
-    // Message to use to tell the user that we have to stop the service\r
-    int nServiceShutdownMsgID;\r
-\r
-    // Message to use for the progress dialog that is shown while\r
-    // waiting for the service to stop.\r
-    int nServiceShutdownProgressMsgID;\r
-\r
-    // Location in registry of a key we can use to know that the app is installed\r
-    char *pszAppKey;\r
-\r
-    // Location in registry of this app's install dir\r
-    struct REGVALUE regInstallDir;\r
-\r
-    // Path Info\r
-    char *pszLocalRoot;     // The root dir below the install dir\r
-    char *pszBinPath;       // Path to remove from the system path\r
-\r
-    // Generated files and directories to delete.  These are both multistring lists.\r
-    char *pszDirsToDel;     // All files in these dirs will be deleted\r
-    char *pszFilesToDel;    // Use this if you want to delete files but leave the dir.  Wildcards can be used.\r
-\r
-    // Registry values to remove\r
-    struct REGVALUE *pRegValues;\r
-    struct REGVALUE *pWinNTRegValues;   // Only remove these if running WinNT\r
-    struct REGVALUE *pWin9XRegValues;   // Only remove these if running Win9X\r
-\r
-    // Start menu entries to delete\r
-    char *pszStartMenuEntries;\r
-\r
-    // Registry keys to save if a user wants to preserve config info during uninstall\r
-    char *pszRegKeysToPreserve;\r
-    int nPreserveConfigInfoMsgID;\r
-\r
-    // Uninstall func - used for things specific to this app\r
-    APP_UNINSTALL_FUNC *pUninstallFunc;\r
-};\r
-\r
-\r
-/*\r
- * App info structure for the Server product\r
- */\r
-struct APPINFO appServer = {\r
-    "AFS Server",\r
-    \r
-    AFSREG_SVR_SVC_NAME,\r
-    AFSREG_SVR_SVC_KEY,\r
-    0,  // No depend on\r
-    AFSREG_SVR_SVC_DISPLAYNAME_DATA,\r
-\r
-    0,  // No network provider order\r
-\r
-    IDS_MUST_STOP_SERVER,\r
-    IDS_WAITING_FOR_SERVER_TO_STOP,\r
-\r
-    AFSREG_SVR_SW_VERSION_KEY,\r
-    \r
-    { AFSREG_SVR_SW_VERSION_KEY, AFSREG_SVR_SW_VERSION_DIR_VALUE },\r
-\r
-    "\\Server",\r
-    "\\usr\\afs\\bin",\r
-\r
-    // Dirs to delete\r
-    TARGETDIR"\\Server\\usr\\afs\\bin\\backup\0"\r
-    TARGETDIR"\\Server\\usr\\afs\\bin\0"\r
-    TARGETDIR"\\Server\\usr\\afs\\db\0"\r
-    TARGETDIR"\\Server\\usr\\afs\\logs\0"\r
-    TARGETDIR"\\Server\\usr\\afs\\etc\0"\r
-    TARGETDIR"\\Server\\usr\\afs\\local\0"\r
-    TARGETDIR"\\Server\\usr\\afs\0"\r
-    TARGETDIR"\\Server\\usr\0",\r
-    \r
-    // Files to delete\r
-    TARGETDIR"\\Common\\*.gid\0"\r
-    TARGETDIR"\\Common\\*.fts\0",\r
-\r
-    0,  // No reg values\r
-    0,  // No NT only reg values\r
-    0,  // No 9x only reg values\r
-\r
-    "Server\0",\r
-\r
-    // Config info to preserve\r
-    AFSREG_SVR_SVC_KEY"\0", \r
-    IDS_PRESERVE_SERVER_CONFIG_INFO,\r
-\r
-    0   // No special uninstall function\r
-};\r
-\r
-// Registry values to remove for the Client\r
-struct REGVALUE clientRegValues[] = {\r
-    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", "{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}" },\r
-    { 0, 0 }    // This indicates there are no more entries\r
-};\r
-\r
-struct REGVALUE clientWinNTRegValues[] = {\r
-    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\File Manager\\AddOns", "AFS Client FME" },\r
-    { 0, 0 }\r
-};\r
-\r
-struct REGVALUE clientWin9XRegValues[] = {\r
-    { "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order", "TransarcAFSDaemon" },\r
-    { 0, 0 }\r
-};\r
-\r
-/*\r
- * App info structure for the Client product\r
- */\r
-struct APPINFO appClient = {\r
-    "AFS Client",\r
-    \r
-    AFSREG_CLT_SVC_NAME,\r
-    AFSREG_CLT_SVC_KEY,\r
-    "5250435353004E657462696F730000",\r
-    AFSREG_CLT_SVC_DISPLAYNAME_DATA,\r
-\r
-    AFSREG_CLT_SVC_NAME,\r
-\r
-    IDS_MUST_STOP_CLIENT,\r
-    IDS_WAITING_FOR_CLIENT_TO_STOP,\r
-\r
-    AFSREG_CLT_SW_VERSION_KEY,\r
-\r
-    { AFSREG_CLT_SW_VERSION_KEY, AFSREG_CLT_SW_VERSION_DIR_VALUE },\r
-\r
-    "\\Client",\r
-    "\\Program",\r
-\r
-    // No dirs to delete\r
-    0,\r
-    \r
-    // Files to delete\r
-    TARGETDIR"\\Common\\*.gid\0"\r
-    TARGETDIR"\\Common\\*.fts\0"\r
-    WINDIR"\\..\\AFSCache\0"\r
-    WINDIR"\\afsd.log\0"\r
-    WINDIR"\\afsd.ini\0"\r
-    WINDIR"\\afsdsbmt.ini\0"\r
-    WINDIR"\\afsd_init.log\0",\r
-    \r
-    clientRegValues,\r
-    clientWinNTRegValues,\r
-    clientWin9XRegValues,\r
-\r
-    // Start menu entries to remove\r
-    "Client\0",\r
-\r
-    // Config info to preserve\r
-    AFSREG_CLT_SVC_KEY"\0",\r
-    IDS_PRESERVE_CLIENT_CONFIG_INFO,\r
-\r
-    ClientSpecificUninstall\r
-};\r
-\r
-\r
-/*\r
- * App info structure for the Light Client product\r
- */\r
-struct APPINFO appLightClient = {\r
-    "AFS Light",\r
-    \r
-    // No service info \r
-    0,\r
-    0,\r
-    0,\r
-    0,\r
-\r
-    AFSREG_CLT_SVC_NAME,\r
-\r
-    // No service shutdown messages\r
-    0,\r
-    0,\r
-\r
-    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Light Client",\r
-\r
-    { AFSREG_CLT_SW_VERSION_KEY, AFSREG_CLT_SW_VERSION_DIR_VALUE },\r
-\r
-    "\\Client",\r
-    "\\Program",\r
-\r
-    // No dirs to delete\r
-    0,\r
-    \r
-    // Files to delete\r
-    TARGETDIR"\\Common\\*.gid\0"\r
-    TARGETDIR"\\Common\\*.fts\0",\r
-\r
-    clientRegValues,\r
-    clientWinNTRegValues,\r
-    clientWin9XRegValues,\r
-\r
-    // Start menu entries to remove\r
-    "Light\0",\r
-\r
-    // Config info to preserve\r
-    AFSREG_CLT_SVC_KEY"\0",\r
-    IDS_PRESERVE_LIGHT_CLIENT_CONFIG_INFO,\r
-\r
-    UninstallCredsTool\r
-};\r
-\r
-\r
-/*\r
- * App info structure for the Control Center product\r
- */\r
-struct APPINFO appControlCenter = {\r
-    "AFS Control Center",\r
-    \r
-    // No service info\r
-    0,\r
-    0,\r
-    0,\r
-    0,\r
-\r
-    // No network provider order\r
-    0,\r
-\r
-    // No service shutdown messages    \r
-    0,\r
-    0,\r
-\r
-    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Control Center",\r
-    \r
-    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Control Center\\CurrentVersion", "PathName" },\r
-\r
-    "\\Control Center",\r
-    "",\r
-\r
-    // No dirs to delete\r
-    0,\r
-    \r
-    // Files to delete\r
-    TARGETDIR"\\Common\\*.gid\0"\r
-    TARGETDIR"\\Common\\*.fts\0",\r
-    \r
-    0,  // No reg values\r
-    0,  // No NT only reg values\r
-    0,  // No 9x only reg values\r
-\r
-    // Start menu entries to remove\r
-    "Control Center\0",\r
-\r
-    // Config info to preserve\r
-    AFSREG_CLT_SVC_KEY"\0",\r
-    IDS_PRESERVE_CC_CONFIG_INFO,\r
-\r
-    0   // No uninstall function\r
-};\r
-\r
-\r
-/*\r
- * App info structure for the Sys Admin Doc files\r
- */\r
-struct APPINFO appDocs = {\r
-    "AFS Supplemental Documentation",\r
-\r
-    // No service info\r
-    0,\r
-    0,\r
-    0,\r
-    0,\r
-\r
-    // No network provider order\r
-    0,\r
-\r
-    // No service shutdown messages    \r
-    0,\r
-    0,\r
-\r
-    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Supplemental Documentation",\r
-    \r
-    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Supplemental Documentation\\CurrentVersion", "PathName" },\r
-\r
-    "\\Documentation",\r
-    "",\r
-\r
-    // No dirs to delete\r
-    0,\r
-    \r
-    // Files to delete\r
-    TARGETDIR"\\Common\\*.gid\0"\r
-    TARGETDIR"\\Common\\*.fts\0",\r
-\r
-    0,  // No reg values\r
-    0,  // No NT only reg values\r
-    0,  // No 9x only reg values\r
-\r
-    // Start menu entries to remove\r
-    "Documentation\\AFS for Windows Backup Command Reference.lnk\0Documentation\\AFS Command Reference Manual.lnk\0Documentation\\AFS System Administrator's Guide.lnk\0",\r
-\r
-    0,  // No config info to preserve\r
-\r
-    0   // No uninstall function\r
-};\r
-\r
-\r
-// Shared and in-use files\r
-struct FILEINFO {\r
-    char *pszName;\r
-    int nUsedBy;\r
-};\r
-\r
-#define SERVER  1\r
-#define CLIENT  2\r
-#define LCLIENT 4\r
-#define CC      8\r
-#define DOCS    16\r
-\r
-\r
-struct FILEINFO fileInfo[] = {\r
-    { TARGETDIR"\\Common\\afsbosadmin.dll",             SERVER | CC },\r
-    { TARGETDIR"\\Common\\afscfgadmin.dll",             SERVER | CC },\r
-    { TARGETDIR"\\Common\\afsclientadmin.dll",          SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afskasadmin.dll",             SERVER | CC },\r
-    { TARGETDIR"\\Common\\afsptsadmin.dll",             SERVER | CC },\r
-    { TARGETDIR"\\Common\\afsvosadmin.dll",             SERVER | CC },\r
-    { TARGETDIR"\\Common\\afsadminutil.dll",            SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afsrpc.dll",                  SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afsauthent.dll",              SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\pthread.dll",                 SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\TaAfsAppLib.dll",             SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afsprocmgmt.dll",             SERVER | CLIENT | LCLIENT },\r
-    { TARGETDIR"\\Common\\afs_config.exe",              CLIENT | LCLIENT| CC },\r
-    { TARGETDIR"\\Common\\afseventmsg_????.dll",        SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afslegal_????.dll",           SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afsserver_????.dll",          SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afssvrcfg_????.dll",          SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\TaAfsAccountManager_????.dll",SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\TaAfsAppLib_????.dll",        SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\TaAfsServerManager_????.dll", SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afscreds_????.dll",           SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs_config_????.dll",         SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs_cpa_????.dll",            SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs_shl_ext_????.dll",        SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-nt.hlp",                  SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-nt.cnt",                  SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafssvrmgr.cnt",             SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafssvrmgr.hlp",             SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafsusrmgr.cnt",             SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafsusrmgr.hlp",             SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-cc.cnt",                  SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-cc.hlp",                  SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-light.cnt",               SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\afs-light.hlp",               SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafscfg.cnt",                SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Common\\taafscfg.hlp",                SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Client\\PROGRAM\\afs_shl_ext.dll",    CLIENT | LCLIENT },\r
-    { TARGETDIR"\\Client\\PROGRAM\\libafsconf.dll",     CLIENT | LCLIENT },\r
-    { TARGETDIR"\\Client\\PROGRAM\\afslogon.dll",       CLIENT },\r
-    { TARGETDIR"\\Client\\PROGRAM\\afslog95.dll",       LCLIENT },\r
-    { TARGETDIR"\\Control Center\\TaAfsAdmSvr.exe",     CC },\r
-    { WINSYSDIR"\\afs_cpa.cpl",                         CLIENT | LCLIENT | CC },\r
-    { WINSYSDIR"\\afsserver.cpl",                       SERVER },\r
-    { TARGETDIR"\\Common\\afsdcell.ini",                CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Documentation\\Html\\banner.gif",     SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\books.gif",      SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\bot.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\index.gif",      SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\index.htm",      SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\next.gif",       SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\prev.gif",       SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\toc.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\top.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },\r
-    { TARGETDIR"\\Documentation\\Html\\ReleaseNotes\\relnotes.htm",\r
-                                                        SERVER | CLIENT | LCLIENT | CC },\r
-    { TARGETDIR"\\Documentation\\Html\\InstallGd\\afsnt35i.htm",\r
-                                                        SERVER | CLIENT | LCLIENT | CC },\r
-    { 0,                                                0 }     // End of list\r
-};\r
-\r
-\r
-/*\r
- * VARIABLES _________________________________________________________________\r
- *\r
- */\r
-HINSTANCE hinst;\r
-\r
-static HWND hDlg;\r
-static BOOL bPreserveConfigInfo;\r
-static BOOL bSilentMode;\r
-static char *pszInstallDir;\r
-\r
-\r
-/*\r
- * FUNCTIONS _________________________________________________________________\r
- *\r
- */\r
-\r
-static BOOL UpgradeClientIntParm(HKEY hKey, char *pszOldParm, char *pszNewParm)\r
-{\r
-    int nData;\r
-    LONG result = ERROR_SUCCESS;\r
-\r
-    nData = GetPrivateProfileInt("AFS Client", pszOldParm, -1, "afsd.ini");\r
-    if (nData > -1)\r
-        result = RegSetValueEx(hKey, pszNewParm, 0, REG_DWORD, (BYTE *)&nData, sizeof(nData));\r
-\r
-    return (result == ERROR_SUCCESS);\r
-}\r
-\r
-static BOOL UpgradeClientStringParm(HKEY hKey, char *pszOldParm, char *pszNewParm)\r
-{\r
-    char szData[1024];\r
-    LONG result = ERROR_SUCCESS;\r
-\r
-    GetPrivateProfileString("AFS Client", pszOldParm, "", szData, sizeof(szData), "afsd.ini");\r
-    if (szData[0])\r
-        result = RegSetValueEx(hKey, pszNewParm, 0, REG_SZ, (PBYTE)szData, strlen(szData) + 1);\r
-\r
-    return (result == ERROR_SUCCESS);\r
-}\r
-\r
-int SUCALLCONV Upgrade34ClientConfigInfo()\r
-{\r
-    HKEY hKey;\r
-    LONG result;\r
-    int nData;\r
-    \r
-    result = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_CLT_SVC_PARAM_KEY, KEY_WRITE, TRUE, &hKey, 0);\r
-    if (result != ERROR_SUCCESS)\r
-        return -1;\r
-\r
-    UpgradeClientIntParm(hKey, "CacheSize", "CacheSize");\r
-    UpgradeClientIntParm(hKey, "Stats", "Stats");\r
-    UpgradeClientIntParm(hKey, "LogoffTokenTransfer", "LogoffTokenTransfer");\r
-    UpgradeClientIntParm(hKey, "LogoffTokenTransferTimeout", "LogoffTokenTransferTimeout");\r
-    UpgradeClientIntParm(hKey, "TrapOnPanic", "TrapOnPanic");\r
-    UpgradeClientIntParm(hKey, "TraceBufferSize", "TraceBufferSize");\r
-    UpgradeClientIntParm(hKey, "TraceOnShutdown", "TraceOnShutdown");\r
-    UpgradeClientIntParm(hKey, "ReportSessionStartups", "ReportSessionStartups");\r
-    \r
-    UpgradeClientStringParm(hKey, "MountRoot", "MountRoot");\r
-    UpgradeClientStringParm(hKey, "Cell", "Cell");\r
-\r
-    /* BlockSize to ChunkSize requires convertion */\r
-    nData = GetPrivateProfileInt("AFS Client", "BlockSize", -1, "afsd.ini");\r
-    if (nData > -1) {\r
-       DWORD chunkSize;\r
-       for (chunkSize = 0; (1 << chunkSize) < nData; chunkSize++);\r
-        (void) RegSetValueEx(hKey, "ChunkSize", 0, REG_DWORD, (BYTE *)&chunkSize, sizeof(chunkSize));\r
-    }\r
-\r
-    RegCloseKey(hKey);\r
-\r
-    return 0;\r
-}\r
-\r
-int SUCALLCONV Eradicate34Client()\r
-{\r
-    if (Client34Eradicate(TRUE) != ERROR_SUCCESS)\r
-        return -1;\r
-\r
-    return 0;\r
-}\r
-\r
-// This function was written a long time ago by Mike Comer for use by the \r
-// original DFS Client for NT install program.\r
-int SUCALLCONV CheckIfAdmin(void)\r
-{\r
-    HANDLE                  token = INVALID_HANDLE_VALUE;\r
-    PVOID                   buffer = 0;\r
-    DWORD                   bufLength;\r
-    DWORD                   realBufLength;\r
-    TOKEN_PRIMARY_GROUP     *pgroup;\r
-    TOKEN_GROUPS            *groups;\r
-    int                     result = -1;\r
-    DWORD                   groupCount;\r
-    LONG                    status;\r
-    PSID                    AdministratorSID = NULL;\r
-    SID_IDENTIFIER_AUTHORITY    authority = SECURITY_NT_AUTHORITY;\r
-\r
-    // allocate the SID for the Administrators group\r
-    if (!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorSID)) {\r
-        status = GetLastError();\r
-        goto getout;\r
-    }\r
-\r
-    // open the process token\r
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) {\r
-        status = GetLastError();\r
-        token = INVALID_HANDLE_VALUE;\r
-        goto getout;\r
-    }\r
-\r
-    // check primary group first\r
-    buffer = GlobalAlloc(GMEM_FIXED, sizeof(TOKEN_PRIMARY_GROUP));\r
-    if (!buffer) {\r
-        goto getout;\r
-    }\r
-\r
-    bufLength = sizeof(TOKEN_PRIMARY_GROUP);\r
-    while(1) {\r
-        if (!GetTokenInformation(token, TokenPrimaryGroup, buffer, bufLength, &realBufLength)) {\r
-            if (realBufLength > bufLength) {\r
-                // not enough space\r
-                GlobalFree(buffer);\r
-                bufLength = realBufLength;\r
-                buffer = GlobalAlloc(GMEM_FIXED, realBufLength);\r
-                if (!buffer) {\r
-                    goto getout;\r
-                }\r
-                continue;\r
-            }\r
-\r
-            goto getout;\r
-        }\r
-        break;\r
-    }\r
-\r
-    pgroup = (TOKEN_PRIMARY_GROUP *)buffer;\r
-    if (EqualSid(pgroup->PrimaryGroup, AdministratorSID)) {\r
-        result = 0;\r
-    } else {\r
-        // okay, try the secondary groups\r
-        while(1) {\r
-            if (!GetTokenInformation(token, TokenGroups, buffer, bufLength, &realBufLength)) {\r
-                if (realBufLength > bufLength) {\r
-                    // not enough space\r
-                    GlobalFree(buffer);\r
-                    bufLength = realBufLength;\r
-                    buffer = GlobalAlloc(GMEM_FIXED, realBufLength);\r
-                    if (!buffer) {\r
-                        goto getout;\r
-                    }\r
-                    continue;\r
-                }\r
-\r
-                // a real error\r
-                goto getout;\r
-            }\r
-            break;\r
-        }\r
-\r
-        // we have the list of groups here.  Process them:\r
-        groups = (TOKEN_GROUPS *)buffer;\r
-        for(groupCount = 0; groupCount < groups->GroupCount; groupCount++) {\r
-            if (EqualSid(groups->Groups[groupCount].Sid, AdministratorSID)) {\r
-                result = 0;\r
-                break;\r
-            }\r
-        }\r
-    }\r
-\r
-getout:\r
-\r
-    if (token != INVALID_HANDLE_VALUE) {\r
-        CloseHandle(token);\r
-    }\r
-\r
-    if (buffer) {\r
-        GlobalFree(buffer);\r
-    }\r
-\r
-    if (AdministratorSID) {\r
-        FreeSid(AdministratorSID);\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-static void SetSharedFileRefCount(char *pszFile, int nRefCount)\r
-{\r
-    LONG result;\r
-    HKEY hKey;\r
-    \r
-    result = RegOpenKeyAlt(AFSREG_NULL_KEY, MS_SHARED_FILES_KEY, KEY_WRITE, FALSE, &hKey, 0);\r
-    if (result != ERROR_SUCCESS)\r
-        return;\r
-    \r
-    if (nRefCount <= 0)\r
-        RegDeleteValue(hKey, pszFile);\r
-    else\r
-        RegSetValueEx(hKey, pszFile, 0, REG_DWORD, (BYTE *)&nRefCount, sizeof(int));    \r
-    \r
-    RegCloseKey(hKey);\r
-}\r
-\r
-static char *GetTimeStamp()\r
-{\r
-    char szTime[64], szDate[64];\r
-    static char szTimeDate[128];\r
-\r
-    _strtime(szTime);\r
-    _strdate(szDate);\r
-\r
-    sprintf(szTimeDate, "[%s %s] ", szTime, szDate);\r
-    \r
-    return szTimeDate;\r
-}\r
-\r
-int SUCALLCONV WriteToInstallErrorLog(char *pszMsg)\r
-{\r
-    static BOOL bWritten = FALSE;\r
-    FILE *fp;\r
-\r
-    // On the first write, recreate the file    \r
-    fp = fopen(INSTALL_ERROR_LOG_NAME, bWritten ? "a" : "w");\r
-    if (!fp)\r
-        return -1;\r
-        \r
-    fprintf(fp, "%s%s\r\n", GetTimeStamp(), pszMsg);\r
-    \r
-    fclose(fp);\r
-    \r
-    bWritten = TRUE;\r
-    \r
-    return 0;\r
-}\r
-\r
-static void WriteToUninstallErrorLog(char *pszMsg)\r
-{\r
-    static BOOL bWritten = FALSE;\r
-    FILE *fp;\r
-\r
-    // On the first write, recreate the file    \r
-    fp = fopen(UNINSTALL_ERROR_LOG_NAME, bWritten ? "a" : "w");\r
-    if (!fp)\r
-        return;\r
-        \r
-    fprintf(fp, "%s%s\r\n", GetTimeStamp(), pszMsg);\r
-    \r
-    fclose(fp);\r
-    \r
-    bWritten = TRUE;\r
-}\r
-\r
-static char *LoadResString(UINT uID)\r
-{\r
-    static char str[256];\r
-    GetString (str, uID);\r
-    return str;\r
-}\r
-\r
-static void ShowError(UINT nResID, LONG nError)\r
-{\r
-    char szErr[256];\r
-    char szPrompt[256];\r
-    char szMsg[256];\r
-    char szTitle[256];\r
-    char *psz;\r
-\r
-    psz = LoadResString(nResID);\r
-    if (psz)\r
-        strcpy(szErr, psz);\r
-    else\r
-        sprintf(szErr, "unknown error msg (Msg ID = %d)", nResID);\r
-    \r
-    psz = LoadResString(IDS_INSTALLATION_FAILURE);\r
-    strcpy(szPrompt, psz ? psz : "An error has occurred:  %s (Last Error = %ld).");\r
-\r
-    sprintf(szMsg, szPrompt, szErr, nError);\r
-\r
-    psz = LoadResString(IDS_TITLE);\r
-    strcpy(szTitle, psz ? psz : "AFS");\r
-\r
-    if (bSilentMode)\r
-        WriteToUninstallErrorLog(szMsg);\r
-    else\r
-        MessageBox(hDlg, szMsg, szTitle, MB_OK);\r
-}\r
-\r
-static int ShowMsg(UINT nResID, int nType)\r
-{\r
-    char szTitle[256];\r
-    char *psz;\r
-\r
-    psz = LoadResString(IDS_TITLE);\r
-    strcpy(szTitle, psz ? psz : "AFS");\r
-\r
-    return MessageBox(hDlg, LoadResString(nResID), szTitle, nType);\r
-}\r
-\r
-static char *GetAppInstallDir(struct APPINFO *pApp, BOOL bRemembered)\r
-{\r
-    HKEY hKey;\r
-    LONG nResult;\r
-    DWORD dwType;\r
-    static char szInstallDir[256];\r
-    DWORD dwSize;\r
-    char *pszKey;\r
-    char *pszValue;\r
-\r
-    pszKey = bRemembered ? UNINSTALL_TEMP_INFO_KEY : pApp->regInstallDir.pszKey;\r
-    pszValue = bRemembered ? INSTALL_DIR_VALUE_NAME : pApp->regInstallDir.pszValue;\r
-\r
-    dwSize = sizeof(szInstallDir);\r
-\r
-    nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);\r
-    if (nResult == ERROR_SUCCESS) {\r
-        nResult = RegQueryValueEx(hKey, pszValue, 0, &dwType, (PBYTE)szInstallDir, &dwSize);\r
-        RegCloseKey(hKey);\r
-    }\r
-\r
-    if (nResult != ERROR_SUCCESS) {\r
-        ShowError(IDS_CANT_DETERMINE_APP_PATH, nResult);\r
-        return 0;\r
-    }\r
-\r
-    FilepathNormalizeEx(szInstallDir, FPN_BACK_SLASHES);\r
-\r
-    return szInstallDir;\r
-}\r
-\r
-static BOOL DoesRegKeyExist(char *pszKey)\r
-{\r
-    HKEY hKey;\r
-    LONG nResult;\r
-\r
-    nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);\r
-    if (nResult == ERROR_SUCCESS) {\r
-        RegCloseKey(hKey);\r
-        return TRUE;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
-\r
-static BOOL IsAppInstalled(struct APPINFO *pApp)\r
-{\r
-    return DoesRegKeyExist(pApp->pszAppKey);\r
-}\r
-\r
-static void BuildShortPath(char *pszShortPath, UINT nShortPathLen, char *pszInstallDir, char *pszPath)\r
-{\r
-    strncpy(pszShortPath, pszInstallDir, nShortPathLen);\r
-    strncat(pszShortPath, pszPath, nShortPathLen);\r
-    \r
-    GetShortPathName(pszShortPath, pszShortPath, nShortPathLen);\r
-}\r
-\r
-static BOOL IsWin95()\r
-{\r
-    OSVERSIONINFO versionInformation;\r
-\r
-    versionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
-    \r
-    GetVersionEx(&versionInformation);\r
-    \r
-    if ((versionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&\r
-        (versionInformation.dwMinorVersion == 0))\r
-        return TRUE;\r
-        \r
-    return FALSE;\r
-}\r
-\r
-int IsWin98()\r
-{\r
-    OSVERSIONINFO versionInformation;\r
-\r
-    versionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
-    \r
-    GetVersionEx(&versionInformation);\r
-    \r
-    if ((versionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&\r
-        (versionInformation.dwMinorVersion == 10))\r
-        return 0;\r
-        \r
-    return -1;\r
-}\r
-\r
-static BOOL IsServiceInstalled(char *pszServiceKey)\r
-{\r
-    HKEY hKey;\r
-\r
-    if (RegOpenKeyAlt(0, pszServiceKey, KEY_READ, FALSE, &hKey, 0) == ERROR_SUCCESS) {\r
-        RegCloseKey(hKey);\r
-        return TRUE;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
-\r
-// If this fails in anyway we just return.  No error is displayed.\r
-static void MakeSureServiceDoesNotExist(char *pszName)\r
-{\r
-    SC_HANDLE hServer = 0, hSCM = 0;\r
-    SERVICE_STATUS status;\r
-\r
-    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);\r
-    if (hSCM) {\r
-        hServer = OpenService(hSCM, pszName, SERVICE_ALL_ACCESS | DELETE);\r
-        if (hServer) {\r
-            if (QueryServiceStatus(hServer, &status)) {\r
-                if (status.dwCurrentState != SERVICE_STOPPED) {\r
-                    if (!ControlService(hServer, SERVICE_CONTROL_STOP, &status)) {\r
-                        CloseServiceHandle(hServer);\r
-                        CloseServiceHandle(hSCM);\r
-                        return;\r
-                    }\r
-                }\r
-            }\r
-            \r
-            // Try to delete even if status query fails\r
-            DeleteService(hServer);\r
-        }\r
-    }\r
-\r
-    if (hServer)\r
-        CloseServiceHandle(hServer);\r
-    if (hSCM)\r
-        CloseServiceHandle(hSCM);\r
-}\r
-\r
-static int InstallService(char *pszName, char *pszDependOn, char *pszDisplayName, char *pszServicePath, BOOL bInteractive)\r
-{\r
-    SC_HANDLE hServer = 0, hSCM;\r
-    BOOL bRestoreOldConfig = FALSE;\r
-\r
-    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);\r
-    if (!hSCM) {\r
-        ShowError(IDS_SCM_OPEN_FAILED, GetLastError());\r
-        return -1;\r
-    }\r
-\r
-/*  This code is not used, but it could be handy in the future so I am keeping it here.\r
-\r
-    // If the service exists, then we (most probably) are in the middle of an upgrade or reinstall.\r
-    bRestoreOldConfig = IsServiceInstalled(pszName);\r
-\r
-    if (bRestoreOldConfig) {\r
-        hServer = OpenService(hSCM, pszName, SERVICE_ALL_ACCESS);\r
-        if (!hServer || !ChangeServiceConfig(hServer, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, 0, 0, 0, 0, 0, 0, 0)) {\r
-            ShowError(IDS_RESTORE_OF_PREVIOUS_CONFIG_FAILED, GetLastError());\r
-            bRestoreOldConfig = FALSE;\r
-            // Fall through to service creation below\r
-        }\r
-    } \r
-*/\r
-    \r
-    if (!bRestoreOldConfig) {\r
-        DWORD dwServiceType;\r
-\r
-        // If the service already exists, the create call will fail.  This can\r
-        // happen if uninstall failed (which is not infrequent).  Making sure the\r
-        // service does not exist makes it easier for a user to install over top of\r
-        // a previously failed uninstall.\r
-        MakeSureServiceDoesNotExist(pszName);\r
-\r
-        dwServiceType = SERVICE_WIN32_OWN_PROCESS;\r
-        if (bInteractive)\r
-            dwServiceType |= SERVICE_INTERACTIVE_PROCESS;\r
-    \r
-        hServer = CreateService(hSCM, pszName, pszDisplayName,\r
-            SERVICE_ALL_ACCESS, dwServiceType, SERVICE_AUTO_START, \r
-            SERVICE_ERROR_NORMAL, pszServicePath, 0, 0, "RPCSS\0Netbios\0\0", 0, 0);\r
-    \r
-        if (!hServer)\r
-            ShowError(IDS_SERVICE_CREATE_FAILED, GetLastError());\r
-    }\r
-\r
-    if (hServer)\r
-        CloseServiceHandle(hServer);\r
-\r
-    CloseServiceHandle(hSCM);\r
-\r
-    return 0;\r
-}\r
-\r
-int SUCALLCONV InstallServerService(char *pszServicePath)\r
-{\r
-    return InstallService(appServer.pszSvcName, 0, appServer.pszSvcDisplayName, pszServicePath, TRUE);\r
-}\r
-\r
-int SUCALLCONV InstallClientService(char *pszServicePath)\r
-{\r
-    return InstallService(appClient.pszSvcName, appClient.pszSvcDependOn, appClient.pszSvcDisplayName, pszServicePath, FALSE);\r
-}\r
-\r
-static int UninstallService(struct APPINFO *pAppInfo)\r
-{\r
-    SC_HANDLE hServer, hSCM;\r
-    SERVICE_STATUS status;\r
-    BOOL bOk;\r
-    BOOL bServer = FALSE;\r
-    BOOL bShowingProgressDlg = FALSE;\r
-\r
-    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);\r
-    if (!hSCM) {\r
-        ShowError(IDS_SCM_OPEN_FAILED, GetLastError());\r
-        return -1;\r
-    }\r
-    \r
-    hServer = OpenService(hSCM, pAppInfo->pszSvcName, SERVICE_ALL_ACCESS | DELETE);\r
-    if (!hServer) {\r
-        ShowError(IDS_SERVICE_OPEN_FAILED, GetLastError());\r
-        CloseServiceHandle(hSCM);\r
-        return -1;\r
-    }\r
-\r
-    if (!QueryServiceStatus(hServer, &status)) {\r
-        ShowError(IDS_SERVICE_QUERY_FAILED, GetLastError());\r
-        CloseServiceHandle(hServer);\r
-        CloseServiceHandle(hSCM);\r
-        return -1;\r
-    }\r
-\r
-    if (status.dwCurrentState != SERVICE_STOPPED) {\r
-        if (pAppInfo->nServiceShutdownMsgID) {\r
-            if (!bSilentMode && (ShowMsg(pAppInfo->nServiceShutdownMsgID, MB_YESNO | MB_ICONQUESTION) == IDNO)) {\r
-                CloseServiceHandle(hServer);\r
-                CloseServiceHandle(hSCM);\r
-                return 1;\r
-            }\r
-        }\r
-\r
-        if (!bSilentMode)\r
-            bShowingProgressDlg = ShowProgressDialog(LoadResString(pAppInfo->nServiceShutdownProgressMsgID));\r
-\r
-        if (!ControlService(hServer, SERVICE_CONTROL_STOP, &status)) {\r
-            if (bShowingProgressDlg)\r
-                HideProgressDialog();\r
-            ShowError(IDS_SERVICE_STOP_FAILED, GetLastError());\r
-            CloseServiceHandle(hServer);\r
-            CloseServiceHandle(hSCM);\r
-            return -1;\r
-        }\r
-    }\r
-\r
-    // Wait for the service to stop\r
-    while (status.dwCurrentState != SERVICE_STOPPED) {\r
-        // I stopped waiting on dwWaitHint because it seemed the wait hint was too long.\r
-        // The service would be stopped but we'd still be asleep for a long time yet.\r
-        Sleep(5000);    //status.dwWaitHint);\r
-\r
-        if (!QueryServiceStatus(hServer, &status)) {\r
-            if (bShowingProgressDlg)\r
-                HideProgressDialog();\r
-            ShowError(IDS_SERVICE_QUERY_FAILED, GetLastError());\r
-            CloseServiceHandle(hServer);\r
-            CloseServiceHandle(hSCM);\r
-            return -1;\r
-        }\r
-    }\r
-\r
-    // The service has been stopped\r
-    if (bShowingProgressDlg)\r
-        HideProgressDialog();\r
-\r
-    // This code to disable the service may be of use some day so I am keeping it here.\r
-    // bOk = ChangeServiceConfig(hServer, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, 0, 0, 0, 0, 0, 0, 0); \r
-\r
-    bOk = DeleteService(hServer);\r
-\r
-    if (!bOk)\r
-        ShowError(IDS_SERVICE_DELETE_FAILED, GetLastError());\r
-\r
-    CloseServiceHandle(hServer);\r
-    CloseServiceHandle(hSCM);\r
-\r
-    return (bOk ? 0 : -1);\r
-}\r
-\r
-int SUCALLCONV AddToNetworkProviderOrder(char *pszWhatToAdd)\r
-{\r
-    return AddToProviderOrder(pszWhatToAdd) ? 0 : -1;\r
-}\r
-\r
-static int RemoveFromNetworkProviderOrder(char *pszWhatToDel)\r
-{\r
-    return RemoveFromProviderOrder(pszWhatToDel) ? 0 : -1;\r
-}\r
-\r
-int SUCALLCONV AddToPath(char *pszPath)\r
-{\r
-    return AddToSystemPath(pszPath) ? 0 : -1;\r
-}\r
-\r
-static int RemoveFromPath(char *pszPath)\r
-{\r
-    return RemoveFromSystemPath(pszPath) ? 0 : -1;\r
-}\r
-\r
-static void RemoveFiles(char *pszFileSpec)\r
-{\r
-    struct _finddata_t fileinfo;\r
-    long hSearch;\r
-    char szDel[MAX_PATH];\r
-    char szDir[MAX_PATH];\r
-    char *p;\r
-\r
-    strcpy(szDir, pszFileSpec);\r
-    p = strrchr(szDir, '\\');\r
-    if (p)\r
-        *p = 0;\r
-    \r
-    hSearch = _findfirst(pszFileSpec, &fileinfo);\r
-    if (hSearch == -1)\r
-        return;\r
-\r
-    while (1) {\r
-        if ((strcmp(fileinfo.name, ".") != 0) && (strcmp(fileinfo.name, "..") != 0)) {\r
-            sprintf(szDel, "%s\\%s", szDir, fileinfo.name);\r
-            DeleteFile(szDel);\r
-        }\r
-\r
-        if (_findnext(hSearch, &fileinfo) == -1)\r
-            break;\r
-    }\r
-\r
-    _findclose(hSearch);\r
-}\r
-\r
-static void RemoveDir(char *pszDir)\r
-{\r
-    char szFileSpec[MAX_PATH];\r
-\r
-    sprintf(szFileSpec, "%s\\*.*", pszDir);\r
-\r
-    RemoveFiles(szFileSpec);\r
-    RemoveDirectory(pszDir);\r
-}\r
-\r
-static void RemoveRegValues(struct REGVALUE *pRegValues)\r
-{\r
-    struct REGVALUE *pCurValue;\r
-    HKEY hKey;\r
-    LONG nResult;\r
-\r
-    if (!pRegValues)\r
-        return;\r
-\r
-    for (pCurValue = pRegValues; pCurValue->pszKey; pCurValue++) {\r
-        nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pCurValue->pszKey, KEY_ALL_ACCESS, FALSE, &hKey, 0);\r
-\r
-        if (nResult == ERROR_SUCCESS) {\r
-            nResult = RegDeleteValue(hKey, pCurValue->pszValue);\r
-            RegCloseKey(hKey);\r
-        }\r
-\r
-        if (nResult != ERROR_SUCCESS)\r
-            ShowError(IDS_REG_DELETE_VALUE_ERROR, nResult);\r
-    }\r
-}\r
-\r
-static BOOL UninstallCredsTool()\r
-{\r
-    int nResult = WinExec("afscreds /uninstall", SW_HIDE);\r
-\r
-    if (nResult <= 31) {\r
-        if (nResult != ERROR_FILE_NOT_FOUND)\r
-            ShowError(IDS_CANT_UNINSTALL_AFSCREDS, nResult);\r
-    }\r
-\r
-    // Always return true.  We don't want the uninstall to completely fail just\r
-    // because the creds tool didn't uninstall.\r
-    return TRUE;\r
-}\r
-\r
-\r
-static char *GetTempDir()\r
-{\r
-    DWORD result;\r
-    static char szTempDir[MAX_PATH];\r
-\r
-    result = GetTempPath(sizeof(szTempDir) - 1, szTempDir);\r
-    if (result == 0)\r
-        return "\\";\r
-        \r
-    return szTempDir;\r
-}\r
-\r
-static char *GetRootInstallDir()\r
-{\r
-    char *psz;\r
-    static char szRootInstallDir[MAX_PATH] = "";\r
-\r
-    if (szRootInstallDir[0] == 0) {\r
-        strcpy(szRootInstallDir, pszInstallDir);\r
-    \r
-        // Strip off the app specific part of the install dir\r
-        psz = strrchr(szRootInstallDir, '\\');\r
-        if (psz)\r
-            *psz = 0;\r
-    }\r
-\r
-    return szRootInstallDir;\r
-}\r
-\r
-static BOOL ClientSpecificUninstall()\r
-{\r
-    int nChoice;\r
-\r
-    // This function needs to do two things.  First it needs to see if the server is\r
-    // installed, and if it is, ask the user if they really want to uninstall the\r
-    // client given that the server needs the client.  Second, if we are uninstalling\r
-    // the client, we need to uninstall the creds tool.\r
-\r
-    if (!bSilentMode) {\r
-        if (IsAppInstalled(&appServer)) {\r
-            nChoice = ShowMsg(IDS_CLIENT_NEEDED_BY_SERVER, MB_ICONQUESTION | MB_YESNO);\r
-            if (nChoice == IDNO)\r
-                return FALSE;       // Cancel the uninstall\r
-        }\r
-    }\r
-    \r
-    UninstallCredsTool();\r
-\r
-    return TRUE;\r
-}\r
-\r
-static struct APPINFO *GetApp()\r
-{\r
-#ifdef SERVER_UNINST\r
-    return &appServer;\r
-#elif CLIENT_UNINST\r
-    return &appClient;\r
-#elif CC_UNINST\r
-    return &appControlCenter;\r
-#elif LIGHT_CLIENT_UNINST\r
-    return &appLightClient;\r
-#elif DOCS_UNINST\r
-    return &appDocs;\r
-#else\r
-    return 0;\r
-#endif;\r
-}\r
-\r
-static void RememberInstallDir(char *pszInstallDir)\r
-{\r
-    HKEY hKey;\r
-\r
-    // We remember the install dir so that when the UninstUninitialize function is called\r
-    // by the InstallShield uninstaller, we can find out where we were installed to.  We\r
-    // have to do this because by the time that function is called, the registry values\r
-    // created at install time are already gone.  We need to be able to find out where we\r
-    // were installed so we can clean up anything IS couldn't uninstall.  If this fails in \r
-    // any way then we don't care.  The only consequence is that some junk might be left on\r
-    // the users' system after an uninstall.\r
-    \r
-    LONG result = RegOpenKeyAlt(AFSREG_NULL_KEY, UNINSTALL_TEMP_INFO_KEY, KEY_WRITE, TRUE, &hKey, 0);\r
-    if (result != ERROR_SUCCESS)\r
-        return;\r
-\r
-    RegSetValueEx(hKey, INSTALL_DIR_VALUE_NAME, 0, REG_SZ, (PBYTE)pszInstallDir, strlen(pszInstallDir) + 1);    \r
-\r
-    RegCloseKey(hKey);\r
-}\r
-\r
-int SUCALLCONV SetSilentMode()\r
-{\r
-    bSilentMode = TRUE;\r
-\r
-    return 0;\r
-}\r
-\r
-static char *GetWinDir()\r
-{\r
-    static char szWinDir[MAX_PATH] = "";\r
-\r
-    if (!szWinDir[0]) \r
-        GetWindowsDirectory(szWinDir, sizeof(szWinDir));\r
-    \r
-    return szWinDir;\r
-}\r
-\r
-static char *GetWinSysDir()\r
-{\r
-    static char szWinSysDir[MAX_PATH] = "";\r
-\r
-    if (!szWinSysDir[0])\r
-        GetSystemDirectory(szWinSysDir, sizeof(szWinSysDir));\r
-    \r
-    return szWinSysDir;\r
-} \r
-\r
-static char *GetLocaleID()\r
-{\r
-    static char szID[25] = "";\r
-\r
-    if (szID[0] == 0) {\r
-        LCID dwID = GetSystemDefaultLCID();\r
-        \r
-         // Nuke the high word.  It contains a sort ID.\r
-        dwID &= 0x0000FFFF;\r
-        \r
-        // Convert locale ID to a string\r
-        itoa(dwID, szID, 10);\r
-\r
-        // This thing should never be more than LOCALE_ID_LEN characters long.\r
-        szID[LOCALE_ID_LEN] = 0;\r
-    }\r
-\r
-    return szID;\r
-}\r
-\r
-static char *ExpandPath(char *pszFile)\r
-{\r
-    static char szPath[MAX_PATH];\r
-    char *psz;\r
-\r
-    szPath[0] = 0;\r
-\r
-    // Convert a path containing TARGETDIR, WINDIR, or WINSYSDIR to a \r
-    // real path in the file system.  One of these MUST be the start of\r
-    // the file path passed in.  Also convert the string ???? to an\r
-    // actual locale number.\r
-    if (strncmp(pszFile, TARGETDIR, strlen(TARGETDIR)) == 0)\r
-        strcpy(szPath, GetRootInstallDir());\r
-    else if (strncmp(pszFile, WINDIR, strlen(WINDIR)) == 0)\r
-        strcpy(szPath, GetWinDir());\r
-    else if (strncmp(pszFile, WINSYSDIR, strlen(WINSYSDIR)) == 0)\r
-        strcpy(szPath, GetWinSysDir());\r
-    \r
-    if (szPath[0]) {    \r
-        psz = strchr(pszFile, '\\');\r
-        if (psz)\r
-            strcat(szPath, psz);\r
-    } else\r
-        strcpy(szPath, pszFile);\r
-\r
-    // Is this a language dll?\r
-    psz = strstr(szPath, "????.");\r
-    \r
-    // If it is, replace ???? with the locale number\r
-    if (psz)\r
-        strncpy(psz, GetLocaleID(), LOCALE_ID_LEN);\r
-\r
-    return szPath;\r
-}\r
-\r
-static BOOL FileNeededByOtherApp(struct APPINFO *pApp, struct FILEINFO *pFileInfo)\r
-{\r
-    // If the file is used by the server, the app being uninstalled is not the server, and\r
-    // the server is installed, then this file is used by another app.\r
-    if (!IsWinNT()) {\r
-        if ((pFileInfo->nUsedBy & LCLIENT) && (pApp != &appLightClient) && IsAppInstalled(&appLightClient))\r
-            return TRUE;\r
-        return FALSE;\r
-    }\r
-\r
-    if ((pFileInfo->nUsedBy & SERVER) && (pApp != &appServer) && IsAppInstalled(&appServer))\r
-        return TRUE;\r
-\r
-    if ((pFileInfo->nUsedBy & CLIENT) && (pApp != &appClient) && IsAppInstalled(&appClient))\r
-        return TRUE;\r
-\r
-    if ((pFileInfo->nUsedBy & CC) && (pApp != &appControlCenter) && IsAppInstalled(&appControlCenter))\r
-        return TRUE;\r
-    \r
-    return FALSE;\r
-}\r
-\r
-static void DeleteInUseFiles(struct APPINFO *pAppInfo, struct FILEINFO *pFileInfo)\r
-{\r
-    char szSrcPath[MAX_PATH];\r
-    char szDestPath[MAX_PATH];\r
-    char szTempDir[MAX_PATH];\r
-    int ii;\r
-\r
-    // If some app's file has been loaded before the app is uninstalled, then\r
-    // when an uninstall is attempted, the application and all of the dlls that\r
-    // its uses will be in use and IS will not be able to delete them.  Normally this\r
-    // is not a problem because IS will tell the user to reboot to finish the uninstall.\r
-    // However, we must support the ability to perform a silent uninstall followed\r
-    // immediatly by an install of the same product to the same directories.  If we let\r
-    // IS handle the uninstall of these files, this is not possible.  The reason is that\r
-    // when IS fails to remove these in use files, it marks them for deletion after the\r
-    // next reboot, which is fine.  Unfortunately, it leaves them in the dirs they were\r
-    // installed to.  So if we don't immediately reboot and perform an install to the\r
-    // same dirs, once a reboot is performed, those files get deleted and we have a \r
-    // broken installation.\r
-\r
-    // What we will do to fix all of this, is when the client is uninstalled, but\r
-    // before IS does anything, we will move the in use files and associated dlls\r
-    // into the temp dir and mark them for delete after a reboot.  Then an install\r
-    // that follows will succeed.\r
-\r
-    // Delete the files that may be in use.  If they are we actually move\r
-    // them to the temp dir and mark them for deletion after the next reboot.\r
-    for (ii = 0; pFileInfo[ii].pszName != 0; ii++) {\r
-        // Get the source path\r
-        strcpy(szSrcPath, ExpandPath(pFileInfo[ii].pszName));\r
-\r
-        // Only delete the file if it is not used by some other app\r
-        if (FileNeededByOtherApp(pAppInfo, &pFileInfo[ii]))\r
-            continue;\r
-\r
-        // If the file doesn't exist then go on to the next file.\r
-        if (_access(szSrcPath, 0) != 0)\r
-            continue;\r
-            \r
-        // See if we can do a regular delete of the file\r
-        if (DeleteFile(szSrcPath)) {\r
-            SetSharedFileRefCount(szSrcPath, 0);\r
-            continue;\r
-        }\r
-\r
-        // Get a temp dir that is on the same drive as the src path.\r
-        // We can't move an in use file to a different drive.\r
-        strcpy(szTempDir, GetTempDir());\r
-        if (szTempDir[0] != szSrcPath[0]) {\r
-            // Get the drive, colon, and slash of the src path\r
-            strncpy(szTempDir, szSrcPath, 3);\r
-            szTempDir[3] = 0;\r
-        }\r
-        \r
-        // Get the dest path - we will rename the file during the move\r
-        GetTempFileName(szTempDir, "AFS", 0, szDestPath);\r
-\r
-        // Move from source to dest, marking the file for deletion after a reboot\r
-        if (IsWin95()) {\r
-            if (MoveFile(szSrcPath, szDestPath)) {            \r
-                WritePrivateProfileString("rename", szSrcPath, szDestPath, "wininit.ini");\r
-                SetSharedFileRefCount(szSrcPath, 0);\r
-            }\r
-        } else {    // WinNT or Win98\r
-            if (MoveFileEx(szSrcPath, szDestPath, MOVEFILE_REPLACE_EXISTING)) {\r
-                SetFileAttributes(szDestPath, FILE_ATTRIBUTE_NORMAL);\r
-                MoveFileEx(szDestPath, 0, MOVEFILE_DELAY_UNTIL_REBOOT);\r
-                SetSharedFileRefCount(szSrcPath, 0);\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-// Delete a directory and all its files and subdirectories - Yee haaa!\r
-static void RemoveDirectoryTree(char *pszDir)\r
-{\r
-    HANDLE hFind;\r
-    WIN32_FIND_DATA findFileData;\r
-    char szSpec[MAX_PATH];\r
-    char szSubFileOrDir[MAX_PATH];\r
-    BOOL bContinue;\r
-\r
-    sprintf(szSpec, "%s\\*.*", pszDir);\r
-    \r
-    // First delete the contents of the dir\r
-    hFind = FindFirstFile(szSpec, &findFileData);\r
-    bContinue = (hFind != INVALID_HANDLE_VALUE);\r
-    \r
-    while (bContinue) {\r
-        if ((strcmp(findFileData.cFileName, ".") != 0) && (strcmp(findFileData.cFileName, "..") != 0)) {\r
-            sprintf(szSubFileOrDir, "%s\\%s", pszDir, findFileData.cFileName);\r
-            \r
-            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r
-                RemoveDirectoryTree(szSubFileOrDir);\r
-            else\r
-                DeleteFile(szSubFileOrDir);\r
-        }\r
-\r
-        bContinue = FindNextFile(hFind, &findFileData);\r
-    }\r
-\r
-    FindClose(hFind);\r
-        \r
-    // Now remove the dir\r
-    RemoveDirectory(pszDir);\r
-} \r
-\r
-static char *GetStartMenuRoot()\r
-{\r
-    HKEY hKey;\r
-    LONG nResult;\r
-    DWORD dwType;\r
-    DWORD dwSize;\r
-    char *pszKey;\r
-    char *pszValue;\r
-\r
-    static char szStartMenuRoot[MAX_PATH] = "";\r
-\r
-    if (szStartMenuRoot[0] == 0) {\r
-        dwSize = sizeof(szStartMenuRoot);\r
-    \r
-        if (IsWinNT()) {\r
-            pszKey = WINNT_START_MENU_REG_KEY;\r
-            pszValue = WINNT_START_MENU_REG_VALUE;\r
-        } else {\r
-            pszKey = WIN9X_START_MENU_REG_KEY;\r
-            pszValue = WIN9X_START_MENU_REG_VALUE;\r
-        }\r
-        \r
-        nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);\r
-        if (nResult == ERROR_SUCCESS) {\r
-            nResult = RegQueryValueEx(hKey, pszValue, 0, &dwType, (PBYTE)szStartMenuRoot, &dwSize);\r
-            RegCloseKey(hKey);\r
-        }\r
-\r
-        if (nResult != ERROR_SUCCESS)\r
-            return 0;\r
-    }\r
-\r
-    FilepathNormalizeEx(szStartMenuRoot, FPN_BACK_SLASHES);\r
-\r
-    return szStartMenuRoot;\r
-}\r
-\r
-static char *GetAfsStartMenuRoot()\r
-{\r
-    static char szAfsStartMenuRoot[MAX_PATH] = "";\r
-    char *pszStartMenuRoot;\r
-    \r
-    if (szAfsStartMenuRoot[0] == 0) {    \r
-        pszStartMenuRoot = GetStartMenuRoot();\r
-        if (!pszStartMenuRoot)\r
-            return 0;\r
-\r
-        if (bSilentMode)\r
-            sprintf(szAfsStartMenuRoot, "%s\\IBM WebSphere\\Performance Pack\\AFS", pszStartMenuRoot );\r
-        else\r
-            sprintf(szAfsStartMenuRoot, "%s\\IBM AFS", pszStartMenuRoot );\r
-    }\r
-\r
-    return szAfsStartMenuRoot;\r
-}\r
-\r
-static BOOL IsADir(char *pszName)\r
-{\r
-    struct _stat statbuf;\r
-\r
-    if (_stat(pszName, &statbuf) < 0)\r
-        return FALSE;\r
-\r
-    return statbuf.st_mode & _S_IFDIR;\r
-}\r
-\r
-static void DeleteStartMenuEntries(char *pszEntries)\r
-{\r
-    char szStartMenuPath[MAX_PATH];\r
-    char *pszAfsStartMenuRoot;\r
-    char *pszCurEntry;\r
-\r
-    pszAfsStartMenuRoot = GetAfsStartMenuRoot();\r
-\r
-    if (!pszAfsStartMenuRoot)\r
-        return;\r
-        \r
-    for (pszCurEntry = pszEntries; *pszCurEntry; pszCurEntry += strlen(pszCurEntry) + 1) {\r
-        sprintf(szStartMenuPath, "%s\\%s", pszAfsStartMenuRoot, pszCurEntry);\r
-        if (IsADir(szStartMenuPath))\r
-            RemoveDirectoryTree(szStartMenuPath);\r
-        else\r
-            DeleteFile(szStartMenuPath);\r
-    }\r
-}\r
-\r
-static void RefreshStartMenu()\r
-{\r
-    char *pszAfsStartMenuRoot;\r
-    char szTemp[MAX_PATH];\r
-    \r
-    pszAfsStartMenuRoot = GetAfsStartMenuRoot();\r
-    if (!pszAfsStartMenuRoot)\r
-        return;\r
-\r
-    sprintf(szTemp, "%s - Refresh Attempt", pszAfsStartMenuRoot);\r
-        \r
-    // Deleting items from below the root level of the start menu does not \r
-    // cause it to refresh.  In order that users can see changes without\r
-    // rebooting we will temporarily rename our root most entry, which \r
-    // does cause a refresh of the start menu.\r
-    MoveFileEx(pszAfsStartMenuRoot, szTemp, MOVEFILE_REPLACE_EXISTING);\r
-    MoveFileEx(szTemp, pszAfsStartMenuRoot, MOVEFILE_REPLACE_EXISTING);\r
-}\r
-\r
-static BOOL PreserveConfigInfo(struct APPINFO *pApp)\r
-{\r
-    char *pszRegKey;\r
-    char szDestKey[256];\r
-    LONG result;\r
-\r
-    bPreserveConfigInfo = TRUE;\r
-\r
-    // If not in silent mode, ask user if they want to preserve the cfg info\r
-    if (!bSilentMode) {\r
-        int nChoice = ShowMsg(pApp->nPreserveConfigInfoMsgID, MB_ICONQUESTION | MB_YESNOCANCEL);\r
-        if (nChoice == IDCANCEL)\r
-            return FALSE;                   // Cancel the uninstall\r
-        else if (nChoice == IDNO) {     \r
-            bPreserveConfigInfo = FALSE;    // User doesn't want to preserve the config info\r
-            return TRUE;\r
-        }\r
-    }\r
-\r
-    // Copy each reg key (and all of its subkeys and values) to another place in the registry.\r
-    for (pszRegKey = pApp->pszRegKeysToPreserve; *pszRegKey; pszRegKey += strlen(pszRegKey) + 1) {\r
-        if (!DoesRegKeyExist(pszRegKey))\r
-            continue;\r
-\r
-        // Create the destination path for the copy\r
-        sprintf(szDestKey, "%s\\%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName, pszRegKey);\r
-\r
-        // Try to copy it\r
-        result = RegDupKeyAlt(pszRegKey, szDestKey);\r
-\r
-        if ((result != ERROR_SUCCESS) && (result != ERROR_FILE_NOT_FOUND)) {\r
-            // If the copy failed, then delete any copies that succeeded\r
-            sprintf(szDestKey, "%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);\r
-            RegDeleteEntryAlt(szDestKey, REGENTRY_KEY);\r
-               goto done;\r
-        }\r
-    }\r
-\r
-       // Remember the integrated login setting if this app supports that and it was turned on\r
-       if (pApp->pszNetworkProviderOrder) {\r
-               // Was integerated login turned on?\r
-               BOOL bOn, bOk;\r
-               bOk = InNetworkProviderOrder(pApp->pszNetworkProviderOrder, &bOn);\r
-               if (bOk && bOn) {\r
-                       HKEY hKey;\r
-                       sprintf(szDestKey, "%s\\%s\\IntegratedLogin", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);\r
-                       result = RegOpenKeyAlt(AFSREG_NULL_KEY, szDestKey, KEY_WRITE, TRUE, &hKey, 0);\r
-                       // The existance of the key is a flag indicating that integrated login was turned on\r
-                       RegCloseKey(hKey);\r
-               }\r
-       }\r
-       \r
-done:\r
-       if ((result == ERROR_SUCCESS) || bSilentMode)\r
-           return TRUE;    // Continue with uninstall\r
-\r
-    // Report the error and ask the user if they want to continue the uninstall\r
-    return (ShowMsg(IDS_SAVE_OF_CONFIG_INFO_FAILED, MB_ICONEXCLAMATION | MB_YESNO) == IDYES);                  \r
-}\r
-\r
-int SUCALLCONV RestoreConfigInfo(int nApp)\r
-{\r
-    char *pszRegKey;\r
-    char szSrcKey[256];\r
-    struct APPINFO *pApp = 0;\r
-    BOOL bError = FALSE;\r
-    LONG result;\r
-\r
-    switch (nApp) {\r
-        case SERVER:    pApp = &appServer;          break;\r
-        case CLIENT:    pApp = &appClient;          break;\r
-        case LCLIENT:   pApp = &appLightClient;     break;\r
-        case CC:        pApp = &appControlCenter;   break;\r
-    }\r
-    \r
-    if (!pApp)\r
-        return -1;\r
-        \r
-    // Copy each reg key (and all of its subkeys and values) back to its original place in the registry.\r
-    for (pszRegKey = pApp->pszRegKeysToPreserve; *pszRegKey; pszRegKey += strlen(pszRegKey) + 1) {\r
-        // Create the source path for the copy\r
-        sprintf(szSrcKey, "%s\\%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName, pszRegKey);\r
-\r
-        if (!DoesRegKeyExist(szSrcKey))\r
-            continue;\r
-\r
-        // Try to restore as many of the keys as possible.  Report any errors at the end.\r
-\r
-        // Try to copy it\r
-        result = RegDupKeyAlt(szSrcKey, pszRegKey);\r
-        if ((result != ERROR_SUCCESS) && (result != ERROR_FILE_NOT_FOUND))\r
-            bError = TRUE;\r
-    }\r
-\r
-       // Restore integrated login if this app was using it\r
-       if (pApp->pszNetworkProviderOrder) {\r
-               // Check if integrated login was turned on.  The IntegratedLogin key is a flag\r
-               // telling us that it was on.  If the key does not exist, integrated login was\r
-               // not on.\r
-               sprintf(szSrcKey, "%s\\%s\\IntegratedLogin", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);\r
-               if (DoesRegKeyExist(szSrcKey)) {\r
-                       if (!AddToProviderOrder(pApp->pszNetworkProviderOrder))\r
-                               bError = TRUE;\r
-               }\r
-       }\r
-\r
-    // Remove our saved copies of the config info\r
-    sprintf(szSrcKey, "%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);\r
-    RegDeleteEntryAlt(szSrcKey, REGENTRY_KEY);\r
-            \r
-    if (bError)\r
-        ShowError(IDS_RESTORE_OF_PREVIOUS_CONFIG_FAILED, 0);\r
-\r
-    return TRUE;\r
-}\r
-\r
-static BOOL DoSubKeysExist(char *pszKey)\r
-{\r
-    LONG result;\r
-    HKEY hKey;\r
-    char *pszSubKeys = 0;\r
-    BOOL bExist;\r
-    \r
-    result = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);\r
-    if (result != ERROR_SUCCESS)\r
-        return FALSE;\r
-        \r
-    result = RegEnumKeyAlt(hKey,  &pszSubKeys);\r
-    RegCloseKey(hKey);\r
-    \r
-    if (result != ERROR_SUCCESS)\r
-        return FALSE;\r
-   \r
-    if (pszSubKeys) {\r
-        bExist = TRUE;\r
-        free(pszSubKeys);\r
-    } else\r
-        bExist = FALSE;    \r
-\r
-    return bExist;\r
-}\r
-\r
-/*\r
- * The following definitions are taken from richedit.h:\r
- *\r
- */\r
-\r
-#define EM_SETBKGNDCOLOR               (WM_USER + 67) // from Richedit.h\r
-#define EM_STREAMIN                            (WM_USER + 73) // from Richedit.h\r
-#define SF_RTF                         0x0002\r
-\r
-typedef DWORD (CALLBACK *EDITSTREAMCALLBACK)(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);\r
-\r
-typedef struct _editstream {\r
-       DWORD dwCookie;         /* user value passed to callback as first parameter */\r
-       DWORD dwError;          /* last error */\r
-       EDITSTREAMCALLBACK pfnCallback;\r
-} EDITSTREAM;\r
-\r
-/*\r
- *\r
- */\r
-\r
-DWORD CALLBACK License_StreamText (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)\r
-{\r
-   LPTSTR psz = (LPTSTR)dwCookie;\r
-   LONG cchAvail = lstrlen(psz);\r
-   if ((*pcb = min(cchAvail, cb)) != 0) {\r
-      memcpy (pbBuff, psz, *pcb);\r
-      memmove (psz, &psz[*pcb], cchAvail - *pcb + 1);\r
-   }\r
-   return 0;\r
-}\r
-\r
-\r
-void License_OnInitDialog (HWND hDlg, LPTSTR pszFile)\r
-{\r
-    // Open the license file and shove its text in our RichEdit control\r
-    //\r
-    HANDLE hFile;\r
-    if ((hFile = CreateFile (pszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) {\r
-\r
-        size_t cbText;\r
-        if ((cbText = GetFileSize (hFile, NULL)) != 0) {\r
-\r
-            LPTSTR abText = (LPTSTR)GlobalAlloc (GMEM_FIXED, cbText + 3);\r
-\r
-            DWORD cbRead;\r
-            if (ReadFile (hFile, abText, cbText, &cbRead, NULL)) {\r
-                abText[ cbRead ] = 0;\r
-\r
-                EDITSTREAM Stream;\r
-                memset (&Stream, 0x00, sizeof(Stream));\r
-                Stream.dwCookie = (DWORD)abText;\r
-                Stream.pfnCallback = License_StreamText;\r
-\r
-                SendDlgItemMessage (hDlg, IDC_TEXT, EM_STREAMIN, SF_RTF, (LPARAM)&Stream);\r
-            }\r
-\r
-            GlobalFree (abText);\r
-        }\r
-\r
-        CloseHandle (hFile);\r
-    }\r
-\r
-    // Make the control's background be gray\r
-    //\r
-    SendDlgItemMessage (hDlg, IDC_TEXT, EM_SETBKGNDCOLOR, FALSE, (LPARAM)GetSysColor(COLOR_BTNFACE));\r
-}\r
-\r
-BOOL CALLBACK License_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)\r
-{\r
-    switch (msg) {\r
-        case WM_INITDIALOG:\r
-            SetWindowLong (hDlg, DWL_USER, lp);\r
-            License_OnInitDialog (hDlg, (LPTSTR)lp);\r
-            break;\r
-\r
-        case WM_COMMAND:\r
-            switch (LOWORD(wp)) {\r
-                case IDCANCEL:\r
-                case IDOK:\r
-                    EndDialog (hDlg, LOWORD(wp));\r
-                    break;\r
-\r
-                case IDC_PRINT:\r
-                    TCHAR szDir[ MAX_PATH ];\r
-                    GetCurrentDirectory (MAX_PATH, szDir);\r
-                    ShellExecute (hDlg, TEXT("print"), (LPTSTR)GetWindowLong (hDlg, DWL_USER), NULL, szDir, SW_HIDE);\r
-                    break;\r
-            }\r
-            break;\r
-    }\r
-    return FALSE;\r
-}\r
-\r
-BOOL FindAfsInstallationPathByComponent (LPTSTR pszInstallationPath, LPTSTR pszComponent)\r
-{\r
-    *pszInstallationPath = 0;\r
-\r
-    TCHAR szRegPath[ MAX_PATH ];\r
-    wsprintf (szRegPath, TEXT("Software\\TransarcCorporation\\%s\\CurrentVersion"), pszComponent);\r
-\r
-    HKEY hk;\r
-    if (RegOpenKey (HKEY_LOCAL_MACHINE, szRegPath, &hk) == 0) {\r
-        DWORD dwType = REG_SZ;\r
-        DWORD dwSize = MAX_PATH;\r
-\r
-        if (RegQueryValueEx (hk, TEXT("PathName"), NULL, &dwType, (PBYTE)pszInstallationPath, &dwSize) == 0) {\r
-            *(LPTSTR)FindBaseFileName (pszInstallationPath) = TEXT('\0');\r
-\r
-            if (pszInstallationPath[0] && (pszInstallationPath[ lstrlen(pszInstallationPath)-1 ] == TEXT('\\')))\r
-            pszInstallationPath[ lstrlen(pszInstallationPath)-1 ] = TEXT('\0');\r
-        }\r
-\r
-        RegCloseKey (hk);\r
-    }\r
-\r
-    return !!*pszInstallationPath;\r
-}\r
-\r
-BOOL FindAfsInstallationPath (LPTSTR pszInstallationPath)\r
-{\r
-   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Client")))\r
-      return TRUE;\r
-   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Control Center")))\r
-      return TRUE;\r
-   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Server")))\r
-      return TRUE;\r
-   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Supplemental Documentation")))\r
-      return TRUE;\r
-   return FALSE;\r
-}\r
-\r
-HINSTANCE LoadRichTextControl (void)\r
-{\r
-    HINSTANCE hInst;\r
-    if ((hInst = LoadLibrary ("riched20.dll")) != NULL)\r
-        return hInst;\r
-    if ((hInst = LoadLibrary ("riched32.dll")) != NULL)\r
-        return hInst;\r
-    if ((hInst = LoadLibrary ("riched.dll")) != NULL)\r
-        return hInst;\r
-    if ((hInst = LoadLibrary ("richedit.dll")) != NULL)\r
-        return hInst;\r
-    return NULL;\r
-}\r
-\r
-int SUCALLCONV ShowLicense (char *pszTarget, char *pszSource)\r
-{\r
-    // If the license already lives on this user's machine, don't show\r
-    // it again. This only has to be done if the user has never\r
-    // accepted the license agreement before (it's part of the setup\r
-    // program, so it gets installed if they've accepted it).\r
-    //\r
-    // We were handed a relative path of the form:\r
-    //    Documentation/html/license.rtf\r
-    //\r
-    // We'll need to find the AFS installation directory, in order to\r
-    // find that Documentation subtree.\r
-    //\r
-    BOOL fShowLicense = TRUE;\r
-\r
-    TCHAR szInstallationPath[ MAX_PATH ];\r
-    if (FindAfsInstallationPath (szInstallationPath)) {\r
-        TCHAR szLicensePath[ MAX_PATH ];\r
-        wsprintf (szLicensePath, TEXT("%s\\%s"), szInstallationPath, pszTarget);\r
-\r
-        if (GetFileAttributes (szLicensePath) != (DWORD)-1) {\r
-            fShowLicense = FALSE;\r
-        }\r
-    }\r
-\r
-    // Before we can show the license file, we have to prepare the RichEdit\r
-    // control. That means loading the appropriate library and calling its\r
-    // initialization functions.\r
-    //\r
-    HINSTANCE hRichEdit;\r
-    if ((hRichEdit = LoadRichTextControl()) != NULL) {\r
-\r
-        // If we must show the license, do so now. This is a modal dialog,\r
-        // so we'll know whether or not the user accepts the license.\r
-        //\r
-        if (ModalDialogParam (IDD_LICENSE, GetActiveWindow(), License_DlgProc, (LPARAM)pszSource) == IDCANCEL) {\r
-            // The user rejected the license; fail setup\r
-            return FALSE;\r
-        }\r
-\r
-       FreeLibrary (hRichEdit);\r
-    }\r
-\r
-    // The user accepted the license, so we can continue with Setup.\r
-    // The license file is installed as part of Setup.\r
-    return TRUE;\r
-}\r
-\r
-int SUCALLCONV UninstInitialize(HWND hIS, HINSTANCE hIS5, long Reserved)\r
-{\r
-    char szPath[MAX_PATH];\r
-    struct APPINFO *pAppInfo;\r
-    char *pszFile = 0;\r
-    char *pszSubDir = 0;\r
-\r
-    hDlg = hIS;\r
-\r
-    bSilentMode = !IsWindowVisible(hIS);\r
-\r
-    // Which app are we uninstalling?\r
-    pAppInfo = GetApp();\r
-    if (!pAppInfo) {\r
-        ShowError(IDS_CANT_DETERMINE_PRODUCT, 0);\r
-        return -1;\r
-    }\r
-\r
-    // Get the app's install dir\r
-    pszInstallDir = GetAppInstallDir(pAppInfo, FALSE);\r
-    if (!pszInstallDir)\r
-        return -1;\r
-\r
-    // If this app has a custom uninstall func, call it here\r
-    if (pAppInfo->pUninstallFunc)\r
-        if (!pAppInfo->pUninstallFunc())\r
-            return -1;\r
-\r
-    if (pAppInfo->pszRegKeysToPreserve)\r
-        if (!PreserveConfigInfo(pAppInfo))\r
-            return -1;\r
-\r
-    // Unconfigure the service, if there is one for this app\r
-    if (pAppInfo->pszSvcKey) {\r
-        if (IsServiceInstalled(pAppInfo->pszSvcKey))\r
-            if (UninstallService(pAppInfo) == 1)\r
-                return -1;\r
-    }\r
-\r
-    RememberInstallDir(pszInstallDir);\r
-\r
-    DeleteInUseFiles(pAppInfo, fileInfo);\r
-\r
-    // Remove the app's bin path from the system path\r
-    if (pAppInfo->pszBinPath) {\r
-        BuildShortPath(szPath, sizeof(szPath), pszInstallDir, pAppInfo->pszBinPath);\r
-        RemoveFromPath(szPath);\r
-    }\r
-\r
-    // Remove entry from NetworkProvider\Order key in registry\r
-    if (pAppInfo->pszNetworkProviderOrder)\r
-        RemoveFromNetworkProviderOrder(pAppInfo->pszNetworkProviderOrder);\r
-\r
-    // Remove any generated subdirectories\r
-    if (!bPreserveConfigInfo && pAppInfo->pszDirsToDel) {\r
-        for (pszSubDir = pAppInfo->pszDirsToDel; *pszSubDir; pszSubDir += strlen(pszSubDir) + 1)\r
-            RemoveDir(ExpandPath(pszSubDir));\r
-    }\r
-\r
-    // Remove any generated files\r
-    if (!bPreserveConfigInfo && pAppInfo->pszFilesToDel) {\r
-        for (pszFile = pAppInfo->pszFilesToDel; *pszFile; pszFile += strlen(pszFile) + 1)\r
-            RemoveFiles(ExpandPath(pszFile));\r
-    }\r
-\r
-    // Remove any registry values that IS can't handle\r
-    RemoveRegValues(pAppInfo->pRegValues);\r
-    if (IsWinNT())\r
-        RemoveRegValues(pAppInfo->pWinNTRegValues);\r
-    else    \r
-        RemoveRegValues(pAppInfo->pWin9XRegValues);\r
-\r
-    // Remove the start menu entries for this app\r
-    if (pAppInfo->pszStartMenuEntries) {\r
-        DeleteStartMenuEntries(pAppInfo->pszStartMenuEntries);\r
-        RefreshStartMenu();\r
-    }\r
-\r
-    // Remove the install dir\r
-    RemoveDirectory(pszInstallDir);\r
-\r
-    return 0;\r
-}\r
-\r
-void SUCALLCONV UninstUnInitialize(HWND hIS, HINSTANCE hIS5, long Reserved)\r
-{\r
-    char *pszInstallDir;\r
-    char szDirPath[MAX_PATH];\r
-    char *psz;\r
-    struct APPINFO *pAppInfo;\r
-\r
-    // If we just uninstalled the last AFS app, then do some cleanup.\r
-    if (IsAppInstalled(&appServer) || IsAppInstalled(&appClient) ||\r
-        IsAppInstalled(&appControlCenter) || IsAppInstalled(&appLightClient) ||\r
-        IsAppInstalled(&appDocs))\r
-    {\r
-        return;\r
-    }\r
-\r
-    bSilentMode = !IsWindowVisible(hIS);\r
-    \r
-    // Which app did we just uninstall?\r
-    pAppInfo = GetApp();\r
-    if (!pAppInfo) {\r
-        ShowError(IDS_CANT_DETERMINE_PRODUCT, 0);\r
-        return;\r
-    }\r
-\r
-    // Get the app's install dir\r
-    pszInstallDir = GetAppInstallDir(pAppInfo, TRUE);\r
-    if (!pszInstallDir)\r
-        return;\r
-\r
-    // Remove the reg key we used to remember the app install dir\r
-    RegDeleteEntryAlt(UNINSTALL_TEMP_INFO_KEY, REGENTRY_KEY);\r
-\r
-    // Try to remove the reg key used to store config info, but only\r
-    // if there are no app config info sub keys present.\r
-    if (!DoSubKeysExist(AFS_PRESERVED_CFG_INFO_KEY))\r
-        RegDeleteEntryAlt(AFS_PRESERVED_CFG_INFO_KEY, REGENTRY_KEY);\r
-\r
-    // Remove the install dir\r
-    RemoveDirectory(pszInstallDir);\r
-\r
-    // Attempt to remove the install root and common directories.  The are \r
-    // shared and so no single app knows to delete them.\r
-\r
-    // Strip off the app specific part of the install dir\r
-    psz = strrchr(pszInstallDir, '\\');\r
-    if (psz)\r
-        *psz = 0;\r
-\r
-    sprintf(szDirPath, "%s\\%s", pszInstallDir, "Common");\r
-    RemoveDirectory(szDirPath);\r
-\r
-    // Remove the Common directory from the system path\r
-    RemoveFromPath(szDirPath);\r
-\r
-    // Remove all of the documentation dirs\r
-    sprintf(szDirPath, "%s\\%s", pszInstallDir, "Documentation");\r
-    RemoveDirectoryTree(szDirPath);\r
-\r
-    // Ok, up to this point we have been removing files we know we\r
-    // created.  However, after this point we are into the path\r
-    // that the user chose for our install root.  The default for\r
-    // this is IBM/Afs, but they could have chosen anything,\r
-    // including a dir or dirs that have other products in them.\r
-    // We will check to see if it is IBM\AFS and if it is then we \r
-    // will attempt to remove them.\r
-    \r
-    // Back up a level and look for AFS\r
-    psz = strrchr(pszInstallDir, '\\');\r
-    if (psz) {\r
-        if (stricmp(psz + 1, "AFS") == 0) {\r
-            RemoveDirectory(pszInstallDir);\r
-            *psz = 0;\r
-        }\r
-    }\r
-\r
-    // Back up a level and look for IBM\r
-    psz = strrchr(pszInstallDir, '\\');\r
-    if (psz) {\r
-        if (stricmp(psz + 1, "IBM") == 0) {\r
-            RemoveDirectory(pszInstallDir);\r
-            *psz = 0;\r
-        }\r
-    }\r
-\r
-    // Remove the root afs start menu entry\r
-    psz = GetStartMenuRoot();\r
-    if (psz) {\r
-        if (bSilentMode) {\r
-            // Remove everything under our branch\r
-            sprintf(szDirPath, "%s\\IBM WebSphere\\Performance Pack\\AFS", psz);\r
-            RemoveDirectoryTree(szDirPath);\r
-            \r
-            // Remove the IBM stuff only if the dirs are empty\r
-            sprintf(szDirPath, "%s\\IBM WebSphere\\Performance Pack", psz);\r
-            if (RemoveDirectory(szDirPath)) {\r
-                sprintf(szDirPath, "%s\\IBM WebSphere", psz);\r
-                RemoveDirectory(szDirPath);\r
-            }\r
-        } else {\r
-            sprintf(szDirPath, "%s\\IBM AFS", psz);\r
-            RemoveDirectoryTree(szDirPath);\r
-        }\r
-    }\r
-}\r
-\r
-BOOLEAN _stdcall DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved)\r
-{\r
-    if (reason == DLL_PROCESS_ATTACH) {\r
-        hinst = (HINSTANCE)dll;\r
-        TaLocale_LoadCorrespondingModuleByName (hinst, "afs_setup_utils.dll");\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-extern "C" int WINAPI Test (HINSTANCE hInst, HINSTANCE hPrev, LPSTR psz, int nCmdShow)\r
-{\r
-   ShowLicense ("TEST", "\\\\fury\\afssetup\\license\\ja_JP.rtf");\r
-   return 0;\r
-}\r
-\r
-\r
+ * INCLUDES _________________________________________________________________
+ *
+ */
+
+extern "C" {
+#include <afs/param.h>
+#include <afs/stds.h>
+#include <afs/fileutil.h>
+}
+
+#include <windows.h>
+#include <stdio.h>
+#include <time.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <io.h>
+#include <string.h>
+#include <SYS\STAT.H>
+#include <shellapi.h>
+
+#include <WINNT/afsreg.h>
+#include <WINNT/afssw.h>
+#include <WINNT/talocale.h>
+
+#include "resource.h"
+#include "progress_dlg.h"
+#include "sutil.h"
+#include "forceremove.h"
+
+
+/*
+ * PROTOTYPES _________________________________________________________________
+ *
+ */
+static char *GetAppInstallDir(struct APPINFO *pApp, BOOL bRemembered);
+BOOL UninstallCredsTool();
+BOOL ServerSpecificUninstall();
+BOOL ClientSpecificUninstall();
+
+
+
+/*
+ * DEFINITIONS _________________________________________________________________
+ *
+ */
+#define SUCALLCONV  WINAPI
+
+#define UNINSTALL_TEMP_INFO_KEY     "HKEY_LOCAL_MACHINE\\Software\\AfsUninstallTempInfo"
+#define INSTALL_DIR_VALUE_NAME      "InstallDir"
+
+#define AFS_PRESERVED_CFG_INFO_KEY  "HKEY_LOCAL_MACHINE\\Software\\AfsPreservedConfigInfo"
+
+#define MS_SHARED_FILES_KEY         "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs"
+
+// Log file to use when running in silent mode
+#define UNINSTALL_ERROR_LOG_NAME    "\\AfsUninstallErrorLog.txt"
+#define INSTALL_ERROR_LOG_NAME      "\\AfsInstallErrorLog.txt"
+
+#define TARGETDIR                   "<TARGETDIR>"
+#define WINDIR                      "<WINDIR>"
+#define WINSYSDIR                   "<WINSYSDIR>"
+
+#define WIN9X_START_MENU_REG_KEY    "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+#define WIN9X_START_MENU_REG_VALUE  "Programs"
+    
+#define WINNT_START_MENU_REG_KEY    "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+#define WINNT_START_MENU_REG_VALUE  "Common Programs"
+
+#define LOCALE_ID_LEN               4
+
+struct REGVALUE {
+    char *pszKey;
+    char *pszValue;
+};
+
+
+typedef BOOL (APP_UNINSTALL_FUNC)();
+
+
+
+struct APPINFO {
+    char *pszAppName;
+
+    // Service Info
+    char *pszSvcName;
+    char *pszSvcKey;
+    char *pszSvcDependOn;
+    char *pszSvcDisplayName;
+
+    char *pszNetworkProviderOrder;
+
+    // Message to use to tell the user that we have to stop the service
+    int nServiceShutdownMsgID;
+
+    // Message to use for the progress dialog that is shown while
+    // waiting for the service to stop.
+    int nServiceShutdownProgressMsgID;
+
+    // Location in registry of a key we can use to know that the app is installed
+    char *pszAppKey;
+
+    // Location in registry of this app's install dir
+    struct REGVALUE regInstallDir;
+
+    // Path Info
+    char *pszLocalRoot;     // The root dir below the install dir
+    char *pszBinPath;       // Path to remove from the system path
+
+    // Generated files and directories to delete.  These are both multistring lists.
+    char *pszDirsToDel;     // All files in these dirs will be deleted
+    char *pszFilesToDel;    // Use this if you want to delete files but leave the dir.  Wildcards can be used.
+
+    // Registry values to remove
+    struct REGVALUE *pRegValues;
+    struct REGVALUE *pWinNTRegValues;   // Only remove these if running WinNT
+    struct REGVALUE *pWin9XRegValues;   // Only remove these if running Win9X
+
+    // Start menu entries to delete
+    char *pszStartMenuEntries;
+
+    // Registry keys to save if a user wants to preserve config info during uninstall
+    char *pszRegKeysToPreserve;
+    int nPreserveConfigInfoMsgID;
+
+    // Uninstall func - used for things specific to this app
+    APP_UNINSTALL_FUNC *pUninstallFunc;
+};
+
+
+/*
+ * App info structure for the Server product
+ */
+struct APPINFO appServer = {
+    "AFS Server",
+    
+    AFSREG_SVR_SVC_NAME,
+    AFSREG_SVR_SVC_KEY,
+    0,  // No depend on
+    AFSREG_SVR_SVC_DISPLAYNAME_DATA,
+
+    0,  // No network provider order
+
+    IDS_MUST_STOP_SERVER,
+    IDS_WAITING_FOR_SERVER_TO_STOP,
+
+    AFSREG_SVR_SW_VERSION_KEY,
+    
+    { AFSREG_SVR_SW_VERSION_KEY, AFSREG_SVR_SW_VERSION_DIR_VALUE },
+
+    "\\Server",
+    "\\usr\\afs\\bin",
+
+    // Dirs to delete
+    TARGETDIR"\\Server\\usr\\afs\\bin\\backup\0"
+    TARGETDIR"\\Server\\usr\\afs\\bin\0"
+    TARGETDIR"\\Server\\usr\\afs\\db\0"
+    TARGETDIR"\\Server\\usr\\afs\\logs\0"
+    TARGETDIR"\\Server\\usr\\afs\\etc\0"
+    TARGETDIR"\\Server\\usr\\afs\\local\0"
+    TARGETDIR"\\Server\\usr\\afs\0"
+    TARGETDIR"\\Server\\usr\0",
+    
+    // Files to delete
+    TARGETDIR"\\Common\\*.gid\0"
+    TARGETDIR"\\Common\\*.fts\0",
+
+    0,  // No reg values
+    0,  // No NT only reg values
+    0,  // No 9x only reg values
+
+    "Server\0",
+
+    // Config info to preserve
+    AFSREG_SVR_SVC_KEY"\0", 
+    IDS_PRESERVE_SERVER_CONFIG_INFO,
+
+    0   // No special uninstall function
+};
+
+// Registry values to remove for the Client
+struct REGVALUE clientRegValues[] = {
+    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", "{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}" },
+    { 0, 0 }    // This indicates there are no more entries
+};
+
+struct REGVALUE clientWinNTRegValues[] = {
+    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\File Manager\\AddOns", "AFS Client FME" },
+    { "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NetBT\\Paramet
+ers", "SMBDeviceEnabled" },
+    { 0, 0 }
+};
+
+struct REGVALUE clientWin9XRegValues[] = {
+    { "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order", "TransarcAFSDaemon" },
+    { 0, 0 }
+};
+
+/*
+ * App info structure for the Client product
+ */
+struct APPINFO appClient = {
+    "AFS Client",
+    
+    AFSREG_CLT_SVC_NAME,
+    AFSREG_CLT_SVC_KEY,
+    "5250435353004E657462696F730000",
+    AFSREG_CLT_SVC_DISPLAYNAME_DATA,
+
+    AFSREG_CLT_SVC_NAME,
+
+    IDS_MUST_STOP_CLIENT,
+    IDS_WAITING_FOR_CLIENT_TO_STOP,
+
+    AFSREG_CLT_SW_VERSION_KEY,
+
+    { AFSREG_CLT_SW_VERSION_KEY, AFSREG_CLT_SW_VERSION_DIR_VALUE },
+
+    "\\Client",
+    "\\Program",
+
+    // No dirs to delete
+    0,
+    
+    // Files to delete
+    TARGETDIR"\\Common\\*.gid\0"
+    TARGETDIR"\\Common\\*.fts\0"
+    WINDIR"\\..\\AFSCache\0"
+    WINDIR"\\afsd.log\0"
+    WINDIR"\\afsd.ini\0"
+    WINDIR"\\afsdsbmt.ini\0"
+    WINDIR"\\afsdcell.ini\0"
+    WINDIR"\\afsd_init.log\0",
+    
+    clientRegValues,
+    clientWinNTRegValues,
+    clientWin9XRegValues,
+
+    // Start menu entries to remove
+    "Client\0",
+
+    // Config info to preserve
+    AFSREG_CLT_SVC_KEY"\0",
+    IDS_PRESERVE_CLIENT_CONFIG_INFO,
+
+    ClientSpecificUninstall
+};
+
+
+/*
+ * App info structure for the Light Client product
+ */
+struct APPINFO appLightClient = {
+    "AFS Light",
+    
+    // No service info 
+    0,
+    0,
+    0,
+    0,
+
+    AFSREG_CLT_SVC_NAME,
+
+    // No service shutdown messages
+    0,
+    0,
+
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Light Client",
+
+    { AFSREG_CLT_SW_VERSION_KEY, AFSREG_CLT_SW_VERSION_DIR_VALUE },
+
+    "\\Client",
+    "\\Program",
+
+    // No dirs to delete
+    0,
+    
+    // Files to delete
+    TARGETDIR"\\Common\\*.gid\0"
+    TARGETDIR"\\Common\\*.fts\0",
+
+    clientRegValues,
+    clientWinNTRegValues,
+    clientWin9XRegValues,
+
+    // Start menu entries to remove
+    "Light\0",
+
+    // Config info to preserve
+    AFSREG_CLT_SVC_KEY"\0",
+    IDS_PRESERVE_LIGHT_CLIENT_CONFIG_INFO,
+
+    UninstallCredsTool
+};
+
+
+/*
+ * App info structure for the Control Center product
+ */
+struct APPINFO appControlCenter = {
+    "AFS Control Center",
+    
+    // No service info
+    0,
+    0,
+    0,
+    0,
+
+    // No network provider order
+    0,
+
+    // No service shutdown messages    
+    0,
+    0,
+
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Control Center",
+    
+    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Control Center\\CurrentVersion", "PathName" },
+
+    "\\Control Center",
+    "",
+
+    // No dirs to delete
+    0,
+    
+    // Files to delete
+    TARGETDIR"\\Common\\*.gid\0"
+    TARGETDIR"\\Common\\*.fts\0",
+    
+    0,  // No reg values
+    0,  // No NT only reg values
+    0,  // No 9x only reg values
+
+    // Start menu entries to remove
+    "Control Center\0",
+
+    // Config info to preserve
+    AFSREG_CLT_SVC_KEY"\0",
+    IDS_PRESERVE_CC_CONFIG_INFO,
+
+    0   // No uninstall function
+};
+
+
+/*
+ * App info structure for the Sys Admin Doc files
+ */
+struct APPINFO appDocs = {
+    "AFS Supplemental Documentation",
+
+    // No service info
+    0,
+    0,
+    0,
+    0,
+
+    // No network provider order
+    0,
+
+    // No service shutdown messages    
+    0,
+    0,
+
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Supplemental Documentation",
+    
+    { "HKEY_LOCAL_MACHINE\\SOFTWARE\\TransarcCorporation\\AFS Supplemental Documentation\\CurrentVersion", "PathName" },
+
+    "\\Documentation",
+    "",
+
+    // No dirs to delete
+    0,
+    
+    // Files to delete
+    TARGETDIR"\\Common\\*.gid\0"
+    TARGETDIR"\\Common\\*.fts\0",
+
+    0,  // No reg values
+    0,  // No NT only reg values
+    0,  // No 9x only reg values
+
+    // Start menu entries to remove
+    "Documentation\\AFS for Windows Backup Command Reference.lnk\0Documentation\\AFS Command Reference Manual.lnk\0Documentation\\AFS System Administrator's Guide.lnk\0",
+
+    0,  // No config info to preserve
+
+    0   // No uninstall function
+};
+
+
+// Shared and in-use files
+struct FILEINFO {
+    char *pszName;
+    int nUsedBy;
+};
+
+#define SERVER  1
+#define CLIENT  2
+#define LCLIENT 4
+#define CC      8
+#define DOCS    16
+
+
+struct FILEINFO fileInfo[] = {
+    { TARGETDIR"\\Common\\afsbosadmin.dll",             SERVER | CC },
+    { TARGETDIR"\\Common\\afscfgadmin.dll",             SERVER | CC },
+    { TARGETDIR"\\Common\\afsclientadmin.dll",          SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afskasadmin.dll",             SERVER | CC },
+    { TARGETDIR"\\Common\\afsptsadmin.dll",             SERVER | CC },
+    { TARGETDIR"\\Common\\afsvosadmin.dll",             SERVER | CC },
+    { TARGETDIR"\\Common\\afsadminutil.dll",            SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afsrpc.dll",                  SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afsauthent.dll",              SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\pthread.dll",                 SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\TaAfsAppLib.dll",             SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afsprocmgmt.dll",             SERVER | CLIENT | LCLIENT },
+    { TARGETDIR"\\Common\\afs_config.exe",              CLIENT | LCLIENT| CC },
+    { TARGETDIR"\\Common\\afseventmsg_????.dll",        SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afslegal_????.dll",           SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afsserver_????.dll",          SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afssvrcfg_????.dll",          SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\TaAfsAccountManager_????.dll",SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\TaAfsAppLib_????.dll",        SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\TaAfsServerManager_????.dll", SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afscreds_????.dll",           SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs_config_????.dll",         SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs_cpa_????.dll",            SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs_shl_ext_????.dll",        SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-nt.hlp",                  SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-nt.cnt",                  SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafssvrmgr.cnt",             SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafssvrmgr.hlp",             SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafsusrmgr.cnt",             SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafsusrmgr.hlp",             SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-cc.cnt",                  SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-cc.hlp",                  SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-light.cnt",               SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\afs-light.hlp",               SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafscfg.cnt",                SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Common\\taafscfg.hlp",                SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Client\\PROGRAM\\afs_shl_ext.dll",    CLIENT | LCLIENT },
+    { TARGETDIR"\\Client\\PROGRAM\\libafsconf.dll",     CLIENT | LCLIENT },
+    { TARGETDIR"\\Client\\PROGRAM\\afslogon.dll",       CLIENT },
+    { TARGETDIR"\\Client\\PROGRAM\\afslog95.dll",       LCLIENT },
+    { TARGETDIR"\\Control Center\\TaAfsAdmSvr.exe",     CC },
+    { WINSYSDIR"\\afs_cpa.cpl",                         CLIENT | LCLIENT | CC },
+    { WINSYSDIR"\\afsserver.cpl",                       SERVER },
+    { TARGETDIR"\\Common\\afsdcell.ini",                CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Documentation\\Html\\banner.gif",     SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\books.gif",      SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\bot.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\index.gif",      SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\index.htm",      SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\next.gif",       SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\prev.gif",       SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\toc.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\top.gif",        SERVER | CLIENT | LCLIENT | CC | DOCS },
+    { TARGETDIR"\\Documentation\\Html\\ReleaseNotes\\relnotes.htm",
+                                                        SERVER | CLIENT | LCLIENT | CC },
+    { TARGETDIR"\\Documentation\\Html\\InstallGd\\afsnt35i.htm",
+                                                        SERVER | CLIENT | LCLIENT | CC },
+    { 0,                                                0 }     // End of list
+};
+
+
+/*
+ * VARIABLES _________________________________________________________________
+ *
+ */
+HINSTANCE hinst;
+
+static HWND hDlg;
+static BOOL bPreserveConfigInfo;
+static BOOL bSilentMode;
+static char *pszInstallDir;
+
+
+/*
+ * FUNCTIONS _________________________________________________________________
+ *
+ */
+
+static BOOL UpgradeClientIntParm(HKEY hKey, char *pszOldParm, char *pszNewParm)
+{
+    int nData;
+    LONG result = ERROR_SUCCESS;
+
+    nData = GetPrivateProfileInt("AFS Client", pszOldParm, -1, "afsd.ini");
+    if (nData > -1)
+        result = RegSetValueEx(hKey, pszNewParm, 0, REG_DWORD, (BYTE *)&nData, sizeof(nData));
+
+    return (result == ERROR_SUCCESS);
+}
+
+static BOOL UpgradeClientStringParm(HKEY hKey, char *pszOldParm, char *pszNewParm)
+{
+    char szData[1024];
+    LONG result = ERROR_SUCCESS;
+
+    GetPrivateProfileString("AFS Client", pszOldParm, "", szData, sizeof(szData), "afsd.ini");
+    if (szData[0])
+        result = RegSetValueEx(hKey, pszNewParm, 0, REG_SZ, (PBYTE)szData, strlen(szData) + 1);
+
+    return (result == ERROR_SUCCESS);
+}
+
+int SUCALLCONV Upgrade34ClientConfigInfo()
+{
+    HKEY hKey;
+    LONG result;
+    int nData;
+    
+    result = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_CLT_SVC_PARAM_KEY, KEY_WRITE, TRUE, &hKey, 0);
+    if (result != ERROR_SUCCESS)
+        return -1;
+
+    UpgradeClientIntParm(hKey, "CacheSize", "CacheSize");
+    UpgradeClientIntParm(hKey, "Stats", "Stats");
+    UpgradeClientIntParm(hKey, "LogoffTokenTransfer", "LogoffTokenTransfer");
+    UpgradeClientIntParm(hKey, "LogoffTokenTransferTimeout", "LogoffTokenTransferTimeout");
+    UpgradeClientIntParm(hKey, "TrapOnPanic", "TrapOnPanic");
+    UpgradeClientIntParm(hKey, "TraceBufferSize", "TraceBufferSize");
+    UpgradeClientIntParm(hKey, "TraceOnShutdown", "TraceOnShutdown");
+    UpgradeClientIntParm(hKey, "ReportSessionStartups", "ReportSessionStartups");
+    
+    UpgradeClientStringParm(hKey, "MountRoot", "MountRoot");
+    UpgradeClientStringParm(hKey, "Cell", "Cell");
+
+    /* BlockSize to ChunkSize requires convertion */
+    nData = GetPrivateProfileInt("AFS Client", "BlockSize", -1, "afsd.ini");
+    if (nData > -1) {
+       DWORD chunkSize;
+       for (chunkSize = 0; (1 << chunkSize) < nData; chunkSize++);
+        (void) RegSetValueEx(hKey, "ChunkSize", 0, REG_DWORD, (BYTE *)&chunkSize, sizeof(chunkSize));
+    }
+
+    RegCloseKey(hKey);
+
+    return 0;
+}
+
+int SUCALLCONV Eradicate34Client()
+{
+    if (Client34Eradicate(TRUE) != ERROR_SUCCESS)
+        return -1;
+
+    return 0;
+}
+
+// This function was written a long time ago by Mike Comer for use by the 
+// original DFS Client for NT install program.
+int SUCALLCONV CheckIfAdmin(void)
+{
+    HANDLE                  token = INVALID_HANDLE_VALUE;
+    PVOID                   buffer = 0;
+    DWORD                   bufLength;
+    DWORD                   realBufLength;
+    TOKEN_PRIMARY_GROUP     *pgroup;
+    TOKEN_GROUPS            *groups;
+    int                     result = -1;
+    DWORD                   groupCount;
+    LONG                    status;
+    PSID                    AdministratorSID = NULL;
+    SID_IDENTIFIER_AUTHORITY    authority = SECURITY_NT_AUTHORITY;
+
+    // allocate the SID for the Administrators group
+    if (!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorSID)) {
+        status = GetLastError();
+        goto getout;
+    }
+
+    // open the process token
+    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) {
+        status = GetLastError();
+        token = INVALID_HANDLE_VALUE;
+        goto getout;
+    }
+
+    // check primary group first
+    buffer = GlobalAlloc(GMEM_FIXED, sizeof(TOKEN_PRIMARY_GROUP));
+    if (!buffer) {
+        goto getout;
+    }
+
+    bufLength = sizeof(TOKEN_PRIMARY_GROUP);
+    while(1) {
+        if (!GetTokenInformation(token, TokenPrimaryGroup, buffer, bufLength, &realBufLength)) {
+            if (realBufLength > bufLength) {
+                // not enough space
+                GlobalFree(buffer);
+                bufLength = realBufLength;
+                buffer = GlobalAlloc(GMEM_FIXED, realBufLength);
+                if (!buffer) {
+                    goto getout;
+                }
+                continue;
+            }
+
+            goto getout;
+        }
+        break;
+    }
+
+    pgroup = (TOKEN_PRIMARY_GROUP *)buffer;
+    if (EqualSid(pgroup->PrimaryGroup, AdministratorSID)) {
+        result = 0;
+    } else {
+        // okay, try the secondary groups
+        while(1) {
+            if (!GetTokenInformation(token, TokenGroups, buffer, bufLength, &realBufLength)) {
+                if (realBufLength > bufLength) {
+                    // not enough space
+                    GlobalFree(buffer);
+                    bufLength = realBufLength;
+                    buffer = GlobalAlloc(GMEM_FIXED, realBufLength);
+                    if (!buffer) {
+                        goto getout;
+                    }
+                    continue;
+                }
+
+                // a real error
+                goto getout;
+            }
+            break;
+        }
+
+        // we have the list of groups here.  Process them:
+        groups = (TOKEN_GROUPS *)buffer;
+        for(groupCount = 0; groupCount < groups->GroupCount; groupCount++) {
+            if (EqualSid(groups->Groups[groupCount].Sid, AdministratorSID)) {
+                result = 0;
+                break;
+            }
+        }
+    }
+
+getout:
+
+    if (token != INVALID_HANDLE_VALUE) {
+        CloseHandle(token);
+    }
+
+    if (buffer) {
+        GlobalFree(buffer);
+    }
+
+    if (AdministratorSID) {
+        FreeSid(AdministratorSID);
+    }
+
+    return result;
+}
+
+static void SetSharedFileRefCount(char *pszFile, int nRefCount)
+{
+    LONG result;
+    HKEY hKey;
+    
+    result = RegOpenKeyAlt(AFSREG_NULL_KEY, MS_SHARED_FILES_KEY, KEY_WRITE, FALSE, &hKey, 0);
+    if (result != ERROR_SUCCESS)
+        return;
+    
+    if (nRefCount <= 0)
+        RegDeleteValue(hKey, pszFile);
+    else
+        RegSetValueEx(hKey, pszFile, 0, REG_DWORD, (BYTE *)&nRefCount, sizeof(int));    
+    
+    RegCloseKey(hKey);
+}
+
+static char *GetTimeStamp()
+{
+    char szTime[64], szDate[64];
+    static char szTimeDate[128];
+
+    _strtime(szTime);
+    _strdate(szDate);
+
+    sprintf(szTimeDate, "[%s %s] ", szTime, szDate);
+    
+    return szTimeDate;
+}
+
+int SUCALLCONV WriteToInstallErrorLog(char *pszMsg)
+{
+    static BOOL bWritten = FALSE;
+    FILE *fp;
+
+    // On the first write, recreate the file    
+    fp = fopen(INSTALL_ERROR_LOG_NAME, bWritten ? "a" : "w");
+    if (!fp)
+        return -1;
+        
+    fprintf(fp, "%s%s\r\n", GetTimeStamp(), pszMsg);
+    
+    fclose(fp);
+    
+    bWritten = TRUE;
+    
+    return 0;
+}
+
+static void WriteToUninstallErrorLog(char *pszMsg)
+{
+    static BOOL bWritten = FALSE;
+    FILE *fp;
+
+    // On the first write, recreate the file    
+    fp = fopen(UNINSTALL_ERROR_LOG_NAME, bWritten ? "a" : "w");
+    if (!fp)
+        return;
+        
+    fprintf(fp, "%s%s\r\n", GetTimeStamp(), pszMsg);
+    
+    fclose(fp);
+    
+    bWritten = TRUE;
+}
+
+static char *LoadResString(UINT uID)
+{
+    static char str[256];
+    GetString (str, uID);
+    return str;
+}
+
+static void ShowError(UINT nResID, LONG nError)
+{
+    char szErr[256];
+    char szPrompt[256];
+    char szMsg[256];
+    char szTitle[256];
+    char *psz;
+
+    psz = LoadResString(nResID);
+    if (psz)
+        strcpy(szErr, psz);
+    else
+        sprintf(szErr, "unknown error msg (Msg ID = %d)", nResID);
+    
+    psz = LoadResString(IDS_INSTALLATION_FAILURE);
+    strcpy(szPrompt, psz ? psz : "An error has occurred:  %s (Last Error = %ld).");
+
+    sprintf(szMsg, szPrompt, szErr, nError);
+
+    psz = LoadResString(IDS_TITLE);
+    strcpy(szTitle, psz ? psz : "AFS");
+
+    if (bSilentMode)
+        WriteToUninstallErrorLog(szMsg);
+    else
+        MessageBox(hDlg, szMsg, szTitle, MB_OK);
+}
+
+static int ShowMsg(UINT nResID, int nType)
+{
+    char szTitle[256];
+    char *psz;
+
+    psz = LoadResString(IDS_TITLE);
+    strcpy(szTitle, psz ? psz : "AFS");
+
+    return MessageBox(hDlg, LoadResString(nResID), szTitle, nType);
+}
+
+static char *GetAppInstallDir(struct APPINFO *pApp, BOOL bRemembered)
+{
+    HKEY hKey;
+    LONG nResult;
+    DWORD dwType;
+    static char szInstallDir[256];
+    DWORD dwSize;
+    char *pszKey;
+    char *pszValue;
+
+    pszKey = bRemembered ? UNINSTALL_TEMP_INFO_KEY : pApp->regInstallDir.pszKey;
+    pszValue = bRemembered ? INSTALL_DIR_VALUE_NAME : pApp->regInstallDir.pszValue;
+
+    dwSize = sizeof(szInstallDir);
+
+    nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);
+    if (nResult == ERROR_SUCCESS) {
+        nResult = RegQueryValueEx(hKey, pszValue, 0, &dwType, (PBYTE)szInstallDir, &dwSize);
+        RegCloseKey(hKey);
+    }
+
+    if (nResult != ERROR_SUCCESS) {
+        ShowError(IDS_CANT_DETERMINE_APP_PATH, nResult);
+        return 0;
+    }
+
+    FilepathNormalizeEx(szInstallDir, FPN_BACK_SLASHES);
+
+    return szInstallDir;
+}
+
+static BOOL DoesRegKeyExist(char *pszKey)
+{
+    HKEY hKey;
+    LONG nResult;
+
+    nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);
+    if (nResult == ERROR_SUCCESS) {
+        RegCloseKey(hKey);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static BOOL IsAppInstalled(struct APPINFO *pApp)
+{
+    return DoesRegKeyExist(pApp->pszAppKey);
+}
+
+static void BuildShortPath(char *pszShortPath, UINT nShortPathLen, char *pszInstallDir, char *pszPath)
+{
+    strncpy(pszShortPath, pszInstallDir, nShortPathLen);
+    strncat(pszShortPath, pszPath, nShortPathLen);
+    
+    GetShortPathName(pszShortPath, pszShortPath, nShortPathLen);
+}
+
+static BOOL IsWin95()
+{
+    OSVERSIONINFO versionInformation;
+
+    versionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    
+    GetVersionEx(&versionInformation);
+    
+    if ((versionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
+        (versionInformation.dwMinorVersion == 0))
+        return TRUE;
+        
+    return FALSE;
+}
+
+int IsWin98()
+{
+    OSVERSIONINFO versionInformation;
+
+    versionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    
+    GetVersionEx(&versionInformation);
+    
+    if ((versionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
+        (versionInformation.dwMinorVersion == 10))
+        return 0;
+        
+    return -1;
+}
+
+static BOOL IsServiceInstalled(char *pszServiceKey)
+{
+    HKEY hKey;
+
+    if (RegOpenKeyAlt(0, pszServiceKey, KEY_READ, FALSE, &hKey, 0) == ERROR_SUCCESS) {
+        RegCloseKey(hKey);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+// If this fails in anyway we just return.  No error is displayed.
+static void MakeSureServiceDoesNotExist(char *pszName)
+{
+    SC_HANDLE hServer = 0, hSCM = 0;
+    SERVICE_STATUS status;
+
+    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
+    if (hSCM) {
+        hServer = OpenService(hSCM, pszName, SERVICE_ALL_ACCESS | DELETE);
+        if (hServer) {
+            if (QueryServiceStatus(hServer, &status)) {
+                if (status.dwCurrentState != SERVICE_STOPPED) {
+                    if (!ControlService(hServer, SERVICE_CONTROL_STOP, &status)) {
+                        CloseServiceHandle(hServer);
+                        CloseServiceHandle(hSCM);
+                        return;
+                    }
+                }
+            }
+            
+            // Try to delete even if status query fails
+            DeleteService(hServer);
+        }
+    }
+
+    if (hServer)
+        CloseServiceHandle(hServer);
+    if (hSCM)
+        CloseServiceHandle(hSCM);
+}
+
+static int InstallService(char *pszName, char *pszDependOn, char *pszDisplayName, char *pszServicePath, BOOL bInteractive)
+{
+    SC_HANDLE hServer = 0, hSCM;
+    BOOL bRestoreOldConfig = FALSE;
+
+    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
+    if (!hSCM) {
+        ShowError(IDS_SCM_OPEN_FAILED, GetLastError());
+        return -1;
+    }
+
+/*  This code is not used, but it could be handy in the future so I am keeping it here.
+
+    // If the service exists, then we (most probably) are in the middle of an upgrade or reinstall.
+    bRestoreOldConfig = IsServiceInstalled(pszName);
+
+    if (bRestoreOldConfig) {
+        hServer = OpenService(hSCM, pszName, SERVICE_ALL_ACCESS);
+        if (!hServer || !ChangeServiceConfig(hServer, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, 0, 0, 0, 0, 0, 0, 0)) {
+            ShowError(IDS_RESTORE_OF_PREVIOUS_CONFIG_FAILED, GetLastError());
+            bRestoreOldConfig = FALSE;
+            // Fall through to service creation below
+        }
+    } 
+*/
+    
+    if (!bRestoreOldConfig) {
+        DWORD dwServiceType;
+
+        // If the service already exists, the create call will fail.  This can
+        // happen if uninstall failed (which is not infrequent).  Making sure the
+        // service does not exist makes it easier for a user to install over top of
+        // a previously failed uninstall.
+        MakeSureServiceDoesNotExist(pszName);
+
+        dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+        if (bInteractive)
+            dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
+    
+        hServer = CreateService(hSCM, pszName, pszDisplayName,
+            SERVICE_ALL_ACCESS, dwServiceType, SERVICE_AUTO_START, 
+            SERVICE_ERROR_NORMAL, pszServicePath, 0, 0, "RPCSS\0Netbios\0\0", 0, 0);
+    
+        if (!hServer)
+            ShowError(IDS_SERVICE_CREATE_FAILED, GetLastError());
+    }
+
+    if (hServer)
+        CloseServiceHandle(hServer);
+
+    CloseServiceHandle(hSCM);
+
+    return 0;
+}
+
+int SUCALLCONV InstallServerService(char *pszServicePath)
+{
+    return InstallService(appServer.pszSvcName, 0, appServer.pszSvcDisplayName, pszServicePath, TRUE);
+}
+
+int SUCALLCONV InstallClientService(char *pszServicePath)
+{
+    return InstallService(appClient.pszSvcName, appClient.pszSvcDependOn, appClient.pszSvcDisplayName, pszServicePath, FALSE);
+}
+
+static int UninstallService(struct APPINFO *pAppInfo)
+{
+    SC_HANDLE hServer, hSCM;
+    SERVICE_STATUS status;
+    BOOL bOk;
+    BOOL bServer = FALSE;
+    BOOL bShowingProgressDlg = FALSE;
+
+    hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
+    if (!hSCM) {
+        ShowError(IDS_SCM_OPEN_FAILED, GetLastError());
+        return -1;
+    }
+    
+    hServer = OpenService(hSCM, pAppInfo->pszSvcName, SERVICE_ALL_ACCESS | DELETE);
+    if (!hServer) {
+        ShowError(IDS_SERVICE_OPEN_FAILED, GetLastError());
+        CloseServiceHandle(hSCM);
+        return -1;
+    }
+
+    if (!QueryServiceStatus(hServer, &status)) {
+        ShowError(IDS_SERVICE_QUERY_FAILED, GetLastError());
+        CloseServiceHandle(hServer);
+        CloseServiceHandle(hSCM);
+        return -1;
+    }
+
+    if (status.dwCurrentState != SERVICE_STOPPED) {
+        if (pAppInfo->nServiceShutdownMsgID) {
+            if (!bSilentMode && (ShowMsg(pAppInfo->nServiceShutdownMsgID, MB_YESNO | MB_ICONQUESTION) == IDNO)) {
+                CloseServiceHandle(hServer);
+                CloseServiceHandle(hSCM);
+                return 1;
+            }
+        }
+
+        if (!bSilentMode)
+            bShowingProgressDlg = ShowProgressDialog(LoadResString(pAppInfo->nServiceShutdownProgressMsgID));
+
+        if (!ControlService(hServer, SERVICE_CONTROL_STOP, &status)) {
+            if (bShowingProgressDlg)
+                HideProgressDialog();
+            ShowError(IDS_SERVICE_STOP_FAILED, GetLastError());
+            CloseServiceHandle(hServer);
+            CloseServiceHandle(hSCM);
+            return -1;
+        }
+    }
+
+    // Wait for the service to stop
+    while (status.dwCurrentState != SERVICE_STOPPED) {
+        // I stopped waiting on dwWaitHint because it seemed the wait hint was too long.
+        // The service would be stopped but we'd still be asleep for a long time yet.
+        Sleep(5000);    //status.dwWaitHint);
+
+        if (!QueryServiceStatus(hServer, &status)) {
+            if (bShowingProgressDlg)
+                HideProgressDialog();
+            ShowError(IDS_SERVICE_QUERY_FAILED, GetLastError());
+            CloseServiceHandle(hServer);
+            CloseServiceHandle(hSCM);
+            return -1;
+        }
+    }
+
+    // The service has been stopped
+    if (bShowingProgressDlg)
+        HideProgressDialog();
+
+    // This code to disable the service may be of use some day so I am keeping it here.
+    // bOk = ChangeServiceConfig(hServer, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, 0, 0, 0, 0, 0, 0, 0); 
+
+    bOk = DeleteService(hServer);
+
+    if (!bOk)
+        ShowError(IDS_SERVICE_DELETE_FAILED, GetLastError());
+
+    CloseServiceHandle(hServer);
+    CloseServiceHandle(hSCM);
+
+    return (bOk ? 0 : -1);
+}
+
+int SUCALLCONV AddToNetworkProviderOrder(char *pszWhatToAdd)
+{
+    return AddToProviderOrder(pszWhatToAdd) ? 0 : -1;
+}
+
+static int RemoveFromNetworkProviderOrder(char *pszWhatToDel)
+{
+    return RemoveFromProviderOrder(pszWhatToDel) ? 0 : -1;
+}
+
+int SUCALLCONV AddToPath(char *pszPath)
+{
+    return AddToSystemPath(pszPath) ? 0 : -1;
+}
+
+static int RemoveFromPath(char *pszPath)
+{
+    return RemoveFromSystemPath(pszPath) ? 0 : -1;
+}
+
+static void RemoveFiles(char *pszFileSpec)
+{
+    struct _finddata_t fileinfo;
+    long hSearch;
+    char szDel[MAX_PATH];
+    char szDir[MAX_PATH];
+    char *p;
+
+    strcpy(szDir, pszFileSpec);
+    p = strrchr(szDir, '\\');
+    if (p)
+        *p = 0;
+    
+    hSearch = _findfirst(pszFileSpec, &fileinfo);
+    if (hSearch == -1)
+        return;
+
+    while (1) {
+        if ((strcmp(fileinfo.name, ".") != 0) && (strcmp(fileinfo.name, "..") != 0)) {
+            sprintf(szDel, "%s\\%s", szDir, fileinfo.name);
+            DeleteFile(szDel);
+        }
+
+        if (_findnext(hSearch, &fileinfo) == -1)
+            break;
+    }
+
+    _findclose(hSearch);
+}
+
+static void RemoveDir(char *pszDir)
+{
+    char szFileSpec[MAX_PATH];
+
+    sprintf(szFileSpec, "%s\\*.*", pszDir);
+
+    RemoveFiles(szFileSpec);
+    RemoveDirectory(pszDir);
+}
+
+static void RemoveRegValues(struct REGVALUE *pRegValues)
+{
+    struct REGVALUE *pCurValue;
+    HKEY hKey;
+    LONG nResult;
+
+    if (!pRegValues)
+        return;
+
+    for (pCurValue = pRegValues; pCurValue->pszKey; pCurValue++) {
+        nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pCurValue->pszKey, KEY_ALL_ACCESS, FALSE, &hKey, 0);
+
+        if (nResult == ERROR_SUCCESS) {
+            nResult = RegDeleteValue(hKey, pCurValue->pszValue);
+            RegCloseKey(hKey);
+        }
+
+        if (nResult != ERROR_SUCCESS)
+            ShowError(IDS_REG_DELETE_VALUE_ERROR, nResult);
+    }
+}
+
+static BOOL UninstallCredsTool()
+{
+    int nResult = WinExec("afscreds /uninstall", SW_HIDE);
+
+    if (nResult <= 31) {
+        if (nResult != ERROR_FILE_NOT_FOUND)
+            ShowError(IDS_CANT_UNINSTALL_AFSCREDS, nResult);
+    }
+
+    // Always return true.  We don't want the uninstall to completely fail just
+    // because the creds tool didn't uninstall.
+    return TRUE;
+}
+
+
+static char *GetTempDir()
+{
+    DWORD result;
+    static char szTempDir[MAX_PATH];
+
+    result = GetTempPath(sizeof(szTempDir) - 1, szTempDir);
+    if (result == 0)
+        return "\\";
+        
+    return szTempDir;
+}
+
+static char *GetRootInstallDir()
+{
+    char *psz;
+    static char szRootInstallDir[MAX_PATH] = "";
+
+    if (szRootInstallDir[0] == 0) {
+        strcpy(szRootInstallDir, pszInstallDir);
+    
+        // Strip off the app specific part of the install dir
+        psz = strrchr(szRootInstallDir, '\\');
+        if (psz)
+            *psz = 0;
+    }
+
+    return szRootInstallDir;
+}
+
+static BOOL ClientSpecificUninstall()
+{
+    int nChoice;
+
+    // This function needs to do two things.  First it needs to see if the server is
+    // installed, and if it is, ask the user if they really want to uninstall the
+    // client given that the server needs the client.  Second, if we are uninstalling
+    // the client, we need to uninstall the creds tool.
+
+    if (!bSilentMode) {
+        if (IsAppInstalled(&appServer)) {
+            nChoice = ShowMsg(IDS_CLIENT_NEEDED_BY_SERVER, MB_ICONQUESTION | MB_YESNO);
+            if (nChoice == IDNO)
+                return FALSE;       // Cancel the uninstall
+        }
+    }
+    
+    UninstallCredsTool();
+
+    return TRUE;
+}
+
+static struct APPINFO *GetApp()
+{
+#ifdef SERVER_UNINST
+    return &appServer;
+#elif CLIENT_UNINST
+    return &appClient;
+#elif CC_UNINST
+    return &appControlCenter;
+#elif LIGHT_CLIENT_UNINST
+    return &appLightClient;
+#elif DOCS_UNINST
+    return &appDocs;
+#else
+    return 0;
+#endif;
+}
+
+static void RememberInstallDir(char *pszInstallDir)
+{
+    HKEY hKey;
+
+    // We remember the install dir so that when the UninstUninitialize function is called
+    // by the InstallShield uninstaller, we can find out where we were installed to.  We
+    // have to do this because by the time that function is called, the registry values
+    // created at install time are already gone.  We need to be able to find out where we
+    // were installed so we can clean up anything IS couldn't uninstall.  If this fails in 
+    // any way then we don't care.  The only consequence is that some junk might be left on
+    // the users' system after an uninstall.
+    
+    LONG result = RegOpenKeyAlt(AFSREG_NULL_KEY, UNINSTALL_TEMP_INFO_KEY, KEY_WRITE, TRUE, &hKey, 0);
+    if (result != ERROR_SUCCESS)
+        return;
+
+    RegSetValueEx(hKey, INSTALL_DIR_VALUE_NAME, 0, REG_SZ, (PBYTE)pszInstallDir, strlen(pszInstallDir) + 1);    
+
+    RegCloseKey(hKey);
+}
+
+int SUCALLCONV SetSilentMode()
+{
+    bSilentMode = TRUE;
+
+    return 0;
+}
+
+static char *GetWinDir()
+{
+    static char szWinDir[MAX_PATH] = "";
+
+    if (!szWinDir[0]) 
+        GetWindowsDirectory(szWinDir, sizeof(szWinDir));
+    
+    return szWinDir;
+}
+
+static char *GetWinSysDir()
+{
+    static char szWinSysDir[MAX_PATH] = "";
+
+    if (!szWinSysDir[0])
+        GetSystemDirectory(szWinSysDir, sizeof(szWinSysDir));
+    
+    return szWinSysDir;
+} 
+
+static char *GetLocaleID()
+{
+    static char szID[25] = "";
+
+    if (szID[0] == 0) {
+        LCID dwID = GetSystemDefaultLCID();
+        
+         // Nuke the high word.  It contains a sort ID.
+        dwID &= 0x0000FFFF;
+        
+        // Convert locale ID to a string
+        itoa(dwID, szID, 10);
+
+        // This thing should never be more than LOCALE_ID_LEN characters long.
+        szID[LOCALE_ID_LEN] = 0;
+    }
+
+    return szID;
+}
+
+static char *ExpandPath(char *pszFile)
+{
+    static char szPath[MAX_PATH];
+    char *psz;
+
+    szPath[0] = 0;
+
+    // Convert a path containing TARGETDIR, WINDIR, or WINSYSDIR to a 
+    // real path in the file system.  One of these MUST be the start of
+    // the file path passed in.  Also convert the string ???? to an
+    // actual locale number.
+    if (strncmp(pszFile, TARGETDIR, strlen(TARGETDIR)) == 0)
+        strcpy(szPath, GetRootInstallDir());
+    else if (strncmp(pszFile, WINDIR, strlen(WINDIR)) == 0)
+        strcpy(szPath, GetWinDir());
+    else if (strncmp(pszFile, WINSYSDIR, strlen(WINSYSDIR)) == 0)
+        strcpy(szPath, GetWinSysDir());
+    
+    if (szPath[0]) {    
+        psz = strchr(pszFile, '\\');
+        if (psz)
+            strcat(szPath, psz);
+    } else
+        strcpy(szPath, pszFile);
+
+    // Is this a language dll?
+    psz = strstr(szPath, "????.");
+    
+    // If it is, replace ???? with the locale number
+    if (psz)
+        strncpy(psz, GetLocaleID(), LOCALE_ID_LEN);
+
+    return szPath;
+}
+
+static BOOL FileNeededByOtherApp(struct APPINFO *pApp, struct FILEINFO *pFileInfo)
+{
+    // If the file is used by the server, the app being uninstalled is not the server, and
+    // the server is installed, then this file is used by another app.
+    if (!IsWinNT()) {
+        if ((pFileInfo->nUsedBy & LCLIENT) && (pApp != &appLightClient) && IsAppInstalled(&appLightClient))
+            return TRUE;
+        return FALSE;
+    }
+
+    if ((pFileInfo->nUsedBy & SERVER) && (pApp != &appServer) && IsAppInstalled(&appServer))
+        return TRUE;
+
+    if ((pFileInfo->nUsedBy & CLIENT) && (pApp != &appClient) && IsAppInstalled(&appClient))
+        return TRUE;
+
+    if ((pFileInfo->nUsedBy & CC) && (pApp != &appControlCenter) && IsAppInstalled(&appControlCenter))
+        return TRUE;
+    
+    return FALSE;
+}
+
+static void DeleteInUseFiles(struct APPINFO *pAppInfo, struct FILEINFO *pFileInfo)
+{
+    char szSrcPath[MAX_PATH];
+    char szDestPath[MAX_PATH];
+    char szTempDir[MAX_PATH];
+    int ii;
+
+    // If some app's file has been loaded before the app is uninstalled, then
+    // when an uninstall is attempted, the application and all of the dlls that
+    // its uses will be in use and IS will not be able to delete them.  Normally this
+    // is not a problem because IS will tell the user to reboot to finish the uninstall.
+    // However, we must support the ability to perform a silent uninstall followed
+    // immediatly by an install of the same product to the same directories.  If we let
+    // IS handle the uninstall of these files, this is not possible.  The reason is that
+    // when IS fails to remove these in use files, it marks them for deletion after the
+    // next reboot, which is fine.  Unfortunately, it leaves them in the dirs they were
+    // installed to.  So if we don't immediately reboot and perform an install to the
+    // same dirs, once a reboot is performed, those files get deleted and we have a 
+    // broken installation.
+
+    // What we will do to fix all of this, is when the client is uninstalled, but
+    // before IS does anything, we will move the in use files and associated dlls
+    // into the temp dir and mark them for delete after a reboot.  Then an install
+    // that follows will succeed.
+
+    // Delete the files that may be in use.  If they are we actually move
+    // them to the temp dir and mark them for deletion after the next reboot.
+    for (ii = 0; pFileInfo[ii].pszName != 0; ii++) {
+        // Get the source path
+        strcpy(szSrcPath, ExpandPath(pFileInfo[ii].pszName));
+
+        // Only delete the file if it is not used by some other app
+        if (FileNeededByOtherApp(pAppInfo, &pFileInfo[ii]))
+            continue;
+
+        // If the file doesn't exist then go on to the next file.
+        if (_access(szSrcPath, 0) != 0)
+            continue;
+            
+        // See if we can do a regular delete of the file
+        if (DeleteFile(szSrcPath)) {
+            SetSharedFileRefCount(szSrcPath, 0);
+            continue;
+        }
+
+        // Get a temp dir that is on the same drive as the src path.
+        // We can't move an in use file to a different drive.
+        strcpy(szTempDir, GetTempDir());
+        if (szTempDir[0] != szSrcPath[0]) {
+            // Get the drive, colon, and slash of the src path
+            strncpy(szTempDir, szSrcPath, 3);
+            szTempDir[3] = 0;
+        }
+        
+        // Get the dest path - we will rename the file during the move
+        GetTempFileName(szTempDir, "AFS", 0, szDestPath);
+
+        // Move from source to dest, marking the file for deletion after a reboot
+        if (IsWin95()) {
+            if (MoveFile(szSrcPath, szDestPath)) {            
+                WritePrivateProfileString("rename", szSrcPath, szDestPath, "wininit.ini");
+                SetSharedFileRefCount(szSrcPath, 0);
+            }
+        } else {    // WinNT or Win98
+            if (MoveFileEx(szSrcPath, szDestPath, MOVEFILE_REPLACE_EXISTING)) {
+                SetFileAttributes(szDestPath, FILE_ATTRIBUTE_NORMAL);
+                MoveFileEx(szDestPath, 0, MOVEFILE_DELAY_UNTIL_REBOOT);
+                SetSharedFileRefCount(szSrcPath, 0);
+            }
+        }
+    }
+}
+
+// Delete a directory and all its files and subdirectories - Yee haaa!
+static void RemoveDirectoryTree(char *pszDir)
+{
+    HANDLE hFind;
+    WIN32_FIND_DATA findFileData;
+    char szSpec[MAX_PATH];
+    char szSubFileOrDir[MAX_PATH];
+    BOOL bContinue;
+
+    sprintf(szSpec, "%s\\*.*", pszDir);
+    
+    // First delete the contents of the dir
+    hFind = FindFirstFile(szSpec, &findFileData);
+    bContinue = (hFind != INVALID_HANDLE_VALUE);
+    
+    while (bContinue) {
+        if ((strcmp(findFileData.cFileName, ".") != 0) && (strcmp(findFileData.cFileName, "..") != 0)) {
+            sprintf(szSubFileOrDir, "%s\\%s", pszDir, findFileData.cFileName);
+            
+            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                RemoveDirectoryTree(szSubFileOrDir);
+            else
+                DeleteFile(szSubFileOrDir);
+        }
+
+        bContinue = FindNextFile(hFind, &findFileData);
+    }
+
+    FindClose(hFind);
+        
+    // Now remove the dir
+    RemoveDirectory(pszDir);
+} 
+
+static char *GetStartMenuRoot()
+{
+    HKEY hKey;
+    LONG nResult;
+    DWORD dwType;
+    DWORD dwSize;
+    char *pszKey;
+    char *pszValue;
+
+    static char szStartMenuRoot[MAX_PATH] = "";
+
+    if (szStartMenuRoot[0] == 0) {
+        dwSize = sizeof(szStartMenuRoot);
+    
+        if (IsWinNT()) {
+            pszKey = WINNT_START_MENU_REG_KEY;
+            pszValue = WINNT_START_MENU_REG_VALUE;
+        } else {
+            pszKey = WIN9X_START_MENU_REG_KEY;
+            pszValue = WIN9X_START_MENU_REG_VALUE;
+        }
+        
+        nResult = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);
+        if (nResult == ERROR_SUCCESS) {
+            nResult = RegQueryValueEx(hKey, pszValue, 0, &dwType, (PBYTE)szStartMenuRoot, &dwSize);
+            RegCloseKey(hKey);
+        }
+
+        if (nResult != ERROR_SUCCESS)
+            return 0;
+    }
+
+    FilepathNormalizeEx(szStartMenuRoot, FPN_BACK_SLASHES);
+
+    return szStartMenuRoot;
+}
+
+static char *GetAfsStartMenuRoot()
+{
+    static char szAfsStartMenuRoot[MAX_PATH] = "";
+    char *pszStartMenuRoot;
+    
+    if (szAfsStartMenuRoot[0] == 0) {    
+        pszStartMenuRoot = GetStartMenuRoot();
+        if (!pszStartMenuRoot)
+            return 0;
+
+        if (bSilentMode)
+            sprintf(szAfsStartMenuRoot, "%s\\IBM WebSphere\\Performance Pack\\AFS", pszStartMenuRoot );
+        else
+            sprintf(szAfsStartMenuRoot, "%s\\IBM AFS", pszStartMenuRoot );
+    }
+
+    return szAfsStartMenuRoot;
+}
+
+static BOOL IsADir(char *pszName)
+{
+    struct _stat statbuf;
+
+    if (_stat(pszName, &statbuf) < 0)
+        return FALSE;
+
+    return statbuf.st_mode & _S_IFDIR;
+}
+
+static void DeleteStartMenuEntries(char *pszEntries)
+{
+    char szStartMenuPath[MAX_PATH];
+    char *pszAfsStartMenuRoot;
+    char *pszCurEntry;
+
+    pszAfsStartMenuRoot = GetAfsStartMenuRoot();
+
+    if (!pszAfsStartMenuRoot)
+        return;
+        
+    for (pszCurEntry = pszEntries; *pszCurEntry; pszCurEntry += strlen(pszCurEntry) + 1) {
+        sprintf(szStartMenuPath, "%s\\%s", pszAfsStartMenuRoot, pszCurEntry);
+        if (IsADir(szStartMenuPath))
+            RemoveDirectoryTree(szStartMenuPath);
+        else
+            DeleteFile(szStartMenuPath);
+    }
+}
+
+static void RefreshStartMenu()
+{
+    char *pszAfsStartMenuRoot;
+    char szTemp[MAX_PATH];
+    
+    pszAfsStartMenuRoot = GetAfsStartMenuRoot();
+    if (!pszAfsStartMenuRoot)
+        return;
+
+    sprintf(szTemp, "%s - Refresh Attempt", pszAfsStartMenuRoot);
+        
+    // Deleting items from below the root level of the start menu does not 
+    // cause it to refresh.  In order that users can see changes without
+    // rebooting we will temporarily rename our root most entry, which 
+    // does cause a refresh of the start menu.
+    MoveFileEx(pszAfsStartMenuRoot, szTemp, MOVEFILE_REPLACE_EXISTING);
+    MoveFileEx(szTemp, pszAfsStartMenuRoot, MOVEFILE_REPLACE_EXISTING);
+}
+
+static BOOL PreserveConfigInfo(struct APPINFO *pApp)
+{
+    char *pszRegKey;
+    char szDestKey[256];
+    LONG result;
+
+    bPreserveConfigInfo = TRUE;
+
+    // If not in silent mode, ask user if they want to preserve the cfg info
+    if (!bSilentMode) {
+        int nChoice = ShowMsg(pApp->nPreserveConfigInfoMsgID, MB_ICONQUESTION | MB_YESNOCANCEL);
+        if (nChoice == IDCANCEL)
+            return FALSE;                   // Cancel the uninstall
+        else if (nChoice == IDNO) {     
+            bPreserveConfigInfo = FALSE;    // User doesn't want to preserve the config info
+            return TRUE;
+        }
+    }
+
+    // Copy each reg key (and all of its subkeys and values) to another place in the registry.
+    for (pszRegKey = pApp->pszRegKeysToPreserve; *pszRegKey; pszRegKey += strlen(pszRegKey) + 1) {
+        if (!DoesRegKeyExist(pszRegKey))
+            continue;
+
+        // Create the destination path for the copy
+        sprintf(szDestKey, "%s\\%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName, pszRegKey);
+
+        // Try to copy it
+        result = RegDupKeyAlt(pszRegKey, szDestKey);
+
+        if ((result != ERROR_SUCCESS) && (result != ERROR_FILE_NOT_FOUND)) {
+            // If the copy failed, then delete any copies that succeeded
+            sprintf(szDestKey, "%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);
+            RegDeleteEntryAlt(szDestKey, REGENTRY_KEY);
+               goto done;
+        }
+    }
+
+       // Remember the integrated login setting if this app supports that and it was turned on
+       if (pApp->pszNetworkProviderOrder) {
+               // Was integerated login turned on?
+               BOOL bOn, bOk;
+               bOk = InNetworkProviderOrder(pApp->pszNetworkProviderOrder, &bOn);
+               if (bOk && bOn) {
+                       HKEY hKey;
+                       sprintf(szDestKey, "%s\\%s\\IntegratedLogin", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);
+                       result = RegOpenKeyAlt(AFSREG_NULL_KEY, szDestKey, KEY_WRITE, TRUE, &hKey, 0);
+                       // The existance of the key is a flag indicating that integrated login was turned on
+                       RegCloseKey(hKey);
+               }
+       }
+       
+done:
+       if ((result == ERROR_SUCCESS) || bSilentMode)
+           return TRUE;    // Continue with uninstall
+
+    // Report the error and ask the user if they want to continue the uninstall
+    return (ShowMsg(IDS_SAVE_OF_CONFIG_INFO_FAILED, MB_ICONEXCLAMATION | MB_YESNO) == IDYES);                  
+}
+
+int SUCALLCONV RestoreConfigInfo(int nApp)
+{
+    char *pszRegKey;
+    char szSrcKey[256];
+    struct APPINFO *pApp = 0;
+    BOOL bError = FALSE;
+    LONG result;
+
+    switch (nApp) {
+        case SERVER:    pApp = &appServer;          break;
+        case CLIENT:    pApp = &appClient;          break;
+        case LCLIENT:   pApp = &appLightClient;     break;
+        case CC:        pApp = &appControlCenter;   break;
+    }
+    
+    if (!pApp)
+        return -1;
+        
+    // Copy each reg key (and all of its subkeys and values) back to its original place in the registry.
+    for (pszRegKey = pApp->pszRegKeysToPreserve; *pszRegKey; pszRegKey += strlen(pszRegKey) + 1) {
+        // Create the source path for the copy
+        sprintf(szSrcKey, "%s\\%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName, pszRegKey);
+
+        if (!DoesRegKeyExist(szSrcKey))
+            continue;
+
+        // Try to restore as many of the keys as possible.  Report any errors at the end.
+
+        // Try to copy it
+        result = RegDupKeyAlt(szSrcKey, pszRegKey);
+        if ((result != ERROR_SUCCESS) && (result != ERROR_FILE_NOT_FOUND))
+            bError = TRUE;
+    }
+
+       // Restore integrated login if this app was using it
+       if (pApp->pszNetworkProviderOrder) {
+               // Check if integrated login was turned on.  The IntegratedLogin key is a flag
+               // telling us that it was on.  If the key does not exist, integrated login was
+               // not on.
+               sprintf(szSrcKey, "%s\\%s\\IntegratedLogin", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);
+               if (DoesRegKeyExist(szSrcKey)) {
+                       if (!AddToProviderOrder(pApp->pszNetworkProviderOrder))
+                               bError = TRUE;
+               }
+       }
+
+    // Remove our saved copies of the config info
+    sprintf(szSrcKey, "%s\\%s", AFS_PRESERVED_CFG_INFO_KEY, pApp->pszAppName);
+    RegDeleteEntryAlt(szSrcKey, REGENTRY_KEY);
+            
+    if (bError)
+        ShowError(IDS_RESTORE_OF_PREVIOUS_CONFIG_FAILED, 0);
+
+    return TRUE;
+}
+
+static BOOL DoSubKeysExist(char *pszKey)
+{
+    LONG result;
+    HKEY hKey;
+    char *pszSubKeys = 0;
+    BOOL bExist;
+    
+    result = RegOpenKeyAlt(AFSREG_NULL_KEY, pszKey, KEY_READ, FALSE, &hKey, 0);
+    if (result != ERROR_SUCCESS)
+        return FALSE;
+        
+    result = RegEnumKeyAlt(hKey,  &pszSubKeys);
+    RegCloseKey(hKey);
+    
+    if (result != ERROR_SUCCESS)
+        return FALSE;
+   
+    if (pszSubKeys) {
+        bExist = TRUE;
+        free(pszSubKeys);
+    } else
+        bExist = FALSE;    
+
+    return bExist;
+}
+
+/*
+ * The following definitions are taken from richedit.h:
+ *
+ */
+
+#define EM_SETBKGNDCOLOR               (WM_USER + 67) // from Richedit.h
+#define EM_STREAMIN                            (WM_USER + 73) // from Richedit.h
+#define SF_RTF                         0x0002
+
+typedef DWORD (CALLBACK *EDITSTREAMCALLBACK)(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
+
+typedef struct _editstream {
+       DWORD dwCookie;         /* user value passed to callback as first parameter */
+       DWORD dwError;          /* last error */
+       EDITSTREAMCALLBACK pfnCallback;
+} EDITSTREAM;
+
+/*
+ *
+ */
+
+DWORD CALLBACK License_StreamText (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+   LPTSTR psz = (LPTSTR)dwCookie;
+   LONG cchAvail = lstrlen(psz);
+   if ((*pcb = min(cchAvail, cb)) != 0) {
+      memcpy (pbBuff, psz, *pcb);
+      memmove (psz, &psz[*pcb], cchAvail - *pcb + 1);
+   }
+   return 0;
+}
+
+
+void License_OnInitDialog (HWND hDlg, LPTSTR pszFile)
+{
+    // Open the license file and shove its text in our RichEdit control
+    //
+    HANDLE hFile;
+    if ((hFile = CreateFile (pszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) {
+
+        size_t cbText;
+        if ((cbText = GetFileSize (hFile, NULL)) != 0) {
+
+            LPTSTR abText = (LPTSTR)GlobalAlloc (GMEM_FIXED, cbText + 3);
+
+            DWORD cbRead;
+            if (ReadFile (hFile, abText, cbText, &cbRead, NULL)) {
+                abText[ cbRead ] = 0;
+
+                EDITSTREAM Stream;
+                memset (&Stream, 0x00, sizeof(Stream));
+                Stream.dwCookie = (DWORD)abText;
+                Stream.pfnCallback = License_StreamText;
+
+                SendDlgItemMessage (hDlg, IDC_TEXT, EM_STREAMIN, SF_RTF, (LPARAM)&Stream);
+            }
+
+            GlobalFree (abText);
+        }
+
+        CloseHandle (hFile);
+    }
+
+    // Make the control's background be gray
+    //
+    SendDlgItemMessage (hDlg, IDC_TEXT, EM_SETBKGNDCOLOR, FALSE, (LPARAM)GetSysColor(COLOR_BTNFACE));
+}
+
+BOOL CALLBACK License_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
+{
+    switch (msg) {
+        case WM_INITDIALOG:
+            SetWindowLong (hDlg, DWL_USER, lp);
+            License_OnInitDialog (hDlg, (LPTSTR)lp);
+            break;
+
+        case WM_COMMAND:
+            switch (LOWORD(wp)) {
+                case IDCANCEL:
+                case IDOK:
+                    EndDialog (hDlg, LOWORD(wp));
+                    break;
+
+                case IDC_PRINT:
+                    TCHAR szDir[ MAX_PATH ];
+                    GetCurrentDirectory (MAX_PATH, szDir);
+                    ShellExecute (hDlg, TEXT("print"), (LPTSTR)GetWindowLong (hDlg, DWL_USER), NULL, szDir, SW_HIDE);
+                    break;
+            }
+            break;
+    }
+    return FALSE;
+}
+
+BOOL FindAfsInstallationPathByComponent (LPTSTR pszInstallationPath, LPTSTR pszComponent)
+{
+    *pszInstallationPath = 0;
+
+    TCHAR szRegPath[ MAX_PATH ];
+    wsprintf (szRegPath, TEXT("Software\\TransarcCorporation\\%s\\CurrentVersion"), pszComponent);
+
+    HKEY hk;
+    if (RegOpenKey (HKEY_LOCAL_MACHINE, szRegPath, &hk) == 0) {
+        DWORD dwType = REG_SZ;
+        DWORD dwSize = MAX_PATH;
+
+        if (RegQueryValueEx (hk, TEXT("PathName"), NULL, &dwType, (PBYTE)pszInstallationPath, &dwSize) == 0) {
+            *(LPTSTR)FindBaseFileName (pszInstallationPath) = TEXT('\0');
+
+            if (pszInstallationPath[0] && (pszInstallationPath[ lstrlen(pszInstallationPath)-1 ] == TEXT('\\')))
+            pszInstallationPath[ lstrlen(pszInstallationPath)-1 ] = TEXT('\0');
+        }
+
+        RegCloseKey (hk);
+    }
+
+    return !!*pszInstallationPath;
+}
+
+BOOL FindAfsInstallationPath (LPTSTR pszInstallationPath)
+{
+   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Client")))
+      return TRUE;
+   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Control Center")))
+      return TRUE;
+   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Server")))
+      return TRUE;
+   if (FindAfsInstallationPathByComponent (pszInstallationPath, TEXT("AFS Supplemental Documentation")))
+      return TRUE;
+   return FALSE;
+}
+
+HINSTANCE LoadRichTextControl (void)
+{
+    HINSTANCE hInst;
+    if ((hInst = LoadLibrary ("riched20.dll")) != NULL)
+        return hInst;
+    if ((hInst = LoadLibrary ("riched32.dll")) != NULL)
+        return hInst;
+    if ((hInst = LoadLibrary ("riched.dll")) != NULL)
+        return hInst;
+    if ((hInst = LoadLibrary ("richedit.dll")) != NULL)
+        return hInst;
+    return NULL;
+}
+
+int SUCALLCONV ShowLicense (char *pszTarget, char *pszSource)
+{
+    // If the license already lives on this user's machine, don't show
+    // it again. This only has to be done if the user has never
+    // accepted the license agreement before (it's part of the setup
+    // program, so it gets installed if they've accepted it).
+    //
+    // We were handed a relative path of the form:
+    //    Documentation/html/license.rtf
+    //
+    // We'll need to find the AFS installation directory, in order to
+    // find that Documentation subtree.
+    //
+    BOOL fShowLicense = TRUE;
+
+    TCHAR szInstallationPath[ MAX_PATH ];
+    if (FindAfsInstallationPath (szInstallationPath)) {
+        TCHAR szLicensePath[ MAX_PATH ];
+        wsprintf (szLicensePath, TEXT("%s\\%s"), szInstallationPath, pszTarget);
+
+        if (GetFileAttributes (szLicensePath) != (DWORD)-1) {
+            fShowLicense = FALSE;
+        }
+    }
+
+    // Before we can show the license file, we have to prepare the RichEdit
+    // control. That means loading the appropriate library and calling its
+    // initialization functions.
+    //
+    HINSTANCE hRichEdit;
+    if ((hRichEdit = LoadRichTextControl()) != NULL) {
+
+        // If we must show the license, do so now. This is a modal dialog,
+        // so we'll know whether or not the user accepts the license.
+        //
+        if (ModalDialogParam (IDD_LICENSE, GetActiveWindow(), License_DlgProc, (LPARAM)pszSource) == IDCANCEL) {
+            // The user rejected the license; fail setup
+            return FALSE;
+        }
+
+       FreeLibrary (hRichEdit);
+    }
+
+    // The user accepted the license, so we can continue with Setup.
+    // The license file is installed as part of Setup.
+    return TRUE;
+}
+
+int SUCALLCONV UninstInitialize(HWND hIS, HINSTANCE hIS5, long Reserved)
+{
+    char szPath[MAX_PATH];
+    struct APPINFO *pAppInfo;
+    char *pszFile = 0;
+    char *pszSubDir = 0;
+
+    hDlg = hIS;
+
+    bSilentMode = !IsWindowVisible(hIS);
+
+    // Which app are we uninstalling?
+    pAppInfo = GetApp();
+    if (!pAppInfo) {
+        ShowError(IDS_CANT_DETERMINE_PRODUCT, 0);
+        return -1;
+    }
+
+    // Get the app's install dir
+    pszInstallDir = GetAppInstallDir(pAppInfo, FALSE);
+    if (!pszInstallDir)
+        return -1;
+
+    // If this app has a custom uninstall func, call it here
+    if (pAppInfo->pUninstallFunc)
+        if (!pAppInfo->pUninstallFunc())
+            return -1;
+
+    if (pAppInfo->pszRegKeysToPreserve)
+        if (!PreserveConfigInfo(pAppInfo))
+            return -1;
+
+    // Unconfigure the service, if there is one for this app
+    if (pAppInfo->pszSvcKey) {
+        if (IsServiceInstalled(pAppInfo->pszSvcKey))
+            if (UninstallService(pAppInfo) == 1)
+                return -1;
+    }
+
+    RememberInstallDir(pszInstallDir);
+
+    DeleteInUseFiles(pAppInfo, fileInfo);
+
+    // Remove the app's bin path from the system path
+    if (pAppInfo->pszBinPath) {
+        BuildShortPath(szPath, sizeof(szPath), pszInstallDir, pAppInfo->pszBinPath);
+        RemoveFromPath(szPath);
+    }
+
+    // Remove entry from NetworkProvider\Order key in registry
+    if (pAppInfo->pszNetworkProviderOrder)
+        RemoveFromNetworkProviderOrder(pAppInfo->pszNetworkProviderOrder);
+
+    // Remove any generated subdirectories
+    if (!bPreserveConfigInfo && pAppInfo->pszDirsToDel) {
+        for (pszSubDir = pAppInfo->pszDirsToDel; *pszSubDir; pszSubDir += strlen(pszSubDir) + 1)
+            RemoveDir(ExpandPath(pszSubDir));
+    }
+
+    // Remove any generated files
+    if (!bPreserveConfigInfo && pAppInfo->pszFilesToDel) {
+        for (pszFile = pAppInfo->pszFilesToDel; *pszFile; pszFile += strlen(pszFile) + 1)
+            RemoveFiles(ExpandPath(pszFile));
+    }
+
+    // Remove any registry values that IS can't handle
+    RemoveRegValues(pAppInfo->pRegValues);
+    if (IsWinNT())
+        RemoveRegValues(pAppInfo->pWinNTRegValues);
+    else    
+        RemoveRegValues(pAppInfo->pWin9XRegValues);
+
+    // Remove the start menu entries for this app
+    if (pAppInfo->pszStartMenuEntries) {
+        DeleteStartMenuEntries(pAppInfo->pszStartMenuEntries);
+        RefreshStartMenu();
+    }
+
+    // Remove the install dir
+    RemoveDirectory(pszInstallDir);
+
+    return 0;
+}
+
+void SUCALLCONV UninstUnInitialize(HWND hIS, HINSTANCE hIS5, long Reserved)
+{
+    char *pszInstallDir;
+    char szDirPath[MAX_PATH];
+    char *psz;
+    struct APPINFO *pAppInfo;
+
+    // If we just uninstalled the last AFS app, then do some cleanup.
+    if (IsAppInstalled(&appServer) || IsAppInstalled(&appClient) ||
+        IsAppInstalled(&appControlCenter) || IsAppInstalled(&appLightClient) ||
+        IsAppInstalled(&appDocs))
+    {
+        return;
+    }
+
+    bSilentMode = !IsWindowVisible(hIS);
+    
+    // Which app did we just uninstall?
+    pAppInfo = GetApp();
+    if (!pAppInfo) {
+        ShowError(IDS_CANT_DETERMINE_PRODUCT, 0);
+        return;
+    }
+
+    // Get the app's install dir
+    pszInstallDir = GetAppInstallDir(pAppInfo, TRUE);
+    if (!pszInstallDir)
+        return;
+
+    // Remove the reg key we used to remember the app install dir
+    RegDeleteEntryAlt(UNINSTALL_TEMP_INFO_KEY, REGENTRY_KEY);
+
+    // Try to remove the reg key used to store config info, but only
+    // if there are no app config info sub keys present.
+    if (!DoSubKeysExist(AFS_PRESERVED_CFG_INFO_KEY))
+        RegDeleteEntryAlt(AFS_PRESERVED_CFG_INFO_KEY, REGENTRY_KEY);
+
+    // Remove the install dir
+    RemoveDirectory(pszInstallDir);
+
+    // Attempt to remove the install root and common directories.  The are 
+    // shared and so no single app knows to delete them.
+
+    // Strip off the app specific part of the install dir
+    psz = strrchr(pszInstallDir, '\\');
+    if (psz)
+        *psz = 0;
+
+    sprintf(szDirPath, "%s\\%s", pszInstallDir, "Common");
+    RemoveDirectory(szDirPath);
+
+    // Remove the Common directory from the system path
+    RemoveFromPath(szDirPath);
+
+    // Remove all of the documentation dirs
+    sprintf(szDirPath, "%s\\%s", pszInstallDir, "Documentation");
+    RemoveDirectoryTree(szDirPath);
+
+    // Ok, up to this point we have been removing files we know we
+    // created.  However, after this point we are into the path
+    // that the user chose for our install root.  The default for
+    // this is IBM/Afs, but they could have chosen anything,
+    // including a dir or dirs that have other products in them.
+    // We will check to see if it is IBM\AFS and if it is then we 
+    // will attempt to remove them.
+    
+    // Back up a level and look for AFS
+    psz = strrchr(pszInstallDir, '\\');
+    if (psz) {
+        if (stricmp(psz + 1, "AFS") == 0) {
+            RemoveDirectory(pszInstallDir);
+            *psz = 0;
+        }
+    }
+
+    // Back up a level and look for IBM
+    psz = strrchr(pszInstallDir, '\\');
+    if (psz) {
+        if (stricmp(psz + 1, "IBM") == 0) {
+            RemoveDirectory(pszInstallDir);
+            *psz = 0;
+        }
+    }
+
+    // Remove the root afs start menu entry
+    psz = GetStartMenuRoot();
+    if (psz) {
+        if (bSilentMode) {
+            // Remove everything under our branch
+            sprintf(szDirPath, "%s\\IBM WebSphere\\Performance Pack\\AFS", psz);
+            RemoveDirectoryTree(szDirPath);
+            
+            // Remove the IBM stuff only if the dirs are empty
+            sprintf(szDirPath, "%s\\IBM WebSphere\\Performance Pack", psz);
+            if (RemoveDirectory(szDirPath)) {
+                sprintf(szDirPath, "%s\\IBM WebSphere", psz);
+                RemoveDirectory(szDirPath);
+            }
+        } else {
+            sprintf(szDirPath, "%s\\IBM AFS", psz);
+            RemoveDirectoryTree(szDirPath);
+        }
+    }
+}
+
+BOOLEAN _stdcall DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved)
+{
+    if (reason == DLL_PROCESS_ATTACH) {
+        hinst = (HINSTANCE)dll;
+        TaLocale_LoadCorrespondingModuleByName (hinst, "afs_setup_utils.dll");
+    }
+
+    return TRUE;
+}
+
+extern "C" int WINAPI Test (HINSTANCE hInst, HINSTANCE hPrev, LPSTR psz, int nCmdShow)
+{
+   ShowLicense ("TEST", "\\\\fury\\afssetup\\license\\ja_JP.rtf");
+   return 0;
+}
+
+
index 8df9385..310191c 100644 (file)
@@ -271,6 +271,11 @@ Entry102=SERVER_GROUP_NAME
 Entry103=CLIENT_GROUP_NAME
 Entry104=CCENTER_GROUP_NAME
 Entry105=LIGHT_GROUP_NAME
+Entry106=CELLNAME_DEFAULT
+Entry107=WELCOME_MESSAGE
+Entry108=CELLSERVDB_WEB
+Entry109=CELLSERVDB_INSTALL
+Entry110=CELLSERVDB_CONFIGNAME
 
 [CONFIGURING_AFS_CREDS]
 Comment=
@@ -432,3 +437,18 @@ Comment=
 [LIGHT_GROUP_NAME]
 Comment=
 
+[CELLNAME_DEFAULT]
+Comment=Default Cell name
+
+[WELCOME_MESSAGE]
+Comment=Display in Welcome Box
+
+[CELLSERVDB_WEB]
+Comment=Web address to load cellservdb
+
+[CELLSERVDB_INSTALL]
+Comment=Source file for installable Cellservdb
+
+[CELLSERVDB_CONFIGNAME]
+Comment=Cellservdb file name
+
similarity index 87%
rename from src/WINNT/install/InstallShield5/Default.rge
rename to src/WINNT/install/InstallShield5/Default.txt
index 1ec9276..f7c0882 100644 (file)
@@ -1,36 +1,21 @@
-[Client]
----Comment---=
----FileGroup---=
-HKLM0=Software\TransarcCorporation\AFS Client\CurrentVersion
-HKLM1=Software\TransarcCorporation\AFS Client
-HKLM2=Software\TransarcCorporation\AFS Client\1.0 4.01
-HKLM3=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon
-HKCR0=CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
-HKLM4=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
-HKCR1=CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}\InprocServer32
-HKLM5=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider
-HKCR2=*\shellex\ContextMenuHandlers\AFS Client Shell Extension
-HKCR3=FOLDER\shellex\ContextMenuHandlers\AFS Client Shell Extension
-
-[Client:HKCR:*\shellex\ContextMenuHandlers\AFS Client Shell Extension]
+[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
+Cell=S,CELLNAME_DEFAULT
+(Default)=S,
 ---Comment---=
-(Default)=S,{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
 
 [Client:HKCR:CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}\InprocServer32]
----Comment---=
 (Default)=S,<TARGETDIR>\Client\Program\afs_shl_ext.dll
+---Comment---=
 ThreadingModel=S,Apartment
 
-[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
-Cell=S,
+[Client:HKCR:*\shellex\ContextMenuHandlers\AFS Client Shell Extension]
+(Default)=S,{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
 ---Comment---=
-(Default)=S,
 
-[Server:HKLM:System\CurrentControlSet\Services\EventLog\Application\AFS Service]
+[WinNT_Client_NoUninstall:HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\File Manager\AddOns]
 (Default)=S,
 ---Comment---=
-EventMessageFile=S,<EVENT_MSG_DLL>
-TypesSupported=N,7
+AFS Client FME=S,<TARGETDIR>\Client\Program\afs_fme.dll
 
 [Server]
 ---Comment---=
@@ -38,109 +23,123 @@ TypesSupported=N,7
 HKLM0=Software\TransarcCorporation\AFS Server\CurrentVersion
 HKLM1=System\CurrentControlSet\Services\EventLog\Application\AFS Service
 HKLM2=Software\TransarcCorporation\AFS Server
-HKLM3=Software\TransarcCorporation\AFS Server\1.0 4.01
+HKLM3=Software\TransarcCorporation\AFS Server\%1.%2 %3.%4
 
-[WinNT_Client_NoUninstall:HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\File Manager\AddOns]
+[Server:HKLM:System\CurrentControlSet\Services\EventLog\Application\AFS Service]
 ---Comment---=
 (Default)=S,
-AFS Client FME=S,<TARGETDIR>\Client\Program\afs_fme.dll
+EventMessageFile=S,<EVENT_MSG_DLL>
+TypesSupported=N,7
 
 [Control_Center]
 ---Comment---=
 ---FileGroup---=
 HKLM0=Software\TransarcCorporation\AFS Control Center\CurrentVersion
 HKLM1=Software\TransarcCorporation\AFS Control Center
-HKLM2=Software\TransarcCorporation\AFS Control Center\1.0 4.01
+HKLM2=Software\TransarcCorporation\AFS Control Center\%1.%2 %3.%4
 
-[Client:HKLM:Software\TransarcCorporation\AFS Client\1.0 4.01]
-PatchLevel=N,401
-BetaLevel=N,1
-Revision=N,0
+[Light_Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
+(Default)=S,
+---Comment---=
+Gateway=S,
+
+[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon]
 ---Comment---=
 (Default)=S,
-MajorVersion=N,1
-Title=S,<CLIENT_TITLE>
-InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Client
-Software Type=S,File System
-MinorVersion=N,0
-ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,<CLIENT_DESC>
 
 [Client_NoUninstall]
 ---Comment---=
 ---FileGroup---=
 HKLM0=SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved
 
-[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon]
+[Control_Center:HKLM:Software\TransarcCorporation\AFS Control Center]
 (Default)=S,
 ---Comment---=
 
-[Light_Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
+[Client_NoUninstall:HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
 ---Comment---=
 (Default)=S,
-Gateway=S,
+{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}=S,AFS Client Shell Extension
 
-[Control_Center:HKLM:Software\TransarcCorporation\AFS Control Center\1.0 4.01]
-PatchLevel=N,401
-BetaLevel=N,1
+[Server:HKLM:Software\TransarcCorporation\AFS Server\%1.%2 %3.%4]
 Revision=N,0
----Comment---=
+PatchLevel=N,%3%4
 (Default)=S,
-MajorVersion=N,1
+---Comment---=
+MajorVersion=N,%1
 InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Control Center
+PathName=S,<TARGETDIR>\Server
+BetaLevel=N,1
 Software Type=S,File System
-MinorVersion=N,0
+MinorVersion=N,%2
 ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,AFS Control Center for Windows NT
-
-[Client_NoUninstall:HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
-{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}=S,AFS Client Shell Extension
-(Default)=S,
----Comment---=
+VersionString=S,%5
+Description=S,AFS Server for Windows NT
 
-[Control_Center:HKLM:Software\TransarcCorporation\AFS Control Center]
+[Light_Client]
 ---Comment---=
-(Default)=S,
+---FileGroup---=
+HKLM0=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
 
 [Control_Center:HKLM:Software\TransarcCorporation\AFS Control Center\CurrentVersion]
-PatchLevel=N,401
-BetaLevel=N,1
 Revision=N,0
----Comment---=
+PatchLevel=N,%3%4
 (Default)=S,
-MajorVersion=N,1
+---Comment---=
+MajorVersion=N,%1
 InstallDateString=S,<INSTALL_DATE>
 PathName=S,<TARGETDIR>\Control Center
+BetaLevel=N,1
 Software Type=S,File System
-MinorVersion=N,0
+MinorVersion=N,%2
 ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
+VersionString=S,%5
 Description=S,AFS Control Center for Windows NT
 
-[Light_Client]
+[Docs:HKLM:Software\TransarcCorporation\AFS Supplemental Documentation\%1.%2 %3.%4]
+Revision=N,0
+PatchLevel=N,%3%4
+(Default)=S,
 ---Comment---=
----FileGroup---=
-HKLM0=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
+MajorVersion=N,%1
+InstallDateString=S,<INSTALL_DATE>
+PathName=S,<TARGETDIR>\Documentation
+BetaLevel=N,1
+Software Type=S,File System
+MinorVersion=N,%2
+ReleaseType=S,<RELEASE_TYPE>
+VersionString=S,%5
+Description=S,AFS System Administration Documentation
 
 [Full_Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
----Comment---=
 (Default)=S,
-IsGateway=N,0
-
-[Server:HKLM:Software\TransarcCorporation\AFS Server]
 ---Comment---=
-(Default)=S,
+IsGateway=N,0
 
 [Docs]
 ---Comment---=
 ---FileGroup---=
 HKLM0=Software\TransarcCorporation\AFS Supplemental Documentation\CurrentVersion
 HKLM1=Software\TransarcCorporation\AFS Supplemental Documentation
-HKLM2=Software\TransarcCorporation\AFS Supplemental Documentation\1.0 4.01
+HKLM2=Software\TransarcCorporation\AFS Supplemental Documentation\%1.%2 %3.%4
+
+[Server:HKLM:Software\TransarcCorporation\AFS Server]
+(Default)=S,
+---Comment---=
+
+[Client]
+---Comment---=
+---FileGroup---=
+HKLM0=Software\TransarcCorporation\AFS Client\CurrentVersion
+HKLM1=Software\TransarcCorporation\AFS Client
+HKLM2=Software\TransarcCorporation\AFS Client\%1.%2 %3.%4
+HKCR0=CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
+HKLM3=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon
+HKCR1=CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}\InprocServer32
+HKLM4=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
+HKCR2=*\shellex\ContextMenuHandlers\AFS Client Shell Extension
+HKLM5=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider
+HKCR3=FOLDER\shellex\ContextMenuHandlers\AFS Client Shell Extension
 
 [Data]
 Set0=Server
@@ -152,122 +151,122 @@ Set5=Light_Client
 Set6=Full_Client
 Set7=Docs
 
-[Client:HKLM:Software\TransarcCorporation\AFS Client\CurrentVersion]
-PatchLevel=N,401
-BetaLevel=N,1
+[Docs:HKLM:Software\TransarcCorporation\AFS Supplemental Documentation\CurrentVersion]
 Revision=N,0
----Comment---=
+PatchLevel=N,%3%4
 (Default)=S,
-MajorVersion=N,1
-Title=S,<CLIENT_TITLE>
+---Comment---=
+MajorVersion=N,%1
 InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Client
+PathName=S,<TARGETDIR>\Documentation
+BetaLevel=N,1
 Software Type=S,File System
-MinorVersion=N,0
+MinorVersion=N,%2
 ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,<CLIENT_DESC>
+VersionString=S,%5
+Description=S,AFS System Administration Documentation
 
 [Full_Client]
 ---Comment---=
 ---FileGroup---=
 HKLM0=SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters
 
-[Docs:HKLM:Software\TransarcCorporation\AFS Supplemental Documentation\CurrentVersion]
-PatchLevel=N,401
-BetaLevel=N,1
+[Client:HKLM:Software\TransarcCorporation\AFS Client\CurrentVersion]
 Revision=N,0
----Comment---=
+PatchLevel=N,%3%4
 (Default)=S,
-MajorVersion=N,1
-InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Documentation
-Software Type=S,File System
-MinorVersion=N,0
-ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,AFS System Administration Documentation
-
-[Server:HKLM:Software\TransarcCorporation\AFS Server\1.0 4.01]
-PatchLevel=N,401
-BetaLevel=N,1
-Revision=N,0
 ---Comment---=
-(Default)=S,
-MajorVersion=N,1
+Title=S,<CLIENT_TITLE>
+MajorVersion=N,%1
 InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Server
+PathName=S,<TARGETDIR>\Client
+BetaLevel=N,1
 Software Type=S,File System
-MinorVersion=N,0
+MinorVersion=N,%2
 ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,AFS Server for Windows NT
+VersionString=S,%5
+Description=S,<CLIENT_DESC>
 
-[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider]
+[Client:HKLM:Software\TransarcCorporation\AFS Client]
 (Default)=S,
 ---Comment---=
-Class=N,2
-Name=S,TransarcAFSDaemon
-ProviderPath=S,<LOGON_DLL>
-AuthentProviderPath=S,<LOGON_DLL>
 
 [WinNT_Client_NoUninstall:HKLM:SOFTWARE\Microsoft\Windows NT\Current Version\File Manager\AddOns]
-(Default)=S,
 ---Comment---=
+(Default)=S,
 AFS Client FME=S,<TARGETDIR>\Client\Program\afs_fme.dll
 
-[Client:HKLM:Software\TransarcCorporation\AFS Client]
+[Client:HKLM:SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider]
 ---Comment---=
 (Default)=S,
+Class=N,2
+Name=S,TransarcAFSDaemon
+ProviderPath=S,<LOGON_DLL>
+AuthentProviderPath=S,<LOGON_DLL>
 
 [WinNT_Client_NoUninstall]
 ---Comment---=
 ---FileGroup---=
 HKLM0=SOFTWARE\Microsoft\Windows NT\CurrentVersion\File Manager\AddOns
 
-[Docs:HKLM:Software\TransarcCorporation\AFS Supplemental Documentation\1.0 4.01]
-PatchLevel=N,401
-BetaLevel=N,1
-Revision=N,0
+[Client:HKCR:FOLDER\shellex\ContextMenuHandlers\AFS Client Shell Extension]
+(Default)=S,{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
 ---Comment---=
-(Default)=S,
-MajorVersion=N,1
-InstallDateString=S,<INSTALL_DATE>
-PathName=S,<TARGETDIR>\Documentation
-Software Type=S,File System
-MinorVersion=N,0
-ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
-Description=S,AFS System Administration Documentation
 
 [General]
 Type=REGISTRYDATA
 Version=1.00.000
 
-[Client:HKCR:FOLDER\shellex\ContextMenuHandlers\AFS Client Shell Extension]
+[Client:HKLM:Software\TransarcCorporation\AFS Client\%1.%2 %3.%4]
+Revision=N,0
+PatchLevel=N,%3%4
+(Default)=S,
 ---Comment---=
-(Default)=S,{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
+Title=S,<CLIENT_TITLE>
+MajorVersion=N,%1
+InstallDateString=S,<INSTALL_DATE>
+PathName=S,<TARGETDIR>\Client
+BetaLevel=N,1
+Software Type=S,File System
+MinorVersion=N,%2
+ReleaseType=S,<RELEASE_TYPE>
+VersionString=S,%5
+Description=S,<CLIENT_DESC>
 
 [Server:HKLM:Software\TransarcCorporation\AFS Server\CurrentVersion]
-PatchLevel=N,401
-BetaLevel=N,1
 Revision=N,0
----Comment---=
+PatchLevel=N,%3%4
 (Default)=S,
-MajorVersion=N,1
+---Comment---=
+MajorVersion=N,%1
 InstallDateString=S,<INSTALL_DATE>
 PathName=S,<TARGETDIR>\Server
+BetaLevel=N,1
 Software Type=S,File System
-MinorVersion=N,0
+MinorVersion=N,%2
 ReleaseType=S,<RELEASE_TYPE>
-VersionString=S,1.0 4.01
+VersionString=S,%5
 Description=S,AFS Server for Windows NT
 
-[Client:HKCR:CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}]
+[Control_Center:HKLM:Software\TransarcCorporation\AFS Control Center\%1.%2 %3.%4]
+Revision=N,0
+PatchLevel=N,%3%4
+(Default)=S,
 ---Comment---=
-(Default)=S,AFS Client Shell Extension
+MajorVersion=N,%1
+InstallDateString=S,<INSTALL_DATE>
+PathName=S,<TARGETDIR>\Control Center
+BetaLevel=N,1
+Software Type=S,File System
+MinorVersion=N,%2
+ReleaseType=S,<RELEASE_TYPE>
+VersionString=S,%5
+Description=S,AFS Control Center for Windows NT
 
 [Docs:HKLM:Software\TransarcCorporation\AFS Supplemental Documentation]
----Comment---=
 (Default)=S,
+---Comment---=
 
+[Client:HKCR:CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}]
+(Default)=S,AFS Client Shell Extension
+---Comment---=
index 27dcbfe..4f85471 100644 (file)
@@ -23,6 +23,9 @@ copy "Script Files\setup.rul" .
 
 copy "Setup Files\Uncompressed Files\Language Independent\OS Independent\setup.bmp" .
 
+
+copy "Setup Files\Uncompressed Files\Language Independent\OS Independent\_isuser.dll" .
+
 copy "Shell Objects\Default.shl" .\Default.shell
 
 copy "String Tables\Default.shl" .
index ad3ba1c..70537ce 100755 (executable)
 Copyright 2000, International Business Machines Corporation and others.
 All Rights Reserved.
-
 This software has been released under the terms of the IBM Public
 License.  For details, see the LICENSE file in the top-level source
 directory or online at http://www.openafs.org/dl/license10.html
-
 HOW TO SET THE AFS FOR WINDOWS VERSION INFORMATION
 
+Set AFSPRODUCT_VERSION in the following files:
+src\config\NTMakefile.i386_win95 
+src\config\NTMakefile.i386_nt40
 
-DECIDE WHAT THE VERSION INFO SHOULD BE
-
-First decide what the version information should be.  There are
-the following values that will need to be set:
-
-MajorVersion
-MinorVersion
-PatchLevel
-BetaLevel
-ReleaseType
-Title (called VersionString in the registry)
-
-MajorVersion is the first number in a dotted version scheme.  For 
-example, if the version is 3.5, then MajorVersion is set to 3.
-
-MinorVersion is the second number in a dotted version scheme.  For
-example, if the version is 3.5, then MinorVersion is set to 5.
-
-PatchLevel is an integer number representing the patch level.  If
-the patch level is 4, then PatchLevel is set to 400.  If the patch 
-level is 3.32, then PatchLevel is set to 332.  The reason patch
-numbers aren't just 1, 2, etc., is that they are currently set to
-the cml configuration number of the build used to produce the patch.
-We may later switch to just making the patch level a single digit,
-in which case the PatchLevel value must be set to something big
-enough so that in a comparison with the old patch levels, it will
-evaluate as bigger.  So if you want a patch level of 4, use a 
-PatchLevel setting of 400.  If this is not a patch release, then
-set PatchLevel to 0.
-
-BetaLevel is an integer number representing the beta level.  This is
-just a way to have multiple beta releases.  So if this is the first
-beta release, set BetaLevel to 1.  If this is not a beta release,
-then set BetaLevel to 0.
-
-ReleaseType is kind of redundant; it is set to the string "GA" if 
-this is a non-beta release and "Beta" if this is a beta release.
-
-Title is the product version as a full string.  So if this is
-release 3.5 3.22, then Title is set to "3.5 3.22".  If this is
-3.6 Beta 2, then Title is set to "3.6 Beta 2".
-
-Title is used when showing the version to the user, like, for
-example, in the afs creds tool.
-
-************************* NOTE ******************************
-You MUST set all of these values correctly and in a consistent
-manner from one release to the next so that the installer can
-properly determine whether to perform upgrades, downgrades, or
-reinstalls.
-
-Look at the function CompareVersions in file setup.rul to see
-how these values are used to make version info decisions.
-
-
-SET THE VERSION IN THE INSTALLSHIELD FILES
-
-You will need to edit the following InstallShield files:
-
-value.shl:
-
-This file contains all of the strings used by the program.  Set
-all of the following identifiers to the new version number:
-
-TITLE_MAIN
-UNINST_DISPLAY_NAME_CC
-UNINST_DISPLAY_NAME_CLIENT
-UNINST_DISPLAY_NAME_DOCS
-UNINST_DISPLAY_NAME_LIGHT_CLIENT
-UNINST_DISPLAY_NAME_SERVER
-
-These identifiers below correspond to the version information
-discussed in the first section above.
-
-PRODUCT_VERSION_MAJOR
-PRODUCT_VERSION_MINOR
-PRODUCT_VERSION_PATCH_LEVEL
-PRODUCT_VERSION_BETA_LEVEL
-PRODUCT_VERSION_RELEASE_TYPE
-PRODUCT_VERSION_TITLE
-
-Default.rge:
-
-This file contains information that will be written to the registry
-at install time.
-
-Change all occurances of the following to the proper verison info:
-
-MajorVersion (set to same value as PRODUCT_VERSION_MAJOR in value.shl)
-MinorVersion (set to same value as PRODUCT_VERSION_MINOR in value.shl)
-PatchLevel (set to same value as PRODUCT_VERSION_PATCH_LEVEL in value.shl)
-BetaLevel (set to same value as PRODUCT_VERSION_BETA_LEVEL in value.shl)
-ReleaseType (set to same value as PRODUCT_RELEASE_TYPE in value.shl)
-VersionString (set to same value as PRODUCT_VERSION_TITLE in value.shl)
-
-Finally, change any string matching the form below to have the new verison
-info:
-
-HKLMn=Software\TransarcCorporation\Product Name\Version
-
-For example, one such string may be:
+The format of this variable should be
+x.y.z.p or x.y.z p
 
-HKLM2=Software\TransarcCorporation\AFS Control Center\3.5 3.32
+x= major verson (1-9)
+y= minor verson (1-9)
+z.p= patch level z=(1-9) p=(1-99 or a-z)
 
-To update the verison info to 3.6 patch 3, the string would change
-to:
+For example:
+AFSPRODUCT_VERSION=1.1.1 a
+AFSPRODUCT_VERSION=1.1.1.1
+AFSPRODUCT_VERSION=1.1.101
+AFSPRODUCT_VERSION=1.1.1a
 
-HKLM2=Software\TransarcCorporation\AFS Control Center\3.6 3
+These examples represent different forms of the same version.
+However the version will be displayed to the user as they are shown!
 
-That's it!  Build and test the thing, making sure that the version info
-in the registry is correct for each app, and that upgrades of previous
-versions, downgrades to previous versions from this version, and reinstalls
-of this version work correctly.
 
-If you're the poor sucker who had to do this, then I offer you my sympathy!
 
 
index a5d74a8..3bfe5ae 100644 (file)
@@ -8,23 +8,52 @@
 !INCLUDE ..\..\..\config\NTMakefile.$(SYS_NAME)
 !INCLUDE ..\..\..\config\NTMakefile.version
 
-############################################################################
-
-CELLSERVDB = $(DESTDIR)\root.client\usr\vice\etc\afsdcell.ini
+#  Install comments
+#             Don't use '=' in the following strings!
+#             WELCOMEMESSAGE=Display during installation process
+#             AFSBUILDCOMMENTS=Displayed in properity page for install file
+#             CELLSERVDB_CONFIGNAME = name of configuration file (ThisCell)
 
-$(CELLSERVDB): afsdcell.ini
-    copy $** $@
+CELLSERVDB_CONFIGNAME=afsdcell.ini
+WELCOMEMESSAGE=Default Configuration Information:\nBuild:*DatE* *TimE* Ver:$(AFSPRODUCT_VERSION)\nCellname:$(CELLNAME_DEFAULT)\nCellSrvDB:$(CELLSERVDB_INSTALL)
+AFSBUILDCOMMENTS=Build:*DatE* *TimE* CellServDB:$(CELLSERVDB_INSTALL)
+############################################################################
 
-prep: $(CELLSERVDB) AFS_component_version_number.txt
+prep: AFS_component_version_number.txt
+       $(DESTDIR)\bin\util_cr.exe } "$(AFSPRODUCT_VERSION)" ".\lang\en_US\valuee.shl"
+       $(DESTDIR)\bin\util_cr.exe } "$(AFSPRODUCT_VERSION)" "default.txt" "default.rge"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\lang\en_US\value.shl" "[DATA] CELLSERVDB_CONFIGNAME=$(CELLSERVDB_CONFIGNAME)"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\lang\en_US\value.shl" "[DATA] CELLNAME_DEFAULT=$(CELLNAME_DEFAULT)"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\lang\en_US\value.shl" "[DATA] CELLSERVDB_INSTALL=$(CELLSERVDB_INSTALL)"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\lang\en_US\value.shl" "[DATA] CELLSERVDB_WEB=$(CELLSERVDB_WEB)"
+!IF "$(WELCOMEMESSAGE)" != ""
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\lang\en_US\value.shl" "[DATA] WELCOME_MESSAGE=$(WELCOMEMESSAGE)"
+!ENDIF
+!     IF ((EXIST("$(ISWEB)")) &&("$(ISWEB)"!=""))
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Version=$(AFSPRODUCT_VERSION)"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Comments=$(AFSBUILDCOMMENTS)"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] ApplicationName=AFSforWindows"
+       $(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Company=Open AFS"
+      
+!     ENDIF
     CreateISDirTree.bat
     ScatterFiles.bat
     CreateGeneratedFiles.bat
     CompileScript.bat
+       $(COPY) $(DESTDIR)\WinInstall\Config\wininet.dll ".\Setup Files\Compressed Files\0009-English\Intel 32\."
+       $(COPY) $(DESTDIR)\WinInstall\Config\shlwapi.dll ".\Setup Files\Compressed Files\0009-English\Intel 32\."
+       $(COPY) ..\..\afs_setup_utils\_isuser\_isuser.dll ".\Setup Files\Compressed Files\0009-English\Intel 32\."
+       $(COPY) ..\..\afs_setup_utils\getwebdll\getwebdll.dll ".\Setup Files\Compressed Files\0009-English\Intel 32\."
+       $(COPY) $(DESTDIR)\WinInstall\Config\$(CELLSERVDB_INSTALL) ".\Setup Files\Compressed Files\0009-English\Intel 32\$(CELLSERVDB_CONFIGNAME)"
+       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\root.client\usr\vice\etc\$(CELLSERVDB_CONFIGNAME)"
+       $(DESTDIR)\bin\util_cr.exe ~ ".\Setup Files\Compressed Files\0009-English\Intel 32\_ISUSER.DLL"
+       $(DESTDIR)\bin\util_cr.exe ~ ".\Setup Files\Compressed Files\0009-English\Intel 32\shlwapi.DLL"
+       $(DESTDIR)\bin\util_cr.exe ~ ".\Setup Files\Compressed Files\0009-English\Intel 32\wininet.DLL"
+       $(DESTDIR)\bin\util_cr.exe ~ ".\Setup Files\Compressed Files\0009-English\Intel 32\GETWEBDLL.DLL"
 
 build:
     BuildSetup.bat
-    xcopy/s/e/y "Media\Transarc AFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall
-    copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt
 !IF ((EXIST("$(ISWEB)")) &&("$(ISWEB)"!=""))
 !      IF (!EXIST($(DESTDIR)\Wininstall\PackageWeb))
                $(MKDIR) $(DESTDIR)\Wininstall\PackageWeb
@@ -32,6 +61,8 @@ build:
        $(DEL) /q $(DESTDIR)\Wininstall\PackageWeb\*.*
        $(ISWEB)\Pftwwiz.exe $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a 
 !ENDIF
-    $(DEL) /q "Media\Transarc AFS\Disk Images\disk1\*.*"
+       xcopy/s/e/y "Media\Transarc AFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall
+       copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt
+       $(DEL) /q "Media\Transarc AFS\Disk Images\disk1\*.*"
 
 install: prep build
index fffb472..228b418 100644 (file)
@@ -24,6 +24,7 @@ copy setup.rul "Script Files"
 
 rem Only copy this file when NOT doing a WSPP build
 if not defined AFSBLD_IS_WSPP copy setup.bmp "Setup Files\Uncompressed Files\Language Independent\OS Independent"
+if not defined AFSBLD_IS_WSPP copy _isuser.dll "Setup Files\Uncompressed Files\Language Independent\OS Independent"
 
 copy %AFSROOT%\DEST\root.server\usr\afs\bin\InstallUtils.dll "Setup Files\Compressed Files\Language Independent\OS Independent"
 copy %AFSROOT%\DEST\root.server\usr\afs\bin\afs_setup_utils_*.dll "Setup Files\Compressed Files\Language Independent\OS Independent"
@@ -1,36 +1,41 @@
 [Data]
 DEFAULT_INSTALL_DIR=IBM\AFS
+CELLNAME_DEFAULT=almaden.ibm.com
+CELLSERVDB_CONFIGNAME=
+CELLSERVDB_WEB=
+CELLSERVDB_INSTALL=
+WELCOME_MESSAGE=
 NOTHING_SELECTED_MSG=You must select something to install before continuing.
 DOWNGRADE_LIGHT_CLIENT_MSG=Downgrade AFS Light Client
 SETUP_FINISHED_MSG=Setup has finished installing AFSĀ® for Windows on your computer.
-TITLE_MAIN=Open AFS for Windows 1.0 4.01
+TITLE_MAIN=Open AFS for Windows %5
 SEVERE_DIALOG_TITLE=Open AFS for Windows
 UPGRADE_CLIENT_MSG=Upgrade AFS Client
-PRODUCT_VERSION_MINOR=0
+PRODUCT_VERSION_MINOR=%2
 CONFIGURING_AFS_CLIENT_SERVICE=Configuring the AFS Client service
 PRODUCT_NAME_CC=AFS Control Center
 PRODUCT_NAME_SERVER=AFS Server
 UPGRADE_CC_MSG=Upgrade AFS Control Center
 DOWNGRADE_SERVER_MSG=Downgrade AFS Server
-UNINST_DISPLAY_NAME_LIGHT_CLIENT=AFS Light 1.0 4.01
+UNINST_DISPLAY_NAME_LIGHT_CLIENT=AFS Light %5
 PRODUCT_NAME_LIGHT_CLIENT=AFS Light
 ERROR_COMPONENT=Component:
 COMPANY_NAME=TransarcCorporation
 REINSTALL_CLIENT_MSG=Reinstall AFS Client
 DOWNGRADE_CC_MSG=Downgrade AFS Control Center
-UNINST_DISPLAY_NAME_DOCS=AFS Supplemental Documentation 1.0 4.01
+UNINST_DISPLAY_NAME_DOCS=AFS Supplemental Documentation %5
 UNINST_KEY_SERVER=AFS Server
 VIEW_README_PROMPT_MSG=View the readme file
 INSTALL_LIGHT_CLIENT_MSG=AFS Light Client
-PRODUCT_VERSION_TITLE=1.0 4.01
-UNINST_DISPLAY_NAME_CC=AFS Control Center 1.0 4.01
+PRODUCT_VERSION_TITLE=%5
+UNINST_DISPLAY_NAME_CC=AFS Control Center %5
 ERROR_FILEGROUP=File Group:
 ERROR_MOVEDATA=An error occurred during the move data process: %d
 CONFIGURING_AFS_SERVER_SERVICE=Configuring the AFS Server service
 CLIENT_DESC=AFS Client
 SET_NETWORK_PROVIDER_ERROR=Unable to configure the AFS Client as a Network Provider.
-PRODUCT_VERSION_MAJOR=1
-UNINST_DISPLAY_NAME_SERVER=AFS Server 1.0 4.01
+PRODUCT_VERSION_MAJOR=%1
+UNINST_DISPLAY_NAME_SERVER=AFS Server %5
 SETUPUTILS_NOT_FOUND=The file InstallUtils.dll could not be loaded.  Setup cannot continue.
 LIGHT_CLIENT_ALREADY_INSTALLED_MSG=AFS Light is already installed on this computer.
 SETUP_TYPE_MSG=Select the AFSĀ® for Windows products that you wish to install:
@@ -68,13 +73,13 @@ UNINST_KEY_CC=AFS Control Center
 UNINST_KEY_CLIENT=AFS Client
 UPGRADE_DOCS_MSG=Upgrade AFS Supplemental Documentation
 DOWNGRADE_PREP_MSG=Preparing to downgrade the %s.  Please wait...this may be a lengthy process.
-PRODUCT_VERSION_PATCH_LEVEL=401
+PRODUCT_VERSION_PATCH_LEVEL=%3%4
 NON_UPGRADABLE_SOFTWARE_INSTALLED_ERROR_MSG=Non-upgradable versions of this product are installed on your computer.  These \nversions must be uninstalled before the current versions can be installed.
 CANT_INSTALL_BOTH_CLIENTS_MSG=Please select only one of the AFS Clients to install.  You cannot install both.
 UNINST_KEY_LIGHT_CLIENT=AFS Light
 UPGRADE_LIGHT_CLIENT_MSG=Upgrade AFS Light Client
 UNINST_KEY_DOCS=AFS Supplemental Documentation
-UNINST_DISPLAY_NAME_CLIENT=AFS Client 1.0 4.01
+UNINST_DISPLAY_NAME_CLIENT=AFS Client %5
 REINSTALL_DOCS_MSG=Reinstall AFS Supplemental Documentation
 UPGRADE_PREP_MSG=Preparing to upgrade the %s.  Please wait...this may be a lengthy process.
 MUST_BE_AN_ADMIN_MSG=You must be a member of the local Administrators group on this Windows system in order to install this product.
index d7bbe28..b75bf97 100644 (file)
@@ -1,14 +1,12 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (C) 1998  OpenAFS
-// All rights reserved.
-//
+
 //
-//    File Name:  Setup.rul
+//     Copyright 2000, International Business Machines Corporation and others.
+//     All Rights Reserved.
 //
-//  Description:  InstallShield script
+//     This software has been released under the terms of the IBM Public
+//     License.  For details, see the LICENSE file in the top-level source
+//     directory or online at http://www.openafs.org/dl/license10.html
 //
-////////////////////////////////////////////////////////////////////////////////
 
 
 // Include header files
@@ -321,6 +319,746 @@ end;
        BOOL            bPreinstallReplace;
 
 
+////////////////////////////////////////////////////////////////////////////////
+//
+//   Function Name: Template
+//
+//     Description: This dialog will show a dialog template which can be
+//                  used for creating any user-defined dialog with the
+//                  Windows 95 look and feel.
+//        Comments:
+//
+////////////////////////////////////////////////////////////////////////////////
+
+number nvSection,nFileIsLocked;
+STRING szTemp;
+
+#define IDC_HOMEPATH                    301
+#define IDC_ROOTPATH                    302
+#define IDC_HOMEDRIVELIST               1007
+#define IDC_ROOTDRIVELIST               1008
+#define IDC_ENABLEROOT                  1010
+#define IDC_ENABLEHOME                  1011
+#define IDC_INSTALL                            1011
+#define IDC_WEB                         1016
+#define IDC_CHECK_INSTALL               1018
+#define IDC_CHECK_WEB                   1019
+#define IDC_CHECK_BROWSEFILE            1020
+#define IDC_CHECK_PREVIOUSFILE          1021
+#define IDC_PREVIOUSFILE                1024
+#define IDC_BROWSE                      1025
+#define IDC_BROWSEFILE                  1026
+#define DLG_TEMPLATE                    13029
+#define DLG_DRIVEPATH                   13030
+#define DLG_CELLSERVDB                  13031
+#define IDC_PATH                        13032
+
+prototype Logit(STRING);
+function Logit(szMsg)
+HWND handle;
+begin
+       return;
+       OpenFileMode(FILE_MODE_APPEND);
+       if (OpenFile (handle, "y:\\dest", "silent.log") < 0) then
+           CreateFile(handle,"y:\\dest", "silent.log");
+     endif;
+       WriteLine(handle,szMsg);
+    CloseFile(handle);
+end;
+
+prototype Logitn(STRING,NUMBER);
+function Logitn(szMsg,i)
+HWND handle;
+STRING sz;
+begin
+    Sprintf(sz,szMsg,i);
+       Logit(sz);
+end;
+prototype INT GetWebDll.BrowseFile(NUMBER,BYREF STRING,BYREF STRING,NUMBER);
+prototype INT GetWebDll.GetWebPage(BYREF STRING,BYREF STRING,BYREF STRING);
+prototype INT GetWebDll.GetUserLogon(BYREF STRING);
+prototype SetCellServDB(STRING,BYREF NUMBER,BYREF STRING,BYREF STRING,BYREF STRING,BYREF STRING);
+prototype FormErrorMessage(NUMBER,BYREF STRING);
+prototype SetHomeRoot( STRING,BYREF STRING,BYREF STRING,BYREF STRING,BYREF STRING );
+prototype BOOL getWebCellSrvDB(STRING,STRING);
+
+prototype BOOL GetDefaultDrive(BYREF NUMBER);
+function GetDefaultDrive(listAv)
+       NUMBER listAc;
+       NUMBER I,nResult;
+       STRING item,iitem;
+begin
+   listAc = ListCreate (STRINGLIST);
+       Enable (STATUS);
+       SetStatusWindow (50, "Scaning for available Drives...");
+       nResult=GetValidDrivesList (listAc, -1,-1);
+       SetStatusWindow (100, "Completed.");
+       Delay (2);
+       if (nResult<0) then
+           SetStatusWindow(0, "");
+               MessageBox ("Scan Drive Error" , SEVERE);
+               abort;
+       endif;
+    SetStatusWindow(0, "");
+   listAv = ListCreate (STRINGLIST);
+   ListAddString(listAv,"None:",AFTER);
+   ListGetFirstString(listAc, iitem);
+       for I=67 to 90
+               Sprintf(item,"%c",I);
+               nResult=ListFindString(listAc,item);
+               if nResult==END_OF_LIST then
+                       ListAddString(listAv,item+":",AFTER);
+               endif;
+               ListGetNextString(listAc,iitem);        
+   endfor;
+    ListDestroy(listAc);
+       return TRUE;
+end;
+
+function FormErrorMessage(nResult,szResult)
+begin
+       switch(nResult)
+       case COPY_ERR_CREATEDIR:
+               szResult=TARGETDIR+ "could not be created. Make sure that you have access rights to the target drive.";
+       case COPY_ERR_MEMORY:
+               szResult="The function was unable to allocate the memory required to complete the copy file process. Terminate as many running applications as possible to free memory.";
+       case COPY_ERR_NODISKSPACE:
+               szResult="The function could not find enough disk space on "+TARGETDIR+" to copy the files. Free disk space on the target drive.";
+       case COPY_ERR_OPENINPUT:
+               szResult="The function was unable to open the input file in "+SRCDIR+". Make sure the source file is a valid filename and that both the source file and target directory exist.";
+       case COPY_ERR_OPENOUTPUT:
+               szResult="The function was unable to copy the requested file.";
+       case COPY_ERR_TARGETREADONLY:
+               szResult="The file in "+TARGETDIR+" is read-only. Remove the read-only attribute from the target file and try again.";
+       default:
+               szResult="Unknown error";
+       endswitch;
+end;
+
+function getWebCellSrvDB(szDefaultWeb,szDestFile)
+       NUMBER nResult;
+       STRING szFile,szErrMsg,szURL;
+begin
+       szErrMsg="                                                                 ";
+       Enable (STATUS);
+       SetStatusWindow (50, "Now Downloading CellServDB file...");
+       nResult=GetWebPage(szErrMsg,szDestFile,szDefaultWeb);
+       SetStatusWindow (100, "Downloading completed.");
+       Delay (2);
+       if (nResult!=0) then
+           SetStatusWindow(0, "");
+               MessageBox (szErrMsg, INFORMATION);
+               return FALSE;
+       endif;
+    // setup default status
+    SetStatusWindow(0, "");
+   return TRUE;
+end;
+
+// Transfer file to CELLSERVDB
+prototype BOOL InstallCellServDB(NUMBER,STRING,STRING);
+function InstallCellServDB(DefaultItem,szDefaultWeb,szDefaultBrowse)
+STRING szFile,svErrorMessage;
+begin
+       switch (DefaultItem)
+       case IDC_CHECK_WEB:
+               nResult=getWebCellSrvDB(szDefaultWeb,TARGETDIR^@CELLSERVDB_CONFIGNAME);
+       case IDC_CHECK_BROWSEFILE:
+               // open file and copy to area
+               ParsePath(szFile,szDefaultBrowse,PATH);
+               SRCDIR=szFile;
+               ParsePath(szFile,szDefaultBrowse,FILENAME);
+               nResult=CopyFile ( szFile ,@CELLSERVDB_CONFIGNAME );
+               if nResult < 0 then
+                   if nResult = -1 then
+                       MessageBox ( "CopyFile failed with error code -1!", WARNING );
+                   else
+                       FormErrorMessage(nResult,svErrorMessage);
+                       SprintfBox ( WARNING, "",
+                           "CopyFile failed!\n\nError code: %ld\nMessage text: %s",
+                           nResult, svErrorMessage );
+                   endif;
+                   nResult=FALSE;
+                else
+                       nResult=TRUE;
+                endif;
+       case IDC_CHECK_INSTALL: //need to delete because install will never overwrite
+               SRCDIR=SUPPORTDIR;
+               nResult=CopyFile (@CELLSERVDB_CONFIGNAME,@CELLSERVDB_CONFIGNAME );
+               if nResult < 0 then
+                   if nResult = -1 then
+                       MessageBox ( "CopyFile failed with error code -1!", WARNING );
+                   else
+                       FormErrorMessage(nResult,svErrorMessage);
+                       SprintfBox ( WARNING, "",
+                           "CopyFile failed!\n\nError code: %ld\nMessage text: %s",
+                                   nResult, svErrorMessage );
+                           endif;
+                       nResult=FALSE;
+               else
+                       nResult=TRUE;
+               endif;
+       case IDC_CHECK_PREVIOUSFILE:
+               nResult=TRUE;// work is done, it will use previous file
+       default:
+               nResult=TRUE;
+               ;
+       endswitch;
+       return nResult;
+end;
+
+// Return TRUE if silent mode active
+prototype BOOL SilentSetCellServDB(STRING,NUMBER,NUMBER,NUMBER,BYREF STRING,BYREF STRING);
+function SilentSetCellServDB(szDlg,option,nResult,DefaultItem,szDefaultWeb,szDefaultBrowse)
+STRING svSection,szTemp;
+NUMBER nTemp;
+begin
+       switch (option)
+       case 0:         //READ function
+               if (MODE!=SILENTMODE) then
+                       return FALSE;
+               endif;
+               SdMakeName( svSection, szDlg, "", nvSection );
+        SilentReadData( svSection, "Result", DATA_NUMBER,szTemp,nResult);
+        if (nResult!=NEXT) then
+               return TRUE;
+        endif;
+           SilentReadData( svSection, "DefaultItem", DATA_NUMBER,szTemp,DefaultItem);
+               SilentReadData( svSection, "szDefaultWeb", DATA_STRING, szDefaultWeb,nTemp);
+               SilentReadData( svSection, "szDefaultBrowse", DATA_STRING,szDefaultBrowse,nTemp );
+               if (InstallCellServDB(DefaultItem,szDefaultWeb,szDefaultBrowse)==FALSE) then
+               nResult=CANCEL;
+               else
+                       nResult=NEXT;
+               endif;
+               return TRUE;
+       default:        //write
+               SdMakeName( svSection, szDlg, "", nvSection );
+        SilentWriteData( svSection, "Result", DATA_NUMBER,szTemp, nResult );
+        SilentWriteData( svSection, "DefaultItem", DATA_NUMBER,szTemp, DefaultItem );
+        SilentWriteData( svSection, "szDefaultWeb", DATA_STRING, szDefaultWeb,nTemp );
+        SilentWriteData( svSection, "szDefaultBrowse", DATA_STRING, szDefaultBrowse,nTemp );
+               return TRUE;            
+    endswitch;
+end;
+
+function SetCellServDB( szTitle,DefaultItem,szPreviousInstall,szDefaultWeb,szDefaultBrowse,szDefaultInstall)
+STRING  szDlg, szTemp,szResult[256],svErrorMessage,szFile,svSection;
+NUMBER  bDone, nId, nMessage, nTemp,AvailableDrives,nResult;
+INT     hwndDlg,hwndItem;
+
+begin
+        szDlg = "DLG_CELLSERVDB";
+        // record data produced by this dialog
+               if SilentSetCellServDB(szDlg,0,nResult,DefaultItem,szDefaultWeb,szDefaultBrowse) then
+                       return nResult;
+               endif;
+
+        // ensure general initialization is complete
+        if (!bSdInit) then
+           SdInit();
+        endif;
+
+        if (EzDefineDialog( szDlg, "", "",
+                            DLG_CELLSERVDB ) = DLG_ERR) then
+           return -1;
+        endif;
+
+        // Loop in dialog until the user selects a standard button
+               Disable(LOGGING);
+               VarSave(SRCTARGETDIR);
+               TARGETDIR=WINDIR;
+               doagain:
+        bDone = FALSE;
+
+        while (!bDone)
+
+           nId = WaitOnDialog( szDlg );
+           hwndDlg = CmdGetHwndDlg( szDlg );
+
+           switch(nId)
+
+           case DLG_INIT:
+                // Initialize List Control
+                // set file
+                CtrlSetState (szDlg, DefaultItem,BUTTON_CHECKED);
+                               if !Is(FILE_EXISTS,szPreviousInstall) then
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_CHECK_PREVIOUSFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               endif;
+                               hwndItem = GetDlgItem( hwndDlg, IDC_PREVIOUSFILE );
+                               EnableWindow( hwndItem, DefaultItem==IDC_CHECK_PREVIOUSFILE);
+                               hwndItem = GetDlgItem( hwndDlg, IDC_BROWSEFILE );
+                               EnableWindow( hwndItem, DefaultItem==IDC_CHECK_BROWSEFILE);
+                               hwndItem = GetDlgItem( hwndDlg, IDC_BROWSE );
+                               EnableWindow( hwndItem, DefaultItem==IDC_CHECK_BROWSEFILE);
+                               hwndItem = GetDlgItem( hwndDlg, IDC_WEB );
+                               EnableWindow( hwndItem, DefaultItem==IDC_CHECK_WEB);
+                               hwndItem = GetDlgItem( hwndDlg, IDC_INSTALL );
+                               EnableWindow( hwndItem, DefaultItem==IDC_CHECK_INSTALL);
+                               CtrlSetText (szDlg, IDC_PREVIOUSFILE, szPreviousInstall);
+                               CtrlSetText (szDlg, IDC_BROWSEFILE, szDefaultBrowse);
+                               CtrlSetText (szDlg, IDC_WEB, szDefaultWeb);
+                               CtrlSetText (szDlg, IDC_INSTALL, szDefaultInstall);
+
+                SdGeneralInit( szDlg, hwndDlg, STYLE_NORMAL, szSdProduct );
+                       
+                //This function sets the caption for old style dialogs or
+                //sets the text in the top banner area of win2k style dialogs
+//                SdSetDlgTitle(szDlg, hwndDlg, szTitle); //Version 6.0 only
+
+           case OK:
+                nId    = NEXT;
+                bDone  = TRUE;
+
+           case BACK:
+                nId    = BACK;
+                bDone  = TRUE;
+
+           case DLG_ERR:
+                SdError( -1, "DLG_CELLSERVDB" );
+                nId    = -1;
+                bDone  = TRUE;
+
+           case DLG_CLOSE:
+                SdCloseDlg( hwndDlg, nId, bDone );
+
+                  case IDC_BROWSE:
+                               szResult=szDefaultBrowse;
+                               szTitle="Select file to be used for CellServDB";
+                               nResult=BrowseFile(hwndDlg,szTitle,szResult,256);
+                               CtrlSetText (szDlg, IDC_BROWSEFILE, szResult);
+                               szDefaultBrowse=szResult;
+                       
+                  case IDC_CHECK_BROWSEFILE:
+                               hwndItem = GetDlgItem( hwndDlg, IDC_BROWSEFILE );
+                               EnableWindow( hwndItem, TRUE);
+                               hwndItem = GetDlgItem( hwndDlg, IDC_BROWSE );
+                               EnableWindow( hwndItem, TRUE);
+                CtrlSetState (szDlg, DefaultItem,BUTTON_UNCHECKED);
+                CtrlSetState (szDlg, nId,BUTTON_CHECKED);
+                               switch (DefaultItem)
+                               case IDC_CHECK_WEB:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_WEB );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_PREVIOUSFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_PREVIOUSFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_INSTALL:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_INSTALL);
+                                       EnableWindow( hwndItem, FALSE);
+                               default:
+                                       ;
+                               endswitch;
+                               DefaultItem=nId;
+                  case IDC_CHECK_INSTALL:
+                               hwndItem = GetDlgItem( hwndDlg, IDC_INSTALL );
+                               EnableWindow( hwndItem, TRUE);
+                CtrlSetState (szDlg, DefaultItem,BUTTON_UNCHECKED);
+                CtrlSetState (szDlg, nId,BUTTON_CHECKED);
+                               switch (DefaultItem)
+                               case IDC_CHECK_BROWSEFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSE );
+                                       EnableWindow( hwndItem, FALSE);
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSEFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_WEB:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_WEB );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_PREVIOUSFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_PREVIOUSFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               default:
+                                       ;
+                               endswitch;
+                               DefaultItem=nId;
+                  case IDC_CHECK_WEB:
+                               hwndItem = GetDlgItem( hwndDlg, IDC_WEB );
+                               EnableWindow( hwndItem, TRUE);
+                CtrlSetState (szDlg, DefaultItem,BUTTON_UNCHECKED);
+                CtrlSetState (szDlg, nId,BUTTON_CHECKED);
+                               switch (DefaultItem)
+                               case IDC_CHECK_BROWSEFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSE );
+                                       EnableWindow( hwndItem, FALSE);
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSEFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_INSTALL:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_INSTALL);
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_PREVIOUSFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_PREVIOUSFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               default:
+                                       ;
+                               endswitch;
+                               DefaultItem=nId;
+                  case IDC_CHECK_PREVIOUSFILE:
+                               hwndItem = GetDlgItem( hwndDlg, IDC_PREVIOUSFILE );
+                               EnableWindow( hwndItem, TRUE);
+                CtrlSetState (szDlg, DefaultItem,BUTTON_UNCHECKED);
+                CtrlSetState (szDlg, nId,BUTTON_CHECKED);
+                               switch (DefaultItem)
+                               case IDC_CHECK_BROWSEFILE:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSE );
+                                       EnableWindow( hwndItem, FALSE);
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_BROWSEFILE );
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_INSTALL:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_INSTALL);
+                                       EnableWindow( hwndItem, FALSE);
+                               case IDC_CHECK_WEB:
+                                       hwndItem = GetDlgItem( hwndDlg, IDC_WEB );
+                                       EnableWindow( hwndItem, FALSE);
+                               default:
+                                       ;
+                               endswitch;
+                               DefaultItem=nId;
+           default:
+                // check standard handling
+                 if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
+                    bDone = TRUE;
+                endif;
+           endswitch;
+
+        endwhile;
+
+               CtrlGetText (szDlg, IDC_BROWSEFILE, szDefaultBrowse);
+               CtrlGetText (szDlg, IDC_WEB, szDefaultWeb);
+        if (nId != NEXT) then
+                       return nId;
+               endif;
+               if InstallCellServDB(DefaultItem,szDefaultWeb,szDefaultBrowse)==FALSE then
+                       goto doagain;
+               endif;
+        EndDialog( szDlg );
+        ReleaseDialog( szDlg );
+               VarRestore(SRCTARGETDIR);
+               Enable(LOGGING);
+        SdUnInit( );
+        // record data produced by this dialog
+               SilentSetCellServDB(szDlg,1,nId,DefaultItem,szDefaultWeb,szDefaultBrowse);
+        return nId;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//   Function Name: Template
+//
+//     Description: This dialog will show a dialog template which can be
+//                  used for creating any user-defined dialog with the
+//                  Windows 95 look and feel.
+//        Comments:
+//
+////////////////////////////////////////////////////////////////////////////////
+
+prototype BOOL GetUser(BYREF STRING);
+
+function GetUser(sUser)
+       NUMBER nResult;
+begin
+       sUser="                                                                 ";
+       nResult=GetUserLogon(sUser);
+       if (nResult!=1) then
+               sUser="";
+       endif;
+       return (nResult==1);
+end;
+
+
+prototype BOOL SetDriveMaps(STRING,STRING,STRING,STRING,STRING);
+function SetDriveMaps(szPath,szRootDrive,szRootPath,szHomeDrive,szHomePath)
+HWND   handle;
+begin
+       VarSave(SRCTARGETDIR);
+       TARGETDIR=WINDIR;
+       DeleteFile("afsdsbmt.ini");
+       VarRestore(SRCTARGETDIR);
+    CreateFile(handle, szPath, "afsdsbmt.ini");
+    WriteLine(handle, "[AFS Submounts]");
+       if (StrLength(szRootDrive)==2) then
+               WriteLine(handle, "all="+szRootPath);
+       endif;
+    if (StrLength(szHomeDrive)==2) then
+               WriteLine(handle, "home=" + szHomePath);
+       endif;
+       WriteLine(handle, "[AFS Mappings]");
+       if (StrLength(szRootDrive)>0) then
+               WriteLine(handle, szRootDrive+"="+szRootPath);
+    endif;
+       if (StrLength(szHomeDrive)>0) then
+               WriteLine(handle, szHomeDrive+"="+szHomePath);
+    endif;
+       CloseFile(handle);
+end;
+
+// Return TRUE if silent mode active
+prototype BOOL SilentSetHomeRoot(STRING,NUMBER,NUMBER,BYREF STRING,BYREF STRING,BYREF STRING,BYREF STRING);
+function SilentSetHomeRoot(szDlg,option,nResult,szRootDrive,szRootPath,szHomeDrive,szHomePath)
+STRING svSection,szTemp,szTPath,szTShare,szTDrive,szLogname;
+NUMBER nTemp,nCount,I;
+HWND   handle;
+begin
+       Logitn("SilentSetHomeRoot option=%i",option);
+       switch (option)
+       case 0:         //READ function
+               if (MODE!=SILENTMODE) then
+                       return FALSE;
+               endif;                  // this section is a little more complicated, allowing installation of n mappings
+               SdMakeName( svSection, szDlg, "", nvSection );
+               Logit("SdMakeName="+svSection);
+        SilentReadData( svSection, "Result", DATA_NUMBER,szTemp,nResult);
+               Logitn("nResult=%i",nResult);
+        if (nResult!=NEXT) then
+               return TRUE;
+        endif;
+        Logit("Do count");
+               SilentReadData( svSection, "Count", DATA_NUMBER, szTemp,nCount);
+               Logitn("nCount=%i",nCount);
+               if nCount==0 then
+                       return TRUE;
+               endif;
+               VarSave(SRCTARGETDIR);
+               TARGETDIR=WINDIR;
+               DeleteFile("afsdsbmt.ini");
+               VarRestore(SRCTARGETDIR);
+           CreateFile(handle, WINDIR, "afsdsbmt.ini");
+       WriteLine(handle, "[AFS Submounts]");
+               for I=0 to nCount-1
+               Logitn("I=%i",I);               
+                       Sprintf(szTemp,"Path_%i",I);
+                       Logit("Path="+szTemp);                  
+               SilentReadData( svSection, szTemp, DATA_STRING, szTPath,nTemp);
+                       Logit("TPath="+szTPath);                
+               if (szTPath % "%LOGINNAME%") then
+                       //Replace loginname with actual loging name
+                               nTemp=StrFind(szTPath,"%LOGINNAME%");
+                               StrSub(szTemp,szTPath,nTemp+11,StrLength(szTPath));
+                               StrSub(szTPath,szTPath,0,nTemp);
+                           if (GetUser(szLogname)) then
+                                       szTPath=szTPath+szLogname+szTemp;
+                               endif;
+               endif;
+                       Sprintf(szTemp,"Share_%i",I);
+               SilentReadData( svSection, szTemp, DATA_STRING, szTShare,nTemp);
+                       WriteLine(handle, szTShare+"="+szTPath);
+               endfor;
+               WriteLine(handle, "[AFS Mappings]");
+               for I=0 to nCount-1
+                       Sprintf(szTemp,"Drive_%i",I);
+               SilentReadData( svSection, szTemp, DATA_STRING, szTDrive,nTemp);
+                       Sprintf(szTemp,"Path_%i",I);
+               SilentReadData( svSection, szTemp, DATA_STRING, szTPath,nTemp);
+               if (szTPath % "%LOGINNAME%") then
+                       //Replace loginname with actual loging name
+                               nTemp=StrFind(szTPath,"%LOGINNAME%");
+                               StrSub(szTemp,szTPath,nTemp+11,StrLength(szTPath));
+                               StrSub(szTPath,szTPath,0,nTemp);
+                           if (GetUser(szLogname)) then
+                                       szTPath=szTPath+szLogname+szTemp;
+                               endif;
+               endif;
+                       WriteLine(handle, szTDrive+"="+szTPath);
+               endfor;
+           CloseFile(handle);
+               nResult=NEXT;
+               return TRUE;
+       default:        //write
+               SdMakeName( svSection, szDlg, "", nvSection );
+               nCount=0;
+        SilentWriteData( svSection, "Result", DATA_NUMBER,szTemp, nResult );
+        if (StrLength(szRootDrive)==2) then
+                       Sprintf(szTemp,"Drive_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,szRootDrive, nTemp );//root drive
+                       Sprintf(szTemp,"Path_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,szRootPath, nTemp );//root drive
+                       Sprintf(szTemp,"Share_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,"all", nTemp );//root drive
+               nCount++;
+           endif;
+        if (StrLength(szHomeDrive)==2) then
+                       Sprintf(szTemp,"Drive_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,szHomeDrive, nTemp );//root drive
+                       Sprintf(szTemp,"Path_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,szHomePath, nTemp );//root drive
+                       Sprintf(szTemp,"Share_%i",nCount);
+               SilentWriteData( svSection,szTemp, DATA_STRING,"home", nTemp );//root drive
+               nCount++;
+        endif;
+        SilentWriteData( svSection, "Count", DATA_NUMBER,szTemp, nCount );     // only two can be defined through Dialog box
+               SetDriveMaps(WINDIR,szRootDrive,szRootPath,szHomeDrive,szHomePath);
+               return TRUE;            
+    endswitch;
+end;
+
+function SetHomeRoot( szTitle,szRootDrive,szRootPath,szHomeDrive,szHomePath )
+
+STRING  szDlg, szTemp,svSection;
+NUMBER  bDone, nId, nMessage, nTemp,AvailableDrives,nResult;
+INT     hwndDlg,hwndItem,hwndItem2;
+
+begin
+       szDlg = "DLG_DRIVEPATH";
+
+        // record data produced by this dialog
+               Logit("SetHomeRoot");
+               if SilentSetHomeRoot(szDlg,0,nResult,szRootDrive,szRootPath,szHomeDrive,szHomePath ) then
+                       return nResult;
+               endif;
+
+               GetDefaultDrive(AvailableDrives);
+         // ensure general initialization is complete
+        if (!bSdInit) then
+           SdInit();
+        endif;
+
+        if (EzDefineDialog( szDlg, "", "",
+                            DLG_DRIVEPATH ) = DLG_ERR) then
+           return -1;
+        endif;
+
+        // Loop in dialog until the user selects a standard button
+        bDone = FALSE;
+
+        while (!bDone)
+
+           nId = WaitOnDialog( szDlg );
+
+           switch(nId)
+
+           case DLG_INIT:
+                hwndDlg = CmdGetHwndDlg( szDlg );
+                // Initialize List Control
+                       nResult=CtrlSetList( szDlg, IDC_HOMEDRIVELIST, AvailableDrives );
+                   if (nResult != 0) then
+                      // Handle error from CtrlSetList.
+                      MessageBox ("Unable to create folder name list.", SEVERE);
+                      bDone = TRUE;
+                   endif;
+                               if (CtrlSetCurSel(szDlg,IDC_HOMEDRIVELIST,szHomeDrive)!=0) then
+                                       szHomeDrive="None:";
+                                       CtrlSetCurSel(szDlg,IDC_HOMEDRIVELIST,szHomeDrive);
+                               endif;
+
+                       nResult=CtrlSetList( szDlg, IDC_ROOTDRIVELIST, AvailableDrives );
+                   if (nResult != 0) then
+                      // Handle error from CtrlSetList.
+                      MessageBox ("Unable to create folder name list.", SEVERE);
+                      bDone = TRUE;
+                   endif;
+                               if (CtrlSetCurSel(szDlg,IDC_ROOTDRIVELIST,szRootDrive)!=0) then
+                                       szRootDrive="None:";
+                                       CtrlSetCurSel(szDlg,IDC_ROOTDRIVELIST,szRootDrive);
+                               endif;
+
+                       nResult=CtrlSetText( szDlg, IDC_ROOTPATH,szRootPath );
+                   if (nResult != 0) then
+                      MessageBox ("Unable to create szRootPath.", SEVERE);
+                      bDone = TRUE;
+                   endif;
+                       nResult=CtrlSetText( szDlg, IDC_HOMEPATH,szHomePath );
+                   if (nResult != 0) then
+                      MessageBox ("Unable to create szHomePath.", SEVERE);
+                      bDone = TRUE;
+                   endif;
+
+                CtrlSetState (szDlg, IDC_ENABLEHOME,BUTTON_CHECKED);
+                CtrlSetState (szDlg, IDC_ENABLEROOT,BUTTON_CHECKED);
+                SdGeneralInit( szDlg, hwndDlg, STYLE_NORMAL, szSdProduct );
+                       
+                //This function sets the caption for old style dialogs or
+                //sets the text in the top banner area of win2k style dialogs
+           case OK:
+                       if (szRootDrive!=szHomeDrive) then
+                       nId    = NEXT;
+                       bDone  = TRUE;
+                   else
+                       MessageBox("Home and Root drives cannot be the same",WARNING);
+                endif;
+
+           case BACK:
+                nId    = BACK;
+                bDone  = TRUE;
+
+           case DLG_ERR:
+                SdError( -1, "DLG_DRIVEPATH" );
+                nId    = -1;
+                bDone  = TRUE;
+
+           case DLG_CLOSE:
+                SdCloseDlg( hwndDlg, nId, bDone );
+
+                  case IDC_ENABLEROOT:
+                       
+                               hwndItem = GetDlgItem( hwndDlg, IDC_ROOTDRIVELIST );//get handle of control in custom dialog box
+                               hwndItem2 = GetDlgItem( hwndDlg, IDC_ROOTPATH );//get handle of control in custom dialog box
+                               if (CtrlGetState (szDlg, nId)==BUTTON_CHECKED) then
+                                       EnableWindow( hwndItem2, TRUE);
+                                       EnableWindow( hwndItem, TRUE);
+                               else
+                                       EnableWindow( hwndItem2, FALSE);
+                                       EnableWindow( hwndItem, FALSE);
+                               endif;
+                  case IDC_ENABLEHOME:
+                               hwndItem = GetDlgItem( hwndDlg, IDC_HOMEDRIVELIST );//get handle of control in custom dialog box
+                               hwndItem2 = GetDlgItem( hwndDlg, IDC_HOMEPATH );//get handle of control in custom dialog box
+                               if (CtrlGetState (szDlg, nId)==BUTTON_CHECKED) then
+                                       EnableWindow( hwndItem2, TRUE);
+                                       EnableWindow( hwndItem, TRUE);
+                               else
+                                       EnableWindow( hwndItem2, FALSE);
+                                       EnableWindow( hwndItem, FALSE);
+                               endif;
+
+           case IDC_HOMEDRIVELIST:
+                               ;
+           case IDC_ROOTDRIVELIST:
+                               ;
+           case IDC_HOMEPATH:
+                       CtrlGetText (szDlg, nId,szHomePath);
+
+           case IDC_ROOTPATH:
+                       CtrlGetText (szDlg, nId,szRootPath);
+
+           default:
+                // check standard handling
+                 if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
+                    bDone = TRUE;
+                endif;
+           endswitch;
+
+        endwhile;
+
+               CtrlGetCurSel (szDlg, nId, szRootDrive);
+               if (CtrlGetState (szDlg, IDC_ENABLEROOT)==BUTTON_UNCHECKED) then
+               szRootDrive="None:";
+               endif;
+               CtrlGetCurSel (szDlg, nId, szHomeDrive);
+               if (CtrlGetState (szDlg, IDC_ENABLEHOME)==BUTTON_UNCHECKED) then
+               szHomeDrive="None:";
+               endif;
+        EndDialog( szDlg );
+        ReleaseDialog( szDlg );
+
+        SdUnInit( );
+
+        // record data produced by this dialog
+        if (nId==NEXT) then
+                       SilentSetHomeRoot(szDlg,1,nId,szRootDrive,szRootPath,szHomeDrive,szHomePath );
+               endif;
+        ListDestroy (AvailableDrives);
+        return nId;
+
+end;
+
+
+// ---- script function prototypes -----
+
+
+    // your script function prototypes
+
+
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 //   MAIN PROGRAM
@@ -333,26 +1071,40 @@ end;
 //
 ///////////////////////////////////////////////////////////////////////////////
 program
+       Logit("Begin");
+       nvSection=0;
     Disable( BACKGROUND );
-
        if (UseDLL(SUPPORTDIR ^ SETUP_UTILS_DLL_PATH) < 0) then
         ShowError(@SETUPUTILS_NOT_FOUND, SEVERE);
         bInstallAborted = TRUE;
         goto end_install;
     endif;
-
-    SetupInstall();
-
+       Logit("UseDLL1");
+       ChangeDirectory (SUPPORTDIR);
+       if (UseDLL("GetWebDLL.dll") != 0) then
+               MessageBox ("DLL failed.\n\nCouldn't load"+SUPPORTDIR^"GetWebDLL.dll", INFORMATION);
+               abort;
+       endif;
+       Logit("UseDLL2");
+               
+       SetupInstall();
+       Logit("SetupInstall");
+       
     CheckRequirements();
-
-       ParseCommandLine();
+       Logit("CheckRequirements");
        
+       ParseCommandLine();
+       Logit("ParseCommandLine");
+               
        SetupAppInfo();
-
+       Logit("SetupAppInfo");
+       
        LocalizeComponents();
-
+       Logit("LocalizeComponents");
+       
        DetectInstalledComponents();
-
+       Logit("DetectInstalledComponents");
+       
        // Can't upgrade, downgrade, or reinstall the light client, so if it is
        // already installed, we must abort.  This is because on Win9x, we can't
        // move in-use files, and so we can't silently uninstall the light client,
@@ -395,6 +1147,14 @@ program
 
        // Install the Client
        if (bFullClientSel) then
+               RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
+               Enable(LOGGING);
+               if RegDBSetKeyValueEx ("SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters" 
+                       ,"SmbDeviceEnabled", REGDB_NUMBER, "0", 8) < 0 then
+                       MessageBox ("RegDBCreateKeyEx failed.", SEVERE);
+                   abort;
+               endif;
+
                pApp = &appFullClient;
                if (InstallApp(pApp) < 0) goto end_install;
        endif;
@@ -459,12 +1219,13 @@ program
 
        CreateStartMenuEntries();
 
-       if (bFullClientSel || bLightClientSel || bCcSel) then
-               CheckCopyCellServDB();
-       endif;
+//     if (bFullClientSel || bLightClientSel || bCcSel) then
+//             CheckCopyCellServDB();
+//     endif;
 
        end_install:
 
+       UnUseDLL(SUPPORTDIR^"GetWebDLL.dll");
        UnUseDLL(SUPPORTDIR ^ SETUP_UTILS_DLL_PATH);
 
     CleanUpInstall();
@@ -486,37 +1247,80 @@ endprogram
 //
 ///////////////////////////////////////////////////////////////////////////////
 function ShowDialogs()
-    NUMBER  nResult;
+    NUMBER  nResult,handle;
     STRING     szTargetLicense;
     STRING     szSourceLicense;
+       STRING sRootDrive,sHomeDrive,userID,rootPath,homePath;
+       NUMBER  DefaultItem;
+       STRING  szDefaultWeb,szDefaultBrowse,szDefaultInstall,szPreviousInstall;
+       STRING  szResult[256],svResult;
 begin
     Dlg_Start:
     // beginning of dialogs label
-
     Dlg_SdWelcome:
     nResult = DialogShowSdWelcome();
     if (nResult = BACK) goto Dlg_Start;
 
     Dlg_License:
-    szTargetLicense = DOCUMENTATION_LICENSE_PATH;
-    GetLicenseFilename (szSourceLicense);
-    Disable( DIALOGCACHE );
-    nResult = ShowLicense(szTargetLicense,szSourceLicense);
-    if (nResult = 0) then
-       abort;
-    endif;
-    Enable( DIALOGCACHE );
-
+//    szTargetLicense = DOCUMENTATION_LICENSE_PATH;
+//    GetLicenseFilename (szSourceLicense);
+//     Logit("ShowLicense");
+//     Disable( DIALOGCACHE );
+//     if (MODE!=SILENTMODE) then
+//         nResult = ShowLicense(szTargetLicense,szSourceLicense);
+//         if (nResult = 0) then
+//             abort;
+//         endif;
+//         Enable( DIALOGCACHE );
+//     endif;
+    if (nResult = BACK) goto Dlg_Start;
        Dlg_SdCompDlg:
        nResult = DialogShowSdAskComponentDialog();
+       Logit("DialogShowSdAskComponentDialog");
        if (nResult = BACK) goto Dlg_License;
 
     Dlg_SdSelectFolder:
     nResult = DialogShowSdSelectFolder();
-    if (nResult = BACK) goto Dlg_SdCompDlg;
-
-    return 0;
-
+       Logit("DialogShowSdSelectFolder");
+       if (nResult = BACK) goto Dlg_SdCompDlg;
+       if (bFullClientSel || bLightClientSel) then
+               szDefaultWeb=@CELLSERVDB_WEB;
+               szDefaultBrowse=TARGETDIR^"*";
+               szDefaultInstall=@CELLSERVDB_INSTALL;
+               szPreviousInstall=WINDIR^@CELLSERVDB_CONFIGNAME;
+           if (Is(FILE_EXISTS,szPreviousInstall)) then
+                       DefaultItem=IDC_CHECK_PREVIOUSFILE;
+               else
+                       DefaultItem=IDC_CHECK_INSTALL;
+               endif;
+               Dlg_SdSelectCellServDB:
+                       Logit("SetCellServDB-next");
+                       nResult =SetCellServDB("Select AFS Cell Data base (afsdcell.ini)"
+                       ,DefaultItem
+                       ,szPreviousInstall
+                       ,szDefaultWeb
+                       ,szDefaultBrowse
+                       ,szDefaultInstall);
+               Logit("SetCellServDB");
+           if (nResult=BACK) goto Dlg_SdSelectFolder;
+               if (Is(FILE_EXISTS, WINDIR^"afsdsbmt.ini")) then
+                       Logit("AskYesNo next");
+                       if (AskYesNo("Previous Drive Mapping Configuration already exist.\n\nPress Yes to keep previous configuration\nPress No to change previous configuration.",YES)=YES) then
+                               return 0;
+                       endif;
+               endif;
+               userID="                   ";
+           GetUser(userID);
+               sRootDrive="Z:";
+               sHomeDrive="U:";
+               rootPath="/";
+           homePath = "/afs/" + @CELLNAME_DEFAULT + "/u/" + userID;
+           nResult=SetHomeRoot( "Home and Root Drive Assignment\nThese drives will be mapped each time AFS is connected!",sRootDrive,rootPath,sHomeDrive,homePath );
+               Logit("SetHomeRoot");
+               if (nResult = BACK) goto Dlg_SdSelectCellServDB;
+       endif;
+       Logit("ShowDialogs-done");
+       return 0;
 end;
 
 
@@ -1549,7 +2353,7 @@ function DialogShowSdWelcome()
 begin
 
     szTitle = "";
-    szMsg   = "";
+    szMsg   = @WELCOME_MESSAGE;
     nResult = SdWelcome( szTitle, szMsg );
 
     return nResult;
@@ -1799,12 +2603,15 @@ begin
                        ComponentSetData(MEDIA, SERVER_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
                        ComponentSetData(MEDIA, CC_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
                        ComponentSetData(MEDIA, DOCS_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
-               
-                       ComponentSelectItem(MEDIA, SERVER_COMP_NAME, FALSE);
-                       ComponentSelectItem(MEDIA, CC_COMP_NAME, FALSE);
                        ComponentSelectItem(MEDIA, DOCS_COMP_NAME, FALSE);
+                       endif;
+               ComponentSelectItem(MEDIA, SERVER_COMP_NAME, FALSE);
+               if (@CELLNAME_DEFAULT % ".") then
+                       ComponentSelectItem(MEDIA, CC_COMP_NAME, FALSE);
+               else
+                       ComponentSelectItem(MEDIA, CC_COMP_NAME, TRUE);
                endif;
-       else
+else
                ComponentSetData(MEDIA, CLIENT_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
                ComponentSetData(MEDIA, SERVER_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
                ComponentSetData(MEDIA, CC_COMP_NAME, COMPONENT_FIELD_VISIBLE, FALSE, "");
@@ -2652,6 +3459,31 @@ begin
 end;
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 // Function: CreateStartMenuEntries
@@ -2738,8 +3570,3 @@ end;
 
 // --- include script file section ---
 #include "sddialog.rul"
-
-
-
-
-
index d0f8d46..fe95e91 100644 (file)
@@ -5,8 +5,6 @@
 #      License.  For details, see the LICENSE file in the top-level source
 #      directory or online at http://www.openafs.org/dl/license10.html
 
-
-
 !INCLUDE ..\..\..\config\NTMakefile.$(SYS_NAME)
 !INCLUDE ..\..\..\config\NTMakefile.version
 OUTDIR = $(DESTDIR)\WinInstall
@@ -16,7 +14,6 @@ OUTDIR = $(DESTDIR)\WinInstall
 COMPONENTS = \
        INSTALL.BAT \
        afsd.pif \
-       cellservdb \
        readme.RTF \
        license.txt \
        templet.reg \
@@ -37,8 +34,8 @@ COMPONENTS = \
        $(DESTDIR)\lib\win95\pthread.dll \
        $(DESTDIR)\lib\afsrpc.dll
                
-$(COMPONENTS)::\r
-       $(DESTDIR)\bin\util_cr.exe ~ $@ "Missing $@"
+$(COMPONENTS)::
+       $(DESTDIR)\bin\util_cr.exe ~ $@
        $(COPY) $@ $(DESTDIR)\WinInstall\.
 
 !IF (EXIST(ISBUILD.MAK))
@@ -57,6 +54,6 @@ clean ::
     $(DEL) $(OUTDIR)\DiskIm~1\WebInstall\*
 
 prep :
-       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\sock.vxd" "SOCK.VXD is missing from $(DESTDIR)\WinInstall\."
-       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\MMAP.vxd" "MMAP.VXD is missing from $(DESTDIR)\WinInstall\."
-       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\AFSD.EXE" "AFSD.EXE is missing from $(DESTDIR)\WinInstall\."
+       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\sock.vxd"
+       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\MMAP.vxd"
+       $(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\AFSD.EXE"
diff --git a/src/WINNT/install/Win9x/setup.iss b/src/WINNT/install/Win9x/setup.iss
new file mode 100644 (file)
index 0000000..544d9fe
--- /dev/null
@@ -0,0 +1,22 @@
+[InstallShield Silent]
+Version=v6.00.000
+File=Response File
+
+[File Transfer]
+OverwrittenReadOnly=NoToAll
+
+[{EA711160-C786-11D3-A374-00105A6BCA4C}-DlgOrder]
+Dlg0={EA711160-C786-11D3-A374-00105A6BCA4C}-SdWelcome-0
+Count=3
+Dlg1={EA711160-C786-11D3-A374-00105A6BCA4C}-SdAskDestPath-0
+Dlg2={EA711160-C786-11D3-A374-00105A6BCA4C}-SprintfBox-0
+
+[{EA711160-C786-11D3-A374-00105A6BCA4C}-SdWelcome-0]
+Result=1
+
+[{EA711160-C786-11D3-A374-00105A6BCA4C}-SdAskDestPath-0]
+szDir=C:\afs cli
+Result=1
+
+[{EA711160-C786-11D3-A374-00105A6BCA4C}-SprintfBox-0]
+Result=6
index 2853f48..4d39b66 100644 (file)
@@ -164,14 +164,27 @@ BOOL CAfs::Create(CString &msg,CString sCompName,PROCESS_INFORMATION &procInfo)
                      /*DETACHED_PROCESS |*/ CREATE_NEW_CONSOLE | HIGH_PRIORITY_CLASS /*NORMAL_PRIORITY_CLASS*/,
                      NULL, NULL, &m_startUpInfo, &procInfo);
 
-       LOG("AFSD Creation done - wait for notification");
        if (!rc) {
-               msg.Format("Error creating AFS Client Console process, Status=0x%0x", GetLastError());
+               LPVOID lpMsgBuf;
+               FormatMessage( 
+                       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+                       FORMAT_MESSAGE_FROM_SYSTEM | 
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       GetLastError(),
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                       (LPTSTR) &lpMsgBuf,
+                       0,
+                       NULL 
+               );
+               msg.Format("Error creating AFS Client Console process, Status=%s.",lpMsgBuf);
                return FALSE;
        }
+       LOG("AFSD Creation done - wait for notification");
        WPARAM wp;
        CWINAFSLOADAPP->WaitForEvent(logintime*1000,&wp,&msg);
        switch (wp)
+
        {
        case AFS_EXITCODE_NORMAL:
                // extract machine name for logon
@@ -360,6 +373,7 @@ BOOL CAfs::StartExployer(CString &msg,const char *udrive)
        int code;
        WIN32_FIND_DATA FileData;
        CString dir;
+       if ((udrive==NULL) || (strlen(udrive)==0)) return TRUE;
        dir.Format("%s\\*",udrive);
        HANDLE hFile= FindFirstFile(
                dir,               // file name
index 97171ae..7239359 100644 (file)
@@ -118,10 +118,6 @@ BOOL CChange::OnInitDialog()
                szDrive[3]='*';
                m_cDrive.SetCurSel(m_cDrive.FindString(0,szDrive));
        }
-       if (stricmp(m_sDescription,"all")) return TRUE;
-       m_cPath.ModifyStyle(0,WS_DISABLED);
-       m_cShare.ModifyStyle(0,WS_DISABLED);
-       m_cAuto.ModifyStyle(0,WS_DISABLED);
        return TRUE;  // return TRUE unless you set the focus to a control
                      // EXCEPTION: OCX Property Pages should return FALSE
 }
@@ -159,8 +155,6 @@ BOOL CChange::IsValidSubmountName (LPCTSTR pszSubmount)
 {
    if (!*pszSubmount)
       return FALSE;
-   if (stricmp(pszSubmount,"all")==0)
-          return FALSE;                                        //disallow adding a share name of "all"
    for ( ; *pszSubmount; ++pszSubmount)
       {
       if (!isprint(*pszSubmount))
index 4f4c140..8cc9dce 100644 (file)
@@ -48,7 +48,8 @@ RSC=rc.exe
 HLPDIR= .\HELP
 
 prep : 
-       $(DESTDIR)\bin\util_cr.exe ~ "$(MSSDK)\Include\windows.h" "MSSDK must point to SDK include headers "
+       $(DESTDIR)\bin\util_cr.exe ~ "$(MSSDK)\Include\windows.h" "Enviornment variable MSSDK must point to SDK" 
+
 
 !IF  "$(AFSDEV_BUILDTYPE)" == "FREE"
 
@@ -76,7 +77,7 @@ CPP_PROJ=/nologo /MD /W3 /GX /O2 \
        /D "NDEBUG" /D "_MFC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_WINNT" /D "_AFXDLL" /D "ENCRIPT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
 
 MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\WinAfsLoad.res" $(AFSD_INC_MFC) /d "NDEBUG" /d "_AFXDLL" 
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\WinAfsLoad.res" $(AFSD_INC_MFC) /d "AFSPRODUCT_VERSION=\"$(AFSPRODUCT_VERSION)\"" /d "NDEBUG" /d "_AFXDLL" 
 BSC32=bscmake.exe
 BSC32_FLAGS=/nologo /o"$(INTDIR)\WinAfsLoad.bsc" 
 BSC32_SBRS= \
@@ -137,7 +138,7 @@ CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od \
        /D "_DEBUG" /D "WIN32_LEAN_AND_MEAN" /D _WIN32_IE=0x0400 /D "TESTBUTTONS" /D "_MFC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_WINNT" /D "_AFXDLL" /D "ENCRIPT" /D "NOKNOK" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
 
 MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\WinAfsLoad.res" $(AFSD_INC_MFC) /d "_DEBUG" /d "_AFXDLL" 
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\WinAfsLoad.res" $(AFSD_INC_MFC) /d "AFSPRODUCT_VERSION=\"$(AFSPRODUCT_VERSION)\"" /d "_DEBUG" /d "_AFXDLL" 
 BSC32=bscmake.exe
 BSC32_FLAGS=/nologo /o"$(INTDIR)\WinAfsLoad.bsc" 
 BSC32_SBRS= \
index 9c2eec3..44d4181 100644 (file)
@@ -154,6 +154,7 @@ BOOL CWinAfsLoadApp::InitInstance()
        // show userid: password: connect
        CharLower(m_lpCmdLine);
        m_bShowAfs=(strstr(m_lpCmdLine,"show")!=NULL);
+       m_bConnect=(strstr(m_lpCmdLine,"connect")!=NULL);
        if (m_bLogWindow)
                ShowLog(TRUE);
        if (m_bLog)
@@ -170,7 +171,7 @@ BOOL CWinAfsLoadApp::InitInstance()
        {
                cPassWord=(strstr(str,":"));
        }
-//     BOOL bConnect=(strstr(m_lpCmdLine,"connect")!=NULL);
+       m_bNoID=(strstr(m_lpCmdLine,"noid")!=NULL);
 
        if (m_hAfsLoadFinish)   // SOME REASON THE WINDOW WAS NOT SHUT DOWN, SO LETES KILL IT
        {
index 1755af6..b6cdece 100644 (file)
@@ -83,9 +83,7 @@ public:
        UINT m_uEvent;
        UINT m_uNotifyMessage;
        WPARAM m_wParam;
-#if NOKNOK
-       BOOL m_bNokNok;
-#endif
+       BOOL m_bNoID;
 
        //{{AFX_MSG(CWinAfsLoadApp)
        //}}AFX_MSG
index 2260aea..b178468 100644 (file)
@@ -1,19 +1,16 @@
-//generated resource script.
+//Microsoft Developer Studio generated resource script.
 //
-/* Copyright 2000, International Business Machines Corporation and others.
-       All Rights Reserved.
-       This software has been released under the terms of the IBM Public
-       License.  For details, see the LICENSE file in the top-level source
-       directory or online at http://www.openafs.org/dl/license10.html
-*/
-
 #include "resource.h"
 
 // Generated Help ID header file
 #define APSTUDIO_HIDDEN_SYMBOLS
+//#include "resource.hm"
 #undef APSTUDIO_HIDDEN_SYMBOLS
+
 #define APSTUDIO_READONLY_SYMBOLS
+// Microsoft Developer Studio generated Help ID include file.
+// Used by WinAfsLoad.rc
+//
 #define HIDC_STATIC                     0x80fcffff    // IDD_SETTINGS
 
 /////////////////////////////////////////////////////////////////////////////
@@ -63,6 +60,7 @@ BEGIN
     "LANGUAGE 9, 1\r\n"
     "#pragma code_page(1252)\r\n"
     "#endif //_WIN32\r\n"
+    "#include ""res\\WinAfsLoad.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
     "#include ""afxres.rc""         // Standard components\r\n"
     "#endif\r\n"
     "\0"
@@ -265,7 +263,7 @@ END
 
 VS_VERSION_INFO VERSIONINFO
  FILEVERSION 1,0,0,1
- PRODUCTVERSION 2,0,0,0
+ PRODUCTVERSION 1,0,4,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -290,7 +288,7 @@ BEGIN
             VALUE "OriginalFilename", "WinAfsLoad.EXE\0"
             VALUE "PrivateBuild", "\0"
             VALUE "ProductName", "WinAfsLoad Application\0"
-            VALUE "ProductVersion", "2, 0, 0, 0\0"
+            VALUE "ProductVersion", AFSPRODUCT_VERSION,"\0"
             VALUE "SpecialBuild", "\0"
         END
     END
@@ -493,6 +491,10 @@ BEGIN
     IDH_ADD                 "HELP ADD"
     IDH_CHANGE              "Help Change"
     IDH_MAIN                "Help Main"
+END
+
+STRINGTABLE DISCARDABLE 
+BEGIN
     IDM_CLEAR               "Clear Window"
 END
 
@@ -532,6 +534,7 @@ LANGUAGE 9, 1
 #pragma code_page(1252)
 #endif //_WIN32
 #include "afxres.rc"         // Standard components
+//#include "res\WinAfsLoad.rc2"  // non-Microsoft Visual C++ edited resources
 #endif
 
 /////////////////////////////////////////////////////////////////////////////
index 45c7cf4..16e583c 100644 (file)
@@ -333,6 +333,7 @@ BOOL CWinAfsLoadDlg::OnInitDialog()
        LOG("ADVAPI32 %d.%d",(vernum>>16) & 0xff,vernum & 0xff);
        m_pEncript = (CEncript *)new CEncript(this);
        
+
        // initiallze AFS and setup Progress display
        if (!m_cAfs.Init(this,msg))
                HandleError(msg);
@@ -341,7 +342,11 @@ BOOL CWinAfsLoadDlg::OnInitDialog()
        EnableToolTips(TRUE);
        
        m_bServiceIsActive=FALSE;
-       SetWindowText(AFSTITLE);
+       // Obtain Version String
+       CRegkey key(HKEY_LOCAL_MACHINE,"Software\\Open AFS\\AFS Control Center","CurrentVersion");
+       key.GetString("VersionString",m_VersionString,128);
+       msg.Format("%s %s",AFSTITLE,m_VersionString);
+       SetWindowText(msg);
 
        UpdateData(TRUE);
 
@@ -349,7 +354,6 @@ BOOL CWinAfsLoadDlg::OnInitDialog()
        m_sComputername=compName;
        m_sMountDisplay.Format("Connected Drives on Computer:%s",compName);
        m_sUsername="";
-       m_bHomepath=FALSE;
        CRect rect;
        GetWindowRect(&m_OriginalRect);
        m_cOptionLine.GetWindowRect(&rect);
@@ -366,28 +370,41 @@ BOOL CWinAfsLoadDlg::OnInitDialog()
        }
        CHAR pLoginName[UNLEN + 1];
        size=UNLEN;
-       if (GetUserName(pLoginName,&size))
-               m_sLoginName=pLoginName;
-       else
-               m_sLoginName="Bozo";
-       CString sUser,sPass;
-       RegPassword(sUser,sPass,TRUE);
-       if ((m_sUsername=="") || (m_sLoginName.IsEmpty()))
-       {
-               m_sUsername=sUser;
-       }
-       if ((m_sPassword=="") || (m_sPassword.IsEmpty()))
+       if (CWINAFSLOADAPP->m_bNoID)
        {
-               m_sPassword=sPass;
+               CWnd *w=GetDlgItem(IDC_USERNAME);
+               w->EnableWindow(FALSE);
+               w=GetDlgItem(IDC_PASSWORD);
+               w->EnableWindow(FALSE);
+               w=GetDlgItem(IDC_SAVEUSERNAME);
+               w->EnableWindow(FALSE);
+       } else {
+               if (GetUserName(pLoginName,&size))
+               {
+                       m_sLoginName=pLoginName;
+               } else
+                       m_sLoginName="Bozo";
+               CString sUser,sPass;
+               RegPassword(sUser,sPass,TRUE);
+               if (m_sUsername=="")
+               {
+                       m_sUsername=sUser;
+               }
+               if ((m_sUsername=="") && (m_sLoginName!="Bozo"))
+               {
+                       m_sUsername=m_sLoginName;
+               }
+               if ((m_sPassword=="") || (m_sPassword.IsEmpty()))
+               {
+                       m_sPassword=sPass;
+               }
+               if (m_sPassword.IsEmpty())
+               {
+                       m_cSaveUsername.SetCheck(FALSE);
+                       RegLastUser(m_sUsername,TRUE);
+               } else
+                       m_cSaveUsername.SetCheck(TRUE);
        }
-
-       if (m_sPassword.IsEmpty())
-       {
-               m_cSaveUsername.SetCheck(FALSE);
-               RegLastUser(m_sUsername,TRUE);
-       } else
-               m_cSaveUsername.SetCheck(TRUE);
-       
        // Initialize mount control list
 
        m_pImagelist = new CImageList();
@@ -621,13 +638,30 @@ void CWinAfsLoadDlg::OnSysCommand(UINT nID, LPARAM lParam)
                        BYTE *lpData=(BYTE *)new BYTE[rc];
                        if (GetFileVersionInfo(wdir,wHandle,rc,lpData))
                        {
-                               VS_FIXEDFILEINFO *pver;
                                UINT len;
-                               if (VerQueryValue(lpData,"\\",(PVOID *)&pver,&len))
-                               {
-                                       dlgAbout.m_sVersion.Format("WinAFSload Version %d.%d.%d",(pver->dwProductVersionMS>>16) &0xff ,pver->dwProductVersionMS & 0xff,(pver->dwProductVersionLS>>16) &0xff );
+                               struct TRANSLATION {
+                                       WORD langID;         // language ID
+                                       WORD charset;        // character set (code page)
+                               };
+                               CString msg;
+                               TRANSLATION mTrans,* pTrans;
+                               if (VerQueryValue(lpData,
+                                       "\\VarFileInfo\\Translation", (PVOID *)&pTrans, &len) && len >= 4) {
+                                       mTrans = *pTrans;
+                                       TRACE("code page = %d\n", mTrans.charset);
+                                       }
+                               LPCTSTR pVal;
+                               UINT iLenVal;
+                               CString query;
+                               query.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),
+                                       mTrans.langID,
+                                       mTrans.charset,
+                                       _T("ProductVersion"));
+                               if (VerQueryValue(lpData, (LPTSTR)(LPCTSTR)query,
+                                       (LPVOID*)&pVal, &iLenVal)) {
+//                                     dlgAbout.m_sVersion.Format("WinAFSload Version %s",pVal);
                                }
-                       }
+                       }
                        delete lpData;
                }
                dlgAbout.DoModal();
@@ -721,17 +755,20 @@ void CWinAfsLoadDlg::OnConnect()
                return;
        }
        CCancel cancel(m_bConnect,FALSE);               //clear m_bConnect when connection done
-       if (m_sUsername.IsEmpty() || m_sPassword.IsEmpty()) 
+       if (                                                                    // if username is present then must have password
+               IsGetTokens() 
+               && (m_sPassword=="")
+               ) 
        {
-               HandleError("You must enter a username and password!");
-               if (m_sUsername.IsEmpty()) m_cUsername.SetFocus();
-               else m_cPassword.SetFocus();
+               HandleError("You must enter a password!");
+               m_cPassword.SetFocus();
                return;
        }
        CProgress progress(this,7);
        progress.Next();
        if (!m_cAfs.Create(msg,m_sComputername,m_procInfo)) 
        {
+               progress.Finish();
                HandleError(msg);
                m_procInfo.hThread=0;
                return;
@@ -739,12 +776,13 @@ void CWinAfsLoadDlg::OnConnect()
        // CWINAFSLOADAPP->m_sMsg contains the host name used for login
        LOG("AFS Client Console started successfully [%s].",(const char *)m_sComputername);
        CString sDrive;
-       // lets find the All
+
        CString sKey;
+       int iMounted=-1;
        for (int iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
        {
                sKey = m_cMountlist.GetItemText(iItem,COLSHARE);
-               if (stricmp(sKey,"all")!=0) continue;
+               if (stricmp(sKey,"all")!=0) continue;           // lets find the All first
                CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
                if (sAuto!="*")
                        continue;
@@ -754,34 +792,70 @@ void CWinAfsLoadDlg::OnConnect()
                {
                        m_cMountlist.SetCheck(iItem,TRUE);
                        AddMenu(sDrive,sKey);
+                       iMounted=iItem;
                } else {
                        CString msg2;
                        m_cAfs.Shutdown(msg2);
                        m_procInfo.hThread=0;
                        msg2.Format("Connect can't continue: %s",msg);
+                       progress.Finish();
                        HandleError(msg2);
                        return;
                }
                break;
        }
-       if (stricmp(sKey,"all")!=0){
-               m_cAfs.Shutdown(msg);
-               m_procInfo.hThread=0;
-               msg="Connect can't continue, 'all' path not defined";
-               HandleError(msg);
-               return;
+       if (iMounted<0){
+               // Scan for any other connection
+               for (int iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
+               {
+                       CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
+                       if (sAuto!="*")
+                               continue;
+                       sDrive=m_cMountlist.GetItemText(iItem,COLDRIVE);
+                       LOG("Connect %s %s",sDrive,sKey);
+                       if (m_cAfs.Mount(msg,sDrive,sKey))
+                       {
+                               m_cMountlist.SetCheck(iItem,TRUE);
+                               AddMenu(sDrive,sKey);
+                               iMounted=iItem;
+                       } else {
+                               CString msg2;
+                               m_cAfs.Shutdown(msg2);
+                               m_procInfo.hThread=0;
+                               msg2.Format("Connect can't continue: %s",msg);
+                               progress.Finish();
+                               HandleError(msg2);
+                               return;
+                       }
+                       break;
+               }
        }
        progress.Next();
-       if (!m_cAfs.Authencate(msg,m_sUsername,m_sPassword))
+       if  (IsGetTokens())
        {
-               CString msg2;
-               m_cAfs.Dismount(msg2,sDrive,TRUE);
-               m_cMountlist.SetCheck(iItem,FALSE);
-               RemoveMenu(sDrive);
-               m_cAfs.Shutdown(msg2);
-               m_procInfo.hThread=0;
-               HandleError(msg);
-               return;
+#if 0
+               if (iMounted<0)         //have we mounted at least one drive
+               {
+                       m_cAfs.Shutdown(msg);
+                       m_procInfo.hThread=0;
+                       msg="Connect can't continue, mountable drive not defined";
+                       progress.Finish();
+                       HandleError(msg);
+                       return;
+               }
+#endif
+               if (!m_cAfs.Authencate(msg,m_sUsername,m_sPassword))
+               {
+                       CString msg2;
+                       m_cAfs.Dismount(msg2,sDrive,TRUE);
+                       m_cMountlist.SetCheck(iItem,FALSE);
+                       RemoveMenu(sDrive);
+                       m_cAfs.Shutdown(msg2);
+                       m_procInfo.hThread=0;
+                       progress.Finish();
+                       HandleError(msg);
+                       return;
+               }
        }
        progress.Next();        
        // scan through the list for any additional items to connect
@@ -789,7 +863,7 @@ void CWinAfsLoadDlg::OnConnect()
        for (iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
        {
                CString sKey(m_cMountlist.GetItemText(iItem,COLSHARE));
-               if (stricmp(sKey,"all")==0) continue;
+               if (iItem==iMounted) continue;
                CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
                if (sAuto!="*")
                        continue;
@@ -1028,8 +1102,15 @@ void CWinAfsLoadDlg::UpdateConnect()
                m_cConnect.Invalidate();
                m_cCancel.SetWindowText("Cancel");
                m_cCancel.Invalidate();
-               m_cAuthenicate.ModifyStyle(WS_DISABLED,0);
-               m_cAuthenicate.Invalidate();
+               if (!CWINAFSLOADAPP->m_bNoID)
+               {       
+                       m_cAuthenicate.ModifyStyle(WS_DISABLED,0);
+                       if (IsGetTokens())
+                               m_cAuthenicate.SetWindowText("ReAuthenicate");
+                        else   //tokens are not gotten; allow authenication
+                               m_cAuthenicate.SetWindowText("Authenicate");
+                       m_cAuthenicate.Invalidate();
+               }
                m_trayIcon.SetConnectState(0);
                return;
        }
@@ -1073,7 +1154,8 @@ void CWinAfsLoadDlg::OnTrayButton4()
        OnSysCommand(IDM_EXPLORERAFS+64, 0);
 }
 
-#define MAXKEY (SHARENAMESIZE+1)*MAXSHARES
+#define MAXDRIVESIZE (SHARENAMESIZE+5)*MAXSHARES
+
 BOOL CWinAfsLoadDlg::ProfileData(BOOL put)
 {
        CString dINI;
@@ -1106,7 +1188,6 @@ BOOL CWinAfsLoadDlg::ProfileData(BOOL put)
                                dptr=dblock+dused;
                                wsprintf(dptr,"%s=%s%s",sKey,sAuto,sDrive);
                                dused+=len;
-                               if (stricmp(sKey,"all")==0) continue;   //skip 'all' output
                                len=sKey.GetLength()+sPath.GetLength()+2;
                                if (sused+len>=scur)
                                        sblock=(char *)realloc(sblock,(scur+=BLOCKSIZE));
@@ -1121,91 +1202,41 @@ BOOL CWinAfsLoadDlg::ProfileData(BOOL put)
                WritePrivateProfileSection("AFS Drivemounts",dblock,dINI);
                delete dblock;
                delete sblock;
-       } else {
-               char sKey[MAXKEY+2];
+       } else {        //get
+               char sShare[SHARENAMESIZE+1];
                CHAR sPath[MAX_PATH+1];
+               CHAR sDriveMount[MAXDRIVESIZE+2];
                CHAR sDrive[DRIVESIZE+1];
                CHAR sAuto[AUTOSIZE+1];
                strcpy(sAuto," ");
-               int len;
                CString path;
-               int keylen=GetPrivateProfileString("AFS Submounts", NULL, "", sKey, MAXKEY,tINI);
-               PCHAR pkey=sKey;
-               if (keylen>=MAXKEY)
-               {
-                       CString msg;
-                       msg.Format("Profile String Error - Too many entries (%d)",MAXSHARES);
-                       HandleError(msg,TRUE);
-                       return FALSE;
-               }
-               // lets scan for all and home first, we want to place them 
+               // lets scan for all and home first, we want to place them first
                //mode: 0=look for all, 1=look for home, 2=finish the rest              
                for(int mode=0;mode<3;mode++)
                {
-                       while (keylen>1)
+                       int drivelen=GetPrivateProfileString("AFS Drivemounts", NULL, "", sDriveMount, MAXDRIVESIZE,dINI);
+                       if (drivelen>=MAXDRIVESIZE)
                        {
-                               switch (mode)
+                               CString msg;
+                               msg.Format("Profile String Error - Too many entries (%d)",MAXSHARES);
+                               HandleError(msg,TRUE);
+                               return FALSE;
+                       }
+                       PCHAR pDrivekey=sDriveMount;
+                       while (drivelen>1)
+                       {
+                               if ((strlen(pDrivekey)==0) || (strlen(pDrivekey)>SHARENAMESIZE))
                                {
-                               case 0: //we skip looking for all
-                                       break;
-                               case 1:
-                                       if (stricmp(pkey,"home")!=0)
-                                       {
-                                               keylen-=(strlen(pkey)+1);
-                                               pkey+=(strlen(pkey)+1);
-                                               continue;
-                                       }
-                                       break;
-                               default:
-                                       if((stricmp(pkey,"all")==0) || (stricmp(pkey,"home")==0))
-                                       {
-                                               keylen-=(strlen(pkey)+1);
-                                               pkey+=(strlen(pkey)+1);
-                                               continue;
-                                       }
+                                       HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
+                                       ret=FALSE;
                                        break;
                                }
-                               if (strlen(pkey)==0)
+                               strcpy(sShare,pDrivekey);
+                               if (GetPrivateProfileString("AFS Drivemounts", sShare, "", sDrive, DRIVESIZE,dINI)==0)
                                {
-                                       HandleError("Profile String Error - Empty key",FALSE);
+                                       HandleError("Profile String Error - AFS Drivemounts - Drive Name",FALSE);
                                        ret=FALSE;
-                                       keylen-=(strlen(pkey)+1);
-                                       continue;
-                               }
-                               if (mode!=0)
-                               {
-                                       if ((len=GetPrivateProfileString("AFS Submounts", pkey, "", sPath, MAX_PATH,tINI))==0)
-                                       {
-                                               CString msg;
-                                               msg.Format("Profile String Error on Submount key:%s",pkey);
-                                               HandleError(msg,FALSE);
-                                               ret=FALSE;
-                                               keylen-=(strlen(pkey)+1);
-                                               pkey+=(strlen(pkey)+1);
-                                               continue;
-                                       }
-                               } else {
-                                       strcpy(sPath,"\\");
-                                       pkey="all";
-                               }
-                               *sDrive=0;
-                               if ((len=GetPrivateProfileString("AFS Drivemounts", pkey, "", sDrive, DRIVESIZE,dINI))==0)
-                               {
-                                       if ((stricmp("all",pkey)==0)||(stricmp("home",pkey)==0))
-                                       {// allow for no drive id on home
-                                               if (stricmp("home",pkey)==0)
-                                                       strcpy(sDrive,"*U");
-                                               else
-                                                       strcpy(sDrive,"*Z");
-                                       } else {
-                                               CString msg;
-                                               msg.Format("Profile String Error on Path key:%s",pkey);
-                                               HandleError(msg,TRUE);
-                                               ret=FALSE;
-                                               keylen-=(strlen(pkey)+1);
-                                               pkey+=(strlen(pkey)+1);
-                                               continue;
-                                       } 
+                                       break;
                                }
                                if (sDrive[0]=='*')     //test for leading *
                                {
@@ -1215,46 +1246,53 @@ BOOL CWinAfsLoadDlg::ProfileData(BOOL put)
                                } else
                                        strcpy(sAuto," ");
                                sDrive[1]=0;    //force to be single character
-                               if (stricmp("home",pkey)==0)    //force auto connect for home and all
-                               {
-                                       m_bHomepath=TRUE;
-                               } 
                                strupr(sDrive);
-                               if ((strlen(sDrive)!=1)||(strspn(sDrive,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")==0))
+                               if (strspn(sDrive,"DEFGHIJKLMNOPQRSTUVWXYZ")==0)
                                {
-                                       if (stricmp("home",pkey)==0)
-                                               strcpy(sDrive,"U");
-                                       else if (stricmp("all",pkey)==0)
-                                               strcpy(sDrive,"Z");
-                                       else
-                                               strcpy(sDrive,"");
+                                       HandleError("Profile String Error - AFS Drivemounts - Drive Letter",FALSE);
+                                       ret=FALSE;
+                                       break;
                                }
                                strcat(sDrive,":");
-                               if (mode==0) 
-                                       strcpy(sAuto,"*");      //no matter how it turns out 'all' is forced on.
-                               AddToList(sDrive,sPath,pkey,sAuto);
-                               if (mode<2) break;
-                               keylen-=(strlen(pkey)+1);
-                               pkey+=(strlen(pkey)+1);
-                       }
-                       switch (mode)
-                       {
-                       case 0:
-                               if (keylen<=1)  //we never found "all"
-                                       AddToList("Z:","\\","all","*");
-                               keylen=GetPrivateProfileString("AFS Submounts", NULL, "", sKey, MAXKEY,tINI);
-                               pkey=sKey;
-                               break;
-                       case 1:
-                               if (keylen<=1)  //we never found "home"
+                               switch (mode)
+                               {
+                               case 0:
+                                       if (stricmp("all",sShare)!=0) break;
+                                       if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
+                                       {
+                                               strcpy(sPath,"/");      //none defined
+                                       }
+                                       AddToList(sDrive,sPath,sShare,sAuto);
+                                       drivelen=0;
+                                       continue;
+
+                               case 1:
+                                       if (stricmp("home",sShare)!=0) break;
+                                       if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
+                                       {
+                                               HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
+                                               ret=FALSE;
+                                               break;
+                                       }
+                                       AddToList(sDrive,sPath,sShare,sAuto);
+                                       drivelen=0;
+                                       continue;
+                               default:
+                                       if ((stricmp("all",sShare)==0)|| (stricmp("home",sShare)==0)) break;
+                                       if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
+                                       {
+                                               HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
+                                               ret=FALSE;
+                                               break;
+                                       }
+                                       AddToList(sDrive,sPath,sShare,sAuto);
                                        break;
-          &n