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.

423 lines
12 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: misc.hxx
  7. //
  8. // Contents: Miscellaneous helper functions
  9. //
  10. // Classes: none.
  11. //
  12. // Functions: StringFromTrigger, CreateFolders, GetDaysOfWeekString,
  13. // GetExitCodeString, GetSageExitCodeString
  14. //
  15. // History: 08-Dec-95 EricB Created.
  16. //
  17. //-----------------------------------------------------------------------------
  18. #include <job_cls.hxx>
  19. #ifndef __MISC_HXX__
  20. #define __MISC_HXX__
  21. #include <mbstring.h> // for _mbs* funcs
  22. //
  23. // Macro to determine the number of elements in an array
  24. //
  25. #define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
  26. //
  27. // Macro to convert Win32 errors to an HRESULT w/o overwriting the FACILITY.
  28. //
  29. #define _HRESULT_FROM_WIN32(x) \
  30. (HRESULT_FACILITY(x) ? x : HRESULT_FROM_WIN32(x))
  31. //
  32. // minFileTime, maxFileTime - min and max for FILETIMEs
  33. //
  34. inline FILETIME
  35. minFileTime(FILETIME ft1, FILETIME ft2)
  36. {
  37. if (CompareFileTime(&ft1, &ft2) < 0)
  38. {
  39. return ft1;
  40. }
  41. else
  42. {
  43. return ft2;
  44. }
  45. }
  46. inline FILETIME
  47. maxFileTime(FILETIME ft1, FILETIME ft2)
  48. {
  49. if (CompareFileTime(&ft1, &ft2) > 0)
  50. {
  51. return ft1;
  52. }
  53. else
  54. {
  55. return ft2;
  56. }
  57. }
  58. //
  59. // These functions let us use a FILETIME as an unsigned __int64 - which
  60. // it is, after all!
  61. //
  62. inline DWORDLONG
  63. FTto64(FILETIME ft)
  64. {
  65. ULARGE_INTEGER uli = { ft.dwLowDateTime, ft.dwHighDateTime };
  66. return uli.QuadPart;
  67. }
  68. inline FILETIME
  69. FTfrom64(DWORDLONG ft)
  70. {
  71. ULARGE_INTEGER uli;
  72. uli.QuadPart = ft;
  73. FILETIME ftResult = { uli.LowPart, uli.HighPart };
  74. return ftResult;
  75. }
  76. //
  77. // Absolute difference between two filetimes
  78. //
  79. inline DWORDLONG
  80. absFileTimeDiff(FILETIME ft1, FILETIME ft2)
  81. {
  82. if (CompareFileTime(&ft1, &ft2) < 0)
  83. {
  84. return (FTto64(ft2) - FTto64(ft1));
  85. }
  86. else
  87. {
  88. return (FTto64(ft1) - FTto64(ft2));
  89. }
  90. }
  91. //
  92. // GetLocalTimeAsFileTime
  93. //
  94. inline FILETIME
  95. GetLocalTimeAsFileTime()
  96. {
  97. FILETIME ftSystem;
  98. GetSystemTimeAsFileTime(&ftSystem);
  99. FILETIME ftNow;
  100. BOOL fSuccess = FileTimeToLocalFileTime(&ftSystem, &ftNow);
  101. Win4Assert(fSuccess);
  102. return ftNow;
  103. }
  104. //+---------------------------------------------------------------------------
  105. //
  106. // Function: SchedMapRpcError
  107. //
  108. // Purpose: Remap RPC exception codes that are unsuitable for displaying
  109. // to the user to more comprehensible errors.
  110. //
  111. // Arguments: [dwError] - the error returned by RpcExceptionCode().
  112. //
  113. // Returns: An HRESULT.
  114. //
  115. //----------------------------------------------------------------------------
  116. HRESULT
  117. SchedMapRpcError(DWORD dwError);
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Function: ComposeErrorMsg
  121. //
  122. // Purpose: Take the two message IDs and the error code and create an
  123. // error reporting string that can be used by both service
  124. // logging and UI dialogs.
  125. //
  126. // [uErrorClassMsgID] - this indicates the class of error, such
  127. // as "Unable to start task" or "Forced to
  128. // close"
  129. // [dwErrorCode] - if non-zero, then an error from the OS
  130. // that would be expanded by FormatMessage.
  131. // [uHelpHintMsgID] - an optional suggestion as to a possible
  132. // remedy.
  133. // [fIndent] - flag indicating if the text should be
  134. // indented or not.
  135. //
  136. // Returns: A string or NULL on failure.
  137. //
  138. // Notes: Release the string memory when done using LocalFree.
  139. //----------------------------------------------------------------------------
  140. LPTSTR
  141. ComposeErrorMsg(
  142. UINT uErrorClassMsgID,
  143. DWORD dwErrCode,
  144. UINT uHelpHintMsgID = 0,
  145. BOOL fIndent = TRUE);
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Function: GetExitCodeString
  149. //
  150. // Synopsis: Retrieve the string associated with the exit code from a
  151. // message file. Algorithm:
  152. //
  153. // Consult the Software\Microsoft\Job Scheduler subkey.
  154. //
  155. // Attempt to retrieve the ExitCodeMessageFile string value from
  156. // a subkey matching the job executable prefix (i.e., minus the
  157. // extension).
  158. //
  159. // The ExitCodeMessageFile specifies a binary from which the
  160. // message string associated with the exit code value is fetched.
  161. //
  162. // Arguments: [dwExitCode] -- Job exit code.
  163. // [ptszExitCodeValue] -- Job exit code in string form.
  164. // [ptszJobExecutable] -- Binary name executed with the job.
  165. //
  166. // Returns: TCHAR * exit code string
  167. // NULL on error
  168. //
  169. // Notes: FormatMessage allocates the return string. Use LocalFree() to
  170. // deallocate.
  171. //
  172. //----------------------------------------------------------------------------
  173. TCHAR *
  174. GetExitCodeString(DWORD dwExitCode,
  175. TCHAR * ptszExitCodeValue,
  176. TCHAR * ptszJobExecutable);
  177. //+---------------------------------------------------------------------------
  178. //
  179. // Function: GetSageExitCodeString
  180. //
  181. // Synopsis: Retrieve the string associated with the exit code the SAGE
  182. // way. Algorithm:
  183. //
  184. // Consult the Software\Microsoft\System Agent\SAGE subkey.
  185. //
  186. // Enumerate the subkeys to find a subkey with a "Program" string
  187. // value specifying an executable name matching that of the job.
  188. //
  189. // If such a subkey was found, open the Result Codes subkey and
  190. // fetch the value name matching the exit code. The string value
  191. // is the exit code string.
  192. //
  193. // Arguments: [ptszExitCodeValue] -- Job exit code in string form.
  194. // [ptszJobExecutable] -- Binary name executed with the job.
  195. //
  196. // Returns: TCHAR * exit code string
  197. // NULL on error
  198. //
  199. // Notes: FormatMessage allocates the return string. Use LocalFree() to
  200. // deallocate.
  201. //
  202. //----------------------------------------------------------------------------
  203. TCHAR *
  204. GetSageExitCodeString(TCHAR * ptszExitCodeValue, TCHAR * ptszJobExecutable);
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Function: ComposeErrorMessage
  208. //
  209. // Synopsis:
  210. //
  211. // Arguments: [fAutoStart] - If true, service is set to autostart.
  212. //
  213. // Returns: HRESULTs
  214. //
  215. // Notes: FormatMessage allocates the return string. Use LocalFree() to
  216. // deallocate.
  217. //
  218. //----------------------------------------------------------------------------
  219. HRESULT
  220. ComposeErrorMessage(UINT uErrMsgID,
  221. HRESULT hrFailureCode,
  222. UINT uSuggestionID);
  223. //+---------------------------------------------------------------------------
  224. //
  225. // Function: AutoStart
  226. //
  227. // Synopsis: Persists the autostart state in the registry.
  228. //
  229. // Arguments: [fAutoStart] - If true, service is set to autostart.
  230. //
  231. // Returns: HRESULTs
  232. //
  233. // Notes: FormatMessage allocates the return string. Use LocalFree() to
  234. // deallocate.
  235. //
  236. //----------------------------------------------------------------------------
  237. HRESULT
  238. AutoStart(BOOL fAutoStart);
  239. #if !defined(_CHICAGO_)
  240. SC_HANDLE
  241. OpenScheduleService(DWORD dwDesiredAccess);
  242. #endif // !defined(_CHICAGO_)
  243. //
  244. // Temporary macros to map wide-char string routines to the CRT until we
  245. // can substitute our own.
  246. //
  247. #define s_wcscpy(d, s) wcscpy(d, s)
  248. #define s_wcscat(d, s) wcscat(d, s)
  249. #define s_wcslen(s) wcslen(s)
  250. #define s_isDriveLetter(c) ((c >= TEXT('a') && c <= TEXT('z')) || \
  251. (c >= TEXT('A') && c <= TEXT('Z')))
  252. //+----------------------------------------------------------------------------
  253. //
  254. // Function: HasSpaces
  255. //
  256. // Synopsis: Scans the string for space characters.
  257. //
  258. // Arguments: [ptstr] - the string to scan
  259. //
  260. // Returns: TRUE if any space characters are found.
  261. //
  262. //-----------------------------------------------------------------------------
  263. inline BOOL
  264. HasSpacesA(LPCSTR pstr)
  265. {
  266. return _mbschr((PUCHAR) pstr, ' ') != NULL;
  267. }
  268. inline BOOL
  269. HasSpacesW(LPCWSTR pwstr)
  270. {
  271. return wcschr(pwstr, L' ') != NULL;
  272. }
  273. #if defined(UNICODE)
  274. # define HasSpaces HasSpacesW
  275. #else
  276. # define HasSpaces HasSpacesA
  277. #endif
  278. //+----------------------------------------------------------------------------
  279. //
  280. // Function: StringFromTrigger
  281. //
  282. // Synopsis: Returns the string representation of the passed in trigger
  283. // data structure.
  284. //
  285. // Arguments: [pTrigger] - the TASK_TRIGGER struct
  286. // [ppwszTrigger] - the returned string
  287. // [lpDetails] - the SHELLDETAILS struct
  288. //
  289. // Returns: HRESULTS
  290. //
  291. // Notes: The string is allocated by this function with CoTaskMemAlloc.
  292. //-----------------------------------------------------------------------------
  293. HRESULT
  294. StringFromTrigger(const PTASK_TRIGGER pTrigger, LPWSTR * ppwszTrigger, LPSHELLDETAILS lpDetails);
  295. //+----------------------------------------------------------------------------
  296. //
  297. // Function: CreateFolders
  298. //
  299. // Synopsis: Creates any missing directories for any slash delimited folder
  300. // names in the path.
  301. //
  302. // Arguments: [pwszPathName] - the path name
  303. // [fHasFileName] - if true, the path name includes a file name.
  304. //
  305. // Returns: HRESULTS
  306. //
  307. // Notes: pwszPathName should never end in a slash.
  308. // Treats forward and back slashes identically.
  309. //-----------------------------------------------------------------------------
  310. HRESULT
  311. CreateFolders(LPCTSTR pwszPathName, BOOL fHasFileName);
  312. HRESULT GetDaysOfWeekString(WORD rgfDaysOfTheWeek, LPTSTR ptszBuf, UINT cchBuf);
  313. #if defined(_CHICAGO_)
  314. //+-------------------------------------------------------------------------
  315. //
  316. // Operator: new
  317. //
  318. // Synopsis: Allocates memory. Needed for Chicago since we can't use the
  319. // CRTs on that platform.
  320. //
  321. // Arguments: [cb] - a count of bytes to allocate
  322. //
  323. // Returns: a pointer to the allocated block.
  324. //
  325. //--------------------------------------------------------------------------
  326. inline void * __cdecl operator new(unsigned int cb)
  327. {
  328. return LocalAlloc(LPTR, cb);
  329. }
  330. //+-------------------------------------------------------------------------
  331. //
  332. // Operator: delete
  333. //
  334. // Synopsis: Frees memory allocated with new.
  335. //
  336. // Arguments: [ptr] - a pointer to the allocated memory.
  337. //
  338. //--------------------------------------------------------------------------
  339. inline void __cdecl operator delete(void * ptr)
  340. {
  341. if (ptr != NULL)
  342. {
  343. LocalFree(ptr);
  344. }
  345. }
  346. #endif // _CHICAGO_
  347. //+---------------------------------------------------------------------------
  348. //
  349. // Function: GetParentDirectory
  350. //
  351. // Synopsis: Return the parent directory of the path indicated.
  352. //
  353. // Arguments: [ptszPath] -- Input path.
  354. // [tszDirectory] -- Caller-allocated returned directory.
  355. //
  356. // Returns: None.
  357. //
  358. // Notes: None.
  359. //
  360. //----------------------------------------------------------------------------
  361. void
  362. GetParentDirectory(LPCTSTR ptszPath, TCHAR tszDirectory[]);
  363. VOID
  364. GetAppNameFromPath(
  365. LPCTSTR tszAppPathName,
  366. LPTSTR tszCopyTo,
  367. ULONG cchMax);
  368. BOOL SetAppPath(LPCTSTR tszAppPathName, LPTSTR *pptszSavedPath);
  369. #if !defined(_CHICAGO_)
  370. BOOL
  371. IsThreadCallerAnAdmin(HANDLE hThreadToken);
  372. HRESULT
  373. LoadAtJob(CJob * pJob, TCHAR * ptszAtJobFilename);
  374. BOOL IsValidAtFilename(LPCWSTR wszFilename);
  375. #endif // !defined(_CHICAGO_)
  376. #endif // __MISC_HXX__