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.

434 lines
10 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: workitem.cpp
  7. //
  8. // Contents: workitem Table
  9. //
  10. // History:
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "workitem.h"
  14. //----------------------------------------------------
  15. CCriticalSection WorkItemTable::g_TableLock;
  16. //----------------------------------------------------
  17. TLSJBIndex
  18. WorkItemTable::g_TableIndex[] =
  19. {
  20. {
  21. WORKITEM_INDEX_JOBTIME_INDEXNAME,
  22. WORKITEM_INDEX_JOBTIME_INDEXKEY,
  23. -1,
  24. JET_bitIndexIgnoreNull,
  25. TLSTABLE_INDEX_DEFAULT_DENSITY
  26. }
  27. };
  28. int
  29. WorkItemTable::g_NumTableIndex = sizeof(WorkItemTable::g_TableIndex) / sizeof(WorkItemTable::g_TableIndex[0]);
  30. TLSJBColumn
  31. WorkItemTable::g_Columns[] =
  32. {
  33. {
  34. WORKITEM_COLUMN_JOBTIME,
  35. JET_coltypLong,
  36. sizeof(DWORD),
  37. JET_bitColumnNotNULL,
  38. NULL,
  39. 0,
  40. TLS_JETBLUE_COLUMN_CODE_PAGE,
  41. TLS_JETBLUE_COLUMN_COUNTRY_CODE,
  42. TLS_JETBLUE_COLUMN_LANGID
  43. },
  44. {
  45. WORKITEM_COLUMN_JOBRESTARTTIME,
  46. JET_coltypLong,
  47. sizeof(DWORD),
  48. JET_bitColumnNotNULL,
  49. NULL,
  50. 0,
  51. TLS_JETBLUE_COLUMN_CODE_PAGE,
  52. TLS_JETBLUE_COLUMN_COUNTRY_CODE,
  53. TLS_JETBLUE_COLUMN_LANGID
  54. },
  55. {
  56. WORKITEM_COLUMN_JOBTYPE,
  57. JET_coltypLong,
  58. 0,
  59. JET_bitColumnNotNULL,
  60. NULL,
  61. 0,
  62. TLS_JETBLUE_COLUMN_CODE_PAGE,
  63. TLS_JETBLUE_COLUMN_COUNTRY_CODE,
  64. TLS_JETBLUE_COLUMN_LANGID
  65. },
  66. {
  67. WORKITEM_COLUMN_DATA,
  68. JET_coltypLongBinary,
  69. WORKITEM_MAX_DATA_SIZE, // 0x8FFFFFFF, // no limit on data size.
  70. 0,
  71. NULL,
  72. 0,
  73. TLS_JETBLUE_COLUMN_CODE_PAGE,
  74. TLS_JETBLUE_COLUMN_COUNTRY_CODE,
  75. TLS_JETBLUE_COLUMN_LANGID
  76. }
  77. };
  78. int
  79. WorkItemTable::g_NumColumns=sizeof(WorkItemTable::g_Columns) / sizeof(WorkItemTable::g_Columns[0]);
  80. //-------------------------------------------------------------
  81. JBKeyBase*
  82. WorkItemTable::EnumerationIndex(
  83. BOOL bMatchAll,
  84. DWORD dwSearchParam,
  85. WORKITEMRECORD* pRecord,
  86. BOOL* bCompareKey
  87. )
  88. /*
  89. */
  90. {
  91. *bCompareKey = bMatchAll;
  92. return new TLSWorkItemIdxModifyTime(pRecord);
  93. }
  94. //------------------------------------------------------------
  95. BOOL
  96. WorkItemTable::EqualValue(
  97. WORKITEMRECORD& s1,
  98. WORKITEMRECORD& s2,
  99. BOOL bMatchAll,
  100. DWORD dwParam
  101. )
  102. /*
  103. */
  104. {
  105. BOOL bRetCode = TRUE;
  106. if(dwParam & WORKITEM_PROCESS_JOBTIME)
  107. {
  108. bRetCode = (s1.dwScheduledTime == s2.dwScheduledTime);
  109. if(bRetCode != bMatchAll)
  110. goto cleanup;
  111. }
  112. if(dwParam & WORKITEM_PROCESS_JOBRESTARTTIME)
  113. {
  114. bRetCode = (s1.dwRestartTime == s2.dwRestartTime);
  115. if(bRetCode != bMatchAll)
  116. goto cleanup;
  117. }
  118. if(dwParam & WORKITEM_PROCESS_JOBTYPE)
  119. {
  120. bRetCode = (s1.dwJobType == s2.dwJobType);
  121. if(bRetCode != bMatchAll)
  122. goto cleanup;
  123. }
  124. //
  125. // process data must accompany by process data size.
  126. //
  127. if(dwParam & WORKITEM_PROCESS_DATA)
  128. {
  129. bRetCode = (s1.cbData == s2.cbData);
  130. if(bRetCode != bMatchAll)
  131. goto cleanup;
  132. bRetCode = (memcmp(s1.pbData, s2.pbData, s1.cbData) == 0);
  133. }
  134. cleanup:
  135. return bRetCode;
  136. }
  137. //----------------------------------------------------
  138. BOOL
  139. WorkItemTable::ResolveToTableColumn()
  140. /*
  141. */
  142. {
  143. m_JetErr = dwScheduledTime.AttachToTable(
  144. *this,
  145. WORKITEM_COLUMN_JOBTIME
  146. );
  147. if(IsSuccess() == FALSE)
  148. {
  149. DebugOutput(
  150. _TEXT("Can't find column %s in table %s\n"),
  151. WORKITEM_COLUMN_JOBTIME,
  152. GetTableName()
  153. );
  154. goto cleanup;
  155. }
  156. m_JetErr = dwRestartTime.AttachToTable(
  157. *this,
  158. WORKITEM_COLUMN_JOBRESTARTTIME
  159. );
  160. if(IsSuccess() == FALSE)
  161. {
  162. DebugOutput(
  163. _TEXT("Can't find column %s in table %s\n"),
  164. WORKITEM_COLUMN_JOBRESTARTTIME,
  165. GetTableName()
  166. );
  167. goto cleanup;
  168. }
  169. m_JetErr = dwJobType.AttachToTable(
  170. *this,
  171. WORKITEM_COLUMN_JOBTYPE
  172. );
  173. if(IsSuccess() == FALSE)
  174. {
  175. DebugOutput(
  176. _TEXT("Can't find column %s in table %s\n"),
  177. WORKITEM_COLUMN_JOBTYPE,
  178. GetTableName()
  179. );
  180. goto cleanup;
  181. }
  182. m_JetErr = pbData.AttachToTable(
  183. *this,
  184. WORKITEM_COLUMN_DATA
  185. );
  186. if(IsSuccess() == FALSE)
  187. {
  188. DebugOutput(
  189. _TEXT("Can't find column %s in table %s\n"),
  190. WORKITEM_COLUMN_DATA,
  191. GetTableName()
  192. );
  193. }
  194. cleanup:
  195. return IsSuccess();
  196. }
  197. //----------------------------------------------------
  198. CLASS_PRIVATE BOOL
  199. WorkItemTable::ProcessSingleColumn(
  200. IN BOOL bFetch,
  201. IN TLSColumnBase& column,
  202. IN DWORD offset,
  203. IN PVOID pbData,
  204. IN DWORD cbData,
  205. IN PDWORD pcbDataReturn,
  206. IN LPCTSTR szColumnName
  207. )
  208. /*
  209. Abstract:
  210. Fetch/Insert/Update a particular column.
  211. Parameter:
  212. bFetch - TRUE if fetch, FALSE if update/insert.
  213. column - Intended column for operation, reference pointer to TLSColumn
  214. szColumnName - name of the column, for debugging print purpose only
  215. Returns:
  216. TRUE if successful, FALSE otherwise.
  217. */
  218. {
  219. if(bFetch)
  220. {
  221. m_JetErr = column.FetchColumnValue(
  222. pbData,
  223. cbData,
  224. offset,
  225. pcbDataReturn
  226. );
  227. }
  228. else
  229. {
  230. m_JetErr = column.InsertColumnValue(
  231. pbData,
  232. cbData,
  233. offset
  234. );
  235. }
  236. REPORTPROCESSFAILED(
  237. bFetch,
  238. GetTableName(),
  239. szColumnName,
  240. m_JetErr
  241. );
  242. return IsSuccess();
  243. }
  244. //---------------------------------------------------------
  245. CLASS_PRIVATE BOOL
  246. WorkItemTable::ProcessRecord(
  247. WORKITEMRECORD* pRecord,
  248. BOOL bFetch,
  249. DWORD dwParam,
  250. BOOL bUpdate
  251. )
  252. /*
  253. */
  254. {
  255. DWORD dwSize;
  256. if(bFetch == FALSE)
  257. {
  258. BeginUpdate(bUpdate);
  259. if(!(dwParam & WORKITEM_PROCESS_JOBTIME))
  260. {
  261. JB_ASSERT(FALSE);
  262. dwParam |= WORKITEM_PROCESS_JOBTIME;
  263. }
  264. }
  265. else
  266. {
  267. SetLastJetError(JET_errSuccess);
  268. }
  269. if(IsSuccess() == FALSE)
  270. goto cleanup;
  271. if(dwParam & WORKITEM_PROCESS_JOBTIME)
  272. {
  273. ProcessSingleColumn(
  274. bFetch,
  275. dwScheduledTime,
  276. 0,
  277. &(pRecord->dwScheduledTime),
  278. sizeof(pRecord->dwScheduledTime),
  279. &dwSize,
  280. WORKITEM_COLUMN_JOBTIME
  281. );
  282. }
  283. if(IsSuccess() == FALSE)
  284. goto cleanup;
  285. if(dwParam & WORKITEM_PROCESS_JOBRESTARTTIME)
  286. {
  287. ProcessSingleColumn(
  288. bFetch,
  289. dwRestartTime,
  290. 0,
  291. &(pRecord->dwRestartTime),
  292. sizeof(pRecord->dwRestartTime),
  293. &dwSize,
  294. WORKITEM_COLUMN_JOBRESTARTTIME
  295. );
  296. }
  297. if(IsSuccess() == FALSE)
  298. goto cleanup;
  299. if(dwParam & WORKITEM_PROCESS_JOBTYPE)
  300. {
  301. ProcessSingleColumn(
  302. bFetch,
  303. dwJobType,
  304. 0,
  305. &(pRecord->dwJobType),
  306. sizeof(pRecord->dwJobType),
  307. &dwSize,
  308. WORKITEM_COLUMN_JOBTYPE
  309. );
  310. }
  311. if(IsSuccess() == FALSE)
  312. goto cleanup;
  313. if(dwParam & WORKITEM_PROCESS_DATA)
  314. {
  315. if(bFetch == TRUE)
  316. {
  317. m_JetErr = pbData.FetchColumnValue(
  318. NULL,
  319. 0,
  320. 0,
  321. &dwSize // &pRecord->cbData
  322. );
  323. if( pRecord->pbData == NULL || pRecord->cbData < dwSize )
  324. {
  325. if( pRecord->pbData != NULL )
  326. {
  327. FreeMemory(pRecord->pbData);
  328. pRecord->pbData = NULL;
  329. }
  330. pRecord->pbData = (PBYTE)AllocateMemory(dwSize);
  331. if(pRecord->pbData == NULL)
  332. {
  333. pRecord->cbData = 0;
  334. SetLastJetError(JET_errOutOfMemory);
  335. goto cleanup;
  336. }
  337. pRecord->cbData = dwSize;
  338. }
  339. //
  340. // actual memory allocated might be bigger then pRecord->cbData
  341. //
  342. m_JetErr = pbData.FetchColumnValue(
  343. pRecord->pbData,
  344. pRecord->cbData,
  345. 0,
  346. &pRecord->cbData
  347. );
  348. }
  349. else
  350. {
  351. ProcessSingleColumn(
  352. bFetch,
  353. pbData,
  354. 0,
  355. pRecord->pbData,
  356. pRecord->cbData,
  357. &dwSize,
  358. WORKITEM_COLUMN_DATA
  359. );
  360. }
  361. }
  362. cleanup:
  363. //
  364. // For inserting/updating record
  365. if(bFetch == FALSE)
  366. {
  367. JET_ERR jetErr;
  368. jetErr = GetLastJetError();
  369. EndUpdate(IsSuccess() == FALSE);
  370. if(jetErr != JET_errSuccess && IsSuccess() == FALSE)
  371. SetLastJetError(jetErr);
  372. }
  373. return IsSuccess();
  374. }