1438 lines
46 KiB
C++
1438 lines
46 KiB
C++
//Copyright (c) 1998 - 1999 Microsoft Corporation
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
*
|
|
* Module Name:
|
|
*
|
|
* hydraoc.cpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* This file implements the optional component HydraOc for Terminal Server Installations.
|
|
*
|
|
*
|
|
* Author:
|
|
*
|
|
* Makarand Patwardhan - March 6, 1998
|
|
*
|
|
* Environment:
|
|
*
|
|
* User Mode
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
#include "hydraoc.h"
|
|
#include "pages.h"
|
|
#include "subtoggle.h"
|
|
#include "subcore.h"
|
|
#include "ocmanage.h"
|
|
|
|
|
|
#define INITGUID // must be before iadmw.h
|
|
|
|
#include "iadmw.h" // Interface header
|
|
#include "iiscnfg.h" // MD_ & IIS_MD_ defines
|
|
|
|
#define REASONABLE_TIMEOUT 1000
|
|
|
|
#define TRANS_ADD 0
|
|
#define TRANS_DEL 1
|
|
#define TRANS_PRINT_PATH 2
|
|
#define STRING_TS_WEBCLIENT_INSTALL _T("TSWebClient.Install")
|
|
#define STRING_TS_WEBCLIENT_UNINSTALL _T("TSWebClient.UnInstall")
|
|
#define STRING_TS_WEBCLIENT _T("TSWebClient")
|
|
#define STRING_TS_WEBCLIENT_DIR _T("\\web\\tsweb")
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* declarations.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
//
|
|
// component manager message handlers.
|
|
//
|
|
DWORD OnPreinitialize ();
|
|
DWORD OnInitComponent (PSETUP_INIT_COMPONENT psc);
|
|
DWORD OnExtraRoutines (PEXTRA_ROUTINES pExtraRoutines);
|
|
DWORD OnSetLanguage ();
|
|
DWORD OnQueryImage ();
|
|
DWORD OnSetupRequestPages (WizardPagesType ePageType, SETUP_REQUEST_PAGES *pRequestPages);
|
|
DWORD OnQuerySelStateChange (LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag);
|
|
DWORD OnCalcDiskSpace (LPCTSTR SubcomponentId, DWORD addComponent, HDSKSPC dspace);
|
|
DWORD OnQueueFileOps (LPCTSTR SubcomponentId, HSPFILEQ queue);
|
|
DWORD OnNotificationFromQueue ();
|
|
DWORD OnQueryStepCount (LPCTSTR SubComponentId);
|
|
DWORD OnCompleteInstallation (LPCTSTR SubcomponentId);
|
|
DWORD OnCleanup ();
|
|
DWORD OnQueryState (LPCTSTR SubComponentId, UINT whichstate);
|
|
DWORD OnNeedMedia ();
|
|
DWORD OnAboutToCommitQueue (LPCTSTR SubcomponentId);
|
|
DWORD OnQuerySkipPage ();
|
|
DWORD OnWizardCreated ();
|
|
DWORD_PTR WebClientSetup (LPCTSTR, LPCTSTR, UINT, UINT_PTR, PVOID);
|
|
|
|
//
|
|
// private utility functions.
|
|
//
|
|
BOOL OpenMetabaseAndDoStuff(WCHAR *wszVDir, WCHAR *wszDir, int iTrans);
|
|
BOOL GetVdirPhysicalPath(IMSAdminBase *pIMSAdminBase,WCHAR * wszVDir,WCHAR *wszStringPathToFill);
|
|
BOOL AddVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR *wszVDir, WCHAR *wszDir);
|
|
BOOL RemoveVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR *wszVDir);
|
|
INT CheckifServiceExist(LPCTSTR lpServiceName);
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* defines
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* constants
|
|
-------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//
|
|
// global variables and functions to access them.
|
|
//
|
|
|
|
SubCompToggle *gpSubCompToggle = NULL;
|
|
SubCompCoreTS *gpSubCompCoreTS = NULL;
|
|
COCPageData *gpAppSrvUninstallPageData = NULL;
|
|
DefSecPageData *gpSecPageData = NULL;
|
|
COCPageData *gpPermPageData = NULL;
|
|
COCPageData *gpAppPageData = NULL;
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* LPCTSTR GetOCFunctionName(UINT uiFunction)
|
|
* utility function for logging the oc messages.
|
|
* returns oc manager function name from funciton id.
|
|
* returns _T("Unknown Function") if its unknown.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
LPCTSTR GetOCFunctionName(UINT uiFunction)
|
|
{
|
|
struct
|
|
{
|
|
UINT msg;
|
|
TCHAR *desc;
|
|
} gMsgs[] =
|
|
{
|
|
{OC_PREINITIALIZE, TEXT("OC_PREINITIALIZE")},
|
|
{OC_INIT_COMPONENT, TEXT("OC_INIT_COMPONENT")},
|
|
{OC_SET_LANGUAGE, TEXT("OC_SET_LANGUAGE")},
|
|
{OC_QUERY_IMAGE, TEXT("OC_QUERY_IMAGE")},
|
|
{OC_REQUEST_PAGES, TEXT("OC_REQUEST_PAGES")},
|
|
{OC_QUERY_CHANGE_SEL_STATE, TEXT("OC_QUERY_CHANGE_SEL_STATE")},
|
|
{OC_CALC_DISK_SPACE, TEXT("OC_CALC_DISK_SPACE")},
|
|
{OC_QUEUE_FILE_OPS, TEXT("OC_QUEUE_FILE_OPS")},
|
|
{OC_NOTIFICATION_FROM_QUEUE,TEXT("OC_NOTIFICATION_FROM_QUEUE")},
|
|
{OC_QUERY_STEP_COUNT, TEXT("OC_QUERY_STEP_COUNT")},
|
|
{OC_COMPLETE_INSTALLATION, TEXT("OC_COMPLETE_INSTALLATION")},
|
|
{OC_CLEANUP, TEXT("OC_CLEANUP")},
|
|
{OC_QUERY_STATE, TEXT("OC_QUERY_STATE")},
|
|
{OC_NEED_MEDIA, TEXT("OC_NEED_MEDIA")},
|
|
{OC_ABOUT_TO_COMMIT_QUEUE, TEXT("OC_ABOUT_TO_COMMIT_QUEUE")},
|
|
{OC_QUERY_SKIP_PAGE, TEXT("OC_QUERY_SKIP_PAGE")},
|
|
{OC_WIZARD_CREATED, TEXT("OC_WIZARD_CREATED")},
|
|
{OC_EXTRA_ROUTINES, TEXT("OC_EXTRA_ROUTINES")}
|
|
};
|
|
|
|
for (int i = 0; i < sizeof(gMsgs) / sizeof(gMsgs[0]); i++)
|
|
{
|
|
if (gMsgs[i].msg == uiFunction)
|
|
return gMsgs[i].desc;
|
|
}
|
|
|
|
return _T("Unknown Function");
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* called by CRT when _DllMainCRTStartup is the DLL entry point
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
BOOL WINAPI DllMain(IN HINSTANCE hinstance, IN DWORD reason, IN LPVOID /*reserved*/ )
|
|
{
|
|
SetInstance( hinstance );
|
|
|
|
switch(reason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
TCHAR szLogFile[MAX_PATH];
|
|
ExpandEnvironmentStrings(LOGFILE, szLogFile, MAX_PATH);
|
|
LOGMESSAGEINIT(szLogFile, MODULENAME);
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_PROCESS_DETACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
|
|
return(TRUE); // for successful process_attach
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* This is our export function which will be called by OC Manager
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD_PTR HydraOc(
|
|
IN LPCTSTR ComponentId,
|
|
IN LPCTSTR SubcomponentId,
|
|
IN UINT Function,
|
|
IN UINT_PTR Param1,
|
|
IN OUT PVOID Param2
|
|
)
|
|
{
|
|
// we use this variable to track if we receive OnCompleteInstallation or not.
|
|
// there is a problem with ocm which aborts all the components if any of them
|
|
// does something wrong with file queue.
|
|
static BOOL sbGotCompleteMessage = FALSE;
|
|
|
|
LOGMESSAGE1(_T("Entering %s"), GetOCFunctionName(Function));
|
|
LOGMESSAGE2(_T("Component=%s, SubComponent=%s"), ComponentId, SubcomponentId);
|
|
|
|
DWORD_PTR rc;
|
|
|
|
if (SubcomponentId && _tcsicmp(SubcomponentId, _T("tswebClient")) == 0)
|
|
{
|
|
rc = WebClientSetup(ComponentId, SubcomponentId, Function, Param1, Param2);
|
|
LOGMESSAGE2(_T("%s Done. Returning %lu\r\n\r\n"), GetOCFunctionName(Function), rc);
|
|
return rc;
|
|
}
|
|
|
|
// since we are supporting only one component.
|
|
ASSERT(_tcsicmp(APPSRV_COMPONENT_NAME, ComponentId) == 0);
|
|
|
|
|
|
switch(Function)
|
|
{
|
|
case OC_PREINITIALIZE:
|
|
rc = OnPreinitialize();
|
|
break;
|
|
|
|
case OC_INIT_COMPONENT:
|
|
rc = OnInitComponent((PSETUP_INIT_COMPONENT)Param2);
|
|
break;
|
|
|
|
case OC_EXTRA_ROUTINES:
|
|
rc = OnExtraRoutines((PEXTRA_ROUTINES)Param2);
|
|
break;
|
|
|
|
case OC_SET_LANGUAGE:
|
|
rc = OnSetLanguage();
|
|
break;
|
|
|
|
case OC_QUERY_IMAGE:
|
|
rc = OnQueryImage();
|
|
break;
|
|
|
|
case OC_REQUEST_PAGES:
|
|
rc = OnSetupRequestPages(WizardPagesType(Param1), PSETUP_REQUEST_PAGES (Param2));
|
|
break;
|
|
|
|
case OC_QUERY_CHANGE_SEL_STATE:
|
|
rc = OnQuerySelStateChange(SubcomponentId, (UINT)Param1, LONG(ULONG_PTR(Param2)));
|
|
break;
|
|
|
|
case OC_CALC_DISK_SPACE:
|
|
rc = OnCalcDiskSpace(SubcomponentId, (DWORD)Param1, Param2);
|
|
break;
|
|
|
|
case OC_QUEUE_FILE_OPS:
|
|
rc = OnQueueFileOps(SubcomponentId, (HSPFILEQ)Param2);
|
|
break;
|
|
|
|
case OC_NOTIFICATION_FROM_QUEUE:
|
|
rc = OnNotificationFromQueue();
|
|
break;
|
|
|
|
case OC_QUERY_STEP_COUNT:
|
|
rc = OnQueryStepCount(SubcomponentId);
|
|
break;
|
|
|
|
case OC_COMPLETE_INSTALLATION:
|
|
sbGotCompleteMessage = TRUE;
|
|
|
|
rc = OnCompleteInstallation(SubcomponentId);
|
|
break;
|
|
|
|
case OC_CLEANUP:
|
|
rc = OnCleanup();
|
|
|
|
if (!sbGotCompleteMessage)
|
|
{
|
|
if (StateObject.IsStandAlone())
|
|
{
|
|
LOGMESSAGE0(_T("Error:StandAlone:TSOC Did not get OC_COMPLETE_INSTALLATION."));
|
|
}
|
|
else
|
|
{
|
|
LOGMESSAGE0(_T("Error:TSOC Did not get OC_COMPLETE_INSTALLATION."));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case OC_QUERY_STATE:
|
|
rc = OnQueryState(SubcomponentId, (UINT)Param1);
|
|
break;
|
|
|
|
case OC_NEED_MEDIA:
|
|
rc = OnNeedMedia();
|
|
break;
|
|
|
|
case OC_ABOUT_TO_COMMIT_QUEUE:
|
|
rc = OnAboutToCommitQueue(SubcomponentId);
|
|
break;
|
|
|
|
case OC_QUERY_SKIP_PAGE:
|
|
rc = OnQuerySkipPage();
|
|
break;
|
|
|
|
case OC_WIZARD_CREATED:
|
|
rc = OnWizardCreated();
|
|
break;
|
|
|
|
default:
|
|
rc = 0; // it means we do not recognize this command.
|
|
break;
|
|
}
|
|
|
|
LOGMESSAGE2(_T("%s Done. Returning %lu\r\n\r\n"), GetOCFunctionName(Function), rc);
|
|
return rc;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OC Manager message handlers
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnPreinitialize(VOID)
|
|
{
|
|
#ifdef ANSI
|
|
return OCFLAG_ANSI;
|
|
#else
|
|
return OCFLAG_UNICODE;
|
|
#endif
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnInitComponent()
|
|
*
|
|
* handler for OC_INIT_COMPONENT
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnInitComponent(PSETUP_INIT_COMPONENT psc)
|
|
{
|
|
ASSERT(psc);
|
|
|
|
//
|
|
// let the ocmanager know our version
|
|
//
|
|
|
|
psc->ComponentVersion = COMPONENT_VERSION;
|
|
|
|
//
|
|
// Is this component written for newer version than the oc manager ?
|
|
//
|
|
|
|
if (COMPONENT_VERSION > psc->OCManagerVersion)
|
|
{
|
|
LOGMESSAGE2(_T("ERROR:OnInitComponent: COMPONENT_VERSION(%x) > psc->OCManagerVersion(%x)"), COMPONENT_VERSION, psc->OCManagerVersion);
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
if (!StateObject.Initialize(psc))
|
|
{
|
|
return ERROR_CANCELLED; // due to ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
// if its standalone (!guimode) setup, We must have Hydra in product suite by now.
|
|
// ASSERT( StateObject.IsGuiModeSetup() || DoesHydraKeysExists() );
|
|
|
|
|
|
|
|
//
|
|
// now create our subcomponents
|
|
//
|
|
gpSubCompToggle = new SubCompToggle;
|
|
gpSubCompCoreTS = new SubCompCoreTS;
|
|
|
|
if (!gpSubCompToggle || !gpSubCompCoreTS)
|
|
return ERROR_CANCELLED;
|
|
|
|
//
|
|
// if initialization of any of the sub component fails
|
|
// fail the setup
|
|
//
|
|
|
|
if (!gpSubCompToggle->Initialize() ||
|
|
!gpSubCompCoreTS->Initialize())
|
|
|
|
return ERROR_CANCELLED;
|
|
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD
|
|
OnExtraRoutines(
|
|
PEXTRA_ROUTINES pExtraRoutines
|
|
)
|
|
{
|
|
ASSERT(pExtraRoutines);
|
|
|
|
return(SetExtraRoutines(pExtraRoutines) ? ERROR_SUCCESS : ERROR_CANCELLED);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnCalcDiskSpace()
|
|
*
|
|
* handler for OC_ON_CALC_DISK_SPACE
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnCalcDiskSpace(
|
|
LPCTSTR /* SubcomponentId */,
|
|
DWORD addComponent,
|
|
HDSKSPC dspace
|
|
)
|
|
{
|
|
return gpSubCompCoreTS->OnCalcDiskSpace(addComponent, dspace);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnQueueFileOps()
|
|
*
|
|
* handler for OC_QUEUE_FILE_OPS
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQueueFileOps(LPCTSTR SubcomponentId, HSPFILEQ queue)
|
|
{
|
|
if (SubcomponentId == NULL)
|
|
{
|
|
return gpSubCompCoreTS->OnQueueFiles( queue );
|
|
}
|
|
else if (_tcsicmp(SubcomponentId, APPSRV_COMPONENT_NAME) == 0)
|
|
{
|
|
return gpSubCompToggle->OnQueueFiles( queue );
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
LOGMESSAGE1(_T("ERROR, Got a OnQueueFileOps with unknown SubComp(%s)"), SubcomponentId);
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnCompleteInstallation
|
|
*
|
|
* handler for OC_COMPLETE_INSTALLATION
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnCompleteInstallation(LPCTSTR SubcomponentId)
|
|
{
|
|
static BOOL sbStateUpdated = FALSE;
|
|
|
|
if (!sbStateUpdated)
|
|
{
|
|
StateObject.UpdateState();
|
|
sbStateUpdated = TRUE;
|
|
}
|
|
|
|
if (SubcomponentId == NULL)
|
|
{
|
|
return gpSubCompCoreTS->OnCompleteInstall();
|
|
}
|
|
else if (_tcsicmp(SubcomponentId, APPSRV_COMPONENT_NAME) == 0)
|
|
{
|
|
return gpSubCompToggle->OnCompleteInstall();
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
LOGMESSAGE1(_T("ERROR, Got a Complete Installation with unknown SubComp(%s)"), SubcomponentId);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnSetLanguage()
|
|
*
|
|
* handler for OC_SET_LANGUAGE
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnSetLanguage()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnSetLanguage()
|
|
*
|
|
* handler for OC_SET_LANGUAGE
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQueryImage()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnSetupRequestPages
|
|
*
|
|
* Prepares wizard pages and returns them to the OC Manager
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnSetupRequestPages (WizardPagesType ePageType, SETUP_REQUEST_PAGES *pRequestPages)
|
|
{
|
|
if (ePageType == WizPagesEarly)
|
|
{
|
|
ASSERT(pRequestPages);
|
|
const UINT uiPages = 4;
|
|
|
|
// if we are provided sufficient space for our pages
|
|
if (pRequestPages->MaxPages >= uiPages )
|
|
{
|
|
//
|
|
// Pages will be deleted in PSPCB_RELEASE in OCPage::PropSheetPageProc
|
|
//
|
|
|
|
gpAppPageData = new COCPageData;
|
|
AppSrvWarningPage *pAppSrvWarnPage = new AppSrvWarningPage(gpAppPageData);
|
|
|
|
gpSecPageData = new DefSecPageData;
|
|
DefaultSecurityPage *pSecPage = new DefaultSecurityPage(gpSecPageData);
|
|
|
|
gpPermPageData = new COCPageData;
|
|
PermPage *pPermPage = new PermPage(gpPermPageData);
|
|
|
|
gpAppSrvUninstallPageData = new COCPageData;
|
|
AppSrvUninstallpage *pAppSrvUninstallPage = new AppSrvUninstallpage(gpAppSrvUninstallPageData);
|
|
|
|
if (pAppSrvWarnPage && pAppSrvWarnPage->Initialize() &&
|
|
pSecPage && pSecPage->Initialize() &&
|
|
pPermPage && pPermPage->Initialize() &&
|
|
pAppSrvUninstallPage && pAppSrvUninstallPage->Initialize()
|
|
)
|
|
{
|
|
ASSERT(pRequestPages->Pages);
|
|
pRequestPages->Pages[0] = CreatePropertySheetPage((PROPSHEETPAGE *) pAppSrvWarnPage);
|
|
pRequestPages->Pages[1] = CreatePropertySheetPage((PROPSHEETPAGE *) pSecPage);
|
|
pRequestPages->Pages[2] = CreatePropertySheetPage((PROPSHEETPAGE *) pPermPage);
|
|
pRequestPages->Pages[3] = CreatePropertySheetPage((PROPSHEETPAGE *) pAppSrvUninstallPage);
|
|
|
|
ASSERT(pRequestPages->Pages[0]);
|
|
ASSERT(pRequestPages->Pages[1]);
|
|
ASSERT(pRequestPages->Pages[2]);
|
|
ASSERT(pRequestPages->Pages[3]);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// failed to allocate memory
|
|
//
|
|
|
|
if (gpAppPageData)
|
|
delete gpAppPageData;
|
|
|
|
gpAppPageData = NULL;
|
|
|
|
|
|
if (pAppSrvWarnPage)
|
|
delete pAppSrvWarnPage;
|
|
|
|
pAppSrvWarnPage = NULL;
|
|
|
|
if (gpSecPageData)
|
|
delete gpSecPageData;
|
|
|
|
gpSecPageData = NULL;
|
|
|
|
if (pSecPage)
|
|
delete pSecPage;
|
|
|
|
pSecPage = NULL;
|
|
|
|
if (gpPermPageData)
|
|
delete gpPermPageData;
|
|
|
|
gpPermPageData = NULL;
|
|
|
|
if (pPermPage)
|
|
delete pPermPage;
|
|
|
|
pPermPage =NULL;
|
|
|
|
if (gpAppSrvUninstallPageData)
|
|
delete gpAppSrvUninstallPageData;
|
|
|
|
gpAppSrvUninstallPageData = NULL;
|
|
|
|
if (pAppSrvUninstallPage)
|
|
delete pAppSrvUninstallPage;
|
|
|
|
pAppSrvUninstallPage = NULL;
|
|
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return DWORD(-1);
|
|
}
|
|
}
|
|
|
|
return uiPages;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnWizardCreated()
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnWizardCreated()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnQuerySkipPage()
|
|
*
|
|
* don't let the user deselect the sam component
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQuerySkipPage()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnQuerySelStateChange(LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag);
|
|
*
|
|
* informs that user has changed the state of the component/subcomponent and asks approval
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQuerySelStateChange(LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag)
|
|
{
|
|
BOOL bNewState = SelectionState;
|
|
BOOL bDirectSelection = Flag & OCQ_ACTUAL_SELECTION;
|
|
LOGMESSAGE3(_T("OnQuerySelStateChange for %s, NewState = %d, DirectSelect = %s"), SubcomponentId, SelectionState, bDirectSelection ? _T("True") : _T("False"));
|
|
|
|
return gpSubCompToggle->OnQuerySelStateChange(bNewState, bDirectSelection);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnCleanup()
|
|
*
|
|
* handler for OC_CLEANUP
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnCleanup()
|
|
{
|
|
|
|
if (gpAppPageData)
|
|
delete gpAppPageData;
|
|
|
|
if (gpSecPageData)
|
|
delete gpSecPageData;
|
|
|
|
if (gpPermPageData)
|
|
delete gpPermPageData;
|
|
|
|
if (gpAppSrvUninstallPageData)
|
|
delete gpAppSrvUninstallPageData;
|
|
|
|
if (gpSubCompToggle)
|
|
delete gpSubCompToggle;
|
|
|
|
if (gpSubCompCoreTS)
|
|
delete gpSubCompCoreTS;
|
|
|
|
// DestroySetupData();
|
|
DestroyExtraRoutines();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnQueryState()
|
|
*
|
|
* handler for OC_QUERY_STATE
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQueryState(LPCTSTR SubComponentId, UINT whichstate)
|
|
{
|
|
ASSERT(OCSELSTATETYPE_ORIGINAL == whichstate ||
|
|
OCSELSTATETYPE_CURRENT == whichstate ||
|
|
OCSELSTATETYPE_FINAL == whichstate);
|
|
|
|
TCHAR szState[256];
|
|
|
|
switch (whichstate)
|
|
{
|
|
case OCSELSTATETYPE_ORIGINAL:
|
|
_tcscpy(szState, _T("Original"));
|
|
break;
|
|
case OCSELSTATETYPE_CURRENT:
|
|
_tcscpy(szState, _T("Current"));
|
|
break;
|
|
case OCSELSTATETYPE_FINAL:
|
|
_tcscpy(szState, _T("Final"));
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
return ERROR_BAD_ARGUMENTS;
|
|
}
|
|
|
|
DWORD dwReturn = gpSubCompToggle->OnQueryState(whichstate);
|
|
|
|
TCHAR szReturn[] = _T("SubcompUseOcManagerUknownState");
|
|
switch (dwReturn)
|
|
{
|
|
case SubcompOn:
|
|
_tcscpy(szReturn, _T("SubcompOn"));
|
|
break;
|
|
case SubcompUseOcManagerDefault:
|
|
_tcscpy(szReturn, _T("SubcompUseOcManagerDefault"));
|
|
break;
|
|
case SubcompOff:
|
|
_tcscpy(szReturn, _T("SubcompOff"));
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
LOGMESSAGE3(_T("Query State Asked For %s, %s. Returning %s"), SubComponentId, szState, szReturn);
|
|
|
|
return dwReturn;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnNotificationFromQueue()
|
|
*
|
|
* handler for OC_NOTIFICATION_FROM_QUEUE
|
|
*
|
|
* NOTE: although this notification is defined,
|
|
* it is currently unimplemented in oc manager
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnNotificationFromQueue()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnQueryStepCount
|
|
*
|
|
* handler for OC_QUERY_STEP_COUNT
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnQueryStepCount(LPCTSTR /* SubcomponentId */)
|
|
{
|
|
//
|
|
// now return the ticks for the component
|
|
//
|
|
return gpSubCompCoreTS->OnQueryStepCount() + gpSubCompToggle->OnQueryStepCount();
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnNeedMedia()
|
|
*
|
|
* handler for OC_NEED_MEDIA
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnNeedMedia()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* OnAboutToCommitQueue()
|
|
*
|
|
* handler for OC_ABOUT_TO_COMMIT_QUEUE
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
DWORD OnAboutToCommitQueue(LPCTSTR /* SubcomponentId */)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* BOOL DoesHydraKeysExists()
|
|
*
|
|
* checks if Teminal server string exists in the product suite key.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
BOOL DoesHydraKeysExists()
|
|
{
|
|
BOOL bStringExists = FALSE;
|
|
DWORD dw = IsStringInMultiString(
|
|
HKEY_LOCAL_MACHINE,
|
|
PRODUCT_SUITE_KEY,
|
|
PRODUCT_SUITE_VALUE,
|
|
TS_PRODUCT_SUITE_STRING,
|
|
&bStringExists);
|
|
|
|
return (dw == ERROR_SUCCESS) && bStringExists;
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
|
|
* checks if parameter string exists in given multistring.
|
|
* returns error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
|
|
{
|
|
ASSERT(szkey && *szkey);
|
|
ASSERT(szvalue && *szvalue);
|
|
ASSERT(szCheckForString&& *szCheckForString);
|
|
ASSERT(*szkey != '\\');
|
|
ASSERT(pbFound);
|
|
|
|
// not yet found.
|
|
*pbFound = FALSE;
|
|
|
|
CRegistry reg;
|
|
DWORD dwError = reg.OpenKey(hkey, szkey, KEY_READ); // open up the required key.
|
|
if (dwError == NO_ERROR)
|
|
{
|
|
LPTSTR szSuiteValue;
|
|
DWORD dwSize;
|
|
dwError = reg.ReadRegMultiString(szvalue, &szSuiteValue, &dwSize);
|
|
if (dwError == NO_ERROR)
|
|
{
|
|
LPCTSTR pTemp = szSuiteValue;
|
|
while(_tcslen(pTemp) > 0 )
|
|
{
|
|
if (_tcscmp(pTemp, szCheckForString) == 0)
|
|
{
|
|
*pbFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
pTemp += _tcslen(pTemp) + 1; // point to the next string within the multistring.
|
|
if ( DWORD(pTemp - szSuiteValue) > (dwSize / sizeof(TCHAR)))
|
|
break; // temporary pointer passes the size of the szSuiteValue something is wrong with szSuiteValue.
|
|
}
|
|
}
|
|
}
|
|
|
|
return dwError;
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD AppendStringToMultiString(HKEY hkey, LPCTSTR szSuitekey, LPCTSTR szSuitevalue, LPCTSTR szAppend)
|
|
* appends given string to the given multi_sz value
|
|
* the given key / value must exist.
|
|
* returns error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD AppendStringToMultiString(HKEY hkey, LPCTSTR szSuitekey, LPCTSTR szSuitevalue, LPCTSTR szAppend)
|
|
{
|
|
ASSERT(szSuitekey && *szSuitekey);
|
|
ASSERT(szSuitevalue && *szSuitevalue);
|
|
ASSERT(szAppend && *szAppend);
|
|
ASSERT(*szSuitekey != '\\');
|
|
|
|
CRegistry reg;
|
|
// open the registry key.
|
|
DWORD dwResult = reg.OpenKey(hkey, szSuitekey, KEY_READ | KEY_WRITE);
|
|
if (dwResult == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwSize = 0;
|
|
LPTSTR strOriginalString = 0;
|
|
|
|
// read our multi string
|
|
dwResult = reg.ReadRegMultiString(szSuitevalue, &strOriginalString, &dwSize);
|
|
|
|
if (dwResult == ERROR_SUCCESS)
|
|
{
|
|
// now calculate the Memory required for appending the string.
|
|
// as dwOldSize is in bytes and we are using TCHARs
|
|
DWORD dwMemReq = dwSize + ((_tcslen(szAppend) + 2) * sizeof(TCHAR) / sizeof(BYTE));
|
|
|
|
// NOTE: if dwSize is >= 1 we just require
|
|
// dwSize + ((_tcslen(szAppend) + 1) * sizeof(TCHAR) / sizeof(BYTE));
|
|
// But in case its 0 we provide space for an additional terminating null
|
|
|
|
LPTSTR szProductSuite = (LPTSTR ) new BYTE [dwMemReq];
|
|
|
|
if (!szProductSuite)
|
|
{
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
CopyMemory(szProductSuite, strOriginalString, dwSize);
|
|
|
|
// convert the size into TCHARs
|
|
dwSize = dwSize * sizeof(BYTE) / sizeof(TCHAR);
|
|
|
|
if (dwSize <= 2)
|
|
{
|
|
// there are no strings out there.
|
|
_tcscpy(szProductSuite, szAppend);
|
|
|
|
// new size including terminating null in tchar
|
|
dwSize = _tcslen(szAppend) + 2;
|
|
}
|
|
else
|
|
{
|
|
// there are strings in its. so append our string before the terminating null.
|
|
// for example for this string "A\0B\0\0" dwSize == 5 and we are doing tcscat at "A\0B\0\0" + 4
|
|
_tcscpy(szProductSuite + dwSize - 1, szAppend);
|
|
|
|
// new size including terminating null in tchar
|
|
dwSize += _tcslen(szAppend) + 1;
|
|
}
|
|
|
|
// now append a final terminating null character.
|
|
*(szProductSuite + dwSize-1) = NULL;
|
|
|
|
// reconvert size into bytes.
|
|
dwSize *= sizeof(TCHAR) / sizeof(BYTE);
|
|
|
|
// and finally write the final string.
|
|
dwResult = reg.WriteRegMultiString(szSuitevalue, szProductSuite, dwSize);
|
|
|
|
delete [] szProductSuite;
|
|
|
|
}
|
|
}
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* BOOL GetStringValue(HINF hinf, LPCTSTR section, LPCTSTR key, LPTSTR outputbuffer, DWORD dwSize)
|
|
* returns the given string value under given section.
|
|
* returns success
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD GetStringValue(HINF hinf, LPCTSTR section, LPCTSTR key, LPTSTR outputbuffer, DWORD dwSize)
|
|
{
|
|
INFCONTEXT context;
|
|
|
|
BOOL rc = SetupFindFirstLine(
|
|
hinf,
|
|
section,
|
|
key,
|
|
&context
|
|
);
|
|
if (rc)
|
|
{
|
|
rc = SetupGetStringField(
|
|
&context,
|
|
1,
|
|
outputbuffer,
|
|
dwSize,
|
|
&dwSize
|
|
);
|
|
}
|
|
|
|
if (!rc)
|
|
return GetLastError();
|
|
else
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
DWORD_PTR WebClientSetup(LPCTSTR ComponentId,
|
|
LPCTSTR SubcomponentId,
|
|
UINT Function,
|
|
UINT_PTR Param1,
|
|
PVOID Param2)
|
|
{
|
|
DWORD_PTR rc;
|
|
BOOL bCurrentState, bOriginalState;
|
|
static fTSWebWasActualSelected = FALSE;
|
|
|
|
LOGMESSAGE1(_T("Entering %s"), _T("WebClient Setup"));
|
|
|
|
switch(Function)
|
|
{
|
|
case OC_INIT_COMPONENT:
|
|
return NO_ERROR;
|
|
|
|
case OC_QUERY_STATE:
|
|
return SubcompUseOcManagerDefault;
|
|
break;
|
|
|
|
case OC_SET_LANGUAGE:
|
|
return FALSE;
|
|
|
|
case OC_QUERY_IMAGE:
|
|
rc = (DWORD_PTR)LoadImage(GetInstance(), MAKEINTRESOURCE(IDB_WEBCLIENT), IMAGE_BITMAP,
|
|
0, 0, LR_DEFAULTCOLOR);
|
|
LOGMESSAGE1(_T("Bitmap is: %d"), rc);
|
|
return rc;
|
|
|
|
case OC_QUERY_CHANGE_SEL_STATE:
|
|
{
|
|
BOOL rc = TRUE;
|
|
BOOL fActualSelection = (BOOL)((INT_PTR)Param2 & OCQ_ACTUAL_SELECTION);
|
|
BOOL fProposedState = (BOOL)Param1;
|
|
|
|
//
|
|
// Allow an direct selection or
|
|
// allow indirect selection if it's unselect
|
|
//
|
|
if (fActualSelection || !fProposedState) {
|
|
fTSWebWasActualSelected = fProposedState;
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// parent was selected: default is do not install subcomponent
|
|
//
|
|
if (!fTSWebWasActualSelected) {
|
|
return FALSE;
|
|
}
|
|
//
|
|
// we can be here if subcomponent was actually selected but
|
|
// OCM calls us for such event twice: when the component is actually
|
|
// selected and then when it changes state of the parent.
|
|
// So, in this case accept changes, but reset the flag.
|
|
// We need to reset the flag for the scenario: select some
|
|
// subcomponents, return to the parent, unselect the parent and then
|
|
// select parent again. In such case we have to put default again.
|
|
//
|
|
fTSWebWasActualSelected = FALSE;
|
|
return rc;
|
|
|
|
}
|
|
break;
|
|
|
|
case OC_CALC_DISK_SPACE:
|
|
//rc = OnCalcDiskSpace(SubcomponentId, (DWORD)Param1, Param2);
|
|
|
|
//_tcscpy(section, SubcomponentId);
|
|
|
|
if ((DWORD)Param1)
|
|
{
|
|
rc = SetupAddInstallSectionToDiskSpaceList((HDSKSPC)Param2, GetComponentInfHandle(), NULL,
|
|
STRING_TS_WEBCLIENT_INSTALL, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
rc = SetupRemoveInstallSectionFromDiskSpaceList((HDSKSPC)Param2, GetComponentInfHandle(), NULL,
|
|
STRING_TS_WEBCLIENT_INSTALL, 0, 0);
|
|
}
|
|
|
|
LOGMESSAGE1(_T("Query Disk Space return: %d"), rc);
|
|
|
|
if (!rc)
|
|
rc = GetLastError();
|
|
else
|
|
rc = NO_ERROR;
|
|
break;
|
|
|
|
case OC_QUEUE_FILE_OPS:
|
|
rc = NO_ERROR;
|
|
bOriginalState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext,
|
|
STRING_TS_WEBCLIENT, OCSELSTATETYPE_ORIGINAL);
|
|
bCurrentState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext,
|
|
STRING_TS_WEBCLIENT, OCSELSTATETYPE_CURRENT);
|
|
|
|
LOGMESSAGE2(_T("Original=%d, Current=%d"), bOriginalState, bCurrentState);
|
|
|
|
if(bCurrentState) {
|
|
// Only copy files if it's machine upgrade or
|
|
// the component is not previously installed
|
|
if (!StateObject.IsStandAlone() || !bOriginalState) {
|
|
if (!SetupInstallFilesFromInfSection(GetComponentInfHandle(), NULL, (HSPFILEQ)Param2,
|
|
STRING_TS_WEBCLIENT_INSTALL, NULL, 0)) {
|
|
rc = GetLastError();
|
|
LOGMESSAGE2(_T("ERROR:OnQueueFileOps::SetupInstallFilesFromInfSection <%s> failed.GetLastError() = <%ul)"), SubcomponentId, rc);
|
|
}
|
|
}
|
|
|
|
LOGMESSAGE1(_T("Copy files return: %d"), rc);
|
|
}
|
|
else {
|
|
if (!bOriginalState) {
|
|
// Not installed before, do nothing
|
|
return NO_ERROR;
|
|
}
|
|
if (!SetupInstallFilesFromInfSection(GetComponentInfHandle(), NULL, (HSPFILEQ)Param2,
|
|
STRING_TS_WEBCLIENT_UNINSTALL, NULL, 0))
|
|
{
|
|
rc = GetLastError();
|
|
LOGMESSAGE2(_T("ERROR:OnQueueFileOps::SetupInstallFilesFromInfSection <%s> failed.GetLastError() = <%ul)"), SubcomponentId, rc);
|
|
}
|
|
|
|
LOGMESSAGE1(_T("Remove files return: %d"), rc);
|
|
}
|
|
break;
|
|
|
|
|
|
case OC_COMPLETE_INSTALLATION:
|
|
bOriginalState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext, _T("TSWebClient"), OCSELSTATETYPE_ORIGINAL);
|
|
bCurrentState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext, _T("TSWebClient"), OCSELSTATETYPE_CURRENT);
|
|
LOGMESSAGE2(_T("Orinal=%d, Current=%d"), bOriginalState, bCurrentState);
|
|
|
|
if(bOriginalState==bCurrentState) //state does not change
|
|
return NO_ERROR;
|
|
|
|
int iTrans; //mark removing or adding tsweb dir
|
|
int nLength;
|
|
|
|
iTrans = 0;
|
|
WCHAR wszVDirName[MAX_PATH];
|
|
WCHAR wszDirPath[MAX_PATH];
|
|
TCHAR szDirPath[MAX_PATH];
|
|
TCHAR szVDirName[MAX_PATH];
|
|
|
|
if (GetWindowsDirectory(szDirPath, MAX_PATH) == 0) {
|
|
rc = GetLastError();
|
|
return rc;
|
|
}
|
|
|
|
nLength = _tcsclen(szDirPath);
|
|
if(_T('\\')==szDirPath[nLength-1])
|
|
szDirPath[nLength-1]=_T('\0');
|
|
_tcscat(szDirPath, STRING_TS_WEBCLIENT_DIR);
|
|
|
|
if (LoadString(GetInstance(), IDS_STRING_TSWEBCLIENT_VIRTUALPATH, szVDirName, MAX_PATH) == 0) {
|
|
LOGMESSAGE0(_T("Can't load string IDS_STRING_TSWEBCLIENT_VIRTUALPATH"));
|
|
rc = GetLastError();;
|
|
}
|
|
|
|
LOGMESSAGE2(_T("Dir Path is: %s, Virtual Name is: %s"), szDirPath, szVDirName);
|
|
|
|
if(bCurrentState) //enable IIS directory
|
|
iTrans = TRANS_ADD;
|
|
else
|
|
iTrans = TRANS_DEL;
|
|
|
|
#ifndef _UNICODE
|
|
MultiByteToWideChar(CP_ACP, 0, szDirPath, -1, (LPWSTR) wszDirPath, MAX_PATH);
|
|
MultiByteToWideChar(CP_ACP, 0, szVDirName, -1, (LPWSTR) wszVDirName, MAX_PATH);
|
|
#else
|
|
_tcscpy(wszDirPath, szDirPath);
|
|
_tcscpy(wszVDirName, szVDirName);
|
|
#endif
|
|
|
|
rc = OpenMetabaseAndDoStuff(wszVDirName, wszDirPath, iTrans)?0:1;
|
|
|
|
LOGMESSAGE1(_T("Websetup complete, return is: %d"), rc);
|
|
return rc;
|
|
default:
|
|
rc = NO_ERROR; // it means we do not recognize this command.
|
|
break;
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
|
|
BOOL
|
|
OpenMetabaseAndDoStuff(
|
|
WCHAR * wszVDir,
|
|
WCHAR * wszDir,
|
|
int iTrans)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
HRESULT hr;
|
|
IMSAdminBase *pIMSAdminBase = NULL; // Metabase interface pointer
|
|
WCHAR wszPrintString[MAX_PATH + MAX_PATH];
|
|
|
|
// Make sure that IISADMIN service exists
|
|
if (CheckifServiceExist(_T("IISADMIN")) != 0)
|
|
{
|
|
LOGMESSAGE0(_T("IISADMIN service does not exist"));
|
|
// We have to return TRUE here if IIS service does not exist
|
|
return TRUE;
|
|
}
|
|
|
|
if( FAILED (hr = CoInitializeEx( NULL, COINIT_MULTITHREADED )) ||
|
|
FAILED (hr = ::CoCreateInstance(CLSID_MSAdminBase,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IMSAdminBase,
|
|
(void **)&pIMSAdminBase)))
|
|
{
|
|
LOGMESSAGE1(_T("CoCreateInstance failed with error code %u"), hr);
|
|
return FALSE;
|
|
}
|
|
|
|
switch (iTrans) {
|
|
case TRANS_DEL:
|
|
if(RemoveVirtualDir( pIMSAdminBase, wszVDir)) {
|
|
|
|
hr = pIMSAdminBase->SaveData();
|
|
|
|
if( SUCCEEDED( hr )) {
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case TRANS_ADD:
|
|
if(AddVirtualDir( pIMSAdminBase, wszVDir, wszDir)) {
|
|
|
|
hr = pIMSAdminBase->SaveData();
|
|
|
|
if( SUCCEEDED( hr )) {
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (pIMSAdminBase) {
|
|
pIMSAdminBase->Release();
|
|
pIMSAdminBase = NULL;
|
|
}
|
|
|
|
CoUninitialize();
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetVdirPhysicalPath(
|
|
IMSAdminBase *pIMSAdminBase,
|
|
WCHAR * wszVDir,
|
|
WCHAR *wszStringPathToFill)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fRet = FALSE;
|
|
METADATA_HANDLE hMetabase = NULL; // handle to metabase
|
|
METADATA_RECORD mr;
|
|
WCHAR szTmpData[MAX_PATH];
|
|
DWORD dwMDRequiredDataLen;
|
|
|
|
// open key to ROOT on website #1 (default)
|
|
hr = pIMSAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/LM/W3SVC/1",
|
|
METADATA_PERMISSION_READ,
|
|
REASONABLE_TIMEOUT,
|
|
&hMetabase);
|
|
if( FAILED( hr )) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Get the physical path for the WWWROOT
|
|
mr.dwMDIdentifier = MD_VR_PATH;
|
|
mr.dwMDAttributes = 0;
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = sizeof( szTmpData );
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szTmpData);
|
|
|
|
//if nothing specified get the root.
|
|
if (_wcsicmp(wszVDir, L"") == 0) {
|
|
WCHAR wszTempDir[MAX_PATH];
|
|
swprintf(wszTempDir,L"/ROOT/%s", wszVDir);
|
|
hr = pIMSAdminBase->GetData( hMetabase, wszTempDir, &mr, &dwMDRequiredDataLen );
|
|
} else {
|
|
hr = pIMSAdminBase->GetData( hMetabase, L"/ROOT", &mr, &dwMDRequiredDataLen );
|
|
}
|
|
pIMSAdminBase->CloseKey( hMetabase );
|
|
|
|
if( SUCCEEDED( hr )) {
|
|
wcscpy(wszStringPathToFill,szTmpData);
|
|
fRet = TRUE;
|
|
}
|
|
|
|
pIMSAdminBase->CloseKey( hMetabase );
|
|
return fRet;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
AddVirtualDir(
|
|
IMSAdminBase *pIMSAdminBase,
|
|
WCHAR * wszVDir,
|
|
WCHAR * wszDir)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fRet = FALSE;
|
|
METADATA_HANDLE hMetabase = NULL; // handle to metabase
|
|
WCHAR szTempPath[MAX_PATH];
|
|
DWORD dwMDRequiredDataLen = 0;
|
|
DWORD dwAccessPerm = 0;
|
|
METADATA_RECORD mr;
|
|
|
|
// Attempt to open the virtual dir set on Web server #1 (default server)
|
|
hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
|
|
L"/LM/W3SVC/1/ROOT",
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
|
REASONABLE_TIMEOUT,
|
|
&hMetabase );
|
|
|
|
// Create the key if it does not exist.
|
|
if( FAILED( hr )) {
|
|
return FALSE;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
|
|
mr.dwMDIdentifier = MD_VR_PATH;
|
|
mr.dwMDAttributes = 0;
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = sizeof( szTempPath );
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szTempPath);
|
|
|
|
// see if MD_VR_PATH exists.
|
|
hr = pIMSAdminBase->GetData( hMetabase, wszVDir, &mr, &dwMDRequiredDataLen );
|
|
|
|
if( FAILED( hr )) {
|
|
|
|
fRet = FALSE;
|
|
if( hr == MD_ERROR_DATA_NOT_FOUND ||
|
|
HRESULT_CODE(hr) == ERROR_PATH_NOT_FOUND ) {
|
|
|
|
// Write both the key and the values if GetData() failed with any of the two errors.
|
|
|
|
pIMSAdminBase->AddKey( hMetabase, wszVDir );
|
|
|
|
mr.dwMDIdentifier = MD_VR_PATH;
|
|
mr.dwMDAttributes = METADATA_INHERIT;
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = (wcslen(wszDir) + 1) * sizeof(WCHAR);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(wszDir);
|
|
|
|
// Write MD_VR_PATH value
|
|
hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
|
|
fRet = SUCCEEDED( hr );
|
|
|
|
// Set the default authentication method
|
|
if( fRet ) {
|
|
|
|
DWORD dwAuthorization = MD_AUTH_ANONYMOUS; // NTLM only.
|
|
|
|
mr.dwMDIdentifier = MD_AUTHORIZATION;
|
|
mr.dwMDAttributes = METADATA_INHERIT; // need to inherit so that all subdirs are also protected.
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = DWORD_METADATA;
|
|
mr.dwMDDataLen = sizeof(DWORD);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAuthorization);
|
|
|
|
// Write MD_AUTHORIZATION value
|
|
hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
|
|
fRet = SUCCEEDED( hr );
|
|
}
|
|
}
|
|
}
|
|
|
|
// In the following, do the stuff that we always want to do to the virtual dir, regardless of Admin's setting.
|
|
|
|
if( fRet ) {
|
|
|
|
dwAccessPerm = MD_ACCESS_READ | MD_ACCESS_SCRIPT;
|
|
|
|
mr.dwMDIdentifier = MD_ACCESS_PERM;
|
|
mr.dwMDAttributes = METADATA_INHERIT; // Make it inheritable so all subdirectories will have the same rights.
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = DWORD_METADATA;
|
|
mr.dwMDDataLen = sizeof(DWORD);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAccessPerm);
|
|
|
|
// Write MD_ACCESS_PERM value
|
|
hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
|
|
fRet = SUCCEEDED( hr );
|
|
}
|
|
|
|
if( fRet ) {
|
|
|
|
PWCHAR szDefLoadFile = L"Default.htm,Default.asp";
|
|
|
|
mr.dwMDIdentifier = MD_DEFAULT_LOAD_FILE;
|
|
mr.dwMDAttributes = 0; // no need for inheritence
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = (wcslen(szDefLoadFile) + 1) * sizeof(WCHAR);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szDefLoadFile);
|
|
|
|
// Write MD_DEFAULT_LOAD_FILE value
|
|
hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
|
|
fRet = SUCCEEDED( hr );
|
|
}
|
|
|
|
if( fRet ) {
|
|
|
|
PWCHAR szKeyType = IIS_CLASS_WEB_VDIR_W;
|
|
|
|
mr.dwMDIdentifier = MD_KEY_TYPE;
|
|
mr.dwMDAttributes = 0; // no need for inheritence
|
|
mr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = (wcslen(szKeyType) + 1) * sizeof(WCHAR);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szKeyType);
|
|
|
|
// Write MD_DEFAULT_LOAD_FILE value
|
|
hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
|
|
fRet = SUCCEEDED( hr );
|
|
}
|
|
|
|
pIMSAdminBase->CloseKey( hMetabase );
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
RemoveVirtualDir(
|
|
IMSAdminBase *pIMSAdminBase,
|
|
WCHAR * wszVDir)
|
|
{
|
|
METADATA_HANDLE hMetabase = NULL; // handle to metabase
|
|
HRESULT hr;
|
|
|
|
// Attempt to open the virtual dir set on Web server #1 (default server)
|
|
hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
|
|
L"/LM/W3SVC/1/ROOT",
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
|
REASONABLE_TIMEOUT,
|
|
&hMetabase );
|
|
|
|
if( FAILED( hr )) {
|
|
return FALSE;
|
|
}
|
|
|
|
// We don't check the return value since the key may already
|
|
// not exist and we could get an error for that reason.
|
|
pIMSAdminBase->DeleteKey( hMetabase, wszVDir );
|
|
|
|
pIMSAdminBase->CloseKey( hMetabase );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//Check if the service "lpServiceName" exist or not
|
|
// if exist, return 0
|
|
// if not, return error code
|
|
INT CheckifServiceExist(LPCTSTR lpServiceName)
|
|
{
|
|
INT err = 0;
|
|
SC_HANDLE hScManager = NULL;
|
|
SC_HANDLE hService = NULL;
|
|
|
|
if ((hScManager = OpenSCManager(NULL, NULL, GENERIC_ALL)) == NULL
|
|
|| (hService = OpenService(hScManager, lpServiceName, GENERIC_ALL)) == NULL)
|
|
{
|
|
err = GetLastError();
|
|
}
|
|
|
|
if (hService)
|
|
CloseServiceHandle(hService);
|
|
if (hScManager)
|
|
CloseServiceHandle(hScManager);
|
|
return (err);
|
|
}
|
|
|
|
// EOF
|