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.

738 lines
17 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: install.cpp
  6. //
  7. // Purpose: Install/uninstall components
  8. //
  9. //=======================================================================
  10. #include "stdafx.h"
  11. #include "install.h"
  12. #include <advpub.h>
  13. extern CState g_v3state; //defined in CV3.CPP
  14. // This function installs an active setup catalog item.
  15. void InstallActiveSetupItem(LPCTSTR szLocalDir, LPCTSTR pszCifFile, PSELECTITEMINFO pStatusInfo, IWUProgress* pProgress)
  16. {
  17. USES_CONVERSION;
  18. MSG msg;
  19. HRESULT hr;
  20. DWORD dwEngineStatus;
  21. IInstallEngine2* pInsEng = NULL;
  22. ICifFile* picif = NULL;
  23. ICifComponent* pcomp = NULL;
  24. IEnumCifComponents* penum = NULL;
  25. CInstallEngineCallback* pCallback = NULL;
  26. try
  27. {
  28. //
  29. // Create active setup engine
  30. //
  31. hr = CoCreateInstance(CLSID_InstallEngine, NULL, CLSCTX_INPROC_SERVER, IID_IInstallEngine2,(void **)&pInsEng);
  32. if (FAILED(hr))
  33. throw hr;
  34. // Tell active setup the direct and directory to use. This is the directory
  35. // where we downloaded the files previously.
  36. hr = pInsEng->SetDownloadDir(T2A(szLocalDir));
  37. if (FAILED(hr))
  38. throw hr;
  39. hr = pInsEng->SetLocalCif(T2A(pszCifFile));
  40. if (FAILED(hr))
  41. throw hr;
  42. //
  43. // Create the callback object and register the install engines callback interface
  44. //
  45. pCallback = new CInstallEngineCallback;
  46. if (!pCallback)
  47. {
  48. throw HRESULT_FROM_WIN32(GetLastError());
  49. }
  50. pCallback->SetProgressPtr(pProgress);
  51. pInsEng->RegisterInstallEngineCallback((IInstallEngineCallback *)pCallback);
  52. pCallback->SetEnginePtr(pInsEng);
  53. //
  54. // Get a pointer to the CIF interface we need in order to enum the
  55. // CIF components and we need to do that on this single item CIF
  56. // becuase we need to tell the install engine what action to perform.
  57. //
  58. hr = pInsEng->GetICifFile(&picif);
  59. if (FAILED(hr))
  60. throw hr;
  61. hr = picif->EnumComponents(&penum, 0, NULL);
  62. if (FAILED(hr))
  63. throw hr;
  64. hr = penum->Next(&pcomp);
  65. if (FAILED(hr))
  66. throw hr;
  67. // Set action to install and then install the component.
  68. pcomp->SetInstallQueueState(SETACTION_INSTALL);
  69. hr = pInsEng->InstallComponents(EXECUTEJOB_IGNORETRUST | EXECUTEJOB_IGNOREDOWNLOADERROR);
  70. if (FAILED(hr))
  71. {
  72. TRACE_HR(hr, "InstallActiveSetupItem: inseng.InstallComponents failed");
  73. throw hr;
  74. }
  75. do
  76. {
  77. pInsEng->GetEngineStatus(&dwEngineStatus);
  78. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  79. {
  80. TranslateMessage(&msg);
  81. DispatchMessage(&msg);
  82. }
  83. SleepEx(50, TRUE);
  84. } while (dwEngineStatus != ENGINESTATUS_READY);
  85. if (pcomp->IsComponentInstalled() != ICI_INSTALLED)
  86. {
  87. hr = pCallback->LastError();
  88. //
  89. // if we don't know the exact error from the callback, use E_FAIL
  90. //
  91. if (hr == NOERROR)
  92. hr = E_FAIL;
  93. TRACE_HR(hr, "InstallActiveSetupItem: inseng failed to install");
  94. throw hr;
  95. }
  96. //
  97. // get the return status
  98. //
  99. if (pCallback->GetStatus() & STOPINSTALL_REBOOTNEEDED)
  100. pStatusInfo->iStatus = ITEM_STATUS_SUCCESS_REBOOT_REQUIRED;
  101. else
  102. pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
  103. pStatusInfo->hrError = NOERROR;
  104. //
  105. // release interfaces
  106. //
  107. if (penum)
  108. penum->Release();
  109. if (picif)
  110. picif->Release();
  111. if (pInsEng)
  112. pInsEng->Release();
  113. if (pCallback)
  114. delete pCallback;
  115. }
  116. catch(HRESULT hr)
  117. {
  118. pStatusInfo->iStatus = ITEM_STATUS_FAILED;
  119. pStatusInfo->hrError = hr;
  120. if (penum)
  121. penum->Release();
  122. if (picif)
  123. picif->Release();
  124. if (pInsEng)
  125. pInsEng->Release();
  126. if (pCallback)
  127. delete pCallback;
  128. throw hr;
  129. }
  130. }
  131. //This function handles installation of a Device driver package.
  132. void InstallDriverItem(
  133. LPCTSTR szLocalDir, //Local directory where installation files are.
  134. BOOL bWindowsNT, //TRUE if client machine is NT else FALSE.
  135. LPCTSTR pszTitle, //Description of package, Device Manager displays this in its install dialog.
  136. PINVENTORY_ITEM pItem, //Install Item Information
  137. PSELECTITEMINFO pStatusInfo //Returned status information.
  138. )
  139. {
  140. LOG_block("InstallDriverItem");
  141. try
  142. {
  143. //Note: GetCatalog automatically prunes any drivers if the system is
  144. //not either NT 5 or Windows 98 since we only support installation
  145. //of drivers on these platforms.
  146. //If we do not have a hardware id then we cannot install the device.
  147. PWU_VARIABLE_FIELD pvTmp = pItem->pv->Find(WU_CDM_HARDWARE_ID);
  148. if (!pvTmp)
  149. {
  150. pStatusInfo->iStatus = ITEM_STATUS_FAILED;
  151. pStatusInfo->hrError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  152. return;
  153. }
  154. BOOL reboot = FALSE;
  155. CdmInstallDriver(bWindowsNT,
  156. (WU_ITEM_STATE_CURRENT == pItem->ps->state) ? edsCurrent : edsNew,
  157. (LPCTSTR)pvTmp->pData, szLocalDir, pszTitle, (PULONG)&reboot);
  158. if (reboot)
  159. pStatusInfo->iStatus = ITEM_STATUS_SUCCESS_REBOOT_REQUIRED;
  160. else
  161. pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
  162. pStatusInfo->hrError = NOERROR;
  163. }
  164. catch(HRESULT hr)
  165. {
  166. pStatusInfo->iStatus = ITEM_STATUS_FAILED;
  167. pStatusInfo->hrError = hr;
  168. throw hr;
  169. }
  170. }
  171. HRESULT UninstallDriverItem(PINVENTORY_ITEM pItem, PSELECTITEMINFO pStatusInfo)
  172. {
  173. PBYTE pTitle;
  174. PWU_VARIABLE_FIELD pvTitle;
  175. PWU_VARIABLE_FIELD pvTmp;
  176. BOOL bWindowsNT;
  177. TCHAR szLocalDir[MAX_PATH];
  178. BOOL bReboot = FALSE;
  179. bWindowsNT = IsWindowsNT();
  180. if (!(pvTmp = pItem->pv->Find(WU_CDM_HARDWARE_ID)) )
  181. {
  182. pStatusInfo->iStatus = ITEM_STATUS_FAILED;
  183. pStatusInfo->hrError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  184. return E_UNEXPECTED;
  185. }
  186. if (pvTitle = pItem->pd->pv->Find(WU_DESCRIPTION_TITLE))
  187. {
  188. pTitle = (PBYTE)pvTitle->pData;
  189. }
  190. else
  191. {
  192. pTitle = (PBYTE)"";
  193. }
  194. pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
  195. //we will call UpdateCDMDriver with our cache directory but this directory should not
  196. //really be used by UpdateCDMDriver in case of an uninstall since the uninstall case
  197. //reads the correct directory from the registry
  198. GetWindowsUpdateDirectory(szLocalDir);
  199. try
  200. {
  201. CdmInstallDriver(bWindowsNT, edsBackup, (LPCTSTR)pvTmp->pData, szLocalDir, (LPCTSTR)pTitle, (PULONG)&bReboot);
  202. if (bReboot)
  203. {
  204. g_v3state.m_bRebootNeeded = TRUE;
  205. }
  206. }
  207. catch(HRESULT hr)
  208. {
  209. pStatusInfo->iStatus = ITEM_STATUS_FAILED;
  210. pStatusInfo->hrError = hr;
  211. return hr;
  212. }
  213. return S_OK;
  214. }
  215. HRESULT GetUninstallCmdFromKey(LPCTSTR pszUninstallKey, LPTSTR pszCmdValue)
  216. {
  217. const TCHAR UNINSTALLKEY[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
  218. const TCHAR UNINSTALLVALUE[] = _T("UninstallString");
  219. const TCHAR QUIETUNINSTALLVALUE[] = _T("QuietUninstallString");
  220. HKEY hRegKey = NULL;
  221. DWORD dwRegType;
  222. DWORD dwRegSize;
  223. TCHAR szRegKey[256];
  224. LONG lRet;
  225. TCHAR szValue[256];
  226. if (pszUninstallKey == NULL)
  227. return E_FAIL;
  228. if (pszUninstallKey[0] == _T('"'))
  229. {
  230. //strip quotes from the key
  231. lstrcpy(szValue, (pszUninstallKey + 1));
  232. int l = lstrlen(szValue);
  233. if (l > 0)
  234. szValue[l - 1] = _T('\0');
  235. }
  236. else
  237. {
  238. lstrcpy(szValue, pszUninstallKey);
  239. }
  240. lstrcpy(szRegKey, UNINSTALLKEY);
  241. lstrcat(szRegKey, szValue);
  242. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_READ, &hRegKey);
  243. if (lRet != ERROR_SUCCESS)
  244. return HRESULT_FROM_WIN32(lRet);
  245. //check the uninstall value
  246. dwRegSize = sizeof(szValue);
  247. lRet = RegQueryValueEx(hRegKey, UNINSTALLVALUE, NULL, &dwRegType, (LPBYTE)szValue, &dwRegSize);
  248. if (lRet != ERROR_SUCCESS)
  249. {
  250. // try to find quiteuninstall value
  251. dwRegSize = sizeof(szValue);
  252. lRet = RegQueryValueEx(hRegKey, QUIETUNINSTALLVALUE, NULL, &dwRegType, (LPBYTE)szValue, &dwRegSize);
  253. }
  254. if (lRet != ERROR_SUCCESS)
  255. {
  256. HRESULT hr = HRESULT_FROM_WIN32(lRet);
  257. RegCloseKey(hRegKey);
  258. return hr;
  259. }
  260. RegCloseKey(hRegKey);
  261. //
  262. // copy the key to the output parameter
  263. //
  264. lstrcpy(pszCmdValue, szValue);
  265. return S_OK;
  266. }
  267. //Given an uninstall key, looks up in the registry to find the uninsall command and launches it
  268. //If quotes are found around the uninstall key, they are striped. This is done to make it
  269. //compatible with the value specified in the AS CIF file. This function also understands the
  270. //special INF syntax of the uninstall key.
  271. HRESULT UninstallActiveSetupItem(LPCTSTR pszUninstallKey)
  272. {
  273. const TCHAR INFUNINSTALLCOMMAND[] = _T("RunDll32 advpack.dll,LaunchINFSection ");
  274. const TCHAR INFDIRECTORY[] = _T("INF\\");
  275. TCHAR szCmd[256] = {_T('\0')};
  276. TCHAR szActualKey[128] = {_T('\0')};
  277. LONG lRet;
  278. LPCTSTR pszParse;
  279. HRESULT hr = S_OK;
  280. if (pszUninstallKey == NULL)
  281. return E_FAIL;
  282. if (lstristr(pszUninstallKey, _T(".inf")) != NULL)
  283. {
  284. //
  285. // we have .INF syntax: frontpad,fpxpress.inf,uninstall, start parsing
  286. //
  287. pszParse = lstrcpystr(pszUninstallKey, _T(","), szActualKey); // get actual uninstall key
  288. }
  289. else
  290. {
  291. lstrcpy(szActualKey, pszUninstallKey);
  292. pszParse = NULL;
  293. }
  294. //
  295. // get the uninstall command from the registry
  296. //
  297. hr = GetUninstallCmdFromKey(szActualKey, szCmd);
  298. if (SUCCEEDED(hr))
  299. {
  300. // we have the uninstall command, try to launch it
  301. lRet = LaunchProcess(szCmd, NULL, SW_NORMAL, TRUE);
  302. TRACE("Uninstall: %s, %d", szCmd, lRet);
  303. if (lRet != 0)
  304. {
  305. hr = HRESULT_FROM_WIN32(lRet);
  306. }
  307. }
  308. else
  309. {
  310. // we did not get the uninstall command from registry, launch INF
  311. if (pszParse != NULL)
  312. {
  313. TCHAR szTemp[MAX_PATH];
  314. hr = S_OK;
  315. //get INF directory
  316. if (! GetWindowsDirectory(szTemp, sizeof(szTemp) / sizeof(TCHAR)))
  317. {
  318. hr = HRESULT_FROM_WIN32(GetLastError());
  319. TRACE("Uninstall: GetWindowsDirectory failed, hr=0x%x", hr);
  320. return hr;
  321. }
  322. AddBackSlash(szTemp);
  323. lstrcat(szTemp, INFDIRECTORY);
  324. //start building the command
  325. lstrcpy(szCmd, INFUNINSTALLCOMMAND);
  326. lstrcat(szCmd, szTemp);
  327. pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get INF file name
  328. lstrcat(szCmd, szTemp);
  329. lstrcat(szCmd, _T(","));
  330. pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get INF section
  331. lstrcat(szCmd, szTemp);
  332. lRet = LaunchProcess(szCmd, NULL, SW_NORMAL, TRUE);
  333. if (lRet != 0)
  334. {
  335. hr = HRESULT_FROM_WIN32(lRet);
  336. }
  337. TRACE("Uninstall: %s, %d", szCmd, lRet);
  338. if (SUCCEEDED(hr))
  339. {
  340. //
  341. // reboot handling after uninstall only if uninstall was successful
  342. //
  343. pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get the reboot key
  344. if (lstrcmpi(szTemp, _T("reboot")) == 0)
  345. {
  346. g_v3state.m_bRebootNeeded = TRUE;
  347. }
  348. }
  349. }
  350. else
  351. {
  352. hr = E_UNEXPECTED;
  353. }
  354. }
  355. return hr;
  356. }
  357. void InstallPrinterItem(LPCTSTR pszDriverName, LPCTSTR pszInstallFolder, LPCTSTR pszArchitecture)
  358. {
  359. DWORD dw = InstallPrinterDriver(pszDriverName, pszInstallFolder, pszArchitecture);
  360. HRESULT hr = HRESULT_FROM_WIN32(dw);
  361. if (FAILED(hr))
  362. throw hr;
  363. }
  364. HRESULT AdvPackRunSetupCommand(HWND hwnd, LPCSTR pszInfFile, LPCSTR pszSection, LPCSTR pszDir, DWORD dwFlags)
  365. {
  366. HRESULT hr = E_FAIL;
  367. RUNSETUPCOMMAND pfRunSetupCommand;
  368. HINSTANCE hAdvPack = LoadLibrary(_T("advpack.dll"));
  369. if (hAdvPack != NULL)
  370. {
  371. pfRunSetupCommand = (RUNSETUPCOMMAND)GetProcAddress(hAdvPack, "RunSetupCommand");
  372. if (pfRunSetupCommand)
  373. {
  374. dwFlags |= (RSC_FLAG_INF | RSC_FLAG_NGCONV | RSC_FLAG_QUIET);
  375. hr = pfRunSetupCommand(hwnd, pszInfFile, pszSection, pszDir, NULL, NULL, dwFlags, NULL);
  376. }
  377. FreeLibrary(hAdvPack);
  378. }
  379. return hr;
  380. }
  381. // checks to see if inseng is up to date
  382. void CheckLocalDll(LPCTSTR pszServer, LPCTSTR pszDllName, LPCTSTR pszServDllName, LPCTSTR pszDllVersion)
  383. {
  384. USES_CONVERSION;
  385. const TCHAR TEMPINFFN[] = _T("temp.inf");
  386. const TCHAR PERIOD[] = _T(".");
  387. TCHAR szServDllName[32] = _T("\0");
  388. TCHAR szValue[256] = _T("\0");
  389. TCHAR szTempFN[MAX_PATH] = _T("\0");
  390. TCHAR szDllFN[MAX_PATH] = _T("\0");
  391. TCHAR szInfDir[MAX_PATH] = _T("\0");
  392. TCHAR szDllName[MAX_PATH] = _T("\0");
  393. TCHAR szDllVersion[64] = _T("\0");
  394. TCHAR *pszToken = NULL;
  395. DWORD dwIniMSVer = 0;
  396. DWORD dwIniLSVer = 0;
  397. DWORD dwFileMSVer = 0;
  398. DWORD dwFileLSVer = 0;
  399. LPTSTR p = NULL;
  400. HRESULT hr = S_OK;
  401. //check input arguments
  402. if (NULL == pszDllName || NULL == pszServDllName || NULL == pszDllVersion)
  403. {
  404. return ;
  405. }
  406. if (!GetSystemDirectory(szDllFN, sizeof(szDllFN) / sizeof(TCHAR)))
  407. {
  408. return;
  409. }
  410. AddBackSlash(szDllFN);
  411. lstrcat(szDllFN, pszDllName);
  412. lstrcpy(szDllVersion, pszDllVersion);
  413. lstrcpy(szServDllName, pszServDllName);
  414. if (FileExists(szDllFN))
  415. {
  416. // convert file version
  417. ConvertVersionStrToDwords(szDllVersion, &dwIniMSVer, &dwIniLSVer);
  418. // get file version of the DLL
  419. if (!GetFileVersionDwords(szDllFN, &dwFileMSVer, &dwFileLSVer))
  420. {
  421. TRACE("Could not check file version: %s", szDllFN);
  422. return;
  423. }
  424. // compare the versions
  425. if ((dwFileMSVer > dwIniMSVer) || ((dwFileMSVer == dwIniMSVer) && (dwFileLSVer >= dwIniLSVer)))
  426. {
  427. // install version is up to date
  428. return;
  429. }
  430. }
  431. //
  432. // we need to download and install it!
  433. //
  434. BLOCK
  435. {
  436. CWUDownload dl(pszServer, 8192);
  437. if (!dl.Copy(szServDllName, NULL, NULL, NULL, DOWNLOAD_NEWER | CACHE_FILE_LOCALLY, NULL))
  438. {
  439. throw HRESULT_FROM_WIN32(GetLastError());
  440. }
  441. // filename with OS ext
  442. GetWindowsUpdateDirectory(szTempFN);
  443. lstrcat(szTempFN, szServDllName);
  444. // filename with .dll
  445. lstrcpy(szDllFN, szTempFN);
  446. p = _tcschr(szDllFN, _T('.'));
  447. if (p)
  448. *p = _T('\0');
  449. lstrcat(szDllFN, _T(".dll"));
  450. CDiamond dm;
  451. // decompress or copy to .dll name
  452. if (dm.IsValidCAB(szTempFN))
  453. {
  454. hr = dm.Decompress(szTempFN, szDllFN);
  455. if (FAILED(hr))
  456. {
  457. throw hr;
  458. }
  459. }
  460. else
  461. {
  462. if (!CopyFile(szTempFN, szDllFN, FALSE))
  463. {
  464. return;
  465. }
  466. }
  467. }
  468. //
  469. // write out an INF file
  470. //
  471. HANDLE hFile;
  472. DWORD dwBytes;
  473. char szInfText[1024];
  474. sprintf (szInfText,
  475. "[Version]\r\n\
  476. Signature=\"$Chicago$\"\r\n\
  477. AdvancedINF=2.5\r\n\
  478. [DestinationDirs]\r\n\
  479. WUSysDirCopy=11\r\n\
  480. [InstallControl]\r\n\
  481. CopyFiles=WUSysDirCopy\r\n\
  482. RegisterOCXs=WURegisterOCXSection\r\n\
  483. [WUSysDirCopy]\r\n\
  484. %s,,,32\r\n\
  485. [WURegisterOCXSection]\r\n\
  486. %%11%%\\%s\r\n\
  487. [SourceDisksNames]\r\n\
  488. 55=\"Disk\",,0\r\n\
  489. [SourceDisksFiles]\r\n\
  490. %s=55\r\n",
  491. T2A(pszDllName), T2A(pszDllName), T2A(pszDllName));
  492. GetWindowsUpdateDirectory(szTempFN);
  493. lstrcat(szTempFN, TEMPINFFN);
  494. hFile = CreateFile(szTempFN, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  495. if (hFile != INVALID_HANDLE_VALUE)
  496. {
  497. WriteFile(hFile, (LPCVOID)szInfText, strlen(szInfText), &dwBytes, NULL);
  498. CloseHandle(hFile);
  499. }
  500. //
  501. // RunSetupCommand to install the .INF
  502. //
  503. GetWindowsUpdateDirectory(szInfDir);
  504. hr = AdvPackRunSetupCommand(NULL, T2A(szTempFN), "InstallControl", T2A(szInfDir), 0);
  505. if (FAILED(hr))
  506. {
  507. throw hr;
  508. }
  509. }
  510. void CheckDllsToJit(LPCTSTR pszServer)
  511. {
  512. const TCHAR SEPS[] = _T("=");
  513. TCHAR szValue[1024];
  514. TCHAR szTempFN[MAX_PATH];
  515. TCHAR szKey[256];
  516. TCHAR szDllBaseName[64];
  517. TCHAR szDllExt[32];
  518. TCHAR szKeyLhs[64];
  519. TCHAR szDllName[64];
  520. TCHAR szDllTempName[64];
  521. TCHAR szDllVersion[64];
  522. TCHAR *pszValue;
  523. long len;
  524. if (g_v3state.m_bInsengChecked)
  525. return;
  526. g_v3state.m_bInsengChecked = TRUE;
  527. GetWindowsUpdateDirectory(szTempFN);
  528. lstrcat(szTempFN, FILEVERINI_FN);
  529. if (0 == GetPrivateProfileSection(_T("version"), szValue, sizeof(szValue) / sizeof(TCHAR), szTempFN))
  530. {
  531. // version not available for this file
  532. TRACE("Section: version is missing from FileVer.ini");
  533. return;
  534. }
  535. pszValue = szValue;
  536. while (0 != (len = lstrlen(pszValue)))
  537. {
  538. lstrcpyn(szKey, pszValue, len+1);
  539. lstrcat(szKey, _T("\0"));
  540. pszValue += len + 1;
  541. _stscanf(szKey, _T("%[^=]=%s"), szKeyLhs, szDllVersion);
  542. _stscanf(szKeyLhs, _T("%[^.].%s"), szDllBaseName, szDllExt);
  543. wsprintf(szDllName, _T("%s.dll"), szDllBaseName);
  544. wsprintf(szDllTempName, _T("%s."), szDllBaseName);
  545. AppendExtForOS(szDllTempName);
  546. if (0 == lstrcmpi(szDllTempName, szKeyLhs))
  547. CheckLocalDll(pszServer, szDllName, szKeyLhs, szDllVersion);
  548. }
  549. }
  550. // Pings a URL for tracking purposes
  551. //
  552. // NOTE: pszStatus must not contain spaces and cannot be null
  553. void URLPingReport(PINVENTORY_ITEM pItem, CCatalog* pCatalog, PSELECTITEMINFO pSelectItem, LPCTSTR pszStatus)
  554. {
  555. LOG_block("URLPingReport");
  556. //check for input arguments
  557. if (NULL == pItem || NULL == pCatalog)
  558. {
  559. return;
  560. }
  561. // create a download object
  562. try
  563. {
  564. CWUDownload dl(g_v3state.GetIdentServer(), 8192);
  565. // build the URL with parameters
  566. TCHAR szURL[INTERNET_MAX_PATH_LENGTH];
  567. wsprintf(szURL, _T("wutrack.bin?VER=%s&PUID=%d&PLAT=%d&LOCALE=%s&STATUS=%s&ERR=0x%x&SESSID=%s"),
  568. CCV3::s_szControlVer,
  569. pItem->GetPuid(),
  570. pCatalog->GetPlatform(),
  571. pCatalog->GetMachineLocaleSZ(),
  572. pszStatus,
  573. pSelectItem->hrError,
  574. CWUDownload::m_szWUSessionID);
  575. LOG_out("Sending %s", szURL);
  576. // ping the URL and receive the response in memory
  577. PVOID pMemBuf;
  578. ULONG ulMemSize;
  579. if (dl.QCopy(szURL, &pMemBuf, &ulMemSize))
  580. {
  581. // we don't care about the response so we just free it
  582. V3_free(pMemBuf);
  583. }
  584. }
  585. catch(HRESULT hr)
  586. {
  587. return;
  588. }
  589. }