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.

259 lines
8.2 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Scheduling Agent Service
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  7. //
  8. // File: atconv.cxx
  9. //
  10. // Classes: None.
  11. //
  12. // Functions: ConvertAtJobsToTasks
  13. //
  14. // History: 13-Jun-96 EricB Created.
  15. //
  16. //-----------------------------------------------------------------------------
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include <sch_cls.hxx>
  20. #include <job_cls.hxx>
  21. #include "..\inc\debug.hxx"
  22. //
  23. // The constants and types below taken from net\svcdlls\at\server\at.h
  24. //
  25. #define AT_REGISTRY_PATH L"System\\CurrentControlSet\\Services\\Schedule"
  26. #define AT_SCHEDULE_NAME L"Schedule"
  27. #define AT_COMMAND_NAME L"Command"
  28. #define MAXIMUM_COMMAND_LENGTH (MAX_PATH - 1) // == 259, cmd.exe uses this
  29. #define MAXIMUM_JOB_TIME (24 * 60 * 60 * 1000 - 1)
  30. #define DAYS_OF_WEEK 0x7F // 7 bits for 7 days
  31. #define DAYS_OF_MONTH 0x7FFFFFFF // 31 bits for 31 days
  32. #define AT_KEY_BUF_LEN 20 // 9 would suffice, but this is safer
  33. typedef struct _AT_SCHEDULE {
  34. DWORD JobTime; // time of day to run, in seconds from midnight
  35. DWORD DaysOfMonth; // bitmask for days of month to run
  36. UCHAR DaysOfWeek; // bitmask for days of week to run
  37. UCHAR Flags; // see lmat.h
  38. WORD Reserved; // padding, since registry pads them as well
  39. } AT_SCHEDULE;
  40. //+----------------------------------------------------------------------------
  41. //
  42. // Function: ConvertAtJobsToTasks
  43. //
  44. // Synopsis: At setup time, read the AT service jobs out of the registry
  45. // and convert them to Scheduling Agent Tasks.
  46. //
  47. //-----------------------------------------------------------------------------
  48. STDAPI_(void)
  49. ConvertAtJobsToTasks(void)
  50. {
  51. struct KEYNAME {
  52. KEYNAME * pNext;
  53. WCHAR wszName[AT_KEY_BUF_LEN];
  54. };
  55. CSchedule * pSch = new CSchedule;
  56. if (pSch == NULL)
  57. {
  58. ERR_OUT("ConvertAtJobsToTasks, new pSch", E_OUTOFMEMORY);
  59. return;
  60. }
  61. HRESULT hr = pSch->Init();
  62. if (FAILED(hr))
  63. {
  64. pSch->Release();
  65. ERR_OUT("ConvertAtJobsToTasks, pSch->Init", hr);
  66. return;
  67. }
  68. HKEY hKeySvc, hKey;
  69. DWORD index;
  70. WCHAR wszNameBuffer[AT_KEY_BUF_LEN];
  71. FILETIME lastWriteTime;
  72. WCHAR wszCommand[MAXIMUM_COMMAND_LENGTH + 1];
  73. AT_SCHEDULE Schedule;
  74. DWORD Length;
  75. DWORD type;
  76. DWORD NameSize;
  77. DWORD CommandSize;
  78. KEYNAME * pDeleteList = NULL;
  79. long lRet;
  80. //
  81. // Open the AT service registry tree.
  82. //
  83. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  84. AT_REGISTRY_PATH,
  85. 0,
  86. KEY_READ,
  87. &hKeySvc);
  88. if (lRet != ERROR_SUCCESS)
  89. {
  90. ERR_OUT("ConvertAtJobsToTasks: open hKeySvc", lRet);
  91. pSch->Release();
  92. return;
  93. }
  94. for (index = 0; ; index++)
  95. {
  96. //
  97. // Regedit can sometimes display other keys in addition to keys
  98. // found here. Also, it often fails to display last character in
  99. // the Command and after a refresh it may not display some of the
  100. // spurious keys.
  101. //
  102. Length = sizeof(wszNameBuffer) / sizeof(wszNameBuffer[0]);
  103. lRet = RegEnumKeyEx(hKeySvc,
  104. index,
  105. wszNameBuffer, // lpName
  106. &Length, // lpcbName
  107. 0, // lpReserved
  108. NULL, // lpClass
  109. NULL, // lpcbClass
  110. &lastWriteTime);
  111. if (lRet != ERROR_SUCCESS && lRet != ERROR_MORE_DATA)
  112. {
  113. if (lRet != ERROR_NO_MORE_ITEMS)
  114. {
  115. ERR_OUT("ConvertAtJobsToTasks: RegEnumKeyEx", lRet);
  116. }
  117. //
  118. // The only exit point from this loop
  119. //
  120. break;
  121. }
  122. //
  123. // Length returned is the number of characters in a UNICODE string
  124. // representing the key name (not counting the terminating NULL
  125. // character which is also supplied).
  126. //
  127. NameSize = (Length + 1) * sizeof(WCHAR);
  128. lRet = RegOpenKeyEx(hKeySvc,
  129. wszNameBuffer,
  130. 0,
  131. KEY_READ,
  132. &hKey);
  133. if (lRet != ERROR_SUCCESS)
  134. {
  135. ERR_OUT("ConvertAtJobsToTasks: RegOpenKeyEx", lRet);
  136. continue;
  137. }
  138. Length = sizeof(Schedule);
  139. lRet = RegQueryValueEx(hKey,
  140. AT_SCHEDULE_NAME,
  141. NULL,
  142. &type,
  143. (LPBYTE)&Schedule,
  144. &Length);
  145. if (lRet != ERROR_SUCCESS)
  146. {
  147. ERR_OUT("ConvertAtJobsToTasks: RegQueryValueEx(AT_SCHEDULE_NAME)",
  148. lRet);
  149. RegCloseKey(hKey);
  150. continue;
  151. }
  152. if (type != REG_BINARY ||
  153. Length != sizeof(AT_SCHEDULE) ||
  154. (Schedule.DaysOfWeek & ~DAYS_OF_WEEK) != 0 ||
  155. (Schedule.DaysOfMonth & ~DAYS_OF_MONTH) != 0 ||
  156. Schedule.JobTime >= MAXIMUM_JOB_TIME )
  157. {
  158. schDebugOut((DEB_ERROR,"ConvertAtJobsToTasks: RegQueryValueEx invalid data: "
  159. "type=%lu, Length=%lu, DOW=%#x, DOM=%#lx, Time=%lu\n",
  160. type, Length, Schedule.DaysOfWeek, Schedule.DaysOfMonth,
  161. Schedule.JobTime));
  162. RegCloseKey(hKey);
  163. continue;
  164. }
  165. Length = sizeof(wszCommand);
  166. lRet = RegQueryValueEx(hKey,
  167. AT_COMMAND_NAME,
  168. NULL,
  169. &type,
  170. (LPBYTE)wszCommand,
  171. &Length);
  172. RegCloseKey(hKey);
  173. if (lRet != ERROR_SUCCESS)
  174. {
  175. ERR_OUT("ConvertAtJobsToTasks: RegQueryValueEx(AT_COMMAND_NAME)",
  176. lRet);
  177. continue;
  178. }
  179. if (type != REG_SZ)
  180. {
  181. ERR_OUT("ConvertAtJobsToTasks: Command is not of REG_SZ type", 0);
  182. continue;
  183. }
  184. AT_INFO At;
  185. At.Command = wszCommand;
  186. At.JobTime = Schedule.JobTime;
  187. At.DaysOfMonth = Schedule.DaysOfMonth;
  188. At.DaysOfWeek = Schedule.DaysOfWeek;
  189. At.Flags = Schedule.Flags;
  190. hr = pSch->AddAtJob(At, NULL);
  191. if (SUCCEEDED(hr))
  192. {
  193. //
  194. // If the job was successfully converted, then add it to the
  195. // list of jobs to delete from the registry. Don't delete it
  196. // right away, because that would mess up the operation of
  197. // RegEnumKeyEx.
  198. //
  199. KEYNAME * pKey = new KEYNAME;
  200. if (pKey == NULL)
  201. {
  202. ERR_OUT("ConvertAtJobsToTasks: new KEYNAME", GetLastError());
  203. RegDeleteKey(hKeySvc, wszNameBuffer);
  204. break;
  205. }
  206. pKey->pNext = pDeleteList;
  207. pDeleteList = pKey;
  208. StringCchCopy(pKey->wszName, AT_KEY_BUF_LEN, wszNameBuffer);
  209. }
  210. #if DBG == 1
  211. else
  212. {
  213. ERR_OUT("ConvertAtJobsToTasks: AddAtJob", hr);
  214. }
  215. #endif
  216. }
  217. //
  218. // Delete the reg keys for all jobs that were successfully converted
  219. //
  220. KEYNAME * pNext;
  221. for ( ; pDeleteList != NULL; pDeleteList = pNext)
  222. {
  223. RegDeleteKey(hKeySvc, pDeleteList->wszName);
  224. pNext = pDeleteList->pNext;
  225. delete pDeleteList;
  226. }
  227. RegCloseKey(hKeySvc);
  228. pSch->Release();
  229. return;
  230. }