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.

382 lines
8.5 KiB

  1. // QueueFolder.cpp: implementation of the CQueueFolder class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #define __FILE_ID__ 19
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. IMPLEMENT_DYNAMIC(CQueueFolder, CFolder)
  12. DWORD
  13. CQueueFolder::Refresh ()
  14. /*++
  15. Routine name : CQueueFolder::Refresh
  16. Routine description:
  17. Rebuilds the map of the jobs using the client API.
  18. This function is always called in the context of a worker thread.
  19. This function must be called when the data critical section is held.
  20. Author:
  21. Eran Yariv (EranY), Jan, 2000
  22. Arguments:
  23. Return Value:
  24. Standard Win32 error code
  25. --*/
  26. {
  27. DWORD dwRes = ERROR_SUCCESS;
  28. DBG_ENTER(TEXT("CQueueFolder::Refresh"), dwRes, TEXT("Type=%d"), Type());
  29. //
  30. // Enumerate jobs from the server
  31. //
  32. ASSERTION (m_pServer);
  33. HANDLE hFax;
  34. PFAX_JOB_ENTRY_EX pEntries;
  35. DWORD dwNumJobs;
  36. DWORD dw;
  37. dwRes = m_pServer->GetConnectionHandle (hFax);
  38. if (ERROR_SUCCESS != dwRes)
  39. {
  40. CALL_FAIL (RPC_ERR, TEXT("CFolder::GetConnectionHandle"), dwRes);
  41. return dwRes;
  42. }
  43. if (m_bStopRefresh)
  44. {
  45. //
  46. // Quit immediately
  47. //
  48. return dwRes;
  49. }
  50. START_RPC_TIME(TEXT("FaxEnumJobsEx"));
  51. if (!FaxEnumJobsEx (hFax,
  52. m_dwJobTypes,
  53. &pEntries,
  54. &dwNumJobs))
  55. {
  56. dwRes = GetLastError ();
  57. END_RPC_TIME(TEXT("FaxEnumJobsEx"));
  58. m_pServer->SetLastRPCError (dwRes);
  59. CALL_FAIL (RPC_ERR, TEXT("FaxEnumJobsEx"), dwRes);
  60. return dwRes;
  61. }
  62. END_RPC_TIME(TEXT("FaxEnumJobsEx"));
  63. if (m_bStopRefresh)
  64. {
  65. //
  66. // Quit immediately
  67. //
  68. goto exit;
  69. }
  70. //
  71. // Make sure our map is empty
  72. //
  73. ASSERTION (!m_Msgs.size());
  74. //
  75. // Fill the map and the list control
  76. //
  77. for (dw = 0; dw < dwNumJobs; dw++)
  78. {
  79. PFAX_JOB_ENTRY_EX pEntry = &pEntries[dw];
  80. if((pEntry->pStatus->dwQueueStatus & JS_COMPLETED) ||
  81. (pEntry->pStatus->dwQueueStatus & JS_CANCELED))
  82. {
  83. //
  84. // don't display completed or canceled jobs
  85. //
  86. continue;
  87. }
  88. CJob *pJob = NULL;
  89. try
  90. {
  91. pJob = new CJob;
  92. }
  93. catch (...)
  94. {
  95. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  96. CALL_FAIL (MEM_ERR, TEXT("new CJob"), dwRes);
  97. goto exit;
  98. }
  99. //
  100. // Init the message
  101. //
  102. dwRes = pJob->Init (pEntry, m_pServer);
  103. if (ERROR_SUCCESS != dwRes)
  104. {
  105. CALL_FAIL (MEM_ERR, TEXT("CJob::Init"), dwRes);
  106. SAFE_DELETE (pJob);
  107. goto exit;
  108. }
  109. //
  110. // Enter the message into the map
  111. //
  112. EnterData();
  113. try
  114. {
  115. m_Msgs[pEntry->dwlMessageId] = pJob;
  116. }
  117. catch (...)
  118. {
  119. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  120. CALL_FAIL (MEM_ERR, TEXT("map::operator[]"), dwRes);
  121. SAFE_DELETE (pJob);
  122. LeaveData ();
  123. goto exit;
  124. }
  125. LeaveData ();
  126. if (m_bStopRefresh)
  127. {
  128. //
  129. // Quit immediately
  130. //
  131. goto exit;
  132. }
  133. }
  134. AttachView();
  135. if (m_pAssignedView)
  136. {
  137. //
  138. // Folder has a view attached
  139. //
  140. m_pAssignedView->SendMessage (
  141. WM_FOLDER_ADD_CHUNK,
  142. WPARAM (dwRes),
  143. LPARAM (&m_Msgs));
  144. }
  145. else
  146. {
  147. //
  148. // Shutdown in progress
  149. //
  150. }
  151. ASSERTION (ERROR_SUCCESS == dwRes);
  152. exit:
  153. FaxFreeBuffer ((LPVOID)pEntries);
  154. return dwRes;
  155. } // CQueueFolder::Refresh
  156. DWORD
  157. CQueueFolder::OnJobAdded (
  158. DWORDLONG dwlMsgId
  159. )
  160. /*++
  161. Routine name : CQueueFolder::OnJobAdded
  162. Routine description:
  163. Handles notification of a job added to the queue
  164. Author:
  165. Eran Yariv (EranY), Feb, 2000
  166. Arguments:
  167. dwlMsgId [in] - New job unique id
  168. Return Value:
  169. Standard Win32 error code
  170. --*/
  171. {
  172. DWORD dwRes = ERROR_SUCCESS;
  173. DBG_ENTER(TEXT("CQueueFolder::OnJobAdded"),
  174. dwRes,
  175. TEXT("MsgId=0x%016I64x, Type=%d"),
  176. dwlMsgId,
  177. Type());
  178. HANDLE hFax;
  179. PFAX_JOB_ENTRY_EX pFaxJob = NULL;
  180. CJob *pJob = NULL;
  181. EnterData ();
  182. pJob = (CJob*)FindMessage (dwlMsgId);
  183. if (pJob)
  184. {
  185. //
  186. // This job is already in the queue
  187. //
  188. VERBOSE (DBG_MSG, TEXT("Job is already known and visible"));
  189. goto exit;
  190. }
  191. //
  192. // Get information about this job
  193. //
  194. dwRes = m_pServer->GetConnectionHandle (hFax);
  195. if (ERROR_SUCCESS != dwRes)
  196. {
  197. CALL_FAIL (RPC_ERR, TEXT("CFolder::GetConnectionHandle"), dwRes);
  198. goto exit;
  199. }
  200. {
  201. START_RPC_TIME(TEXT("FaxGetJobEx"));
  202. if (!FaxGetJobEx (hFax, dwlMsgId, &pFaxJob))
  203. {
  204. dwRes = GetLastError ();
  205. END_RPC_TIME(TEXT("FaxGetJobEx"));
  206. m_pServer->SetLastRPCError (dwRes);
  207. CALL_FAIL (RPC_ERR, TEXT("FaxGetJobEx"), dwRes);
  208. goto exit;
  209. }
  210. END_RPC_TIME(TEXT("FaxGetJobEx"));
  211. }
  212. //
  213. // Enter a new job to the map
  214. //
  215. try
  216. {
  217. pJob = new CJob;
  218. ASSERTION (pJob);
  219. m_Msgs[pFaxJob->dwlMessageId] = pJob;
  220. }
  221. catch (...)
  222. {
  223. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  224. SAFE_DELETE (pJob);
  225. goto exit;
  226. }
  227. //
  228. // Init the message
  229. //
  230. dwRes = pJob->Init (pFaxJob, m_pServer);
  231. if (ERROR_SUCCESS != dwRes)
  232. {
  233. CALL_FAIL (MEM_ERR, TEXT("CJob::Init"), dwRes);
  234. if (pJob)
  235. {
  236. try
  237. {
  238. m_Msgs.erase (pFaxJob->dwlMessageId);
  239. }
  240. catch (...)
  241. {
  242. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  243. CALL_FAIL (MEM_ERR, TEXT("map::erase"), dwRes);
  244. }
  245. SAFE_DELETE (pJob);
  246. }
  247. goto exit;
  248. }
  249. if (m_pAssignedView)
  250. {
  251. //
  252. // If this folder is alive - tell our view to add the job
  253. //
  254. m_pAssignedView->OnUpdate (NULL, UPDATE_HINT_ADD_ITEM, pJob);
  255. }
  256. ASSERTION (ERROR_SUCCESS == dwRes);
  257. exit:
  258. if(pFaxJob)
  259. {
  260. FaxFreeBuffer(pFaxJob);
  261. }
  262. LeaveData ();
  263. return dwRes;
  264. } // CQueueFolder::OnJobAdded
  265. DWORD
  266. CQueueFolder::OnJobUpdated (
  267. DWORDLONG dwlMsgId,
  268. PFAX_JOB_STATUS pNewStatus
  269. )
  270. /*++
  271. Routine name : CQueueFolder::OnJobUpdated
  272. Routine description:
  273. Handles notification of a job removed from the queue
  274. Author:
  275. Eran Yariv (EranY), Feb, 2000
  276. Arguments:
  277. dwlMsgId [in] - Job unique id
  278. pNewStatus [in] - New status of the job
  279. Return Value:
  280. Standard Win32 error code
  281. --*/
  282. {
  283. DWORD dwRes = ERROR_SUCCESS;
  284. DBG_ENTER(TEXT("CQueueFolder::OnJobUpdated"),
  285. dwRes,
  286. TEXT("MsgId=0x%016I64x, Type=%d"),
  287. dwlMsgId,
  288. Type());
  289. CJob *pJob = NULL;
  290. EnterData ();
  291. pJob = (CJob*)FindMessage (dwlMsgId);
  292. if (!pJob)
  293. {
  294. //
  295. // This job is not in the queue - treat the notification as if the job was added
  296. //
  297. VERBOSE (DBG_MSG, TEXT("Job is not known - adding it"));
  298. LeaveData ();
  299. dwRes = OnJobAdded (dwlMsgId);
  300. return dwRes;
  301. }
  302. //
  303. // Update job's status
  304. //
  305. if(pJob->IsNewStatus(pNewStatus))
  306. {
  307. dwRes = pJob->UpdateStatus (pNewStatus);
  308. if (ERROR_SUCCESS != dwRes)
  309. {
  310. CALL_FAIL (GENERAL_ERR, TEXT("CJob::UpdateStatus"), dwRes);
  311. goto exit;
  312. }
  313. if (m_pAssignedView)
  314. {
  315. //
  316. // If this folder is alive - tell our view to update the job
  317. //
  318. m_pAssignedView->OnUpdate (NULL, UPDATE_HINT_UPDATE_ITEM, pJob);
  319. }
  320. }
  321. ASSERTION (ERROR_SUCCESS == dwRes);
  322. exit:
  323. LeaveData ();
  324. return dwRes;
  325. } // CQueueFolder::OnJobUpdated