ADDRINST.C

// --addrinst.c----------------------------------------------------------------- 
//
// Address Type installation sample.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#include "edk.h"
#include "dapi.h"

//
// Names of Command Line Arguments
//

#define ARG_SITEDN"SITEDN"
#define ARG_NAME"NAME"
#define ARG_MACHINE "MACHINE"
#define ARG_TYPE"TYPE"
#define ARG_SERVER"SERVER"
#define ARG_PROXYDLL "PROXYDLL"
#define ARG_GWPROXY "GWPROXY"
#define ARG_DELETE "DELETE"
#define ARG_HELP1"?"
#define ARG_HELP2"HELP"

//
// Table of Command Line Switches for _HrExpandCommandLineArgument()
//

static char * rgpszArgArray[] = {
ARG_SITEDN,
ARG_NAME,
ARG_MACHINE,
ARG_TYPE,
ARG_SERVER,
ARG_PROXYDLL,
ARG_GWPROXY,
ARG_DELETE,
ARG_HELP1,
ARG_HELP2,
};

#define ARGARRAYSIZE (sizeof(rgpszArgArray)/sizeof(rgpszArgArray[0]))

//
// Variables For Command Line Arguments
//

char szSiteDN[MAX_PATH+1] = {0};
char szDisplayName[MAX_PATH+1] = {0};
char szMachineType[MAX_PATH+1] = {0};
char szAddressType[MAX_PATH+1] = {0};
char szProxygenDll[MAX_PATH+1] = {0};
char szFileName[MAX_PATH+1] = {0};
char szServer[MAX_PATH+1]= {0};
char szGatewayProxy[MAX_PATH+1] = {0};
BOOL fDisplayedHelp= FALSE;
BOOL fDeleteAddrType = FALSE;
LPVOID lpVersionInfo = NULL;
DWORD dwFileVersionMS = 0;
DWORD dwFileVersionLS = 0;

//
// Functions
//

//$--ShowUsage------------------------------------------------------------------
// Show usage information.
// -----------------------------------------------------------------------------
static VOID ShowUsage(void)// RETURNS: nothing
{
DEBUGPRIVATE("ShowUsage()\n");

printf("USAGE: ADDRINST [Flags]\n\n");
printf(" [Flags] Enter ADDRINST /? for details\n");

fDisplayedHelp = TRUE;
}

//$--ShowHelp-------------------------------------------------------------------
// Show help information.
// -----------------------------------------------------------------------------
static VOID ShowHelp(void)// RETURNS: nothing
{
DEBUGPRIVATE("ShowHelp()\n");

printf("Address Type Installation sample.\n\n");
printf("USAGE: ADDRINST [Flags]\n\n");
printf(" Required Flags\n");
printf(" /SITEDN= Address type site distinguished name\n");
printf(" /NAME= Address type display name\n");
printf(" /MACHINE= Proxy generator DLL machine type\n");
printf(" /TYPE= Address type\n");
printf(" /PROXYDLL= Proxy generator DLL (include full path)\n");
printf(" /SERVER= Server computer name\n");
printf(" /GWPROXY= Gateway site proxy\n");
printf("\n");
printf(" Optional Flags\n");
printf(" /DELETE Delete address type\n");
printf(" /HELP or /? Display help\n");

fDisplayedHelp = TRUE;
}

//$--HrConfig-------------------------------------------------------------------
// Read configuration from command line.
// -----------------------------------------------------------------------------
HRESULT HrConfig( // RETURNS: return code
IN int argc, // number of arguments on command line
IN char *argv[]) // array of command line arguments
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
char * pszArgument = NULL;
char * pszValue = NULL;
int i = 0;
UINT dwBytes = 0;
LPVOID lpBuffer = 0;
VS_FIXEDFILEINFO *lpvsFixedFileInfo = 0;

DEBUGPRIVATE("HrConfig()\n");

// If there are no command line arguments then show a usage message.

if (argc < 2)
{
ShowUsage();
hr = E_FAIL;
goto cleanup;
}

// Do an initial check for /? or /HELP. If found, show a help message
// and don't do any other parsing.

for (i = 1; i < argc; i++)
{
hr = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray, ARGARRAYSIZE, NULL, &pszArgument, &pszValue);

if (SUCCEEDED(hr) && pszArgument &&
(!lstrcmpi(pszArgument,ARG_HELP1) ||
!lstrcmpi(pszArgument,ARG_HELP2)))
{
ShowHelp();
hr = E_FAIL;
goto cleanup;
}
}

// Loop through and parse all the command line arguments.

for (i = 1; i < argc; i++)
{
hrT = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray, ARGARRAYSIZE, NULL, &pszArgument, &pszValue);

if (FAILED(hrT))
{
hr = hrT;

if (hr == EDK_E_NOT_FOUND)
{
fprintf(stderr, "ERROR: unknown command line flag: %s\n",
argv[i]);
continue;
}
else
{
fprintf(stderr, "ERROR: unable to parse command line.\n");
goto cleanup;
}
}

// Parse flag arguments that don't take a value.

else if (pszArgument != NULL && pszValue == NULL)
{
if (!lstrcmpi(pszArgument,ARG_DELETE))
{
fDeleteAddrType = TRUE;
}

// Other flag (must take a value).

else
{
fprintf(stderr, "ERROR: flag /%s requires a value\n",
pszArgument);
hr = HR_LOG(E_FAIL);
}
}

// Parse flag arguments that take a value.

else if (pszArgument != NULL && pszValue != NULL)
{

if (!lstrcmpi(pszArgument,ARG_SITEDN))
{
strncpy(szSiteDN, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_NAME))
{
strncpy(szDisplayName, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_MACHINE))
{
strncpy(szMachineType, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_TYPE))
{
strncpy(szAddressType, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_SERVER))
{
strncpy(szServer, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_PROXYDLL))
{
strncpy(szProxygenDll, pszValue, MAX_PATH);
}

else if (!lstrcmpi(pszArgument,ARG_GWPROXY))
{
strncpy(szGatewayProxy, pszValue, MAX_PATH);
}

// Other flag (must not take a value).

else
{
fprintf(stderr, "ERROR: flag /%s does not take a value\n",
pszArgument);
hr = HR_LOG(E_FAIL);
}
}

// Catch unknown arguments.

else
{
fprintf(stderr, "ERROR: unknown argument %s\n", argv[i]);
hr = HR_LOG(E_FAIL);
}
}

// Make sure we have all the info we need.

if (SUCCEEDED(hr))
{
if (szServer[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_SERVER);
hr = HR_LOG(E_FAIL);
}
else
{
DWORD dwService = 0;
DWORD dwCurrentState = 0;

hr = HrGetExchangeStatus(
szServer,
&dwService,
&dwCurrentState);

if(FAILED(hr))
{
fprintf(stderr, "ERROR: please start Exchange on %s\n",szServer);
hr = HR_LOG(E_FAIL);
}
}

if (szSiteDN[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_SITEDN);
hr = HR_LOG(E_FAIL);
}

if (szAddressType[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_TYPE);
hr = HR_LOG(E_FAIL);
}

if (szMachineType[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_MACHINE);
hr = HR_LOG(E_FAIL);
}

if (szGatewayProxy[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_GWPROXY);
hr = HR_LOG(E_FAIL);
}

if(fDeleteAddrType == FALSE)
{
if (szDisplayName[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_NAME);
hr = HR_LOG(E_FAIL);
}

if (szProxygenDll[0] == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_PROXYDLL);
hr = HR_LOG(E_FAIL);
}
else
{
DWORD dwAttrib = 0;

dwAttrib = GetFileAttributes(szProxygenDll);

if(dwAttrib == 0xFFFFFFFF)
{
fprintf(stderr,
"ERROR: please specify an existing file for /%s\n",
ARG_PROXYDLL);

hr = HR_LOG(E_FAIL);
}
}
}
}

if(SUCCEEDED(hr))
{
//
// Get proxy generation DLL file name
//

strncpy(szFileName,
_GetFileNameFromFullPath((LPTSTR)szProxygenDll), MAX_PATH);

//
// Get proxy generation DLL file version
//

hr = HrGetFileVersionInfo(
szProxygenDll,
&lpVersionInfo);

if(FAILED(hr))
{
fprintf(stderr, "ERROR: version unavailable [%08lx] in /%s\n",
hr,
ARG_PROXYDLL);

hr = HR_LOG(E_FAIL);
}
else
{
BOOL fRet = FALSE;

fRet = VerQueryValue(lpVersionInfo,
TEXT("\\"),
&lpBuffer,
&dwBytes);

if(fRet == FALSE)
{
fprintf(stderr, "ERROR: version resource is invalid in /%s\n",
ARG_PROXYDLL);

hr = HR_LOG(E_FAIL);
}
else
{
lpvsFixedFileInfo = (VS_FIXEDFILEINFO *)lpBuffer;

dwFileVersionMS = lpvsFixedFileInfo->dwFileVersionMS;
dwFileVersionLS = lpvsFixedFileInfo->dwFileVersionLS;
}
}
}

hrT = HrAdminProgramExists();

if(FAILED(hrT))
{
fprintf(stderr, "ERROR: install the Exchange administrator program\n");
hr = HR_LOG(E_FAIL);
}

cleanup:

GLOBALFREE(lpVersionInfo);

RETURN(hr);
}

//$--main-----------------------------------------------------------------------
// Main function that performs directory import.
// -----------------------------------------------------------------------------
int main(
IN int argc,
IN char *argv[])
{
HRESULT hr = NOERROR;
FILE *fp = NULL;
BOOL fErrMsg = TRUE;
DWORD dwOldFileVersionMS = 0;
DWORD dwOldFileVersionLS = 0;

printf( "\n" );

//
// Get parameters from the command-line
//

hr = HrConfig(argc, argv);

if (FAILED(hr))
{
fErrMsg = FALSE;
goto cleanup;
}

if(fDeleteAddrType == FALSE)
{
hr = HrAddressTypeExists(
szServer,
szSiteDN,
szAddressType,
szMachineType);

if(SUCCEEDED(hr))
{
hr = HrGetAddressTypeVersion(
szServer,
szSiteDN,
szAddressType,
szMachineType,
&dwOldFileVersionMS,
&dwOldFileVersionLS);

if(FAILED(hr))
{
fprintf(stderr,
"ERROR: file version is missing in %s address type\n",
szAddressType);
hr = HR_LOG(E_FAIL);
goto cleanup;
}

if((dwOldFileVersionMS > dwFileVersionMS) ||
((dwOldFileVersionMS == dwFileVersionMS) &&
(dwOldFileVersionLS > dwFileVersionLS)))
{
fprintf(stderr,
"WARNING: installing older version of %s address type\n",
szAddressType);
}

hr = HrRemoveAddressType(
szServer,
szSiteDN,
szAddressType,
szMachineType);

if(FAILED(hr))
{
fprintf(stderr,
"ERROR: unable to remove %s address type\n",
szAddressType);
hr = HR_LOG(E_FAIL);
goto cleanup;
}
}

hr = HrInstallGatewayProxy(
szServer,
szSiteDN,
szGatewayProxy);

if(FAILED(hr))
{
fprintf(stderr,
"WARNING: unable to add site proxy for %s address type\n",
szAddressType);
}

hr = HrInstallAddressType(
szServer,
szSiteDN,
szDisplayName,
szAddressType,
dwFileVersionMS,
dwFileVersionLS,
szFileName,
szMachineType);
}
else
{
hr = HrAddressTypeExists(
szServer,
szSiteDN,
szAddressType,
szMachineType);

if(FAILED(hr))
{
fprintf(stderr,
"ERROR: the %s address type does not exist\n",
szAddressType);
hr = HR_LOG(E_FAIL);
goto cleanup;
}

hr = HrRemoveGatewayProxy(
szServer,
szSiteDN,
szGatewayProxy);

if(FAILED(hr))
{
fprintf(stderr,
"WARNING: unable to remove site proxy for %s address type\n",
szAddressType);
}

hr = HrRemoveAddressType(
szServer,
szSiteDN,
szAddressType,
szMachineType);
}

cleanup:

// Successful completion.

if (fDisplayedHelp)
{
hr = NOERROR;
}
else if (SUCCEEDED(hr))
{
if(fDeleteAddrType == FALSE)
{
fprintf(stderr, "Address type installed successfully.\n");
}
else
{
fprintf(stderr, "Address type deleted successfully.\n");
}

hr = NOERROR;
}

// Error completion.

else
{
if(fErrMsg == TRUE)
{
fprintf(stderr, "ERROR: error(s) written to NT Event Log.\n");
}
hr = HR_LOG(E_FAIL);
}

// return exit code
return _nEcFromHr(hr);

}