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.

668 lines
18 KiB

  1. // Job.cpp: implementation of the CJob class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #define __FILE_ID__ 17
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. IMPLEMENT_DYNCREATE(CJob, CObject)
  15. DWORD
  16. CJob::Init (
  17. PFAX_JOB_ENTRY_EX pJob,
  18. CServerNode* pServer
  19. )
  20. /*++
  21. Routine name : CJob::Init
  22. Routine description:
  23. Constructs a new job from a FAX_JOB_ENTRY_EX structure
  24. Author:
  25. Eran Yariv (EranY), Jan, 2000
  26. Arguments:
  27. pJob [in] - Pointer to FAX_JOB_ENTRY_EX structure
  28. pServer [in] - pointer to CServerNode object
  29. Return Value:
  30. Standard Win32 error code
  31. --*/
  32. {
  33. DWORD dwRes = ERROR_SUCCESS;
  34. DBG_ENTER(TEXT("CJob::Init"), dwRes);
  35. ASSERTION (pServer);
  36. m_pServer = pServer;
  37. ASSERTION (!m_bValid);
  38. m_dwJobOnlyValidityMask = pJob->dwValidityMask;
  39. try
  40. {
  41. //
  42. // Message id
  43. //
  44. ASSERTION (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_MESSAGE_ID );
  45. m_dwlMessageId = pJob->dwlMessageId;
  46. //
  47. // Broadcast id
  48. //
  49. m_dwlBroadcastId = (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_BROADCAST_ID) ?
  50. pJob->dwlBroadcastId : 0;
  51. //
  52. // Recipient info
  53. //
  54. m_cstrRecipientNumber = pJob->lpctstrRecipientNumber ?
  55. pJob->lpctstrRecipientNumber : TEXT("");
  56. m_cstrRecipientName = pJob->lpctstrRecipientName ?
  57. pJob->lpctstrRecipientName : TEXT("");
  58. //
  59. // Sender info
  60. //
  61. m_cstrSenderUserName = pJob->lpctstrSenderUserName ?
  62. pJob->lpctstrSenderUserName : TEXT("");
  63. m_cstrBillingCode = pJob->lpctstrBillingCode ?
  64. pJob->lpctstrBillingCode : TEXT("");
  65. //
  66. // Document info
  67. //
  68. m_cstrDocumentName = pJob->lpctstrDocumentName ?
  69. pJob->lpctstrDocumentName : TEXT("");
  70. m_cstrSubject = pJob->lpctstrSubject ?
  71. pJob->lpctstrSubject : TEXT("");
  72. //
  73. // Server name
  74. //
  75. m_cstrServerName = m_pServer->Machine();
  76. //
  77. // Original scheduled time
  78. //
  79. if (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_ORIGINAL_SCHEDULE_TIME)
  80. {
  81. m_tmOriginalScheduleTime = pJob->tmOriginalScheduleTime;
  82. }
  83. else
  84. {
  85. m_tmOriginalScheduleTime.Zero ();
  86. }
  87. //
  88. // Submission time
  89. //
  90. if (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_SUBMISSION_TIME)
  91. {
  92. m_tmSubmissionTime = pJob->tmSubmissionTime;
  93. }
  94. else
  95. {
  96. m_tmSubmissionTime.Zero ();
  97. }
  98. //
  99. // Priority
  100. //
  101. if (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_PRIORITY)
  102. {
  103. m_Priority = pJob->Priority;
  104. ASSERTION (m_Priority <= FAX_PRIORITY_TYPE_HIGH);
  105. }
  106. else
  107. {
  108. m_Priority = (FAX_ENUM_PRIORITY_TYPE)-1;
  109. }
  110. }
  111. catch (CException *pException)
  112. {
  113. TCHAR wszCause[1024];
  114. pException->GetErrorMessage (wszCause, 1024);
  115. pException->Delete ();
  116. VERBOSE (EXCEPTION_ERR,
  117. TEXT("CJob::Init caused exception : %s"),
  118. wszCause);
  119. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  120. return dwRes;
  121. }
  122. m_bValid = TRUE;
  123. m_dwPossibleOperations = 0;
  124. if (m_dwJobOnlyValidityMask & FAX_JOB_FIELD_STATUS_SUB_STRUCT)
  125. {
  126. //
  127. // Now update the status
  128. //
  129. dwRes = UpdateStatus (pJob->pStatus);
  130. }
  131. else
  132. {
  133. //
  134. // No status
  135. //
  136. VERBOSE (DBG_MSG, TEXT("Job id 0x%016I64x has no status"), m_dwlMessageId);
  137. m_dwValidityMask = m_dwJobOnlyValidityMask;
  138. ASSERTION_FAILURE;
  139. }
  140. return dwRes;
  141. } // CJob::Init
  142. BOOL
  143. CJob::IsNewStatus (
  144. PFAX_JOB_STATUS pStatus
  145. )
  146. /*++
  147. Routine name : CJob::IsNewStatus
  148. Routine description:
  149. Check if the new status deffer from the current one
  150. Arguments:
  151. pStatus [in] - Pointer to a new status structure
  152. Return Value:
  153. TRUE if the new status deffer from the current one
  154. FALSE otherwize
  155. --*/
  156. {
  157. DBG_ENTER(TEXT("CJob::IsNewStatus"));
  158. ASSERTION (pStatus);
  159. if(m_dwValidityMask != (m_dwJobOnlyValidityMask | (pStatus->dwValidityMask)) ||
  160. m_dwJobID != pStatus->dwJobID ||
  161. m_dwJobType != pStatus->dwJobType ||
  162. m_dwQueueStatus != pStatus->dwQueueStatus ||
  163. m_dwExtendedStatus != pStatus->dwExtendedStatus ||
  164. m_dwSize != pStatus->dwSize ||
  165. m_dwPageCount != pStatus->dwPageCount ||
  166. m_dwCurrentPage != pStatus->dwCurrentPage ||
  167. m_tmScheduleTime != pStatus->tmScheduleTime ||
  168. m_tmTransmissionStartTime != pStatus->tmTransmissionStartTime ||
  169. m_tmTransmissionEndTime != pStatus->tmTransmissionEndTime ||
  170. m_dwDeviceID != pStatus->dwDeviceID ||
  171. m_dwRetries != pStatus->dwRetries ||
  172. m_dwPossibleOperations != (pStatus->dwAvailableJobOperations | FAX_JOB_OP_PROPERTIES))
  173. {
  174. return TRUE;
  175. }
  176. if((pStatus->lpctstrExtendedStatus && m_cstrExtendedStatus.Compare(pStatus->lpctstrExtendedStatus)) ||
  177. (pStatus->lpctstrTsid && m_cstrTsid.Compare(pStatus->lpctstrTsid)) ||
  178. (pStatus->lpctstrCsid && m_cstrCsid.Compare(pStatus->lpctstrCsid)) ||
  179. (pStatus->lpctstrDeviceName && m_cstrDeviceName.Compare(pStatus->lpctstrDeviceName)) ||
  180. (pStatus->lpctstrCallerID && m_cstrCallerID.Compare(pStatus->lpctstrCallerID)) ||
  181. (pStatus->lpctstrRoutingInfo && m_cstrRoutingInfo.Compare(pStatus->lpctstrRoutingInfo)))
  182. {
  183. return TRUE;
  184. }
  185. return FALSE;
  186. } // CJob::IsNewStatus
  187. DWORD
  188. CJob::UpdateStatus (
  189. PFAX_JOB_STATUS pStatus
  190. )
  191. {
  192. DWORD dwRes = ERROR_SUCCESS;
  193. DBG_ENTER(TEXT("CJob::UpdateStatus"), dwRes);
  194. ASSERTION (m_bValid);
  195. ASSERTION (pStatus);
  196. m_dwValidityMask = m_dwJobOnlyValidityMask | (pStatus->dwValidityMask);
  197. try
  198. {
  199. //
  200. // Job id
  201. //
  202. ASSERTION (m_dwValidityMask & FAX_JOB_FIELD_JOB_ID);
  203. m_dwJobID = pStatus->dwJobID;
  204. //
  205. // Job type
  206. //
  207. ASSERTION (m_dwValidityMask & FAX_JOB_FIELD_TYPE);
  208. m_dwJobType = pStatus->dwJobType;
  209. //
  210. // Queue status
  211. //
  212. ASSERTION (m_dwValidityMask & FAX_JOB_FIELD_QUEUE_STATUS);
  213. m_dwQueueStatus = pStatus->dwQueueStatus;
  214. //
  215. // Extended status
  216. //
  217. m_dwExtendedStatus = pStatus->dwExtendedStatus;
  218. m_cstrExtendedStatus = pStatus->lpctstrExtendedStatus;
  219. //
  220. // Size
  221. //
  222. if (m_dwValidityMask & FAX_JOB_FIELD_SIZE)
  223. {
  224. m_dwSize = pStatus->dwSize;
  225. }
  226. else
  227. {
  228. m_dwSize = 0;
  229. }
  230. //
  231. // Page count
  232. //
  233. if (m_dwValidityMask & FAX_JOB_FIELD_PAGE_COUNT)
  234. {
  235. m_dwPageCount = pStatus->dwPageCount;
  236. }
  237. else
  238. {
  239. m_dwPageCount = 0;
  240. }
  241. //
  242. // Current page
  243. //
  244. if (m_dwValidityMask & FAX_JOB_FIELD_CURRENT_PAGE)
  245. {
  246. m_dwCurrentPage = pStatus->dwCurrentPage;
  247. }
  248. else
  249. {
  250. m_dwCurrentPage = 0;
  251. }
  252. //
  253. // TCID and CSID
  254. //
  255. m_cstrTsid = pStatus->lpctstrTsid;
  256. m_cstrCsid = pStatus->lpctstrCsid;
  257. //
  258. // Scheduled time
  259. //
  260. if (m_dwValidityMask & FAX_JOB_FIELD_SCHEDULE_TIME)
  261. {
  262. m_tmScheduleTime = pStatus->tmScheduleTime;
  263. }
  264. else
  265. {
  266. m_tmScheduleTime.Zero ();
  267. }
  268. //
  269. // Start time
  270. //
  271. if (m_dwValidityMask & FAX_JOB_FIELD_TRANSMISSION_START_TIME)
  272. {
  273. m_tmTransmissionStartTime = pStatus->tmTransmissionStartTime;
  274. }
  275. else
  276. {
  277. m_tmTransmissionStartTime.Zero ();
  278. }
  279. //
  280. // End time
  281. //
  282. if (m_dwValidityMask & FAX_JOB_FIELD_TRANSMISSION_END_TIME)
  283. {
  284. m_tmTransmissionEndTime = pStatus->tmTransmissionEndTime;
  285. }
  286. else
  287. {
  288. m_tmTransmissionEndTime.Zero ();
  289. }
  290. //
  291. // Device
  292. //
  293. m_dwDeviceID = pStatus->dwDeviceID;
  294. m_cstrDeviceName = pStatus->lpctstrDeviceName;
  295. //
  296. // Retries
  297. //
  298. if (m_dwValidityMask & FAX_JOB_FIELD_RETRIES)
  299. {
  300. m_dwRetries = pStatus->dwRetries;
  301. }
  302. else
  303. {
  304. m_dwRetries = 0;
  305. }
  306. //
  307. // Caller id and routing info
  308. //
  309. m_cstrCallerID = pStatus->lpctstrCallerID;
  310. m_cstrRoutingInfo = pStatus->lpctstrRoutingInfo;
  311. //
  312. // possible job operations
  313. //
  314. m_dwPossibleOperations = pStatus->dwAvailableJobOperations | FAX_JOB_OP_PROPERTIES;
  315. }
  316. catch (CException *pException)
  317. {
  318. TCHAR wszCause[1024];
  319. pException->GetErrorMessage (wszCause, 1024);
  320. pException->Delete ();
  321. VERBOSE (EXCEPTION_ERR,
  322. TEXT("CJob::UpdateStatus caused exception : %s"),
  323. wszCause);
  324. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  325. m_bValid = FALSE;
  326. return dwRes;
  327. }
  328. ASSERTION (ERROR_SUCCESS == dwRes);
  329. return dwRes;
  330. } // CJob::UpdateStatus
  331. const JobStatusType
  332. CJob::GetStatus () const
  333. /*++
  334. Routine name : CJob::GetStatus
  335. Routine description:
  336. Finds the current job status
  337. Author:
  338. Eran Yariv (EranY), Jan, 2000
  339. Arguments:
  340. Return Value:
  341. Job status
  342. --*/
  343. {
  344. DBG_ENTER(TEXT("CJob::GetStatus"));
  345. ASSERTION (m_dwValidityMask & FAX_JOB_FIELD_STATUS_SUB_STRUCT);
  346. ASSERTION (m_dwValidityMask & FAX_JOB_FIELD_QUEUE_STATUS);
  347. DWORD dwQueueStatus = m_dwQueueStatus;
  348. //
  349. // Start by checking status modifiers:
  350. //
  351. if (dwQueueStatus & JS_PAUSED)
  352. {
  353. return JOB_STAT_PAUSED;
  354. }
  355. //
  356. // We igonre the JS_NOLINE modifier.
  357. // Remove the modifiers now.
  358. //
  359. dwQueueStatus &= ~(JS_PAUSED | JS_NOLINE);
  360. //
  361. // Check other status values
  362. //
  363. switch (dwQueueStatus)
  364. {
  365. case JS_PENDING:
  366. return JOB_STAT_PENDING;
  367. case JS_INPROGRESS:
  368. case JS_FAILED: // The job is about to be deleted in a sec. Do not update status.
  369. return JOB_STAT_INPROGRESS;
  370. case JS_DELETING:
  371. return JOB_STAT_DELETING;
  372. case JS_RETRYING:
  373. return JOB_STAT_RETRYING;
  374. case JS_RETRIES_EXCEEDED:
  375. return JOB_STAT_RETRIES_EXCEEDED;
  376. case JS_COMPLETED:
  377. return JOB_STAT_COMPLETED;
  378. case JS_CANCELED:
  379. return JOB_STAT_CANCELED;
  380. case JS_CANCELING:
  381. return JOB_STAT_CANCELING;
  382. case JS_ROUTING:
  383. return JOB_STAT_ROUTING;
  384. default:
  385. ASSERTION_FAILURE;
  386. return (JobStatusType)-1;
  387. }
  388. } // CJob::StatusValue
  389. DWORD
  390. CJob::GetTiff (
  391. CString &cstrTiffLocation
  392. ) const
  393. /*++
  394. Routine name : CJob::GetTiff
  395. Routine description:
  396. Retrieves the job's TIFF file from the server
  397. Author:
  398. Eran Yariv (EranY), Jan, 2000
  399. Arguments:
  400. cstrTiffLocation [out] - Name of TIFF file
  401. Return Value:
  402. Standard Win32 error code
  403. --*/
  404. {
  405. DWORD dwRes = ERROR_SUCCESS;
  406. DBG_ENTER(TEXT("CJob::GetTiff"), dwRes);
  407. dwRes = CopyTiffFromServer (m_pServer,
  408. m_dwlMessageId,
  409. FAX_MESSAGE_FOLDER_QUEUE,
  410. cstrTiffLocation);
  411. if (ERROR_SUCCESS != dwRes)
  412. {
  413. CALL_FAIL (GENERAL_ERR, TEXT("CopyTiffFromServer"), dwRes);
  414. }
  415. return dwRes;
  416. } // CJob::GetTiff
  417. DWORD
  418. CJob::DoJobOperation (
  419. DWORD dwJobOp
  420. )
  421. /*++
  422. Routine name : CJob::DoJobOperation
  423. Routine description:
  424. Performs an operation on the job
  425. Author:
  426. Eran Yariv (EranY), Jan, 2000
  427. Arguments:
  428. dwJobOp [in] - Operation.
  429. Supported operations are:
  430. FAX_JOB_OP_PAUSE, FAX_JOB_OP_RESUME,
  431. FAX_JOB_OP_RESTART, and FAX_JOB_OP_DELETE.
  432. Return Value:
  433. Standard Win32 error code
  434. --*/
  435. {
  436. DWORD dwRes = ERROR_SUCCESS;
  437. DBG_ENTER(TEXT("CJob::DoJobOperation"), dwRes);
  438. DWORD dwJobCommand;
  439. switch (dwJobOp)
  440. {
  441. case FAX_JOB_OP_PAUSE:
  442. dwJobCommand = JC_PAUSE;
  443. break;
  444. case FAX_JOB_OP_RESUME:
  445. dwJobCommand = JC_RESUME;
  446. break;
  447. case FAX_JOB_OP_RESTART:
  448. dwJobCommand = JC_RESTART;
  449. break;
  450. case FAX_JOB_OP_DELETE:
  451. dwJobCommand = JC_DELETE;
  452. break;
  453. default:
  454. ASSERTION_FAILURE;
  455. dwRes = ERROR_CAN_NOT_COMPLETE;
  456. return dwRes;
  457. }
  458. if (!(dwJobOp & GetPossibleOperations()))
  459. {
  460. VERBOSE (DBG_MSG, TEXT("Job can no longer do operation"));
  461. dwRes = ERROR_CAN_NOT_COMPLETE;
  462. return dwRes;
  463. }
  464. HANDLE hFax;
  465. dwRes = m_pServer->GetConnectionHandle (hFax);
  466. if (ERROR_SUCCESS != dwRes)
  467. {
  468. CALL_FAIL (GENERAL_ERR, TEXT("CServerNode::GetConnectionHandle"), dwRes);
  469. return dwRes;
  470. }
  471. FAX_JOB_ENTRY fje = {0};
  472. fje.SizeOfStruct = sizeof(FAX_JOB_ENTRY);
  473. START_RPC_TIME(TEXT("FaxSetJob"));
  474. if (!FaxSetJob (hFax,
  475. m_dwJobID,
  476. dwJobCommand,
  477. &fje))
  478. {
  479. dwRes = GetLastError ();
  480. END_RPC_TIME(TEXT("FaxSetJob"));
  481. m_pServer->SetLastRPCError (dwRes);
  482. CALL_FAIL (RPC_ERR, TEXT("FaxSetJob"), dwRes);
  483. return dwRes;
  484. }
  485. END_RPC_TIME(TEXT("FaxSetJob"));
  486. //
  487. // Update job status and possible operations
  488. //
  489. switch (dwJobOp)
  490. {
  491. case FAX_JOB_OP_PAUSE:
  492. m_dwQueueStatus |= JS_PAUSED;
  493. m_dwPossibleOperations &= ~FAX_JOB_OP_PAUSE;
  494. m_dwPossibleOperations |= FAX_JOB_OP_RESUME;
  495. break;
  496. case FAX_JOB_OP_RESUME:
  497. m_dwQueueStatus &= ~JS_PAUSED;
  498. m_dwPossibleOperations &= ~FAX_JOB_OP_RESUME;
  499. m_dwPossibleOperations |= FAX_JOB_OP_PAUSE;
  500. break;
  501. case FAX_JOB_OP_RESTART:
  502. m_dwQueueStatus = JS_PENDING;
  503. m_dwPossibleOperations &= ~FAX_JOB_OP_RESTART;
  504. m_dwPossibleOperations |= FAX_JOB_OP_PAUSE;
  505. break;
  506. case FAX_JOB_OP_DELETE:
  507. m_dwPossibleOperations &= ~FAX_JOB_OP_DELETE;
  508. break;
  509. default:
  510. break;
  511. }
  512. ASSERTION (ERROR_SUCCESS == dwRes);
  513. return dwRes;
  514. } // CJob::DoJobOperation
  515. DWORD
  516. CJob::Copy(
  517. const CJob& other
  518. )
  519. {
  520. DWORD dwRes = ERROR_SUCCESS;
  521. DBG_ENTER(TEXT("CJob::Copy"), dwRes);
  522. try
  523. {
  524. m_dwlMessageId = other.m_dwlMessageId;
  525. m_dwlBroadcastId = other.m_dwlBroadcastId;
  526. m_dwValidityMask = other.m_dwValidityMask;
  527. m_dwJobOnlyValidityMask = other.m_dwJobOnlyValidityMask;
  528. m_dwJobID = other.m_dwJobID;
  529. m_dwJobType = other.m_dwJobType;
  530. m_dwQueueStatus = other.m_dwQueueStatus;
  531. m_dwExtendedStatus = other.m_dwExtendedStatus;
  532. m_dwSize = other.m_dwSize;
  533. m_dwPageCount = other.m_dwPageCount;
  534. m_dwCurrentPage = other.m_dwCurrentPage;
  535. m_dwDeviceID = other.m_dwDeviceID;
  536. m_dwRetries = other.m_dwRetries;
  537. m_cstrRecipientNumber = other.m_cstrRecipientNumber;
  538. m_cstrRecipientName = other.m_cstrRecipientName;
  539. m_cstrSenderUserName = other.m_cstrSenderUserName;
  540. m_cstrBillingCode = other.m_cstrBillingCode;
  541. m_cstrDocumentName = other.m_cstrDocumentName;
  542. m_cstrSubject = other.m_cstrSubject;
  543. m_cstrExtendedStatus = other.m_cstrExtendedStatus;
  544. m_cstrTsid = other.m_cstrTsid;
  545. m_cstrCsid = other.m_cstrCsid;
  546. m_cstrDeviceName = other.m_cstrDeviceName;
  547. m_cstrCallerID = other.m_cstrCallerID;
  548. m_cstrRoutingInfo = other.m_cstrRoutingInfo;
  549. m_tmOriginalScheduleTime = other.m_tmOriginalScheduleTime;
  550. m_tmSubmissionTime = other.m_tmSubmissionTime;
  551. m_tmScheduleTime = other.m_tmScheduleTime;
  552. m_tmTransmissionStartTime = other.m_tmTransmissionStartTime;
  553. m_tmTransmissionEndTime = other.m_tmTransmissionEndTime;
  554. m_Priority = other.m_Priority;
  555. m_dwPossibleOperations = other.m_dwPossibleOperations;
  556. m_cstrServerName = other.m_cstrServerName;
  557. m_bValid = other.m_bValid;
  558. }
  559. catch(...)
  560. {
  561. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  562. }
  563. return dwRes;
  564. } // CJob::Copy