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.

508 lines
14 KiB

  1. /*
  2. Copyright 1999 Microsoft Corporation
  3. Upload to the EMI database server
  4. Walter Smith (wsmith)
  5. Rajesh Soy (nsoy) - reorganized code and cleaned it up, added comments 06/06/2000
  6. */
  7. #ifdef THIS_FILE
  8. #undef THIS_FILE
  9. #endif
  10. static char __szTraceSourceFile[] = __FILE__;
  11. #define THIS_FILE __szTraceSourceFile
  12. #include "stdafx.h"
  13. #define NOTRACE
  14. #include "uploadmanager.h"
  15. #include "logging.h"
  16. #include <dbgtrace.h>
  17. #include "UploadmanagerDID.h"
  18. #include "resource.h"
  19. //
  20. // Externs
  21. //
  22. extern CComModule _Module;
  23. //
  24. // PC Health registry stuff
  25. //
  26. const TCHAR szREGKEY_MACHINEINFO[] = _T("Software\\Microsoft\\PCHealth\\MachineInfo");
  27. const TCHAR szREGVALUE_GUID_NONESC[] = _T("CommentPID");
  28. //
  29. // LAMEBTN.DLL registry stuff
  30. //
  31. const TCHAR szREGKEY_ERROR_MESSAGES[] = _T("Software\\Microsoft\\PCHealth\\Clients\\Error Messages");
  32. const TCHAR szREGKEY_DIALOG_COMMENTS[] = _T("Software\\Microsoft\\PCHealth\\Clients\\Dialog Comments");
  33. const TCHAR szREGVALUE_UPLOAD_SERVER[] = _T("Upload URL");
  34. const TCHAR szREGVALUE_UPLOAD_PROVIDER[] = _T("Upload provider");
  35. //
  36. // Routines Defined here:
  37. //
  38. void GetRegValue(HKEY hkRoot, LPCTSTR szKeyName, LPCTSTR szValueName, LPTSTR szValue, DWORD* pcbValue);
  39. LPCTSTR GetUploadRegKey(ENUM_UPLOAD_TYPES type);
  40. void GetMachineSignature(GUIDSTR szGUID);
  41. inline HRESULT ChangeSecurity(IUnknown * pUnknown);
  42. int QueueXMLDocumentUpload(ENUM_UPLOAD_TYPES type, SimpleXMLDocument& doc);
  43. //
  44. // GetRegValue: Get value of required registry entry (throw if not found).
  45. // IN *pcbValue is the size in bytes of szValue
  46. // OUT *pchValue is the size of the retrieved data
  47. //
  48. void
  49. GetRegValue(
  50. HKEY hkRoot,
  51. LPCTSTR szKeyName,
  52. LPCTSTR szValueName,
  53. LPTSTR szValue,
  54. DWORD* pcbValue
  55. )
  56. {
  57. CRegKey rk;
  58. ThrowIfW32Fail( rk.Open(hkRoot, szKeyName, KEY_READ) );
  59. ThrowIfW32Fail( rk.QueryValue(szValue, szValueName, pcbValue) );
  60. rk.Close();
  61. }
  62. //
  63. // GetUploadRegKey: Returns the correct registy key location
  64. //
  65. LPCTSTR
  66. GetUploadRegKey(
  67. ENUM_UPLOAD_TYPES type
  68. )
  69. {
  70. if (type == UPLOAD_MESSAGEBOX)
  71. {
  72. return szREGKEY_ERROR_MESSAGES;
  73. }
  74. else if (type == UPLOAD_LAMEBUTTON)
  75. {
  76. return szREGKEY_DIALOG_COMMENTS;
  77. }
  78. // WTF?!
  79. _ASSERT(false);
  80. throw E_FAIL;
  81. return NULL; // the compiler
  82. }
  83. //
  84. // GetMachineSignature: Obtains the Machine signature. This however, is currently
  85. // not being used at the backend
  86. //
  87. void
  88. GetMachineSignature(
  89. GUIDSTR szGUID // [out] - Machine GUID
  90. )
  91. {
  92. TraceFunctEnter("GetMachineSignature");
  93. CRegKey rk;
  94. DWORD dwSize = 0;
  95. //
  96. // Try to read the Machine GUID from registry
  97. //
  98. if (rk.Open(HKEY_LOCAL_MACHINE, szREGKEY_MACHINEINFO, KEY_READ) == ERROR_SUCCESS)
  99. {
  100. dwSize = sizeof(GUIDSTR);
  101. if (rk.QueryValue(szGUID, szREGVALUE_GUID_NONESC, &dwSize) == ERROR_SUCCESS)
  102. {
  103. rk.Close();
  104. return;
  105. }
  106. }
  107. rk.Close();
  108. //
  109. // If PCHealth's GUID is gone for some reason, We generate a GUID
  110. //
  111. DebugTrace(0, "Generating a new GUID");
  112. lstrcpy(szGUID, _T("{00000000-0000-0000-0000-000000000000}"));
  113. GUID guid;
  114. HRESULT hr;
  115. LPOLESTR lpolestr_guid;
  116. hr = CoCreateGuid(&guid);
  117. if (FAILED(hr))
  118. {
  119. FatalTrace(0, "CoCreateGuid failed. Error: %ld", hr);
  120. goto done;
  121. }
  122. hr = StringFromIID(guid, &lpolestr_guid);
  123. if (FAILED(hr))
  124. {
  125. FatalTrace(0, "StringFromIID failed. Error: %ld", hr);
  126. goto done;
  127. }
  128. lstrcpy(szGUID, lpolestr_guid);
  129. CoTaskMemFree(lpolestr_guid);
  130. //
  131. // We update the generated GUID in the registry
  132. //
  133. DebugTrace(0, "Creating %s", szREGKEY_MACHINEINFO);
  134. if (rk.Create(HKEY_LOCAL_MACHINE, szREGKEY_MACHINEINFO ) == ERROR_SUCCESS)
  135. {
  136. if(rk.SetValue(szGUID, szREGVALUE_GUID_NONESC) != ERROR_SUCCESS)
  137. {
  138. FatalTrace(0, "Failed to set MachineID in registry. Error: %ld", GetLastError());
  139. }
  140. }
  141. done:
  142. rk.Close();
  143. DebugTrace(0, "szGUID: %ls", szGUID);
  144. TraceFunctLeave();
  145. return;
  146. }
  147. //-----------------------------------------------------------------------------
  148. // It's necessary to modify the security settings on a new MPCUpload interface.
  149. //-----------------------------------------------------------------------------
  150. inline HRESULT ChangeSecurity(IUnknown * pUnknown)
  151. {
  152. TraceFunctEnter("ChangeSecurity");
  153. IClientSecurity * pCliSec = NULL;
  154. //
  155. // Query the IClientSecurity interface
  156. //
  157. HRESULT hr = pUnknown->QueryInterface(IID_IClientSecurity, (void **) &pCliSec);
  158. if (FAILED(hr))
  159. {
  160. FatalTrace(0, "pUnknown->QueryInterface failed. hr: %ld", hr);
  161. goto done;
  162. }
  163. DebugTrace(0, "Calling pCliSec->SetBlanket");
  164. //
  165. // Set the correct Security blanket
  166. //
  167. hr = pCliSec->SetBlanket(pUnknown,
  168. RPC_C_AUTHN_WINNT,
  169. RPC_C_AUTHZ_NONE,
  170. NULL,
  171. RPC_C_AUTHN_LEVEL_CONNECT,
  172. RPC_C_IMP_LEVEL_IMPERSONATE,
  173. NULL,
  174. EOAC_DEFAULT);
  175. pCliSec->Release();
  176. done:
  177. TraceFunctLeave();
  178. return hr;
  179. }
  180. //
  181. // QueueXMLDocumentUpload: This routine schedules the XML blob passed to it for upload to Upload Manager
  182. //
  183. int
  184. QueueXMLDocumentUpload(
  185. ENUM_UPLOAD_TYPES type, // [in] - upload type
  186. SimpleXMLDocument& doc // [in] - XML blob to be uploaded
  187. )
  188. {
  189. TCHAR szTemp[1024];
  190. DWORD dwTemp;
  191. UL_STATUS status;
  192. long errCode;
  193. LPCTSTR szRegKey;
  194. TraceFunctEnter("QueueXMLDocumentUpload");
  195. //
  196. // NTRAID#NTBUG9-154248-2000/08/08-jasonr
  197. // NTRAID#NTBUG9-152439-2000/08/08-jasonr
  198. //
  199. // We used to pop up the "Thank You" message box in the new thread.
  200. // Now we pop it up in the dialog box thread instead to fix these bugs.
  201. // The new thread now returns 0 to indicate success, 1 to indicate
  202. // failure. We only pop up the dialog box on success.
  203. //
  204. int iRet = 1;
  205. //
  206. // Make a temporary filename for the XML blob
  207. //
  208. TCHAR szTempFileName[MAX_PATH];
  209. TCHAR szTempPath[MAX_PATH];
  210. try
  211. {
  212. ThrowIfZero( GetTempPath(ARRAYSIZE(szTempPath), szTempPath) );
  213. ThrowIfZero( GetTempFileName(szTempPath, _T("EMI"), 0, szTempFileName) );
  214. }
  215. catch(...)
  216. {
  217. FatalTrace(0, "Unable to get a tempFile name");
  218. //
  219. // Use a default value
  220. //
  221. _tcscpy(szTempFileName, _T("C:\\upload.xml"));
  222. }
  223. DebugTrace(0, "szTempFileName: %ls", szTempFileName);
  224. try {
  225. //
  226. // Generate the XML to the temp file
  227. //
  228. DebugTrace(0, "Saving: %ls", szTempFileName);
  229. doc.SaveFile(szTempFileName);
  230. //
  231. // Tell the PC Health upload library to upload it
  232. //
  233. CComPtr<IMPCUpload> pUploadMgr;
  234. CComPtr<IMPCUploadJob> pJob;
  235. HRESULT hr = S_OK;
  236. //
  237. // Create an instance of MPCUpload
  238. //
  239. DebugTrace(0, "Creating instance of MPCUpload");
  240. //MessageBox(GetFocus(), L"Creating instance of MPCUpload", L"Debug", 0);
  241. hr = pUploadMgr.CoCreateInstance(__uuidof(MPCUpload));
  242. if(FAILED(hr))
  243. {
  244. _Module.RegisterTypeLib();
  245. hr = pUploadMgr.CoCreateInstance(__uuidof(MPCUpload));
  246. if(FAILED(hr))
  247. {
  248. FatalTrace(0, "pUploadMgr.CoCreateInstance failed. hr=0x%x", hr);
  249. ThrowIfFail(hr);
  250. }
  251. }
  252. //
  253. // Set the appropriate security blanket
  254. //
  255. DebugTrace(0, "Changing Security of pUploadMgr");
  256. hr = ChangeSecurity( pUploadMgr );
  257. if(FAILED(hr))
  258. {
  259. FatalTrace(0, "ChangeSecurity Failed. hr=0x%x", hr);
  260. ThrowIfFail(hr);
  261. }
  262. //
  263. // Create an upload job
  264. //
  265. DebugTrace(0, "Creating Job");
  266. //MessageBox(GetFocus(), L"Creating Job", L"Debug", 0);
  267. hr = pUploadMgr->CreateJob(&pJob);
  268. if(FAILED(hr))
  269. {
  270. FatalTrace(0, "pUploadMgr->CreateJob failed hr=0x%x", hr);
  271. TCHAR szErr[1024];
  272. _stprintf(szErr, L"pUploadMgr->CreateJob failed hr=0x%x", hr);
  273. // MessageBox(GetFocus(), szErr, L"Debug", 0);
  274. ThrowIfFail(hr);
  275. }
  276. _ASSERT(pJob != NULL);
  277. //
  278. // Set the appropriate security blanket
  279. //
  280. DebugTrace(0, "Changing Security of pJob");
  281. hr = ChangeSecurity( pJob );
  282. if(FAILED(hr))
  283. {
  284. FatalTrace(0, "ChangeSecurity Failed. hr=0x%x", hr);
  285. ThrowIfFail(hr);
  286. }
  287. //
  288. // Obtain the Machine GUID
  289. //
  290. //GUIDSTR szSig;
  291. //GetMachineSignature(szSig);
  292. //DebugTrace(0, "Machine signature: %ls", CComBSTR(szSig));
  293. //
  294. // nsoy - we are going to use the uploadm GUID henceforth.
  295. // Set the machine signature in the job
  296. //
  297. DebugTrace(0, "Setting Machine signature");
  298. hr = pJob->put_Sig( NULL );
  299. if(FAILED(hr))
  300. {
  301. FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
  302. ThrowIfFail( hr );
  303. }
  304. //
  305. // Obtain the registry key for upload server information
  306. //
  307. szRegKey = GetUploadRegKey(type);
  308. //
  309. // Read the registry key to obtain the upload server information
  310. //
  311. dwTemp = ARRAYSIZE(szTemp);
  312. GetRegValue(HKEY_LOCAL_MACHINE, szRegKey, szREGVALUE_UPLOAD_SERVER, szTemp, &dwTemp);
  313. //
  314. // Set the upload server name in the upload job
  315. //
  316. DebugTrace(0, "Setting Server: %ls", CComBSTR(szTemp));
  317. hr = pJob->put_Server(CComBSTR(szTemp));
  318. if(FAILED(hr))
  319. {
  320. FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
  321. ThrowIfFail( hr );
  322. }
  323. //
  324. // Obtain the upload server provider name from registry
  325. //
  326. dwTemp = ARRAYSIZE(szTemp);
  327. GetRegValue(HKEY_LOCAL_MACHINE, szRegKey, szREGVALUE_UPLOAD_PROVIDER, szTemp, &dwTemp);
  328. //
  329. // Set the upload server provider ID
  330. //
  331. DebugTrace(0, "Setting ProviderID: %ls", CComBSTR(szTemp));
  332. hr = pJob->put_ProviderID(CComBSTR(szTemp));
  333. if(FAILED(hr))
  334. {
  335. FatalTrace(0, "pJob->put_Server failed. hr=%ld", hr);
  336. ThrowIfFail( hr );
  337. }
  338. // REVIEW: probably should be UL_HISTORY_NONE when we think it works
  339. DebugTrace(0, "Setting History to UL_HISTORY_LOG");
  340. hr = pJob->put_History(UL_HISTORY_LOG);
  341. if(FAILED(hr))
  342. {
  343. FatalTrace(0, "put_History failed. hr=%ld", hr);
  344. ThrowIfFail( hr );
  345. }
  346. //
  347. // Set the Compression flag
  348. //
  349. DebugTrace(0, "Setting Compressed flag to TRUE");
  350. hr = pJob->put_Compressed(VARIANT_TRUE);
  351. if(FAILED(hr))
  352. {
  353. FatalTrace(0, "put_Compressed failed. hr=%ld", hr);
  354. ThrowIfFail( hr );
  355. }
  356. //
  357. // Set PersitToDisk flag
  358. //
  359. DebugTrace(0, "Setting PersistToDisk flag to TRUE");
  360. hr = pJob->put_PersistToDisk(VARIANT_TRUE);
  361. if(FAILED(hr))
  362. {
  363. FatalTrace(0, "put_PersistToDisk failed. hr=%ld", hr);
  364. ThrowIfFail( hr );
  365. }
  366. //
  367. // Obtain Status & Error code before putting the job to queue
  368. //
  369. pJob->get_Status(&status);
  370. pJob->get_ErrorCode(&errCode);
  371. DebugTrace(0, "upload status: %d (error %ld)\n", status, errCode);
  372. //
  373. // Let the upload job read the data persisted in to the temp file
  374. //
  375. DebugTrace(0, "Calling GetDataFromFile: %ls", CComBSTR(szTempFileName));
  376. hr = pJob->GetDataFromFile(CComBSTR(szTempFileName));
  377. if(FAILED(hr))
  378. {
  379. FatalTrace(0, "GetDataFromFile failed. hr=%ld", hr);
  380. ThrowIfFail( hr );
  381. }
  382. //
  383. // Delete the temp file
  384. //
  385. if (FALSE == DeleteFile(szTempFileName))
  386. {
  387. FatalTrace(0, "DeleteFile failed on %ls. Error: %ld", szTempFileName, GetLastError());
  388. throw;
  389. }
  390. DebugTrace(0, "Calling ActivateAsyn");
  391. hr = pJob->ActivateAsync();
  392. if(FAILED(hr))
  393. {
  394. FatalTrace(0, "ActivateAsync failed. hr=%ld", hr);
  395. ThrowIfFail( hr );
  396. }
  397. pJob->get_Status(&status);
  398. pJob->get_ErrorCode(&errCode);
  399. DebugTrace(0, "upload status: %d (error %ld)\n", status, errCode);
  400. //
  401. // NTRAID#NTBUG9-154248-2000/08/08-jasonr
  402. // NTRAID#NTBUG9-152439-2000/08/08-jasonr
  403. //
  404. // We used to pop up the "Thank You" message box in the new thread.
  405. // Now we pop it up in the dialog box thread instead to fix these bugs.
  406. // The new thread now returns 0 to indicate success, 1 to indicate
  407. // failure. We only pop up the dialog box on success.
  408. //
  409. iRet = 0;
  410. #if 0
  411. //
  412. // Display Thank you dialog
  413. //
  414. TCHAR szThankYouMessage[1024];
  415. TCHAR szThankYouMessageTitle[1024];
  416. LoadString(_Module.GetResourceInstance(),
  417. IDS_COMMENT_THANKYOU,
  418. szThankYouMessage,
  419. ARRAYSIZE(szThankYouMessage));
  420. LoadString(_Module.GetResourceInstance(),
  421. IDS_COMMENT_THANKYOUTITLE,
  422. szThankYouMessageTitle,
  423. ARRAYSIZE(szThankYouMessageTitle));
  424. MessageBox( NULL, szThankYouMessage, szThankYouMessageTitle, MB_OK);
  425. #endif
  426. }
  427. catch (HRESULT hr) {
  428. FatalTrace(0, "Error Code: %lx", hr);
  429. }
  430. catch (...) {
  431. DebugTrace(0, "Upload CRASHED !!!");
  432. throw;
  433. }
  434. return(iRet);
  435. }