238 lines
6.2 KiB
C++
238 lines
6.2 KiB
C++
/******************************************************************************
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
main.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the WinMain function for HelpSvc.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 03/14/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
//#include <initguid.h>
|
|
|
|
#include "HelpServiceTypeLib.h"
|
|
#include "HelpServiceTypeLib_i.c"
|
|
|
|
static const LPCWSTR c_szVendorID = L"CN=Microsoft Corporation,L=Redmond,S=Washington,C=US";
|
|
static const LPCWSTR c_szProductID = L"{BBFFCB40-76B7-48ec-85B1-F010798EF12C}";
|
|
static const LPCWSTR c_szVersion = L"1.0.0.2";
|
|
|
|
|
|
static const LPCWSTR c_szCabNames[] =
|
|
{
|
|
L"HSCXPSP1.CAB",
|
|
L"HSCMUI.CAB"
|
|
};
|
|
|
|
|
|
|
|
static void PrintUsage(LPCWSTR argv[])
|
|
{
|
|
wprintf(L"Usage: %s [ -i | -u ] CabFileDirectory\n", argv[0]);
|
|
}
|
|
|
|
|
|
static void PrintError(HRESULT hr)
|
|
{
|
|
LPWSTR lpMsgBuf;
|
|
::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
hr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPWSTR)&lpMsgBuf,
|
|
0,
|
|
NULL );
|
|
wprintf(L"Error (hr = %x): %s\n", hr, lpMsgBuf);
|
|
}
|
|
|
|
|
|
static HRESULT UpdatePackage(bool fInstall, LPCWSTR szDir)
|
|
{
|
|
__HCP_FUNC_ENTRY( "UpdatePackage" );
|
|
|
|
HRESULT hr;
|
|
IDispatch *pUpd;
|
|
IUnknown *pUnk;
|
|
|
|
// Create Update object
|
|
wprintf(L"CoCreateInstance ...\n");
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_PCHUpdate, NULL, CLSCTX_ALL, IID_IUnknown, (void **)&pUnk ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pUnk->QueryInterface(IID_IDispatch, (void **)&pUpd));
|
|
|
|
// Update packages
|
|
{
|
|
if (fInstall)
|
|
{
|
|
// Install package
|
|
CComVariant pvars[2];
|
|
DISPPARAMS disp = { pvars, NULL, 2, 0 };
|
|
|
|
for (int i = 0; i < sizeof(c_szCabNames) / sizeof(c_szCabNames[0]); i++)
|
|
{
|
|
// Update package
|
|
MPC::wstring strCab = szDir;
|
|
if (szDir[wcslen(szDir)-1] != L'\\') strCab += L"\\";
|
|
strCab += c_szCabNames[i];
|
|
|
|
wprintf(L"Installing package: %s ...\n", strCab.c_str());
|
|
|
|
// Call UpdatePkg method
|
|
pvars[1] = strCab.c_str();
|
|
pvars[0] = true;
|
|
|
|
pUpd->Invoke(DISPID_HCU_UPDATEPKG, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Uninstall package
|
|
CComVariant pvars[3];
|
|
DISPPARAMS disp = { pvars, NULL, 3, 0 };
|
|
|
|
wprintf(L"Uninstalling package by ID: VendorID = \"%s\", ProductID = \"%s\", Version = \"%s\" ...\n", c_szVendorID, c_szProductID, c_szVersion);
|
|
|
|
// Call RemotePkgByID method
|
|
pvars[2] = c_szVendorID;
|
|
pvars[1] = c_szProductID;
|
|
pvars[0] = c_szVersion;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pUpd->Invoke( DISPID_HCU_REMOVEPKGBYID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL ));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
// Report result
|
|
if (hr == S_OK)
|
|
{
|
|
wprintf(L"Update finished.\n");
|
|
}
|
|
else
|
|
{
|
|
PrintError(hr);
|
|
}
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
|
|
|
|
static HRESULT ProcessArguments( int argc ,
|
|
LPCWSTR* argv )
|
|
{
|
|
__HCP_FUNC_ENTRY( "ProcessArguments" );
|
|
|
|
HRESULT hr;
|
|
LPCWSTR szDir = 0;
|
|
WCHAR szFullDir[MAX_PATH + 1], *szFilePart;
|
|
bool fInstall = true;
|
|
int i;
|
|
|
|
if (argc > 3)
|
|
{
|
|
PrintUsage(argv);
|
|
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
}
|
|
|
|
for(i=1; i<argc; i++)
|
|
{
|
|
LPCWSTR szArg = argv[i];
|
|
|
|
if(szArg[0] == '-' ||
|
|
szArg[0] == '/' )
|
|
{
|
|
szArg++;
|
|
|
|
if(_wcsicmp( szArg, L"i" ) == 0)
|
|
{
|
|
fInstall = true;
|
|
}
|
|
else if(_wcsicmp( szArg, L"u" ) == 0)
|
|
{
|
|
fInstall = false;
|
|
}
|
|
else
|
|
{
|
|
PrintUsage(argv);
|
|
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!szDir) szDir = szArg;
|
|
else
|
|
{
|
|
PrintUsage(argv);
|
|
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
if (!szDir)
|
|
{
|
|
// Get current dir
|
|
__MPC_EXIT_IF_CALL_RETURNS_ZERO(hr, GetCurrentDirectory(MAX_PATH, szFullDir));
|
|
}
|
|
else
|
|
{
|
|
// Get full path
|
|
int nLength = GetFullPathName(szDir, MAX_PATH, szFullDir, &szFilePart);
|
|
if (nLength <= 0 || nLength > MAX_PATH) __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ::GetLastError());
|
|
}
|
|
|
|
szDir = szFullDir;
|
|
|
|
|
|
hr = UpdatePackage(fInstall, szDir);
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
|
|
|
|
extern "C" int _cdecl wmain( int argc, LPCWSTR *argv)
|
|
{
|
|
HRESULT hr;
|
|
if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
|
|
{
|
|
if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
|
|
-1 , // We don't care which authentication service we use.
|
|
NULL ,
|
|
NULL ,
|
|
RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
|
|
RPC_C_IMP_LEVEL_IMPERSONATE, // For package installation
|
|
NULL ,
|
|
EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
|
|
NULL )))
|
|
{
|
|
//
|
|
// Process arguments
|
|
//
|
|
hr = ProcessArguments( argc, argv );
|
|
}
|
|
|
|
::CoUninitialize();
|
|
}
|
|
|
|
return FAILED(hr) ? 1 : 0;
|
|
}
|