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.

409 lines
13 KiB

  1. #include "precomp.hxx"
  2. #include "process.h"
  3. #include "shellapi.h"
  4. #include "urlmon.h"
  5. class CBindStatusCallback : public IBindStatusCallback, public ICodeInstall
  6. {
  7. public:
  8. // IUnknown methods
  9. STDMETHODIMP QueryInterface(REFIID riid,void ** ppv);
  10. STDMETHODIMP_(ULONG) AddRef();
  11. STDMETHODIMP_(ULONG) Release();
  12. // IBindStatusCallback methods
  13. STDMETHODIMP OnStartBinding(DWORD grfBSCOption, IBinding* pbinding);
  14. STDMETHODIMP GetPriority(LONG* pnPriority);
  15. STDMETHODIMP OnLowResource(DWORD dwReserved);
  16. STDMETHODIMP OnProgress(ULONG ulProgress,
  17. ULONG ulProgressMax,
  18. ULONG ulStatusCode,
  19. LPCWSTR szStatusText);
  20. STDMETHODIMP OnStopBinding(HRESULT hrResult, LPCWSTR szError);
  21. STDMETHODIMP GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindinfo);
  22. STDMETHODIMP OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmtetc,
  23. STGMEDIUM* pstgmed);
  24. STDMETHODIMP OnObjectAvailable(REFIID riid, IUnknown* punk);
  25. // ICodeInstall methods
  26. STDMETHODIMP GetWindow(REFGUID guidReason, HWND * phwnd);
  27. STDMETHODIMP OnCodeInstallProblem(ULONG ulStatusCode,
  28. LPCWSTR szDestination,
  29. LPCWSTR szSource,
  30. DWORD dwReserved);
  31. // constructors/destructors
  32. CBindStatusCallback();
  33. ~CBindStatusCallback();
  34. private:
  35. IBindStatusCallback * m_pIBSC;
  36. long _cRef;
  37. HRESULT _hr;
  38. };
  39. extern HINSTANCE ghInstance;
  40. #include "..\appmgr\resource.h"
  41. HRESULT
  42. CAB_FILE::InstallIntoRegistry( HKEY * RegistryKey)
  43. {
  44. // UNDONE - put in dialog box informing the user that we will
  45. // install the cab file here.
  46. #if 0
  47. TCHAR szCaption[256];
  48. TCHAR szBuffer[256];
  49. ::LoadString(ghInstance, IDS_CABCAPTION, szCaption, 256);
  50. ::LoadString(ghInstance, IDS_CABWARNING, szBuffer, 256);
  51. int iReturn = ::MessageBox(NULL, szBuffer,
  52. szCaption,
  53. MB_YESNO);
  54. if (iReturn == IDNO)
  55. {
  56. return E_FAIL;
  57. }
  58. #endif
  59. // Go ahead and install the cab file
  60. IBindCtx *pBC=NULL;
  61. //Synchronous call with bind context.
  62. CBindStatusCallback *pCallback = new CBindStatusCallback();
  63. if (!pCallback)
  64. {
  65. exit (-1);
  66. }
  67. HRESULT hr;
  68. hr = CreateAsyncBindCtx(0, pCallback, NULL, &pBC);
  69. char * szName = GetPackageName();
  70. WCHAR wszName[_MAX_PATH];
  71. MultiByteToWideChar(CP_ACP, 0, szName, -1, wszName, sizeof(wszName)/sizeof(wszName[0]));
  72. IUnknown* punk=NULL;
  73. #if 1
  74. typedef HRESULT (STDAPICALLTYPE *PFNASYNCGETCLASSBITS)(
  75. REFCLSID rclsid, // CLSID
  76. LPCWSTR, LPCWSTR,
  77. DWORD dwFileVersionMS, // CODE=http://foo#Version=a,b,c,d
  78. DWORD dwFileVersionLS, // MAKEDWORD(c,b) of above
  79. LPCWSTR szURL, // CODE= in INSERT tag
  80. IBindCtx *pbc, // bind ctx
  81. DWORD dwClsContext, // CLSCTX flags
  82. LPVOID pvReserved, // Must be NULL
  83. REFIID riid, // Usually IID_IClassFactory
  84. DWORD flags);
  85. PFNASYNCGETCLASSBITS pfnAsyncGetClassBits=NULL;
  86. HINSTANCE hDll;
  87. hDll = LoadLibraryEx("URLMON.DLL", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  88. if (hDll != 0)
  89. {
  90. pfnAsyncGetClassBits = (PFNASYNCGETCLASSBITS)
  91. GetProcAddress(hDll, "AsyncGetClassBits");
  92. if (pfnAsyncGetClassBits == 0)
  93. {
  94. hr = HRESULT_FROM_WIN32(GetLastError());
  95. IUnknown* punk=NULL;
  96. hr=CoGetClassObjectFromURL (
  97. IID_IUnknown,
  98. wszName,
  99. (DWORD) -1,(DWORD) -1, L"", pBC, CLSCTX_SERVER, NULL, IID_IUnknown, (void**) &punk);
  100. if (punk)
  101. {
  102. punk->Release();
  103. }
  104. }
  105. else
  106. {
  107. hr = (*pfnAsyncGetClassBits)(
  108. IID_IUnknown, // bogus CLSID
  109. NULL, NULL,
  110. (DWORD) -1,(DWORD) -1, // don't care about version #
  111. wszName, // URL/Path
  112. pBC, // Bind context with IBSC
  113. CLSCTX_SERVER,
  114. NULL,
  115. IID_IClassFactory,
  116. 1); // 1 == CD_FLAGS_FORCE_DOWNLOAD
  117. }
  118. FreeLibrary(hDll);
  119. }
  120. #else
  121. hr=CoGetClassObjectFromURL (
  122. IID_IUnknown,
  123. wszName,
  124. (DWORD) -1,(DWORD) -1, L"", pBC, CLSCTX_SERVER, NULL, IID_IUnknown, (void**) &punk);
  125. if (punk)
  126. {
  127. punk->Release();
  128. }
  129. #endif
  130. if (hr==MK_S_ASYNCHRONOUS)
  131. {
  132. MSG msg;
  133. while (GetMessage(&msg, NULL, 0,0))
  134. {
  135. TranslateMessage(&msg);
  136. DispatchMessage(&msg);
  137. }
  138. hr=msg.wParam;
  139. }
  140. if (hr==REGDB_E_CLASSNOTREG)
  141. {
  142. hr=S_OK; // Ignore instantiation error since we are asking for IID_IUnknown...
  143. }
  144. pCallback->Release();
  145. pBC->Release();
  146. // i = _spawnlp( P_WAIT,
  147. // "cabinst.exe", // argument
  148. // GetPackageName(), // argument
  149. // 0 ); // argument
  150. return hr;
  151. }
  152. HRESULT
  153. CAB_FILE::InitRegistryKeyToInstallInto(
  154. HKEY * phKey )
  155. {
  156. return CreateMappedRegistryKey( phKey );
  157. }
  158. HRESULT
  159. CAB_FILE::RestoreRegistryKey( HKEY * phKey)
  160. {
  161. return RestoreMappedRegistryKey( phKey);
  162. }
  163. HRESULT
  164. CAB_FILE::DeleteTempKey(HKEY hKey, FILETIME ftLow, FILETIME ftHigh)
  165. {
  166. CleanMappedRegistryKey(hKey, ftLow, ftHigh);
  167. return S_OK;
  168. }
  169. // ===========================================================================
  170. // CBindStatusCallback Implementation
  171. // ===========================================================================
  172. //+---------------------------------------------------------------------------
  173. //
  174. // Method: CBindStatusCallback::CBindStatusCallback
  175. //
  176. // Synopsis: Creates a bind status callback object.
  177. //
  178. //----------------------------------------------------------------------------
  179. CBindStatusCallback::CBindStatusCallback()
  180. : _cRef(1), _hr(MK_S_ASYNCHRONOUS)
  181. {
  182. CreateStdProgressIndicator(GetDesktopWindow(), NULL, NULL, &m_pIBSC);
  183. }
  184. CBindStatusCallback::~CBindStatusCallback()
  185. {
  186. m_pIBSC->Release();
  187. }
  188. //+---------------------------------------------------------------------------
  189. //
  190. // Method: CBindStatusCallback::QueryInterface
  191. //
  192. // Synopsis: Gets an interface pointer to the bind status callback object.
  193. //
  194. //----------------------------------------------------------------------------
  195. STDMETHODIMP
  196. CBindStatusCallback::QueryInterface(REFIID riid, void** ppv)
  197. {
  198. HRESULT hr = S_OK;
  199. *ppv = NULL;
  200. if (IsEqualIID(riid, IID_IUnknown) ||
  201. IsEqualIID(riid, IID_IBindStatusCallback))
  202. {
  203. AddRef();
  204. *ppv = (IBindStatusCallback *) this;
  205. }
  206. else
  207. if (IsEqualIID(riid, IID_ICodeInstall))
  208. {
  209. AddRef();
  210. *ppv = (ICodeInstall *) this;
  211. }
  212. else
  213. {
  214. hr = E_NOINTERFACE;
  215. }
  216. return hr;
  217. }
  218. //+---------------------------------------------------------------------------
  219. //
  220. // Method: CBindStatusCallback::AddRef
  221. //
  222. // Synopsis: Increments the reference count.
  223. //
  224. //----------------------------------------------------------------------------
  225. STDMETHODIMP_(ULONG)
  226. CBindStatusCallback::AddRef()
  227. {
  228. InterlockedIncrement((long *) &_cRef);
  229. return _cRef;
  230. }
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Method: CBindStatusCallback::Release
  234. //
  235. // Synopsis: Decrements the reference count.
  236. //
  237. //----------------------------------------------------------------------------
  238. STDMETHODIMP_(ULONG)
  239. CBindStatusCallback::Release()
  240. {
  241. LONG count = _cRef - 1;
  242. if (0 == InterlockedDecrement((long *) &_cRef))
  243. {
  244. delete this;
  245. count = 0;
  246. }
  247. return count;
  248. }
  249. // ---------------------------------------------------------------------------
  250. // %%Function: CBindStatusCallback::OnStartBinding
  251. // ---------------------------------------------------------------------------
  252. STDMETHODIMP
  253. CBindStatusCallback::OnStartBinding(DWORD grfBSCOption, IBinding* pbinding)
  254. {
  255. return m_pIBSC->OnStartBinding(grfBSCOption, pbinding);
  256. }
  257. // ---------------------------------------------------------------------------
  258. // %%Function: CBindStatusCallback::GetPriority
  259. // ---------------------------------------------------------------------------
  260. STDMETHODIMP
  261. CBindStatusCallback::GetPriority(LONG* pnPriority)
  262. {
  263. return m_pIBSC->GetPriority(pnPriority);
  264. }
  265. // ---------------------------------------------------------------------------
  266. // %%Function: CBindStatusCallback::OnLowResource
  267. // ---------------------------------------------------------------------------
  268. STDMETHODIMP
  269. CBindStatusCallback::OnLowResource(DWORD dwReserved)
  270. {
  271. return m_pIBSC->OnLowResource(dwReserved);
  272. }
  273. // ---------------------------------------------------------------------------
  274. // %%Function: CBindStatusCallback::OnStopBinding
  275. // ---------------------------------------------------------------------------
  276. STDMETHODIMP
  277. CBindStatusCallback::OnStopBinding(HRESULT hrStatus, LPCWSTR pszError)
  278. {
  279. _hr = hrStatus;
  280. PostQuitMessage(hrStatus);
  281. return m_pIBSC->OnStopBinding(hrStatus, pszError);
  282. }
  283. // ---------------------------------------------------------------------------
  284. // %%Function: CBindStatusCallback::GetBindInfo
  285. // ---------------------------------------------------------------------------
  286. STDMETHODIMP
  287. CBindStatusCallback::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
  288. {
  289. return m_pIBSC->GetBindInfo(pgrfBINDF, pbindInfo);
  290. }
  291. // ---------------------------------------------------------------------------
  292. // %%Function: CBindStatusCallback::OnDataAvailable
  293. // This function is called whenever data starts arriving. When the file download is
  294. // complete then the BSCF_LASTDATANOTIFICATION comes and you can get the local cached
  295. // File Name.
  296. // ---------------------------------------------------------------------------
  297. STDMETHODIMP
  298. CBindStatusCallback::OnDataAvailable
  299. (
  300. DWORD grfBSCF,
  301. DWORD dwSize,
  302. FORMATETC* pfmtetc,
  303. STGMEDIUM* pstgmed
  304. )
  305. {
  306. return m_pIBSC->OnDataAvailable(grfBSCF, dwSize, pfmtetc, pstgmed);
  307. }
  308. // ---------------------------------------------------------------------------
  309. // %%Function: CBindStatusCallback::OnObjectAvailable
  310. // ---------------------------------------------------------------------------
  311. STDMETHODIMP
  312. CBindStatusCallback::OnObjectAvailable(REFIID riid, IUnknown* punk)
  313. {
  314. return m_pIBSC->OnObjectAvailable(riid, punk);
  315. }
  316. // ---------------------------------------------------------------------------
  317. // %%Function: CBindStatusCallback::OnProgress
  318. // ---------------------------------------------------------------------------
  319. STDMETHODIMP
  320. CBindStatusCallback::OnProgress
  321. (
  322. ULONG ulProgress,
  323. ULONG ulProgressMax,
  324. ULONG ulStatusCode,
  325. LPCWSTR pwszStatusText
  326. )
  327. {
  328. return m_pIBSC->OnProgress(ulProgress, ulProgressMax, ulStatusCode, pwszStatusText);
  329. }
  330. STDMETHODIMP
  331. CBindStatusCallback::GetWindow(REFGUID guidReason, HWND * phwnd)
  332. {
  333. *phwnd = GetDesktopWindow();
  334. return S_OK;
  335. }
  336. STDMETHODIMP
  337. CBindStatusCallback::OnCodeInstallProblem(ULONG ulStatusCode,
  338. LPCWSTR szDestination,
  339. LPCWSTR szSource,
  340. DWORD dwReserved)
  341. {
  342. HRESULT hr = E_ABORT;
  343. switch (ulStatusCode)
  344. {
  345. case CIP_OLDER_VERSION_EXISTS:
  346. case CIP_NEWER_VERSION_EXISTS:
  347. case CIP_NAME_CONFLICT:
  348. case CIP_TRUST_VERIFICATION_COMPONENT_MISSING:
  349. hr = S_OK;
  350. break;
  351. //case CIP_DRIVE_FULL:
  352. case CIP_ACCESS_DENIED:
  353. default:
  354. break;
  355. }
  356. return hr;
  357. }