Leaked source code of windows server 2003
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.

1982 lines
52 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. MPCUploadJob.cpp
  5. Abstract:
  6. This file contains the implementation of the CMPCUploadJob class,
  7. the descriptor of all jobs present in the Upload Library system.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 04/15/99
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. ////////////////////////////////////////////////////////////////////////////////
  14. HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ UL_HISTORY& val ) { return stream.read ( &val, sizeof(val) ); }
  15. HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const UL_HISTORY& val ) { return stream.write( &val, sizeof(val) ); }
  16. HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ UL_STATUS& val ) { return stream.read ( &val, sizeof(val) ); }
  17. HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const UL_STATUS& val ) { return stream.write( &val, sizeof(val) ); }
  18. HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ UL_MODE& val ) { return stream.read ( &val, sizeof(val) ); }
  19. HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const UL_MODE& val ) { return stream.write( &val, sizeof(val) ); }
  20. ////////////////////////////////////////////////////////////////////////////////
  21. const WCHAR c_szUploadLibPath[] = L"SOFTWARE\\Microsoft\\PCHealth\\MachineInfo";
  22. const WCHAR c_szUploadIDValue[] = L"PID";
  23. static HRESULT ReadGUID( MPC::RegKey& rkBase ,
  24. LPCWSTR szName ,
  25. GUID& guid )
  26. {
  27. __ULT_FUNC_ENTRY( "ReadGUID" );
  28. HRESULT hr;
  29. CComVariant vValue;
  30. bool fFound;
  31. __MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.get_Value( vValue, fFound, szName ));
  32. if(fFound && vValue.vt == VT_BSTR && vValue.bstrVal != NULL)
  33. {
  34. __MPC_EXIT_IF_METHOD_FAILS(hr, ::IIDFromString( vValue.bstrVal, &guid ));
  35. }
  36. else
  37. {
  38. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_FILE_NOT_FOUND);
  39. }
  40. hr = S_OK;
  41. __ULT_FUNC_CLEANUP;
  42. __ULT_FUNC_EXIT(hr);
  43. }
  44. static HRESULT WriteGUID( MPC::RegKey& rkBase ,
  45. LPCWSTR szName ,
  46. GUID& guid )
  47. {
  48. __ULT_FUNC_ENTRY( "WriteGUID" );
  49. HRESULT hr;
  50. CComBSTR bstrGUID( guid );
  51. CComVariant vValue = bstrGUID;
  52. __MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.put_Value( vValue, szName ));
  53. hr = S_OK;
  54. __ULT_FUNC_CLEANUP;
  55. __ULT_FUNC_EXIT(hr);
  56. }
  57. static void GenGUID( LPBYTE rgBuf ,
  58. DWORD dwSize ,
  59. GUID& guid ,
  60. DWORD seed )
  61. {
  62. DWORD* dst = (DWORD*)&guid;
  63. int i;
  64. dwSize /= 4; // Divide the buffer in four parts.
  65. for(i=0;i<4;i++)
  66. {
  67. MPC::ComputeCRC( seed, &rgBuf[dwSize*i], dwSize ); *dst++ = seed;
  68. }
  69. }
  70. static HRESULT GetGUID( /*[out]*/ GUID& guid )
  71. {
  72. __ULT_FUNC_ENTRY( "GetGUID" );
  73. HRESULT hr;
  74. MPC::RegKey rkBase;
  75. MPC::Impersonation imp;
  76. ////////////////////////////////////////////////////////////////////////////////
  77. //
  78. // Open the registry, impersonating the caller.
  79. //
  80. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize ());
  81. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Impersonate());
  82. __MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.SetRoot( HKEY_CURRENT_USER, KEY_ALL_ACCESS ));
  83. __MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.Attach ( c_szUploadLibPath ));
  84. __MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.Create ( ));
  85. if(FAILED(ReadGUID( rkBase, c_szUploadIDValue, guid )))
  86. {
  87. GUID guidSEED;
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateGuid( &guidSEED ));
  89. GenGUID( (LPBYTE)&guidSEED, sizeof(guidSEED), guid, 0xEAB63459 );
  90. __MPC_EXIT_IF_METHOD_FAILS(hr, WriteGUID( rkBase, c_szUploadIDValue, guid ));
  91. }
  92. //
  93. ////////////////////////////////////////////////////////////////////////////////
  94. hr = S_OK;
  95. __ULT_FUNC_CLEANUP;
  96. __ULT_FUNC_EXIT(hr);
  97. }
  98. ////////////////////////////////////////////////////////////////////////////////
  99. ////////////////////////////////////////////////////////////////////////////////
  100. ////////////////////////////////////////////////////////////////////////////////
  101. #define CHECK_MODIFY() __MPC_EXIT_IF_METHOD_FAILS(hr, CanModifyProperties())
  102. /////////////////////////////////////////////////////////////////////////////
  103. // CMPCUploadJob
  104. CMPCUploadJob::CMPCUploadJob()
  105. {
  106. __ULT_FUNC_ENTRY( "CMPCUploadJob::CMPCUploadJob" );
  107. m_mpcuRoot = NULL; // CMPCUpload* m_mpcuRoot;
  108. m_dwRetryInterval = 0; // DWORD m_dwRetryInterval;
  109. //
  110. m_dwInternalSeq = -1; // ULONG m_dwInternalSeq;
  111. //
  112. // Sig m_sigClient;
  113. // CComBSTR m_bstrServer;
  114. // CComBSTR m_bstrJobID;
  115. // CComBSTR m_bstrProviderID;
  116. //
  117. // CComBSTR m_bstrCreator;
  118. // CComBSTR m_bstrUsername;
  119. // CComBSTR m_bstrPassword;
  120. //
  121. // CComBSTR m_bstrFileNameResponse;
  122. // CComBSTR m_bstrFileName;
  123. m_lOriginalSize = 0; // long m_lOriginalSize;
  124. m_lTotalSize = 0; // long m_lTotalSize;
  125. m_lSentSize = 0; // long m_lSentSize;
  126. m_dwCRC = 0; // DWORD m_dwCRC;
  127. //
  128. m_uhHistory = UL_HISTORY_NONE; // UL_HISTORY m_uhHistory;
  129. m_usStatus = UL_NOTACTIVE; // UL_STATUS m_usStatus;
  130. m_dwErrorCode = 0; // DWORD m_dwErrorCode;
  131. //
  132. m_umMode = UL_BACKGROUND; // UL_MODE m_umMode;
  133. m_fPersistToDisk = VARIANT_FALSE; // VARIANT_BOOL m_fPersistToDisk;
  134. m_fCompressed = VARIANT_FALSE; // VARIANT_BOOL m_fCompressed;
  135. m_lPriority = 0; // long m_lPriority;
  136. //
  137. m_dCreationTime = MPC::GetLocalTime(); // DATE m_dCreationTime;
  138. m_dCompleteTime = 0; // DATE m_dCompleteTime;
  139. m_dExpirationTime = 0; // DATE m_dExpirationTime
  140. //
  141. // MPC::Connectivity::Proxy m_Proxy
  142. //
  143. // CComPtr<IDispatch> m_sink_onStatusChange;
  144. // CComPtr<IDispatch> m_sink_onProgressChange;
  145. //
  146. m_fDirty = true; // mutable bool m_fDirty;
  147. }
  148. CMPCUploadJob::~CMPCUploadJob()
  149. {
  150. Unlink();
  151. }
  152. HRESULT CMPCUploadJob::LinkToSystem( /*[in]*/ CMPCUpload* mpcuRoot )
  153. {
  154. __ULT_FUNC_ENTRY( "CMPCUploadJob::LinkToSystem" );
  155. m_mpcuRoot = mpcuRoot; mpcuRoot->AddRef();
  156. __ULT_FUNC_EXIT(S_OK);
  157. }
  158. HRESULT CMPCUploadJob::Unlink()
  159. {
  160. __ULT_FUNC_ENTRY( "CMPCUploadJob::Unlink" );
  161. if(m_mpcuRoot)
  162. {
  163. m_mpcuRoot->Release();
  164. m_mpcuRoot = NULL;
  165. }
  166. __ULT_FUNC_EXIT(S_OK);
  167. }
  168. ////////////////////////////////////////////////////////////////////////////////
  169. ////////////////////////////////////////////////////////////////////////////////
  170. HRESULT CMPCUploadJob::CreateFileName( /*[out]*/ CComBSTR& bstrFileName )
  171. {
  172. __ULT_FUNC_ENTRY( "CMPCUploadJob::CreateFileName" );
  173. HRESULT hr;
  174. MPC::wstring szFile( g_Config.get_QueueLocation() );
  175. WCHAR rgID[64];
  176. swprintf( rgID, L"%08x.data", m_dwInternalSeq ); szFile.append( rgID );
  177. hr = MPC::PutBSTR( bstrFileName, szFile.c_str() );
  178. __ULT_FUNC_EXIT(hr);
  179. }
  180. HRESULT CMPCUploadJob::CreateTmpFileName( /*[out]*/ CComBSTR& bstrTmpFileName )
  181. {
  182. __ULT_FUNC_ENTRY( "CMPCUploadJob::CreateTmpFileName" );
  183. HRESULT hr;
  184. MPC::wstring szFile;
  185. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetTemporaryFileName( szFile, g_Config.get_QueueLocation().c_str() ));
  186. hr = MPC::PutBSTR( bstrTmpFileName, szFile.c_str(), false );
  187. __ULT_FUNC_CLEANUP;
  188. __ULT_FUNC_EXIT(hr);
  189. }
  190. HRESULT CMPCUploadJob::CreateDataFromStream( /*[in]*/ IStream* streamIn, /*[in]*/ DWORD dwQueueSize )
  191. {
  192. __ULT_FUNC_ENTRY( "CMPCUploadJob::CreateDataFromStream" );
  193. HRESULT hr;
  194. STATSTG statstg;
  195. CComBSTR bstrTmpFileName;
  196. CComPtr<MPC::FileStream> stream;
  197. bool fRemove = true; // Clean everything in case of error.
  198. __MPC_PARAMCHECK_BEGIN(hr)
  199. __MPC_PARAMCHECK_NOTNULL(streamIn);
  200. __MPC_PARAMCHECK_END();
  201. //
  202. // Get original file size.
  203. //
  204. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn->Stat( &statstg, STATFLAG_NONAME ));
  205. if(statstg.cbSize.LowPart == 0) // Zero-length files are not allowed.
  206. {
  207. __MPC_EXIT_IF_METHOD_FAILS(hr, E_INVALIDARG);
  208. }
  209. m_lOriginalSize = statstg.cbSize.LowPart;
  210. m_lTotalSize = 0;
  211. m_lSentSize = 0;
  212. m_fDirty = true;
  213. //
  214. // Delete old data.
  215. //
  216. __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveData ());
  217. __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveResponse());
  218. //
  219. // Generate the file name for the data.
  220. //
  221. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateFileName( m_bstrFileName ));
  222. if(m_fCompressed == VARIANT_TRUE)
  223. {
  224. //
  225. // Generate a temporary file name.
  226. //
  227. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateTmpFileName( bstrTmpFileName ));
  228. //
  229. // Copy the data to a tmp file and compress it.
  230. //
  231. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  232. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForWrite( bstrTmpFileName ));
  233. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamIn, stream ));
  234. stream.Release();
  235. //
  236. // Compress it.
  237. //
  238. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CompressAsCabinet( SAFEBSTR( bstrTmpFileName ), SAFEBSTR( m_bstrFileName ), L"PAYLOAD" ));
  239. //
  240. // Reopen the data file, to compute the CRC.
  241. //
  242. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  243. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForRead( SAFEBSTR( m_bstrFileName ) ));
  244. }
  245. else
  246. {
  247. LARGE_INTEGER li;
  248. //
  249. // Copy the data.
  250. //
  251. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  252. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForReadWrite( SAFEBSTR( m_bstrFileName ) ));
  253. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamIn, stream ));
  254. //
  255. // Reset stream to beginning.
  256. //
  257. li.LowPart = 0;
  258. li.HighPart = 0;
  259. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->Seek( li, STREAM_SEEK_SET, NULL ));
  260. }
  261. //
  262. // Compute CRC.
  263. //
  264. MPC::InitCRC( m_dwCRC );
  265. while(1)
  266. {
  267. UCHAR rgBuf[512];
  268. ULONG dwRead;
  269. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->Read( rgBuf, sizeof(rgBuf), &dwRead ));
  270. if(hr == S_FALSE || dwRead == 0) // End of File.
  271. {
  272. fRemove = false;
  273. break;
  274. }
  275. MPC::ComputeCRC( m_dwCRC, rgBuf, dwRead );
  276. m_lTotalSize += dwRead;
  277. }
  278. //
  279. // Check quota limits.
  280. //
  281. if(dwQueueSize + m_lTotalSize > g_Config.get_QueueSize())
  282. {
  283. __MPC_SET_ERROR_AND_EXIT(hr, E_UPLOADLIBRARY_CLIENT_QUOTA_EXCEEDED);
  284. }
  285. hr = S_OK;
  286. __ULT_FUNC_CLEANUP;
  287. stream.Release();
  288. if(bstrTmpFileName.Length())
  289. {
  290. (void)MPC::DeleteFile( bstrTmpFileName );
  291. }
  292. if(fRemove || FAILED(hr))
  293. {
  294. (void)RemoveData ();
  295. (void)RemoveResponse();
  296. m_lOriginalSize = 0;
  297. m_lTotalSize = 0;
  298. m_lSentSize = 0;
  299. m_fDirty = true;
  300. }
  301. __ULT_FUNC_EXIT(hr);
  302. }
  303. HRESULT CMPCUploadJob::OpenReadStreamForData( /*[out]*/ IStream* *pstreamOut )
  304. {
  305. __ULT_FUNC_ENTRY( "CMPCUploadJob::OpenReadStreamForData" );
  306. HRESULT hr;
  307. CComBSTR bstrTmpFileName;
  308. CComPtr<MPC::FileStream> stream;
  309. __MPC_PARAMCHECK_BEGIN(hr)
  310. __MPC_PARAMCHECK_POINTER_AND_SET(pstreamOut,NULL);
  311. __MPC_PARAMCHECK_END();
  312. if(m_lTotalSize == 0 ||
  313. m_bstrFileName.Length() == 0 )
  314. {
  315. __MPC_SET_ERROR_AND_EXIT(hr, E_UPLOADLIBRARY_NO_DATA);
  316. }
  317. //
  318. // Generate a temporary file name.
  319. //
  320. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateTmpFileName( bstrTmpFileName ));
  321. if(m_fCompressed == VARIANT_TRUE)
  322. {
  323. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DecompressFromCabinet( m_bstrFileName, bstrTmpFileName, L"PAYLOAD" ));
  324. }
  325. else
  326. {
  327. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CopyFile( m_bstrFileName, bstrTmpFileName ));
  328. }
  329. //
  330. // Open the file as a stream and set the DeleteOnRelease flag.
  331. //
  332. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  333. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForRead ( bstrTmpFileName ));
  334. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->DeleteOnRelease( true ));
  335. *pstreamOut = stream.Detach();
  336. hr = S_OK;
  337. __ULT_FUNC_CLEANUP;
  338. stream.Release();
  339. if(FAILED(hr) && bstrTmpFileName.Length())
  340. {
  341. (void)MPC::DeleteFile( bstrTmpFileName );
  342. }
  343. __ULT_FUNC_EXIT(hr);
  344. }
  345. /////////////////////////////////////////////////////////////////////////////
  346. /////////////////////////////////////////////////////////////////////////////
  347. HRESULT CMPCUploadJob::SetSequence( /*[in]*/ ULONG lSeq )
  348. {
  349. __ULT_FUNC_ENTRY( "CMPCUploadJob::SetSequence" );
  350. m_dwInternalSeq = lSeq;
  351. m_fDirty = true;
  352. __ULT_FUNC_EXIT(S_OK);
  353. }
  354. HRESULT CMPCUploadJob::CanModifyProperties()
  355. {
  356. __ULT_FUNC_ENTRY( "CMPCUploadJob::CanModifyProperties" );
  357. HRESULT hr;
  358. switch(m_usStatus)
  359. {
  360. case UL_NOTACTIVE:
  361. case UL_SUSPENDED:
  362. case UL_FAILED : hr = S_OK; break;
  363. default : hr = E_ACCESSDENIED; break;
  364. }
  365. __ULT_FUNC_EXIT(hr);
  366. }
  367. HRESULT CMPCUploadJob::CanRelease( bool& fResult )
  368. {
  369. __ULT_FUNC_ENTRY( "CMPCUploadJob::CanRelease" );
  370. HRESULT hr;
  371. MPC::SmartLock<_ThreadModel> lock( this );
  372. fResult = false;
  373. (void)RemoveData ();
  374. (void)RemoveResponse();
  375. if(!m_bstrFileName &&
  376. !m_bstrFileNameResponse )
  377. {
  378. fResult = true;
  379. }
  380. hr = S_OK;
  381. __ULT_FUNC_EXIT(hr);
  382. }
  383. HRESULT CMPCUploadJob::RemoveData()
  384. {
  385. __ULT_FUNC_ENTRY( "CMPCUploadJob::RemoveData" );
  386. HRESULT hr;
  387. MPC::SmartLock<_ThreadModel> lock( this );
  388. if(m_bstrFileName != NULL)
  389. {
  390. if(SUCCEEDED(MPC::DeleteFile( m_bstrFileName )))
  391. {
  392. m_bstrFileName.Empty();
  393. m_fDirty = true;
  394. }
  395. }
  396. hr = S_OK;
  397. __ULT_FUNC_EXIT(hr);
  398. }
  399. HRESULT CMPCUploadJob::RemoveResponse()
  400. {
  401. __ULT_FUNC_ENTRY( "CMPCUploadJob::RemoveResponse" );
  402. HRESULT hr;
  403. MPC::SmartLock<_ThreadModel> lock( this );
  404. if(m_bstrFileNameResponse != NULL)
  405. {
  406. if(SUCCEEDED(MPC::DeleteFile( m_bstrFileNameResponse )))
  407. {
  408. m_bstrFileNameResponse.Empty();
  409. m_fDirty = true;
  410. }
  411. }
  412. hr = S_OK;
  413. __ULT_FUNC_EXIT(hr);
  414. }
  415. /////////////////////////////////////////////////////////////////////////////
  416. /////////////////////////////////////////////////////////////////////////////
  417. //////////////////////////
  418. // //
  419. // Event Firing Methods //
  420. // //
  421. //////////////////////////
  422. HRESULT CMPCUploadJob::Fire_onStatusChange( IMPCUploadJob* mpcujJob, tagUL_STATUS usStatus )
  423. {
  424. CComVariant pvars[2];
  425. CComPtr<IDispatch> pSink;
  426. //
  427. // Only this part should be inside a critical section, otherwise deadlocks could occur.
  428. //
  429. {
  430. MPC::SmartLock<_ThreadModel> lock( this );
  431. pSink = m_sink_onStatusChange;
  432. }
  433. pvars[1] = mpcujJob;
  434. pvars[0] = usStatus;
  435. return FireAsync_Generic( DISPID_UL_UPLOADEVENTS_ONSTATUSCHANGE, pvars, ARRAYSIZE( pvars ), pSink );
  436. }
  437. HRESULT CMPCUploadJob::Fire_onProgressChange( IMPCUploadJob* mpcujJob, LONG lCurrentSize, LONG lTotalSize )
  438. {
  439. CComVariant pvars[3];
  440. CComPtr<IDispatch> pSink;
  441. //
  442. // Only this part should be inside a critical section, otherwise deadlocks could occur.
  443. //
  444. {
  445. MPC::SmartLock<_ThreadModel> lock( this );
  446. pSink = m_sink_onProgressChange;
  447. }
  448. pvars[2] = mpcujJob;
  449. pvars[1] = lCurrentSize;
  450. pvars[0] = lTotalSize;
  451. return FireAsync_Generic( DISPID_UL_UPLOADEVENTS_ONPROGRESSCHANGE, pvars, ARRAYSIZE( pvars ), pSink );
  452. }
  453. /////////////////////////////////////////////////////////////////////////////
  454. /////////////////
  455. // //
  456. // Persistence //
  457. // //
  458. /////////////////
  459. bool CMPCUploadJob::IsDirty()
  460. {
  461. __ULT_FUNC_ENTRY( "CMPCUploadJob::IsDirty" );
  462. bool fRes;
  463. MPC::SmartLock<_ThreadModel> lock( this );
  464. fRes = m_fDirty;
  465. __ULT_FUNC_EXIT(fRes);
  466. }
  467. HRESULT CMPCUploadJob::Load( /*[in]*/ MPC::Serializer& streamIn )
  468. {
  469. __ULT_FUNC_ENTRY( "CMPCUploadJob::Load" );
  470. HRESULT hr;
  471. MPC::SmartLock<_ThreadModel> lock( this );
  472. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dwInternalSeq );
  473. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_sigClient );
  474. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrServer );
  475. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrJobID );
  476. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrProviderID );
  477. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrCreator );
  478. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrUsername );
  479. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrPassword );
  480. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrFileNameResponse);
  481. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_bstrFileName );
  482. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_lOriginalSize );
  483. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_lTotalSize );
  484. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_lSentSize );
  485. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dwCRC );
  486. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_uhHistory );
  487. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_usStatus );
  488. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dwErrorCode );
  489. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_umMode );
  490. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_fPersistToDisk );
  491. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_fCompressed );
  492. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_lPriority );
  493. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dCreationTime );
  494. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dCompleteTime );
  495. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_dExpirationTime );
  496. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn >> m_Proxy );
  497. m_fDirty = false;
  498. hr = S_OK;
  499. if(m_usStatus == UL_TRANSMITTING)
  500. {
  501. m_usStatus = UL_ACTIVE;
  502. }
  503. __ULT_FUNC_CLEANUP;
  504. __ULT_FUNC_EXIT(hr);
  505. }
  506. HRESULT CMPCUploadJob::Save( /*[in]*/ MPC::Serializer& streamOut )
  507. {
  508. __ULT_FUNC_ENTRY( "CMPCUploadJob::Save" );
  509. HRESULT hr;
  510. MPC::SmartLock<_ThreadModel> lock( this );
  511. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dwInternalSeq );
  512. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_sigClient );
  513. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrServer );
  514. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrJobID );
  515. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrProviderID );
  516. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrCreator );
  517. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrUsername );
  518. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrPassword );
  519. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrFileNameResponse);
  520. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_bstrFileName );
  521. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_lOriginalSize );
  522. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_lTotalSize );
  523. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_lSentSize );
  524. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dwCRC );
  525. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_uhHistory );
  526. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_usStatus );
  527. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dwErrorCode );
  528. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_umMode );
  529. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_fPersistToDisk );
  530. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_fCompressed );
  531. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_lPriority );
  532. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dCreationTime );
  533. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dCompleteTime );
  534. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_dExpirationTime );
  535. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut << m_Proxy );
  536. m_fDirty = false;
  537. hr = S_OK;
  538. __ULT_FUNC_CLEANUP;
  539. __ULT_FUNC_EXIT(hr);
  540. }
  541. /////////////////////////////////////////////////////////////////////////////
  542. ////////////////
  543. // //
  544. // Properties //
  545. // //
  546. ////////////////
  547. HRESULT CMPCUploadJob::get_Sequence( /*[out]*/ ULONG *pVal ) // INTERNAL METHOD
  548. {
  549. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_Sequence",hr,pVal,m_dwInternalSeq);
  550. __ULT_END_PROPERTY(hr);
  551. }
  552. STDMETHODIMP CMPCUploadJob::get_Sig( /*[out]*/ BSTR *pVal )
  553. {
  554. __ULT_BEGIN_PROPERTY_GET("CMPCUploadJob::get_Sig",hr,pVal);
  555. CComBSTR bstrSig = m_sigClient.guidMachineID;
  556. *pVal = bstrSig.Detach();
  557. __ULT_END_PROPERTY(hr);
  558. }
  559. //
  560. // if newVal is NULL, the function will try to read the GUID from the registry.
  561. // this is to help the script writer use upload library.
  562. // -- DanielLi
  563. //
  564. STDMETHODIMP CMPCUploadJob::put_Sig( /*[in]*/ BSTR newVal )
  565. {
  566. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Sig",hr);
  567. GUID guid = GUID_NULL;
  568. CHECK_MODIFY();
  569. if(newVal == NULL || ::SysStringLen( newVal ) == 0)
  570. {
  571. __MPC_EXIT_IF_METHOD_FAILS(hr, GetGUID( guid ));
  572. m_sigClient.guidMachineID = guid;
  573. }
  574. else
  575. {
  576. __MPC_EXIT_IF_METHOD_FAILS(hr, ::IIDFromString( newVal, &m_sigClient.guidMachineID ));
  577. }
  578. __ULT_END_PROPERTY(hr);
  579. }
  580. /////////////////////////////////////////////////////////////////////////////
  581. STDMETHODIMP CMPCUploadJob::get_Server( /*[out]*/ BSTR *pVal )
  582. {
  583. MPC::SmartLock<_ThreadModel> lock( this );
  584. return MPC::GetBSTR( m_bstrServer, pVal );
  585. }
  586. STDMETHODIMP CMPCUploadJob::put_Server( /*[in]*/ BSTR newVal )
  587. {
  588. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Server",hr);
  589. BOOL fUrlCorrect;
  590. MPC::URL url;
  591. INTERNET_SCHEME nScheme;
  592. __MPC_PARAMCHECK_BEGIN(hr)
  593. __MPC_PARAMCHECK_STRING_NOT_EMPTY(newVal);
  594. __MPC_PARAMCHECK_END();
  595. CHECK_MODIFY();
  596. //
  597. // Check for proper URL syntax and only allow HTTP and HTTPS protocols.
  598. //
  599. hr = url.put_URL( newVal );
  600. if(SUCCEEDED(hr))
  601. {
  602. if(SUCCEEDED(hr = url.get_Scheme( nScheme )))
  603. {
  604. if(nScheme != INTERNET_SCHEME_HTTP &&
  605. nScheme != INTERNET_SCHEME_HTTPS )
  606. {
  607. hr = E_FAIL;
  608. }
  609. }
  610. }
  611. if(FAILED(hr))
  612. {
  613. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  614. }
  615. __MPC_EXIT_IF_METHOD_FAILS(hr, url.get_Scheme( nScheme ));
  616. m_bstrServer = newVal;
  617. m_fDirty = true;
  618. __ULT_END_PROPERTY(hr);
  619. }
  620. /////////////////////////////////////////////////////////////////////////////
  621. STDMETHODIMP CMPCUploadJob::get_JobID( /*[out]*/ BSTR *pVal )
  622. {
  623. MPC::SmartLock<_ThreadModel> lock( this );
  624. return MPC::GetBSTR( m_bstrJobID, pVal );
  625. }
  626. STDMETHODIMP CMPCUploadJob::put_JobID( /*[in]*/ BSTR newVal )
  627. {
  628. __ULT_FUNC_ENTRY( "CMPCUploadJob::put_JobID" );
  629. HRESULT hr;
  630. CMPCUploadJob* mpcujJob = NULL;
  631. bool fFound;
  632. MPC::SmartLock<_ThreadModel> lock( NULL ); // Don't get the lock immediately.
  633. __MPC_PARAMCHECK_BEGIN(hr)
  634. __MPC_PARAMCHECK_STRING_NOT_EMPTY(newVal);
  635. __MPC_PARAMCHECK_END();
  636. //
  637. // Important, keep these calls outside Locked section, otherwise deadlocks are possibles.
  638. //
  639. if(m_mpcuRoot)
  640. {
  641. __MPC_EXIT_IF_METHOD_FAILS(hr, m_mpcuRoot->GetJobByName( mpcujJob, fFound, newVal ));
  642. }
  643. lock = this; // Get the lock.
  644. if(fFound)
  645. {
  646. //
  647. // Found a job with the same ID.
  648. //
  649. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_ALREADY_EXISTS );
  650. }
  651. CHECK_MODIFY();
  652. m_bstrJobID = newVal;
  653. m_fDirty = true;
  654. hr = S_OK;
  655. __ULT_FUNC_CLEANUP;
  656. if(mpcujJob) mpcujJob->Release();
  657. __ULT_FUNC_EXIT(hr);
  658. }
  659. /////////////////////////////////////////////////////////////////////////////
  660. STDMETHODIMP CMPCUploadJob::get_ProviderID( /*[out]*/ BSTR *pVal )
  661. {
  662. MPC::SmartLock<_ThreadModel> lock( this );
  663. return MPC::GetBSTR( m_bstrProviderID, pVal );
  664. }
  665. STDMETHODIMP CMPCUploadJob::put_ProviderID( /*[in]*/ BSTR newVal )
  666. {
  667. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_ProviderID",hr);
  668. __MPC_PARAMCHECK_BEGIN(hr)
  669. __MPC_PARAMCHECK_STRING_NOT_EMPTY(newVal);
  670. __MPC_PARAMCHECK_END();
  671. CHECK_MODIFY();
  672. m_bstrProviderID = newVal;
  673. m_fDirty = true;
  674. __ULT_END_PROPERTY(hr);
  675. }
  676. /////////////////////////////////////////////////////////////////////////////
  677. HRESULT CMPCUploadJob::put_Creator( /*[in]*/ BSTR newVal )
  678. {
  679. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Creator",hr);
  680. CHECK_MODIFY();
  681. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::PutBSTR( m_bstrCreator, newVal, false ));
  682. m_fDirty = true;
  683. __ULT_END_PROPERTY(hr);
  684. }
  685. STDMETHODIMP CMPCUploadJob::get_Creator( /*[out]*/ BSTR *pVal )
  686. {
  687. MPC::SmartLock<_ThreadModel> lock( this );
  688. return MPC::GetBSTR( m_bstrCreator, pVal );
  689. }
  690. /////////////////////////////////////////////////////////////////////////////
  691. STDMETHODIMP CMPCUploadJob::get_Username( /*[out]*/ BSTR *pVal )
  692. {
  693. MPC::SmartLock<_ThreadModel> lock( this );
  694. return MPC::GetBSTR( m_bstrUsername, pVal );
  695. }
  696. STDMETHODIMP CMPCUploadJob::put_Username( /*[in]*/ BSTR newVal )
  697. {
  698. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Username",hr);
  699. CHECK_MODIFY();
  700. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::PutBSTR( m_bstrUsername, newVal ));
  701. m_fDirty = true;
  702. __ULT_END_PROPERTY(hr);
  703. }
  704. /////////////////////////////////////////////////////////////////////////////
  705. STDMETHODIMP CMPCUploadJob::get_Password( /*[out]*/ BSTR *pVal )
  706. {
  707. MPC::SmartLock<_ThreadModel> lock( this );
  708. return MPC::GetBSTR( m_bstrPassword, pVal );
  709. }
  710. STDMETHODIMP CMPCUploadJob::put_Password( /*[in]*/ BSTR newVal )
  711. {
  712. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Password",hr);
  713. CHECK_MODIFY();
  714. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::PutBSTR( m_bstrPassword, newVal ));
  715. m_fDirty = true;
  716. __ULT_END_PROPERTY(hr);
  717. }
  718. /////////////////////////////////////////////////////////////////////////////
  719. HRESULT CMPCUploadJob::get_FileName( /*[out]*/ BSTR *pVal )
  720. {
  721. MPC::SmartLock<_ThreadModel> lock( this );
  722. return MPC::GetBSTR( m_bstrFileName, pVal );
  723. }
  724. /////////////////////////////////////////////////////////////////////////////
  725. STDMETHODIMP CMPCUploadJob::get_OriginalSize( /*[out]*/ long *pVal )
  726. {
  727. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_OriginalSize",hr,pVal,m_lOriginalSize);
  728. __ULT_END_PROPERTY(hr);
  729. }
  730. /////////////////////////////////////////////////////////////////////////////
  731. STDMETHODIMP CMPCUploadJob::get_TotalSize( /*[out]*/ long *pVal )
  732. {
  733. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_TotalSize",hr,pVal,m_lTotalSize);
  734. __ULT_END_PROPERTY(hr);
  735. }
  736. /////////////////////////////////////////////////////////////////////////////
  737. STDMETHODIMP CMPCUploadJob::get_SentSize( /*[out]*/ long *pVal )
  738. {
  739. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_SentSize",hr,pVal,m_lSentSize);
  740. __ULT_END_PROPERTY(hr);
  741. }
  742. HRESULT CMPCUploadJob::put_SentSize( /*[in]*/ long newVal ) // INTERNAL METHOD.
  743. {
  744. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_SentSize",hr);
  745. long lSentSize;
  746. long lTotalSize;
  747. m_lSentSize = newVal;
  748. m_fDirty = true;
  749. lSentSize = m_lSentSize;
  750. lTotalSize = m_lTotalSize;
  751. lock = NULL; // Release the lock before firing the event.
  752. //
  753. // Important, leave this call outside Locked Sections!!
  754. //
  755. Fire_onProgressChange( this, lSentSize, lTotalSize );
  756. __ULT_END_PROPERTY(hr);
  757. }
  758. HRESULT CMPCUploadJob::put_Response ( /*[in] */ long lSize, /*[in]*/ LPBYTE pData ) // INTERNAL METHOD
  759. {
  760. __ULT_FUNC_ENTRY( "CMPCUploadJob::put_Response" );
  761. HRESULT hr;
  762. CComPtr<MPC::FileStream> stream;
  763. MPC::SmartLock<_ThreadModel> lock( this );
  764. //
  765. // Delete old data.
  766. //
  767. __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveResponse());
  768. if(lSize && m_bstrFileName.Length())
  769. {
  770. ULONG lWritten;
  771. //
  772. // Create the name for the response file.
  773. //
  774. m_bstrFileNameResponse = m_bstrFileName; m_bstrFileNameResponse.Append( L".resp" );
  775. //
  776. // Copy the data to a file.
  777. //
  778. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  779. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForWrite( SAFEBSTR( m_bstrFileNameResponse ) ));
  780. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->Write( pData, lSize, &lWritten ));
  781. }
  782. hr = S_OK;
  783. __ULT_FUNC_CLEANUP;
  784. stream.Release();
  785. if(FAILED(hr))
  786. {
  787. (void)RemoveResponse();
  788. }
  789. __ULT_FUNC_EXIT(hr);
  790. }
  791. /////////////////////////////////////////////////////////////////////////////
  792. STDMETHODIMP CMPCUploadJob::get_History( /*[out]*/ UL_HISTORY *pVal )
  793. {
  794. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_History",hr,pVal,m_uhHistory);
  795. __ULT_END_PROPERTY(hr);
  796. }
  797. STDMETHODIMP CMPCUploadJob::put_History( /*[in]*/ UL_HISTORY newVal )
  798. {
  799. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_History",hr);
  800. CHECK_MODIFY();
  801. //
  802. // During debug, override user settings.
  803. //
  804. if(g_Override_History)
  805. {
  806. newVal = g_Override_History_Value;
  807. }
  808. //
  809. // Check for proper value of input parameters.
  810. //
  811. switch(newVal)
  812. {
  813. case UL_HISTORY_NONE :
  814. case UL_HISTORY_LOG :
  815. case UL_HISTORY_LOG_AND_DATA: break;
  816. default:
  817. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  818. }
  819. m_uhHistory = newVal;
  820. m_fDirty = true;
  821. __ULT_END_PROPERTY(hr);
  822. }
  823. /////////////////////////////////////////////////////////////////////////////
  824. STDMETHODIMP CMPCUploadJob::get_Status( /*[out]*/ UL_STATUS *pVal )
  825. {
  826. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_Status",hr,pVal,m_usStatus);
  827. __ULT_END_PROPERTY(hr);
  828. }
  829. HRESULT CMPCUploadJob::put_Status( /*[in]*/ UL_STATUS newVal ) // INTERNAL METHOD.
  830. {
  831. __ULT_FUNC_ENTRY( "CMPCUploadJob::put_Status" );
  832. HRESULT hr = try_Status( (UL_STATUS)-1, newVal );
  833. __ULT_FUNC_EXIT(hr);
  834. }
  835. HRESULT CMPCUploadJob::try_Status( /*[in]*/ UL_STATUS usPreVal ,
  836. /*[in]*/ UL_STATUS usPostVal )
  837. {
  838. __ULT_FUNC_ENTRY( "CMPCUploadJob::try_Status" );
  839. HRESULT hr;
  840. MPC::SmartLock<_ThreadModel> lock( this );
  841. bool fChanged = false;
  842. UL_STATUS usStatus;
  843. if(usPreVal == m_usStatus ||
  844. usPreVal == -1 )
  845. {
  846. m_usStatus = usPostVal;
  847. m_fDirty = true;
  848. usStatus = m_usStatus;
  849. fChanged = true;
  850. //
  851. // Clean error while tranmitting.
  852. //
  853. if(m_usStatus == UL_TRANSMITTING)
  854. {
  855. m_dwErrorCode = 0;
  856. }
  857. switch(m_usStatus)
  858. {
  859. case UL_FAILED:
  860. case UL_COMPLETED:
  861. case UL_DELETED:
  862. //
  863. // The job is done, successfully or not, so it's time to do some cleanup.
  864. //
  865. switch(m_uhHistory)
  866. {
  867. case UL_HISTORY_NONE:
  868. m_usStatus = UL_DELETED;
  869. case UL_HISTORY_LOG:
  870. __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveData());
  871. case UL_HISTORY_LOG_AND_DATA:
  872. break;
  873. }
  874. case UL_ABORTED:
  875. m_dCompleteTime = MPC::GetLocalTime();
  876. break;
  877. }
  878. }
  879. hr = S_OK;
  880. __ULT_FUNC_CLEANUP;
  881. lock = NULL; // Release the lock before firing the event.
  882. //
  883. // Important, leave these calls outside Locked Sections!!
  884. //
  885. if(SUCCEEDED(hr) && fChanged)
  886. {
  887. Fire_onStatusChange( this, usStatus );
  888. //
  889. // Recompute queue.
  890. //
  891. if(m_mpcuRoot)
  892. {
  893. hr = m_mpcuRoot->TriggerRescheduleJobs();
  894. }
  895. }
  896. __ULT_FUNC_EXIT(hr);
  897. }
  898. /////////////////////////////////////////////////////////////////////////////
  899. STDMETHODIMP CMPCUploadJob::get_ErrorCode( /*[out]*/ long *pVal )
  900. {
  901. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_ErrorCode",hr,pVal,(long)m_dwErrorCode);
  902. __ULT_END_PROPERTY(hr);
  903. }
  904. HRESULT CMPCUploadJob::put_ErrorCode( /*[in]*/ DWORD newVal ) // INTERNAL METHOD.
  905. {
  906. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_ErrorCode",hr);
  907. m_dwErrorCode = newVal;
  908. m_fDirty = true;
  909. __ULT_END_PROPERTY(hr);
  910. }
  911. /////////////////////////////////////////////////////////////////////////////
  912. HRESULT CMPCUploadJob::get_RetryInterval( /*[out]*/ DWORD *pVal ) // INTERNAL METHOD
  913. {
  914. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_RetryInterval",hr,pVal,m_dwRetryInterval);
  915. __ULT_END_PROPERTY(hr);
  916. }
  917. HRESULT CMPCUploadJob::put_RetryInterval( /*[in] */ DWORD newVal ) // INTERNAL METHOD
  918. {
  919. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_RetryInterval",hr);
  920. m_dwRetryInterval = newVal;
  921. __ULT_END_PROPERTY(hr);
  922. }
  923. /////////////////////////////////////////////////////////////////////////////
  924. STDMETHODIMP CMPCUploadJob::get_Mode( /*[out]*/ UL_MODE *pVal )
  925. {
  926. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_Mode",hr,pVal,m_umMode);
  927. __ULT_END_PROPERTY(hr);
  928. }
  929. STDMETHODIMP CMPCUploadJob::put_Mode( /*[in]*/ UL_MODE newVal )
  930. {
  931. __ULT_FUNC_ENTRY( "CMPCUploadJob::put_Mode" );
  932. HRESULT hr;
  933. bool fChanged = false;
  934. MPC::SmartLock<_ThreadModel> lock( this );
  935. CHECK_MODIFY();
  936. //
  937. // Check for proper value of input parameters.
  938. //
  939. switch(newVal)
  940. {
  941. case UL_BACKGROUND:
  942. case UL_FOREGROUND: break;
  943. default:
  944. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  945. }
  946. if(m_umMode != newVal)
  947. {
  948. m_umMode = newVal;
  949. m_fDirty = true;
  950. fChanged = true;
  951. }
  952. hr = S_OK;
  953. __ULT_FUNC_CLEANUP;
  954. lock = NULL; // Release the lock before firing the event.
  955. //
  956. // Important, keep this call outside Locked section, otherwise deadlocks are possibles.
  957. //
  958. if(SUCCEEDED(hr) && fChanged)
  959. {
  960. //
  961. // Recompute queue.
  962. //
  963. if(m_mpcuRoot)
  964. {
  965. hr = m_mpcuRoot->TriggerRescheduleJobs();
  966. }
  967. }
  968. __ULT_FUNC_EXIT(hr);
  969. }
  970. /////////////////////////////////////////////////////////////////////////////
  971. STDMETHODIMP CMPCUploadJob::get_PersistToDisk( /*[out]*/ VARIANT_BOOL *pVal )
  972. {
  973. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_PersistToDisk",hr,pVal,m_fPersistToDisk);
  974. __ULT_END_PROPERTY(hr);
  975. }
  976. STDMETHODIMP CMPCUploadJob::put_PersistToDisk( /*[in]*/ VARIANT_BOOL newVal )
  977. {
  978. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_PersistToDisk",hr);
  979. CHECK_MODIFY();
  980. //
  981. // During debug, override user settings.
  982. //
  983. if(g_Override_Persist)
  984. {
  985. newVal = g_Override_Persist_Value;
  986. }
  987. m_fPersistToDisk = newVal;
  988. m_fDirty = true;
  989. __ULT_END_PROPERTY(hr);
  990. }
  991. /////////////////////////////////////////////////////////////////////////////
  992. STDMETHODIMP CMPCUploadJob::get_Compressed( /*[out]*/ VARIANT_BOOL *pVal )
  993. {
  994. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_Compressed",hr,pVal,m_fCompressed);
  995. __ULT_END_PROPERTY(hr);
  996. }
  997. STDMETHODIMP CMPCUploadJob::put_Compressed( /*[in]*/ VARIANT_BOOL newVal )
  998. {
  999. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_Compressed",hr);
  1000. CHECK_MODIFY();
  1001. //
  1002. // You can't change the compression flag after having set the data!!
  1003. //
  1004. if(m_lOriginalSize != 0)
  1005. {
  1006. __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  1007. }
  1008. //
  1009. // During debug, override user settings.
  1010. //
  1011. if(g_Override_Compressed)
  1012. {
  1013. newVal = g_Override_Compressed_Value;
  1014. }
  1015. m_fCompressed = newVal;
  1016. m_fDirty = true;
  1017. __ULT_END_PROPERTY(hr);
  1018. }
  1019. /////////////////////////////////////////////////////////////////////////////
  1020. STDMETHODIMP CMPCUploadJob::get_Priority( /*[out]*/ long *pVal )
  1021. {
  1022. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_Priority",hr,pVal,m_lPriority);
  1023. __ULT_END_PROPERTY(hr);
  1024. }
  1025. STDMETHODIMP CMPCUploadJob::put_Priority( /*[in]*/ long newVal )
  1026. {
  1027. __ULT_FUNC_ENTRY( "CMPCUploadJob::put_Priority" );
  1028. HRESULT hr;
  1029. bool fChanged = false;
  1030. MPC::SmartLock<_ThreadModel> lock( this );
  1031. CHECK_MODIFY();
  1032. if(m_lPriority != newVal)
  1033. {
  1034. m_lPriority = newVal;
  1035. m_fDirty = true;
  1036. fChanged = true;
  1037. }
  1038. hr = S_OK;
  1039. __ULT_FUNC_CLEANUP;
  1040. lock = NULL; // Release the lock before firing the event.
  1041. //
  1042. // Important, keep this call outside Locked section, otherwise deadlocks are possibles.
  1043. //
  1044. if(SUCCEEDED(hr) && fChanged)
  1045. {
  1046. //
  1047. // Recompute queue.
  1048. //
  1049. if(m_mpcuRoot)
  1050. {
  1051. hr = m_mpcuRoot->TriggerRescheduleJobs();
  1052. }
  1053. }
  1054. __ULT_FUNC_EXIT(hr);
  1055. }
  1056. /////////////////////////////////////////////////////////////////////////////
  1057. STDMETHODIMP CMPCUploadJob::get_CreationTime( /*[out]*/ DATE *pVal )
  1058. {
  1059. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_CreationTime",hr,pVal,m_dCreationTime);
  1060. __ULT_END_PROPERTY(hr);
  1061. }
  1062. /////////////////////////////////////////////////////////////////////////////
  1063. STDMETHODIMP CMPCUploadJob::get_CompleteTime( /*[out]*/ DATE *pVal )
  1064. {
  1065. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_CompleteTime",hr,pVal,m_dCompleteTime);
  1066. __ULT_END_PROPERTY(hr);
  1067. }
  1068. /////////////////////////////////////////////////////////////////////////////
  1069. STDMETHODIMP CMPCUploadJob::get_ExpirationTime( /*[out]*/ DATE *pVal )
  1070. {
  1071. __ULT_BEGIN_PROPERTY_GET2("CMPCUploadJob::get_ExpirationTime",hr,pVal,m_dExpirationTime);
  1072. __ULT_END_PROPERTY(hr);
  1073. }
  1074. /////////////////////////////////////////////////////////////////////////////
  1075. STDMETHODIMP CMPCUploadJob::put_ExpirationTime( /*[in]*/ DATE newVal )
  1076. {
  1077. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_ExpirationTime",hr);
  1078. CHECK_MODIFY();
  1079. m_dExpirationTime = newVal;
  1080. __ULT_END_PROPERTY(hr);
  1081. }
  1082. /////////////////////////////////////////////////////////////////////////////
  1083. /////////////
  1084. // Methods //
  1085. /////////////
  1086. STDMETHODIMP CMPCUploadJob::ActivateSync()
  1087. {
  1088. __ULT_FUNC_ENTRY( "CMPCUploadJob::ActivateSync" );
  1089. HRESULT hr;
  1090. CComPtr<CMPCUploadEvents> mpcueEvent;
  1091. CComPtr<IMPCUploadJob> mpcujJob;
  1092. __MPC_EXIT_IF_METHOD_FAILS(hr, ActivateAsync());
  1093. //
  1094. // Create a new job and link it to the system.
  1095. //
  1096. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &mpcueEvent ));
  1097. __MPC_EXIT_IF_METHOD_FAILS(hr, QueryInterface( IID_IMPCUploadJob, (void**)&mpcujJob ));
  1098. __MPC_EXIT_IF_METHOD_FAILS(hr, mpcueEvent->WaitForCompletion( mpcujJob ));
  1099. hr = S_OK;
  1100. __ULT_FUNC_CLEANUP;
  1101. __ULT_FUNC_EXIT(hr);
  1102. }
  1103. STDMETHODIMP CMPCUploadJob::ActivateAsync()
  1104. {
  1105. __ULT_FUNC_ENTRY( "CMPCUploadJob::ActivateAsync" );
  1106. HRESULT hr;
  1107. UploadLibrary::Signature sigEmpty;
  1108. MPC::SmartLock<_ThreadModel> lock( this );
  1109. CHECK_MODIFY();
  1110. if(m_lOriginalSize == 0)
  1111. {
  1112. __MPC_SET_ERROR_AND_EXIT(hr, E_UPLOADLIBRARY_NO_DATA);
  1113. }
  1114. if(m_sigClient == sigEmpty ||
  1115. m_bstrServer .Length() == 0 ||
  1116. m_bstrProviderID.Length() == 0 )
  1117. {
  1118. __MPC_SET_ERROR_AND_EXIT(hr, E_UPLOADLIBRARY_INVALID_PARAMETERS);
  1119. }
  1120. hr = S_OK;
  1121. __ULT_FUNC_CLEANUP;
  1122. lock = NULL; // Release the lock before firing the event.
  1123. //
  1124. // Important, leave this call outside Locked Sections!!
  1125. //
  1126. if(SUCCEEDED(hr)) put_Status( UL_ACTIVE );
  1127. __ULT_FUNC_EXIT(hr);
  1128. }
  1129. STDMETHODIMP CMPCUploadJob::Suspend()
  1130. {
  1131. __ULT_FUNC_ENTRY( "CMPCUploadJob::Suspend" );
  1132. HRESULT hr;
  1133. UL_STATUS usStatus;
  1134. MPC::SmartLock<_ThreadModel> lock( this );
  1135. usStatus = m_usStatus;
  1136. if(usStatus == UL_ACTIVE ||
  1137. usStatus == UL_TRANSMITTING ||
  1138. usStatus == UL_ABORTED )
  1139. {
  1140. lock = NULL; // Release the lock before firing the event.
  1141. //
  1142. // Important, leave this call outside Locked Sections!!
  1143. //
  1144. hr = try_Status( usStatus, UL_SUSPENDED );
  1145. }
  1146. hr = S_OK;
  1147. __ULT_FUNC_EXIT(hr);
  1148. }
  1149. STDMETHODIMP CMPCUploadJob::Delete()
  1150. {
  1151. __ULT_FUNC_ENTRY( "CMPCUploadJob::Delete" );
  1152. HRESULT hr;
  1153. hr = put_Status( UL_DELETED );
  1154. __ULT_FUNC_EXIT(hr);
  1155. }
  1156. STDMETHODIMP CMPCUploadJob::GetDataFromFile( /*[in]*/ BSTR bstrFileName )
  1157. {
  1158. __ULT_FUNC_ENTRY( "CMPCUploadJob::GetDataFromFile" );
  1159. HRESULT hr;
  1160. CComPtr<MPC::FileStream> streamIn;
  1161. __MPC_PARAMCHECK_BEGIN(hr)
  1162. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFileName);
  1163. __MPC_PARAMCHECK_END();
  1164. ////////////////////////////////////////////////////////////////////////////////
  1165. //
  1166. // Open the destination file, impersonating the caller.
  1167. //
  1168. {
  1169. MPC::Impersonation imp;
  1170. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize ());
  1171. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Impersonate());
  1172. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamIn ));
  1173. __MPC_EXIT_IF_METHOD_FAILS(hr, streamIn->InitForRead( bstrFileName ));
  1174. }
  1175. //
  1176. ////////////////////////////////////////////////////////////////////////////////
  1177. //
  1178. // Copy the source file.
  1179. //
  1180. __MPC_EXIT_IF_METHOD_FAILS(hr, GetDataFromStream( streamIn ));
  1181. hr = S_OK;
  1182. __ULT_FUNC_CLEANUP;
  1183. __ULT_FUNC_EXIT(hr);
  1184. }
  1185. STDMETHODIMP CMPCUploadJob::PutDataIntoFile( /*[in]*/ BSTR bstrFileName )
  1186. {
  1187. __ULT_FUNC_ENTRY( "CMPCUploadJob::PutDataIntoFile" );
  1188. HRESULT hr;
  1189. CComPtr<IUnknown> unk;
  1190. CComPtr<IStream> streamIn;
  1191. CComPtr<MPC::FileStream> streamOut;
  1192. __MPC_PARAMCHECK_BEGIN(hr)
  1193. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFileName);
  1194. __MPC_PARAMCHECK_END();
  1195. //
  1196. // Open the source file.
  1197. //
  1198. __MPC_EXIT_IF_METHOD_FAILS(hr, PutDataIntoStream( &unk ));
  1199. __MPC_EXIT_IF_METHOD_FAILS(hr, unk.QueryInterface( &streamIn ));
  1200. ////////////////////////////////////////////////////////////////////////////////
  1201. //
  1202. // Open the destination file, impersonating the caller.
  1203. //
  1204. {
  1205. MPC::Impersonation imp;
  1206. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize ());
  1207. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Impersonate());
  1208. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamOut ));
  1209. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut->InitForWrite( bstrFileName ));
  1210. }
  1211. //
  1212. ////////////////////////////////////////////////////////////////////////////////
  1213. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamIn, streamOut ));
  1214. hr = S_OK;
  1215. __ULT_FUNC_CLEANUP;
  1216. __ULT_FUNC_EXIT(hr);
  1217. }
  1218. STDMETHODIMP CMPCUploadJob::GetDataFromStream( /*[in]*/ IUnknown* stream )
  1219. {
  1220. __ULT_FUNC_ENTRY( "CMPCUploadJob::GetDataFromStream" );
  1221. HRESULT hr;
  1222. DWORD dwQueueSize;
  1223. CComPtr<IStream> streamIn;
  1224. MPC::SmartLock<_ThreadModel> lock( this );
  1225. __MPC_PARAMCHECK_BEGIN(hr)
  1226. __MPC_PARAMCHECK_NOTNULL(stream);
  1227. __MPC_PARAMCHECK_END();
  1228. CHECK_MODIFY();
  1229. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->QueryInterface( IID_IStream, (void**)&streamIn ));
  1230. //
  1231. // Calculate current queue size.
  1232. //
  1233. lock = NULL; // Release the lock before calling the root.
  1234. if(m_mpcuRoot)
  1235. {
  1236. __MPC_EXIT_IF_METHOD_FAILS(hr, m_mpcuRoot->CalculateQueueSize( dwQueueSize ));
  1237. }
  1238. lock = this; // Reget the lock.
  1239. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateDataFromStream( streamIn, dwQueueSize ));
  1240. hr = S_OK;
  1241. __ULT_FUNC_CLEANUP;
  1242. __ULT_FUNC_EXIT(hr);
  1243. }
  1244. STDMETHODIMP CMPCUploadJob::PutDataIntoStream( /*[out, retval]*/ IUnknown* *pstream )
  1245. {
  1246. __ULT_FUNC_ENTRY( "CMPCUploadJob::PutDataIntoStream" );
  1247. HRESULT hr;
  1248. CComPtr<IStream> streamOut;
  1249. MPC::SmartLock<_ThreadModel> lock( this );
  1250. __MPC_PARAMCHECK_BEGIN(hr)
  1251. __MPC_PARAMCHECK_POINTER_AND_SET(pstream,NULL);
  1252. __MPC_PARAMCHECK_END();
  1253. __MPC_EXIT_IF_METHOD_FAILS(hr, OpenReadStreamForData( &streamOut ));
  1254. __MPC_EXIT_IF_METHOD_FAILS(hr, streamOut.QueryInterface( pstream ));
  1255. hr = S_OK;
  1256. __ULT_FUNC_CLEANUP;
  1257. __ULT_FUNC_EXIT(hr);
  1258. }
  1259. STDMETHODIMP CMPCUploadJob::GetResponseAsStream( /*[out, retval]*/ IUnknown* *pstream )
  1260. {
  1261. __ULT_FUNC_ENTRY( "CMPCUploadJob::GetResponseAsStream" );
  1262. HRESULT hr;
  1263. CComBSTR bstrTmpFileName;
  1264. CComPtr<MPC::FileStream> stream;
  1265. MPC::SmartLock<_ThreadModel> lock( this );
  1266. __MPC_PARAMCHECK_BEGIN(hr)
  1267. __MPC_PARAMCHECK_POINTER_AND_SET(pstream,NULL);
  1268. __MPC_PARAMCHECK_END();
  1269. if(m_bstrFileNameResponse.Length() == 0)
  1270. {
  1271. __MPC_SET_ERROR_AND_EXIT(hr, E_UPLOADLIBRARY_NO_DATA);
  1272. }
  1273. //
  1274. // Generate a temporary file name.
  1275. //
  1276. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateTmpFileName( bstrTmpFileName ));
  1277. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CopyFile( m_bstrFileNameResponse, bstrTmpFileName ));
  1278. //
  1279. // Open the file as a stream and set the DeleteOnRelease flag.
  1280. //
  1281. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &stream ));
  1282. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->InitForRead ( bstrTmpFileName ));
  1283. __MPC_EXIT_IF_METHOD_FAILS(hr, stream->DeleteOnRelease( true ));
  1284. *pstream = stream.Detach();
  1285. hr = S_OK;
  1286. __ULT_FUNC_CLEANUP;
  1287. stream.Release();
  1288. if(FAILED(hr) && bstrTmpFileName.Length())
  1289. {
  1290. (void)MPC::DeleteFile( bstrTmpFileName );
  1291. }
  1292. __ULT_FUNC_EXIT(hr);
  1293. }
  1294. /////////////////////////////////////////////////////////////////////////////
  1295. STDMETHODIMP CMPCUploadJob::put_onStatusChange( /*[in]*/ IDispatch* function )
  1296. {
  1297. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_onStatusChange",hr);
  1298. m_sink_onStatusChange = function;
  1299. __ULT_END_PROPERTY(hr);
  1300. }
  1301. STDMETHODIMP CMPCUploadJob::put_onProgressChange( /*[in]*/ IDispatch* function )
  1302. {
  1303. __ULT_BEGIN_PROPERTY_PUT("CMPCUploadJob::put_onProgressChange",hr);
  1304. m_sink_onProgressChange = function;
  1305. __ULT_END_PROPERTY(hr);
  1306. }
  1307. /////////////////////////////////////////////////////////////////////////////
  1308. HRESULT CMPCUploadJob::SetupRequest( /*[out]*/ UploadLibrary::ClientRequest_OpenSession& crosReq )
  1309. {
  1310. __ULT_FUNC_ENTRY( "CMPCUploadJob::SetupRequest" );
  1311. HRESULT hr;
  1312. crosReq.crHeader.sigClient = m_sigClient;
  1313. crosReq.szJobID = SAFEBSTR( m_bstrJobID );
  1314. crosReq.szProviderID = SAFEBSTR( m_bstrProviderID );
  1315. crosReq.szUsername = SAFEBSTR( m_bstrUsername );
  1316. crosReq.dwSize = m_lTotalSize;
  1317. crosReq.dwSizeOriginal = m_lOriginalSize;
  1318. crosReq.dwCRC = m_dwCRC;
  1319. crosReq.fCompressed = (m_fCompressed == VARIANT_TRUE ? true : false);
  1320. hr = S_OK;
  1321. __ULT_FUNC_EXIT(hr);
  1322. }
  1323. HRESULT CMPCUploadJob::SetupRequest( /*[out]*/ UploadLibrary::ClientRequest_WriteSession& crwsReq, /*[in]*/ DWORD dwSize )
  1324. {
  1325. __ULT_FUNC_ENTRY( "CMPCUploadJob::SetupRequest" );
  1326. HRESULT hr;
  1327. crwsReq.crHeader.sigClient = m_sigClient;
  1328. crwsReq.szJobID = SAFEBSTR( m_bstrJobID );
  1329. crwsReq.dwOffset = m_lSentSize;
  1330. crwsReq.dwSize = dwSize;
  1331. hr = S_OK;
  1332. __ULT_FUNC_EXIT(hr);
  1333. }
  1334. /////////////////////////////////////////////////////////////////////////////
  1335. HRESULT CMPCUploadJob::GetProxySettings()
  1336. {
  1337. __ULT_FUNC_ENTRY( "CMPCUploadJob::GetProxySettings" );
  1338. HRESULT hr;
  1339. MPC::SmartLock<_ThreadModel> lock( this );
  1340. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Proxy.Initialize( true ));
  1341. hr = S_OK;
  1342. __ULT_FUNC_CLEANUP;
  1343. __ULT_FUNC_EXIT(hr);
  1344. }
  1345. HRESULT CMPCUploadJob::SetProxySettings( /*[in]*/ HINTERNET hSession )
  1346. {
  1347. __ULT_FUNC_ENTRY( "CMPCUploadJob::SetProxySettings" );
  1348. HRESULT hr;
  1349. MPC::SmartLock<_ThreadModel> lock( this );
  1350. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Proxy.Apply( hSession ));
  1351. hr = S_OK;
  1352. __ULT_FUNC_CLEANUP;
  1353. __ULT_FUNC_EXIT(hr);
  1354. }