Source code of Windows XP (NT5)
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.

237 lines
6.2 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. main.cpp
  5. Abstract:
  6. This file contains the implementation of the WinMain function for HelpSvc.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 03/14/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. //#include <initguid.h>
  13. #include "HelpServiceTypeLib.h"
  14. #include "HelpServiceTypeLib_i.c"
  15. static const LPCWSTR c_szVendorID = L"CN=Microsoft Corporation,L=Redmond,S=Washington,C=US";
  16. static const LPCWSTR c_szProductID = L"{BBFFCB40-76B7-48ec-85B1-F010798EF12C}";
  17. static const LPCWSTR c_szVersion = L"1.0.0.2";
  18. static const LPCWSTR c_szCabNames[] =
  19. {
  20. L"HSCXPSP1.CAB",
  21. L"HSCMUI.CAB"
  22. };
  23. static void PrintUsage(LPCWSTR argv[])
  24. {
  25. wprintf(L"Usage: %s [ -i | -u ] CabFileDirectory\n", argv[0]);
  26. }
  27. static void PrintError(HRESULT hr)
  28. {
  29. LPWSTR lpMsgBuf;
  30. ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  31. FORMAT_MESSAGE_FROM_SYSTEM |
  32. FORMAT_MESSAGE_IGNORE_INSERTS,
  33. NULL,
  34. hr,
  35. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  36. (LPWSTR)&lpMsgBuf,
  37. 0,
  38. NULL );
  39. wprintf(L"Error (hr = %x): %s\n", hr, lpMsgBuf);
  40. }
  41. static HRESULT UpdatePackage(bool fInstall, LPCWSTR szDir)
  42. {
  43. __HCP_FUNC_ENTRY( "UpdatePackage" );
  44. HRESULT hr;
  45. IDispatch *pUpd;
  46. IUnknown *pUnk;
  47. // Create Update object
  48. wprintf(L"CoCreateInstance ...\n");
  49. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_PCHUpdate, NULL, CLSCTX_ALL, IID_IUnknown, (void **)&pUnk ));
  50. __MPC_EXIT_IF_METHOD_FAILS(hr, pUnk->QueryInterface(IID_IDispatch, (void **)&pUpd));
  51. // Update packages
  52. {
  53. if (fInstall)
  54. {
  55. // Install package
  56. CComVariant pvars[2];
  57. DISPPARAMS disp = { pvars, NULL, 2, 0 };
  58. for (int i = 0; i < sizeof(c_szCabNames) / sizeof(c_szCabNames[0]); i++)
  59. {
  60. // Update package
  61. MPC::wstring strCab = szDir;
  62. if (szDir[wcslen(szDir)-1] != L'\\') strCab += L"\\";
  63. strCab += c_szCabNames[i];
  64. wprintf(L"Installing package: %s ...\n", strCab.c_str());
  65. // Call UpdatePkg method
  66. pvars[1] = strCab.c_str();
  67. pvars[0] = true;
  68. pUpd->Invoke(DISPID_HCU_UPDATEPKG, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL );
  69. }
  70. }
  71. else
  72. {
  73. // Uninstall package
  74. CComVariant pvars[3];
  75. DISPPARAMS disp = { pvars, NULL, 3, 0 };
  76. wprintf(L"Uninstalling package by ID: VendorID = \"%s\", ProductID = \"%s\", Version = \"%s\" ...\n", c_szVendorID, c_szProductID, c_szVersion);
  77. // Call RemotePkgByID method
  78. pvars[2] = c_szVendorID;
  79. pvars[1] = c_szProductID;
  80. pvars[0] = c_szVersion;
  81. __MPC_EXIT_IF_METHOD_FAILS(hr, pUpd->Invoke( DISPID_HCU_REMOVEPKGBYID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL ));
  82. }
  83. }
  84. hr = S_OK;
  85. __HCP_FUNC_CLEANUP;
  86. // Report result
  87. if (hr == S_OK)
  88. {
  89. wprintf(L"Update finished.\n");
  90. }
  91. else
  92. {
  93. PrintError(hr);
  94. }
  95. __HCP_FUNC_EXIT(hr);
  96. }
  97. static HRESULT ProcessArguments( int argc ,
  98. LPCWSTR* argv )
  99. {
  100. __HCP_FUNC_ENTRY( "ProcessArguments" );
  101. HRESULT hr;
  102. LPCWSTR szDir = 0;
  103. WCHAR szFullDir[MAX_PATH + 1], *szFilePart;
  104. bool fInstall = true;
  105. int i;
  106. if (argc > 3)
  107. {
  108. PrintUsage(argv);
  109. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  110. }
  111. for(i=1; i<argc; i++)
  112. {
  113. LPCWSTR szArg = argv[i];
  114. if(szArg[0] == '-' ||
  115. szArg[0] == '/' )
  116. {
  117. szArg++;
  118. if(_wcsicmp( szArg, L"i" ) == 0)
  119. {
  120. fInstall = true;
  121. }
  122. else if(_wcsicmp( szArg, L"u" ) == 0)
  123. {
  124. fInstall = false;
  125. }
  126. else
  127. {
  128. PrintUsage(argv);
  129. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  130. }
  131. }
  132. else
  133. {
  134. if (!szDir) szDir = szArg;
  135. else
  136. {
  137. PrintUsage(argv);
  138. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  139. }
  140. }
  141. }
  142. //////////////////////////////////////////////////////////////////////
  143. if (!szDir)
  144. {
  145. // Get current dir
  146. __MPC_EXIT_IF_CALL_RETURNS_ZERO(hr, GetCurrentDirectory(MAX_PATH, szFullDir));
  147. }
  148. else
  149. {
  150. // Get full path
  151. int nLength = GetFullPathName(szDir, MAX_PATH, szFullDir, &szFilePart);
  152. if (nLength <= 0 || nLength > MAX_PATH) __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ::GetLastError());
  153. }
  154. szDir = szFullDir;
  155. hr = UpdatePackage(fInstall, szDir);
  156. __HCP_FUNC_CLEANUP;
  157. __HCP_FUNC_EXIT(hr);
  158. }
  159. extern "C" int _cdecl wmain( int argc, LPCWSTR *argv)
  160. {
  161. HRESULT hr;
  162. if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
  163. {
  164. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  165. -1 , // We don't care which authentication service we use.
  166. NULL ,
  167. NULL ,
  168. RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
  169. RPC_C_IMP_LEVEL_IMPERSONATE, // For package installation
  170. NULL ,
  171. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  172. NULL )))
  173. {
  174. //
  175. // Process arguments
  176. //
  177. hr = ProcessArguments( argc, argv );
  178. }
  179. ::CoUninitialize();
  180. }
  181. return FAILED(hr) ? 1 : 0;
  182. }