Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

910 lines
23 KiB

#include "stdafx.h"
#include "userenv.h"
#include "userenvp.h"
#include "shlobj.h"
#include "utils.h"
#include "mddefw.h"
#include "mdkey.h"
#include "wizpages.h"
#include "ocmanage.h"
#include "setupapi.h"
#include "k2suite.h"
extern OCMANAGER_ROUTINES gHelperRoutines;
DWORD GetUnattendedMode(HANDLE hUnattended, LPCTSTR szSubcomponent)
{
BOOL b = FALSE;
TCHAR szLine[1024];
DWORD dwMode = SubcompUseOcManagerDefault;
CString csMsg;
csMsg = _T("GetUnattendedMode ");
csMsg += szSubcomponent;
csMsg += _T("\n");
DebugOutput((LPCTSTR)csMsg);
// Try to get the line of interest
if (hUnattended && (hUnattended != INVALID_HANDLE_VALUE))
{
b = SetupGetLineText(NULL, hUnattended, _T("Components"),
szSubcomponent, szLine, sizeof(szLine)/sizeof(szLine[0]), NULL);
if (b)
{
csMsg = szSubcomponent;
csMsg += _T(" = ");
csMsg += szLine;
csMsg += _T("\n");
DebugOutput((LPCTSTR)csMsg);
// Parse the line
if (!lstrcmpi(szLine, _T("on")))
{
dwMode = SubcompOn;
}
else if (!lstrcmpi(szLine, _T("off")))
{
dwMode = SubcompOff;
}
else if (!lstrcmpi(szLine, _T("default")))
{
dwMode = SubcompUseOcManagerDefault;
}
}
else
DebugOutput(_T("SetupGetLineText failed."));
}
return(dwMode);
}
DWORD GetUnattendedModeFromSetupMode(
HANDLE hUnattended,
DWORD dwComponent,
LPCTSTR szSubcomponent)
{
BOOL b = FALSE;
TCHAR szProperty[64];
TCHAR szLine[1024];
DWORD dwMode = SubcompUseOcManagerDefault;
DWORD dwSetupMode;
DebugOutput(_T("GetUnattendedModeFromSetupMode %s"), szSubcomponent);
// Try to get the line of interest
if (hUnattended && (hUnattended != INVALID_HANDLE_VALUE))
{
dwSetupMode = GetIMSSetupMode();
switch (dwSetupMode)
{
case IIS_SETUPMODE_MINIMUM:
case IIS_SETUPMODE_TYPICAL:
case IIS_SETUPMODE_CUSTOM:
// One of the fresh modes
lstrcpy(szProperty, _T("FreshMode"));
break;
case IIS_SETUPMODE_UPGRADEONLY:
case IIS_SETUPMODE_ADDEXTRACOMPS:
// One of the upgrade modes
lstrcpy(szProperty, _T("UpgradeMode"));
break;
case IIS_SETUPMODE_ADDREMOVE:
case IIS_SETUPMODE_REINSTALL:
case IIS_SETUPMODE_REMOVEALL:
// One of the maintenance modes
lstrcpy(szProperty, _T("MaintenanceMode"));
break;
default:
// Error! Use defaults
return(SubcompUseOcManagerDefault);
}
// Get the specified line
b = SetupGetLineText(
NULL,
hUnattended,
_T("Global"),
szProperty,
szLine,
sizeof(szLine)/sizeof(szLine[0]),
NULL);
if (b)
{
DWORD dwOriginalMode;
DebugOutput(_T("%s = %s"), szProperty, szLine);
// See which setup mode we will end up with
if (!lstrcmpi(szLine, _T("Minimal")))
dwSetupMode = IIS_SETUPMODE_MINIMUM;
else if (!lstrcmpi(szLine, _T("Typical")))
dwSetupMode = IIS_SETUPMODE_TYPICAL;
else if (!lstrcmpi(szLine, _T("Custom")))
dwSetupMode = IIS_SETUPMODE_CUSTOM;
else if (!lstrcmpi(szLine, _T("AddRemove")))
dwSetupMode = IIS_SETUPMODE_ADDREMOVE;
else if (!lstrcmpi(szLine, _T("RemoveAll")))
dwSetupMode = IIS_SETUPMODE_REMOVEALL;
else if (!lstrcmpi(szLine, _T("UpgradeOnly")))
dwSetupMode = IIS_SETUPMODE_UPGRADEONLY;
else if (!lstrcmpi(szLine, _T("AddExtraComps")))
dwSetupMode = IIS_SETUPMODE_ADDEXTRACOMPS;
else
return(SubcompUseOcManagerDefault);
// Get the custom unattended setting
dwMode = GetUnattendedMode(hUnattended, szSubcomponent);
// Do the right thing based on the setup mode
SetIMSSetupMode(dwSetupMode);
switch (dwSetupMode)
{
case IIS_SETUPMODE_MINIMUM:
case IIS_SETUPMODE_TYPICAL:
// Minimum & typical means the same:
// Install all for SMTP, none for NNTP
DebugOutput(_T("Unattended mode is MINIMUM/TYPICAL"));
if (dwComponent == MC_IMS)
dwMode = SubcompOn;
else
dwMode = SubcompOff;
break;
case IIS_SETUPMODE_CUSTOM:
// For custom we use the custom setting
DebugOutput(_T("Unattended mode is CUSTOM"));
break;
case IIS_SETUPMODE_UPGRADEONLY:
// Return the original state
DebugOutput(_T("Unattended mode is UPGRADEONLY"));
dwMode = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
szSubcomponent,
OCSELSTATETYPE_ORIGINAL) ? SubcompOn : SubcompOff;
break;
case IIS_SETUPMODE_ADDEXTRACOMPS:
// Turn it on only if the old state is off and the
// custom state is on
DebugOutput(_T("Unattended mode is ADDEXTRACOMPS"));
dwOriginalMode = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
szSubcomponent,
OCSELSTATETYPE_ORIGINAL) ? SubcompOn : SubcompOff;
if (dwOriginalMode == SubcompOff &&
dwMode == SubcompOn)
dwMode = SubcompOn;
else
dwMode = dwOriginalMode;
break;
case IIS_SETUPMODE_ADDREMOVE:
// Return the custom setting
DebugOutput(_T("Unattended mode is ADDREMOVE"));
break;
case IIS_SETUPMODE_REMOVEALL:
// Kill everything
DebugOutput(_T("Unattended mode is REMOVEALL"));
dwMode = SubcompOff;
break;
}
DebugOutput(_T("Unattended state for %s is %s"),
szSubcomponent,
(dwMode == SubcompOn)?_T("ON"):_T("OFF"));
}
else
{
if (GetLastError() != ERROR_LINE_NOT_FOUND)
DebugOutput(_T("SetupGetLineText failed (%x)."), GetLastError());
}
}
return(dwMode);
}
BOOL DetectExistingSmtpServers()
{
// Detect other mail servers
CRegKey regMachine = HKEY_LOCAL_MACHINE;
// System\CurrentControlSet\Services\MsExchangeIMC\Parameters
CRegKey regSMTPParam( regMachine, REG_EXCHANGEIMCPARAMETERS, KEY_READ );
if ((HKEY) regSMTPParam )
{
CString csCaption;
DebugOutput(_T("IMC detected, suppressing SMTP"));
if (!theApp.m_fIsUnattended && !theApp.m_fNTGuiMode)
{
MyLoadString(IDS_MESSAGEBOX_TEXT, csCaption);
PopupOkMessageBox(IDS_SUPPRESS_SMTP, csCaption);
}
return(TRUE);
}
DebugOutput(_T("No other SMTP servers detected, installing IMS."));
return(FALSE);
}
BOOL DetectExistingIISADMIN()
{
//
// Detect is IISADMIN service exists
//
// This is to make sure we don't do any metabase operation if
// IISADMIN doesn't exists, especially in the uninstall cases.
//
DWORD dwStatus = 0;
dwStatus = InetQueryServiceStatus(SZ_MD_SERVICENAME);
if (0 == dwStatus)
{
// some kind of error occur during InetQueryServiceStatus.
DebugOutput(_T("DetectExistingIISADMIN() return FALSE"));
return (FALSE);
}
return(TRUE);
}
BOOL InsertSetupString( LPCSTR REG_PARAMETERS )
{
// set up registry values
CRegKey regMachine = HKEY_LOCAL_MACHINE;
// System\CurrentControlSet\Services\NNTPSVC\Parameters
CRegKey regParam( (LPCTSTR) REG_PARAMETERS, regMachine );
if ((HKEY) regParam) {
regParam.SetValue( _T("MajorVersion"), (DWORD)STAXNT5MAJORVERSION );
regParam.SetValue( _T("MinorVersion"), (DWORD)STAXNT5MINORVERSION );
regParam.SetValue( _T("InstallPath"), theApp.m_csPathInetsrv );
switch (theApp.m_eNTOSType) {
case OT_NTW:
regParam.SetValue( _T("SetupString"), REG_SETUP_STRING_NT5WKSB3 );
break;
default:
_ASSERT(!"Unknown OS type");
// Fall through
case OT_NTS:
case OT_PDC_OR_BDC:
case OT_PDC:
case OT_BDC:
regParam.SetValue( _T("SetupString"), REG_SETUP_STRING_NT5SRVB3 );
break;
}
}
return TRUE;
}
// Scans a multi-sz and finds the first occurrence of the
// specified string
LPTSTR ScanMultiSzForSz(LPTSTR szMultiSz, LPTSTR szSz)
{
LPTSTR lpTemp = szMultiSz;
do
{
if (!lstrcmpi(lpTemp, szSz))
return(lpTemp);
lpTemp += lstrlen(lpTemp);
lpTemp++;
} while (*lpTemp != _T('\0'));
return(NULL);
}
// Removes the said string from a MultiSz
// This places a lot of faith in the caller!
void RemoveSzFromMultiSz(LPTSTR szSz)
{
LPTSTR lpScan = szSz;
TCHAR tcLastChar;
lpScan += lstrlen(szSz);
lpScan++;
tcLastChar = _T('x');
while ((tcLastChar != _T('\0')) ||
(*lpScan != _T('\0')))
{
tcLastChar = *lpScan;
*szSz++ = *lpScan++;
}
*szSz++ = _T('\0');
// Properly terminate it if it's the last one
if (*lpScan == _T('\0'))
*szSz = _T('\0');
}
// This walks the multi-sz and returns a pointer between
// the last string of a multi-sz and the second terminating
// NULL
LPTSTR GetEndOfMultiSz(LPTSTR szMultiSz)
{
LPTSTR lpTemp = szMultiSz;
do
{
lpTemp += lstrlen(lpTemp);
lpTemp++;
} while (*lpTemp != _T('\0'));
return(lpTemp);
}
// This appends a string to the end of a multi-sz
// The buffer must be long enough
BOOL AppendSzToMultiSz(LPTSTR szMultiSz, LPTSTR szSz, DWORD dwMaxSize)
{
LPTSTR szTemp = szMultiSz;
DWORD dwLength = lstrlen(szSz);
// If the string is empty, do not append!
if (*szMultiSz == _T('\0') &&
*(szMultiSz + 1) == _T('\0'))
szTemp = szMultiSz;
else
{
szTemp = GetEndOfMultiSz(szMultiSz);
dwLength += (DWORD)(szTemp - szMultiSz);
}
if (dwLength >= dwMaxSize)
return(FALSE);
lstrcpy(szTemp, szSz);
szMultiSz += dwLength;
*szMultiSz = _T('\0');
*(szMultiSz + 1) = _T('\0');
return(TRUE);
}
BOOL AddServiceToDispatchList(LPTSTR szServiceName)
{
TCHAR szMultiSz[4096];
DWORD dwSize = 4096;
CRegKey RegInetInfo(REG_INETINFOPARAMETERS, HKEY_LOCAL_MACHINE);
if ((HKEY)RegInetInfo)
{
// Default to empty string if not exists
szMultiSz[0] = _T('\0');
szMultiSz[1] = _T('\0');
if (RegInetInfo.QueryValue(SZ_INETINFODISPATCH, szMultiSz, dwSize) == NO_ERROR)
{
// Walk the list to see if the value is already there
if (ScanMultiSzForSz(szMultiSz, szServiceName))
return(TRUE);
}
// Create the value and add it to the list
if (!AppendSzToMultiSz(szMultiSz, szServiceName, dwSize))
return(FALSE);
// Get the size of the new Multi-sz
dwSize = (DWORD)(GetEndOfMultiSz(szMultiSz) - szMultiSz) + 1;
// Write the value back to the registry
if (RegInetInfo.SetValue(SZ_INETINFODISPATCH, szMultiSz, dwSize * (DWORD) sizeof(TCHAR)) == NO_ERROR)
return(TRUE);
}
// If the InetInfo key is not here, there isn't much we can do ...
return(FALSE);
}
BOOL RemoveServiceFromDispatchList(LPTSTR szServiceName)
{
TCHAR szMultiSz[4096];
DWORD dwSize = 4096;
LPTSTR szTemp;
BOOL fFound = FALSE;
CRegKey RegInetInfo(HKEY_LOCAL_MACHINE, REG_INETINFOPARAMETERS);
if ((HKEY)RegInetInfo)
{
if (RegInetInfo.QueryValue(SZ_INETINFODISPATCH, szMultiSz, dwSize) == NO_ERROR)
{
// Walk the list to see if the value is already there
while (szTemp = ScanMultiSzForSz(szMultiSz, szServiceName))
{
RemoveSzFromMultiSz(szTemp);
fFound = TRUE;
}
}
// Write the value back to the registry if necessary, note we
// will indicate success if the string is not found
if (!fFound)
return(TRUE);
// Get the size of the new Multi-sz
dwSize = (DWORD)(GetEndOfMultiSz(szMultiSz) - szMultiSz) + 1;
// Write the value back to the registry
if (RegInetInfo.SetValue(SZ_INETINFODISPATCH, szMultiSz, dwSize * (DWORD) sizeof(TCHAR)) == NO_ERROR)
return(TRUE);
}
// If the InetInfo key is not here, there isn't much we can do ...
return(FALSE);
}
void GetIISProgramGroup(CString &csGroupName, BOOL fIsMcisGroup)
{
TCHAR szName[_MAX_PATH];
CString csTempName;
UINT uType, uSize;
if (fIsMcisGroup) {
csGroupName = "";
} else {
// Get the NT program group name from the private data
uSize = _MAX_PATH * sizeof(TCHAR);
{
// We use the default group name
MyLoadString(IDS_DEFAULT_NT_PROGRAM_GROUP, csTempName);
lstrcpy(szName, csTempName.GetBuffer(_MAX_PATH));
csTempName.ReleaseBuffer();
}
csGroupName = szName;
csGroupName += _T("\\");
// Get the IIS program group name from the private data
uSize = _MAX_PATH * sizeof(TCHAR);
{
// We use the default group name
MyLoadString(IDS_DEFAULT_IIS_PROGRAM_GROUP, csTempName);
lstrcpy(szName, csTempName.GetBuffer(_MAX_PATH));
csTempName.ReleaseBuffer();
}
csGroupName += szName;
}
}
void MyGetGroupPath(LPCTSTR szGroupName, LPTSTR szPath);
BOOL GetFullPathToProgramGroup(DWORD dwMainComponent, CString &csGroupName, BOOL fIsMcisGroup)
{
// add items to the program group
CString csTemp;
TCHAR szPath[MAX_PATH];
// Get the program group name from the private data
GetIISProgramGroup(csTemp, fIsMcisGroup);
// Get the system path to this menu item
MyGetGroupPath((LPCTSTR)csTemp, szPath);
csGroupName = szPath;
// Load up the resource string for the group
if (fIsMcisGroup)
MyLoadString(IDS_PROGGROUP_MCIS_MAIL_AND_NEWS, csTemp);
else
MyLoadString(dwMainComponent == MC_IMS?IDS_PROGGROUP_MAIL:IDS_PROGGROUP_NEWS, csTemp);
// Build the program group
csGroupName += csTemp;
DebugOutput(_T("Program group loaded: %s"), (LPCTSTR)csGroupName);
return(TRUE);
}
BOOL GetFullPathToAdminGroup(DWORD dwMainComponent, CString &csGroupName)
{
// add items to the program group
CString csTemp;
TCHAR szPath[MAX_PATH];
// Get the program group name from the private data
MyLoadString( IDS_PROGGROUP_ADMINTOOLS, csTemp );
// Get the system path to this menu item
MyGetGroupPath((LPCTSTR)csTemp, szPath);
csGroupName = szPath;
DebugOutput(_T("Program group loaded: %s"), (LPCTSTR)csGroupName);
return(TRUE);
}
BOOL RemoveProgramGroupIfEmpty(DWORD dwMainComponent, BOOL fIsMcisGroup)
{
// add items to the program group
CString csGroupName;
CString csTemp;
TCHAR szPath[MAX_PATH];
BOOL fResult;
// Get the program group name from the private data
GetIISProgramGroup(csTemp, fIsMcisGroup);
// Get the system path to this menu item
MyGetGroupPath((LPCTSTR)csTemp, szPath);
csGroupName = szPath;
// Load up the resource string for the group
if (fIsMcisGroup)
MyLoadString(IDS_PROGGROUP_MCIS_MAIL_AND_NEWS, csTemp);
else
MyLoadString(dwMainComponent == MC_IMS?IDS_PROGGROUP_MAIL:IDS_PROGGROUP_NEWS, csTemp);
// Build the program group
csGroupName += csTemp;
DebugOutput(_T("Removing Program group: %s"), (LPCTSTR)csGroupName);
fResult = RemoveDirectory((LPCTSTR)csGroupName);
if (fResult && fIsMcisGroup)
{
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, (LPCTSTR)csGroupName, 0);
csGroupName = szPath;
MyLoadString(IDS_MCIS_2_0, csTemp);
csGroupName += csTemp;
fResult = RemoveDirectory((LPCTSTR)csGroupName);
}
if (fResult)
{
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, (LPCTSTR)csGroupName, 0);
}
return(fResult);
}
BOOL RemoveInternetShortcut(DWORD dwMainComponent, int dwDisplayNameId, BOOL fIsMcisGroup)
{
CString csItemPath;
CString csDisplayName;
MyLoadString(dwDisplayNameId, csDisplayName);
// Build the full path to the program link
GetFullPathToProgramGroup(dwMainComponent, csItemPath, fIsMcisGroup);
csItemPath += _T("\\");
csItemPath += csDisplayName;
csItemPath += _T(".url");
DebugOutput(_T("Removing shortcut file: %s"), (LPCTSTR)csItemPath);
DeleteFile((LPCTSTR)csItemPath);
SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, (LPCTSTR)csItemPath, 0);
RemoveProgramGroupIfEmpty(dwMainComponent, fIsMcisGroup);
return(TRUE);
}
BOOL RemoveNt5InternetShortcut(DWORD dwMainComponent, int dwDisplayNameId)
{
CString csItemPath;
CString csDisplayName;
MyLoadString(dwDisplayNameId, csDisplayName);
// Build the full path to the program link
GetFullPathToAdminGroup(dwMainComponent, csItemPath);
csItemPath += _T("\\");
csItemPath += csDisplayName;
csItemPath += _T(".url");
DebugOutput(_T("Removing shortcut file: %s"), (LPCTSTR)csItemPath);
DeleteFile((LPCTSTR)csItemPath);
SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, (LPCTSTR)csItemPath, 0);
return(TRUE);
}
BOOL RemoveMCIS10MailProgramGroup()
{
CString csGroupName;
CString csNiceName;
MyLoadString(IDS_PROGGROUP_MCIS10_MAIL, csGroupName);
MyLoadString(IDS_PROGITEM_MCIS10_MAIL_STARTPAGE, csNiceName);
MyDeleteItem(csGroupName, csNiceName);
MyLoadString(IDS_PROGITEM_MCIS10_MAIL_WEBADMIN, csNiceName);
MyDeleteItemEx(csGroupName, csNiceName);
return(TRUE);
}
BOOL RemoveMCIS10NewsProgramGroup()
{
CString csGroupName;
CString csNiceName;
// BINLIN:
// BUGBUG: need to figure out how to get
// the old MCIS 1.0 program group path
MyLoadString(IDS_PROGGROUP_MCIS10_NEWS, csGroupName);
MyLoadString(IDS_PROGITEM_MCIS10_NEWS_STARTPAGE, csNiceName);
MyDeleteItem(csGroupName, csNiceName);
MyLoadString(IDS_PROGITEM_MCIS10_NEWS_WEBADMIN, csNiceName);
MyDeleteItemEx(csGroupName, csNiceName);
return(TRUE);
}
BOOL RemoveUninstallEntries(LPCTSTR szInfFile)
{
// All components are removed, we will have to remove
// the Add/Remove option from the control panel
CRegKey regUninstall( HKEY_LOCAL_MACHINE, REG_UNINSTALL);
if ((HKEY)regUninstall)
regUninstall.DeleteTree(szInfFile);
else
return(FALSE);
return(TRUE);
}
BOOL MyDeleteLink(LPTSTR lpszShortcut)
{
TCHAR szFile[_MAX_PATH];
SHFILEOPSTRUCT fos;
ZeroMemory(szFile, sizeof(szFile));
lstrcpy(szFile, lpszShortcut);
// only call SHFileOperation if this file/link exists
if (0xFFFFFFFF != GetFileAttributes(szFile))
{
ZeroMemory(&fos, sizeof(fos));
fos.hwnd = NULL;
fos.wFunc = FO_DELETE;
fos.pFrom = szFile;
fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
SHFileOperation(&fos);
}
return TRUE;
}
void MyGetGroupPath(LPCTSTR szGroupName, LPTSTR szPath)
{
int nLen = 0;
LPITEMIDLIST pidlPrograms;
szPath[0] = NULL;
if (NOERROR != SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &pidlPrograms)) return;
if (!SHGetPathFromIDList(pidlPrograms, szPath)) return;
nLen = lstrlen(szPath);
if (szGroupName) {
if (nLen == 0 || szPath[nLen-1] != _T('\\'))
lstrcat(szPath, _T("\\"));
lstrcat(szPath, szGroupName);
}
return;
}
BOOL MyAddGroup(LPCTSTR szGroupName)
{
TCHAR szPath[MAX_PATH];
CString csPath;
MyGetGroupPath(szGroupName, szPath);
csPath = szPath;
CreateLayerDirectory(csPath);
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATH, szPath, 0);
return TRUE;
}
BOOL MyIsGroupEmpty(LPCTSTR szGroupName)
{
TCHAR szPath[MAX_PATH];
TCHAR szFile[MAX_PATH];
WIN32_FIND_DATA FindData;
HANDLE hFind;
BOOL bFindFile = TRUE;
BOOL fReturn = TRUE;
MyGetGroupPath(szGroupName, szPath);
lstrcpy(szFile, szPath);
lstrcat(szFile, _T("\\*.*"));
hFind = FindFirstFile(szFile, &FindData);
if (INVALID_HANDLE_VALUE != hFind)
{
while (bFindFile)
{
if(*(FindData.cFileName) != _T('.'))
{
fReturn = FALSE;
break;
}
//find the next file
bFindFile = FindNextFile(hFind, &FindData);
}
FindClose(hFind);
}
return fReturn;
}
BOOL MyDeleteGroup(LPCTSTR szGroupName)
{
TCHAR szPath[MAX_PATH];
TCHAR szFile[MAX_PATH];
SHFILEOPSTRUCT fos;
WIN32_FIND_DATA FindData;
HANDLE hFind;
BOOL bFindFile = TRUE;
BOOL fResult;
MyGetGroupPath(szGroupName, szPath);
//we can't remove a directory that is not empty, so we need to empty this one
lstrcpy(szFile, szPath);
lstrcat(szFile, _T("\\*.*"));
ZeroMemory(&fos, sizeof(fos));
fos.hwnd = NULL;
fos.wFunc = FO_DELETE;
fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
hFind = FindFirstFile(szFile, &FindData);
if (INVALID_HANDLE_VALUE != hFind)
{
while (bFindFile)
{
if(*(FindData.cFileName) != _T('.'))
{
//copy the path and file name to our temp buffer
lstrcpy(szFile, szPath);
lstrcat(szFile, _T("\\"));
lstrcat(szFile, FindData.cFileName);
//add a second NULL because SHFileOperation is looking for this
lstrcat(szFile, _T("\0"));
//delete the file
fos.pFrom = szFile;
SHFileOperation(&fos);
}
//find the next file
bFindFile = FindNextFile(hFind, &FindData);
}
FindClose(hFind);
}
fResult = RemoveDirectory(szPath);
if (fResult)
{
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, szPath, 0);
}
return(fResult);
}
void MyDeleteItem(LPCTSTR szGroupName, LPCTSTR szAppName)
{
TCHAR szPath[_MAX_PATH];
MyGetGroupPath(szGroupName, szPath);
lstrcat(szPath, _T("\\"));
lstrcat(szPath, szAppName);
lstrcat(szPath, _T(".lnk"));
MyDeleteLink(szPath);
if (MyIsGroupEmpty(szGroupName))
MyDeleteGroup(szGroupName);
}
// Use to delete files with extension other than ".lnk"
void MyDeleteItemEx(LPCTSTR szGroupName, LPCTSTR szAppName)
{
TCHAR szPath[_MAX_PATH];
MyGetGroupPath(szGroupName, szPath);
lstrcat(szPath, _T("\\"));
lstrcat(szPath, szAppName);
MyDeleteLink(szPath);
if (MyIsGroupEmpty(szGroupName))
MyDeleteGroup(szGroupName);
}
BOOL RemoveISMLink()
{
// add items to the program group
CString csGroupName;
CString csNiceName;
CString csTemp;
DebugOutput(_T("Removing ISM link ..."));
// Get the program group name from the private data
GetIISProgramGroup(csGroupName, TRUE);
MyLoadString(IDS_PROGGROUP_MCIS_MAIL_AND_NEWS, csTemp);
// Build the program group
csGroupName += csTemp;
MyLoadString(IDS_PROGITEM_ISM, csNiceName);
MyDeleteItem(csGroupName, csNiceName);
return(TRUE);
}
void GetInetpubPathFromMD(CString& csPathInetpub)
{
TCHAR szw3root[] = _T("\\wwwroot");
TCHAR szPathInetpub[_MAX_PATH];
ZeroMemory( szPathInetpub, sizeof(szPathInetpub) );
CMDKey W3Key;
DWORD dwScratch;
DWORD dwType;
DWORD dwLength;
// Get W3Root path
W3Key.OpenNode(_T("LM/W3Svc/1/Root"));
if ( (METADATA_HANDLE)W3Key )
{
dwLength = _MAX_PATH;
if (W3Key.GetData(3001, &dwScratch, &dwScratch,
&dwType, &dwLength, (LPBYTE)szPathInetpub))
{
if (dwType == STRING_METADATA)
{
dwScratch = lstrlen(szw3root);
dwLength = lstrlen(szPathInetpub);
// If it ends with "\\wwwroot", then we copy the prefix into csPathInetpub
if ((dwLength > dwScratch) &&
!lstrcmpi(szPathInetpub + (dwLength - dwScratch), szw3root))
{
csPathInetpub.Empty();
lstrcpyn( csPathInetpub.GetBuffer(512), szPathInetpub, (dwLength - dwScratch + 1));
csPathInetpub.ReleaseBuffer();
}
// otherwise fall back to use the default...
}
}
W3Key.Close();
}
return;
}