diff --git a/src/WINNT/install/NSIS/OpenAFS.nsi b/src/WINNT/install/NSIS/OpenAFS.nsi
index e7577b2d3b..3fd63f0c91 100644
--- a/src/WINNT/install/NSIS/OpenAFS.nsi
+++ b/src/WINNT/install/NSIS/OpenAFS.nsi
@@ -787,6 +787,7 @@ skipCheck:
SetOutPath "$INSTDIR\Server\usr\afs\bin"
File "${AFS_SERVER_BUILDDIR}\afskill.exe"
File "${AFS_SERVER_BUILDDIR}\afssvrcfg.exe"
+ File "${AFS_SERVER_BUILDDIR}\asetkey.exe"
File "${AFS_SERVER_BUILDDIR}\bosctlsvc.exe"
File "${AFS_SERVER_BUILDDIR}\bosserver.exe"
File "${AFS_SERVER_BUILDDIR}\buserver.exe"
@@ -1155,6 +1156,7 @@ DoServer:
SetOutPath "$INSTDIR\Server\usr\afs\bin"
File "${AFS_SERVER_BUILDDIR}\afskill.pdb"
File "${AFS_SERVER_BUILDDIR}\afssvrcfg.pdb"
+ File "${AFS_SERVER_BUILDDIR}\asetkey.pdb"
File "${AFS_SERVER_BUILDDIR}\bosctlsvc.pdb"
File "${AFS_SERVER_BUILDDIR}\bosserver.pdb"
File "${AFS_SERVER_BUILDDIR}\buserver.pdb"
diff --git a/src/WINNT/install/loopback/loopbackutils.cpp b/src/WINNT/install/loopback/loopbackutils.cpp
index 72256a5c2f..01248d270b 100644
--- a/src/WINNT/install/loopback/loopbackutils.cpp
+++ b/src/WINNT/install/loopback/loopbackutils.cpp
@@ -57,7 +57,6 @@ extern "C" DWORD UnInstallLoopBack(void)
GUID netGuid;
HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
- TCHAR* deviceDesc;
DWORD index = 0;
BOOL found = FALSE;
DWORD size = 0;
@@ -74,45 +73,80 @@ extern "C" DWORD UnInstallLoopBack(void)
if (hDeviceInfo == INVALID_HANDLE_VALUE)
return GetLastError();
- deviceDesc = (TCHAR *)malloc(MAX_PATH*sizeof(TCHAR));
// enumerate the driver info list
- while (SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData))
+ while (TRUE)
{
+ TCHAR * deviceHwid;
+
+ ok = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData);
+
+ if(!ok)
+ {
+ if(GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ else
+ {
+ index++;
+ continue;
+ }
+ }
+
// try to get the DeviceDesc registry property
- ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData,
- SPDRP_DEVICEDESC,
- NULL, (PBYTE)deviceDesc,
- MAX_PATH * sizeof(TCHAR), &size);
+ ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ NULL,
+ NULL,
+ 0,
+ &size);
if (!ok)
{
ret = GetLastError();
- if (ret != ERROR_INSUFFICIENT_BUFFER)
- break;
- // if the buffer is too small, reallocate
- free(deviceDesc);
- deviceDesc = (TCHAR *)malloc(size);
+ if (ret != ERROR_INSUFFICIENT_BUFFER) {
+ index++;
+ continue;
+ }
+
+ deviceHwid = (TCHAR *)malloc(size);
ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
&DeviceInfoData,
- SPDRP_DEVICEDESC,
- NULL, (PBYTE)deviceDesc,
- size, NULL);
- if (!ok)
- break;
- }
+ SPDRP_HARDWAREID,
+ NULL,
+ (PBYTE)deviceHwid,
+ size,
+ NULL);
+ if (!ok) {
+ free(deviceHwid);
+ deviceHwid = NULL;
+ index++;
+ continue;
+ }
+ } else {
+ // something is wrong. This shouldn't have worked with a NULL buffer
+ ReportMessage(0, "GetDeviceRegistryProperty succeeded with a NULL buffer", NULL, NULL, 0);
+ index++;
+ continue;
+ }
- // case insensitive comparison
- _tcslwr(deviceDesc);
- if( _tcsstr(deviceDesc, DRIVER))
- {
- found = TRUE;
+ for (TCHAR *t = deviceHwid; t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; t += _tcslen(t) + 1)
+ {
+ if(!_tcsicmp(DRIVERHWID, t)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (deviceHwid) {
+ free(deviceHwid);
+ deviceHwid = NULL;
+ }
+
+ if (found)
break;
- }
-
+
index++;
}
- free(deviceDesc);
-
if (found == FALSE)
{
ret = GetLastError();
@@ -126,6 +160,7 @@ extern "C" DWORD UnInstallLoopBack(void)
ret = GetLastError();
goto cleanup;
}
+
ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
if (!ok)
{
@@ -133,6 +168,8 @@ extern "C" DWORD UnInstallLoopBack(void)
goto cleanup;
}
+ ret = 0;
+
cleanup:
// clean up the device info set
if (hDeviceInfo != INVALID_HANDLE_VALUE)
@@ -143,7 +180,6 @@ cleanup:
BOOL IsLoopbackInstalled(void)
{
- TCHAR * hwid = _T("*MSLOOP");
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i,err;
@@ -163,11 +199,21 @@ BOOL IsLoopbackInstalled(void)
//
found = FALSE;
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
- for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++)
+ for (i=0; ;i++)
{
+ BOOL ok;
DWORD DataT;
TCHAR *p, *buffer = NULL;
DWORD buffersize = 0;
+
+ ok = SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData);
+
+ if(!ok) {
+ if(GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ else
+ continue;
+ }
//
// We won't know the size of the HardwareID buffer until we call
@@ -175,7 +221,13 @@ BOOL IsLoopbackInstalled(void)
// use the required buffer size to Alloc the nessicary space.
// Keep calling we have success or an unknown failure.
//
- while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize))
+ while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ &DataT,
+ (PBYTE)buffer,
+ buffersize,
+ &buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
@@ -191,25 +243,32 @@ BOOL IsLoopbackInstalled(void)
}
else
{
+ if (buffer)
+ LocalFree(buffer);
goto cleanup_DeviceInfo;
- }
+ }
}
- if (GetLastError() == ERROR_INVALID_DATA)
+ if (GetLastError() == ERROR_INVALID_DATA) {
+ if (buffer)
+ LocalFree(buffer);
continue;
+ }
// Compare each entry in the buffer multi-sz list with our hwid.
for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
{
- if (!_tcsicmp(hwid,p))
+ if (!_tcsicmp(DRIVERHWID,p))
{
found = TRUE;
break;
}
}
- if (buffer) LocalFree(buffer);
- if (found) break;
+ if (buffer)
+ LocalFree(buffer);
+ if (found)
+ break;
}
// Cleanup.
@@ -323,16 +382,28 @@ extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR ma
// if we successfully find the hardware ID and it turns out to
// be the one for the loopback driver, then we are done.
- if(SetupDiGetDriverInfoDetail(hDeviceInfo,
+ if (SetupDiGetDriverInfoDetail(hDeviceInfo,
&DeviceInfoData,
&DriverInfoData,
pDriverInfoDetail,
sizeof(detailBuf),
- NULL) &&
- !_tcsicmp(pDriverInfoDetail->HardwareID, DRIVERHWID)) {
+ NULL)) {
+ TCHAR * t;
- found = TRUE;
- break;
+ // pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
+ // whole list and see if there is a match somewhere.
+ t = pDriverInfoDetail->HardwareID;
+ while (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) {
+ if (!_tcsicmp(t, DRIVERHWID))
+ break;
+
+ t += _tcslen(t) + 1;
+ }
+
+ if (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) {
+ found = TRUE;
+ break;
+ }
}
index++;
diff --git a/src/WINNT/install/wix/Icon/ico_OpenAFS.ico b/src/WINNT/install/wix/Icon/ico_OpenAFS.ico
new file mode 100644
index 0000000000..3c434f1ea0
Binary files /dev/null and b/src/WINNT/install/wix/Icon/ico_OpenAFS.ico differ
diff --git a/src/WINNT/install/wix/NTMakefile b/src/WINNT/install/wix/NTMakefile
index b335a430ce..d8868af20b 100644
--- a/src/WINNT/install/wix/NTMakefile
+++ b/src/WINNT/install/wix/NTMakefile
@@ -1,3 +1,10 @@
+# Copyright 2004, OpenAFS.ORG 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
+
RELDIR=WINNT\install\wix
!INCLUDE ..\..\..\config\NTMakefile.$(SYS_NAME)
!INCLUDE ..\..\..\config\NTMakefile.version
@@ -32,12 +39,17 @@ languages:
lang:: lang_clean $(MSIFILE)
+uninst:
+ $(CD) uninstall
+ $(MAKE) /f NTMakefile /nologo install
+ $(CD) ..
+
customactions:
$(CD) custom
$(MAKE) /f NTMakefile /nologo install
$(CD) ..
-install: customactions languages
+install: uninst customactions languages
$(MSIFILE): $(WIXOBJ)
light -nologo -out $(MSIFILE) \
@@ -67,6 +79,9 @@ clean::
$(CD) custom
$(MAKE) /f NTMakefile /nologo clean
$(CD) ..
+ $(CD) uninstall
+ $(MAKE) /f NTMakefile /nologo clean
+ $(CD) ..
lang_clean:
-$(DEL) $(WIXOBJ)
diff --git a/src/WINNT/install/wix/feature.wxi b/src/WINNT/install/wix/feature.wxi
index 7d647ceb22..1c4302bc7d 100644
--- a/src/WINNT/install/wix/feature.wxi
+++ b/src/WINNT/install/wix/feature.wxi
@@ -5,6 +5,7 @@
Title="OpenAFS">
+
@@ -124,6 +125,7 @@
+
diff --git a/src/WINNT/install/wix/files.wxi b/src/WINNT/install/wix/files.wxi
index de2f811805..7acc16cd1f 100644
--- a/src/WINNT/install/wix/files.wxi
+++ b/src/WINNT/install/wix/files.wxi
@@ -32,6 +32,11 @@
+
+
+
+
+
@@ -1219,6 +1224,9 @@
+
+
+
@@ -1277,6 +1285,7 @@
+
diff --git a/src/WINNT/install/wix/lang/en_US/strings.wxl b/src/WINNT/install/wix/lang/en_US/strings.wxl
index 45c1273418..dab8cee81d 100644
--- a/src/WINNT/install/wix/lang/en_US/strings.wxl
+++ b/src/WINNT/install/wix/lang/en_US/strings.wxl
@@ -54,5 +54,5 @@
Removing existing installation of OpenAFS
Installation of OpenAFS for Windows was prematurely terminated because OpenAFS [NSISVERSION] was already installed.
-
+ Uninstall OpenAFS from the local machine.
diff --git a/src/WINNT/install/wix/lang/en_US/ui.wxi b/src/WINNT/install/wix/lang/en_US/ui.wxi
index 4e458dc52d..98555f474e 100644
--- a/src/WINNT/install/wix/lang/en_US/ui.wxi
+++ b/src/WINNT/install/wix/lang/en_US/ui.wxi
@@ -1084,4 +1084,5 @@
+
diff --git a/src/WINNT/install/wix/uninstall/NTMakefile b/src/WINNT/install/wix/uninstall/NTMakefile
new file mode 100644
index 0000000000..ff266cda8b
--- /dev/null
+++ b/src/WINNT/install/wix/uninstall/NTMakefile
@@ -0,0 +1,32 @@
+# Copyright 2004, OpenAFS.ORG 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
+
+RELDIR=WINNT\install\wix\uninstall
+!INCLUDE ..\..\..\..\config\NTMakefile.$(SYS_NAME)
+!INCLUDE ..\..\..\..\config\NTMakefile.version
+
+UNINSTALL = $(DESTDIR)\root.client\usr\vice\etc\uninstall.exe
+
+OBJECTS = $(OUT)\uninstall.obj
+
+$(OBJECTS): $$(@B).c
+ $(C2OBJ) $**
+
+$(OUT)\uninstall.res: uninstall.rc AFS_component_version_number.h
+
+$(UNINSTALL): $(OBJECTS) $(OUT)\uninstall.res
+ $(EXECONLINK) msi.lib
+ $(EXEPREP)
+
+install: $(UNINSTALL)
+
+# Cleanup
+clean::
+ -$(DEL) AFS_component_version_number.h
+ -$(DEL) $(OUT)\uninstall.obj
+ -$(DEL) $(OUT)\uninstall.res
+ -$(DEL) $(UNINSTALL)
diff --git a/src/WINNT/install/wix/uninstall/uninstall.c b/src/WINNT/install/wix/uninstall/uninstall.c
new file mode 100644
index 0000000000..4295a9765b
--- /dev/null
+++ b/src/WINNT/install/wix/uninstall/uninstall.c
@@ -0,0 +1,23 @@
+#define _WIN32_MSI 200
+#include
+#include
+
+#define OAFW_UPGRADE_CODE TEXT("{6823EEDD-84FC-4204-ABB3-A80D25779833}")
+int main(void)
+{
+ UINT rc = ERROR_SUCCESS;
+ DWORD iProduct = 0;
+ CHAR szProductCode[39];
+
+ MsiSetInternalUI(INSTALLUILEVEL_PROGRESSONLY, NULL);
+
+ do {
+ rc = MsiEnumRelatedProducts(OAFW_UPGRADE_CODE, 0, iProduct, szProductCode);
+ if ( rc == ERROR_SUCCESS ) {
+ MsiConfigureProduct(szProductCode, 0 /* ignored */, INSTALLSTATE_ABSENT);
+ iProduct++;
+ }
+ } while ( rc == ERROR_SUCCESS );
+
+ return (rc == ERROR_NO_MORE_ITEMS ? 0 : 1);
+}
diff --git a/src/WINNT/install/wix/uninstall/uninstall.rc b/src/WINNT/install/wix/uninstall/uninstall.rc
new file mode 100644
index 0000000000..d846dfd073
--- /dev/null
+++ b/src/WINNT/install/wix/uninstall/uninstall.rc
@@ -0,0 +1,19 @@
+/*
+ * 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
+ */
+
+/* Define VERSIONINFO resource */
+
+#define AFS_VERINFO_FILE_DESCRIPTION "AFS Uninstall Command"
+#define AFS_VERINFO_NAME "uninstall"
+#define AFS_VERINFO_FILENAME "uninstall.exe"
+
+#include "AFS_component_version_number.h"
+#include "..\..\..\..\config\NTVersioninfo.rc"
+
+100 ICON DISCARDABLE "..\Icon\ico_OpenAFS.ico"
\ No newline at end of file
diff --git a/src/config/NTMakefile b/src/config/NTMakefile
index 57fa76cbee..f90a4ba0dc 100644
--- a/src/config/NTMakefile
+++ b/src/config/NTMakefile
@@ -359,6 +359,9 @@ idirs: doclink
! IF (!EXIST($(OJT)\WINNT\install\wix\custom))
$(MKDIR) $(OJT)\WINNT\install\wix\custom
! ENDIF
+! IF (!EXIST($(OJT)\WINNT\install\wix\uninstall))
+ $(MKDIR) $(OJT)\WINNT\install\wix\uninstall
+! ENDIF
! IF (!EXIST($(OJT)\WINNT\install\Win9x))
$(MKDIR) $(OJT)\WINNT\install\Win9x
! ENDIF