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.

483 lines
10 KiB

  1. /*
  2. * Copyright (c) 1996 Microsoft Corporation
  3. *
  4. * Module Name:
  5. *
  6. * util.cpp
  7. *
  8. * Abstract:
  9. *
  10. * This file communicates with exchange
  11. *
  12. * Author:
  13. *
  14. * Pat Styles (patst) 25-March-1997
  15. *
  16. * Environment:
  17. *
  18. * User Mode
  19. */
  20. #define _UTIL_CPP_
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <stdarg.h>
  24. #include <assert.h>
  25. #include <tchar.h>
  26. #include <time.h>
  27. #include "ocgen.h"
  28. #pragma hdrstop
  29. TCHAR glabel[] = TEXT("\n[OCGEN] ");
  30. // for logging
  31. #define gsLogFile TEXT("%windir%\\ocgen.log")
  32. #define gsLogCompletionMsg TEXT(" - complete\r\n")
  33. #define gsLogInitMsg TEXT("\r\n\r\nInitialize setup: OCGEN.DLL %s %s\r\n")
  34. // for trace statements
  35. #define gsTrace TEXT("OCGEN.DLL: Trace")
  36. typedef enum {
  37. nPreInit, // OC_PREINITIALIZE
  38. nInit, // OC_INIT_COMPONENT
  39. nSetLang, // OC_SET_LANGUAGE
  40. nQueryImage, // OC_QUERY_IMAGE
  41. nRequestPages, // OC_REQUEST_PAGES
  42. nQueryChangeSel, // OC_QUERY_CHANGE_SEL_STATE
  43. nCalcSpace, // OC_CALC_DISK_SPACE
  44. nQueueFile, // OC_QUEUE_FILE_OPS
  45. nQueueNot, // OC_NOTIFICATION_FROM_QUEUE
  46. nQueryStep, // OC_QUERY_STEP_COUNT
  47. nComplete, // OC_COMPLETE_INSTALLATION
  48. nCleanup, // OC_CLEANUP
  49. nQueryState, // OC_QUERY_STATE
  50. nNeedMedia, // OC_NEED_MEDIA
  51. nAboutToCommit, // OC_ABOUT_TO_COMMIT_QUEUE
  52. nQuerySkip, // OC_QUERY_SKIP_PAGE
  53. nWizardCreated, // OC_WIZARD_CREATED
  54. nExtraRoutines, // OC_EXTRA_ROUTINES
  55. nMaximum
  56. } notifications;
  57. typedef struct _OcMsgs {
  58. DWORD msg;
  59. TCHAR *desc;
  60. } OcMsgs;
  61. OcMsgs gMsgs[nMaximum] = {
  62. {OC_PREINITIALIZE, TEXT("OC_PREINITIALIZE")},
  63. {OC_INIT_COMPONENT, TEXT("OC_INIT_COMPONENT")},
  64. {OC_SET_LANGUAGE, TEXT("OC_SET_LANGUAGE")},
  65. {OC_QUERY_IMAGE, TEXT("OC_QUERY_IMAGE")},
  66. {OC_REQUEST_PAGES, TEXT("OC_REQUEST_PAGES")},
  67. {OC_QUERY_CHANGE_SEL_STATE, TEXT("OC_QUERY_CHANGE_SEL_STATE")},
  68. {OC_CALC_DISK_SPACE, TEXT("OC_CALC_DISK_SPACE")},
  69. {OC_QUEUE_FILE_OPS, TEXT("OC_QUEUE_FILE_OPS")},
  70. {OC_NOTIFICATION_FROM_QUEUE,TEXT("OC_NOTIFICATION_FROM_QUEUE")},
  71. {OC_QUERY_STEP_COUNT, TEXT("OC_QUERY_STEP_COUNT")},
  72. {OC_COMPLETE_INSTALLATION, TEXT("OC_COMPLETE_INSTALLATION")},
  73. {OC_CLEANUP, TEXT("OC_CLEANUP")},
  74. {OC_QUERY_STATE, TEXT("OC_QUERY_STATE")},
  75. {OC_NEED_MEDIA, TEXT("OC_NEED_MEDIA")},
  76. {OC_ABOUT_TO_COMMIT_QUEUE, TEXT("OC_ABOUT_TO_COMMIT_QUEUE")},
  77. {OC_QUERY_SKIP_PAGE, TEXT("OC_QUERY_SKIP_PAGE")},
  78. {OC_WIZARD_CREATED, TEXT("OC_WIZARD_CREATED")},
  79. {OC_EXTRA_ROUTINES, TEXT("OC_EXTRA_ROUTINES")}
  80. };
  81. TCHAR gUnknown[] = TEXT("Unknown Notification: ");
  82. // determines whether or not to display debug info
  83. DWORD gDebugLevel = (DWORD)-1;
  84. // forward reference
  85. TCHAR *NotificationText(DWORD msg);
  86. BOOL CheckLevel(DWORD level);
  87. /*
  88. * DebugTrace()
  89. */
  90. void DebugTrace(DWORD level, const TCHAR *text)
  91. {
  92. if (!CheckLevel(level))
  93. return;
  94. OutputDebugString(text);
  95. }
  96. /*
  97. * DebugTraceNL()
  98. *
  99. * precedes a trace statement with a newline and id prefix
  100. */
  101. void DebugTraceNL(DWORD level, const TCHAR *text)
  102. {
  103. DebugTrace(level, glabel);
  104. DebugTrace(level, text);
  105. }
  106. /*
  107. * NotificationText()
  108. */
  109. TCHAR *NotificationText(DWORD msg)
  110. {
  111. int i;
  112. static TCHAR desc[S_SIZE];
  113. for (i = 0; i < nMaximum; i++)
  114. {
  115. if (gMsgs[i].msg == msg)
  116. return gMsgs[i].desc;
  117. }
  118. wsprintf(desc, TEXT("OC_%d: "), msg);
  119. return desc;
  120. }
  121. /*
  122. * DebugTraceOCNotification()
  123. */
  124. void DebugTraceOCNotification(DWORD msg, const TCHAR *component)
  125. {
  126. DebugTraceNL(1, NotificationText(msg));
  127. DebugTrace(1, TEXT(": "));
  128. DebugTrace(1, component);
  129. DebugTrace(1, TEXT(" - "));
  130. }
  131. /*
  132. * DebugTraceFileCopy()
  133. */
  134. void DebugTraceFileCopy(const TCHAR *file)
  135. {
  136. DebugTraceNL(5, TEXT("TreeCopy: FILE="));
  137. DebugTrace(5, file);
  138. }
  139. /*
  140. * DebugTraceFileCopyError()
  141. */
  142. void DebugTraceFileCopyError()
  143. {
  144. TCHAR buf[S_SIZE];
  145. _stprintf(buf, FMT(" FAILURE CODE:[%d] "), GetLastError());
  146. DebugTrace(5, buf);
  147. }
  148. /*
  149. * DebugTraceDirCopy()
  150. */
  151. void DebugTraceDirCopy(const TCHAR *dir)
  152. {
  153. DebugTraceNL(3, TEXT("TreeCopy: DIR="));
  154. DebugTrace(3, dir);
  155. }
  156. /*
  157. * CheckLevel()
  158. */
  159. BOOL CheckLevel(DWORD level)
  160. {
  161. if (gDebugLevel == (DWORD)-1)
  162. gDebugLevel = SysGetDebugLevel();
  163. return (gDebugLevel >= level);
  164. }
  165. /*
  166. * MsgBox
  167. *
  168. */
  169. DWORD MsgBox(HWND hwnd, UINT textID, UINT type, ... )
  170. {
  171. static BOOL initialize = true;
  172. static TCHAR caption[S_SIZE];
  173. TCHAR text[S_SIZE];
  174. TCHAR format[S_SIZE];
  175. int len;
  176. va_list vaList;
  177. assert(hwnd && textID && type);
  178. if (initialize)
  179. {
  180. len = LoadString(ghinst, IDS_DIALOG_CAPTION, caption, S_SIZE);
  181. assert(len);
  182. if (!len) {
  183. _tcscpy( caption, TEXT("Setup"));
  184. }
  185. initialize = false;
  186. }
  187. len = LoadString(ghinst, textID, format, S_SIZE);
  188. assert(len);
  189. if (!len) {
  190. _tcscpy( format, TEXT("Unknown Error"));
  191. }
  192. va_start(vaList, type);
  193. tvsprintf(text, format, vaList);
  194. va_end(vaList);
  195. return MessageBox(hwnd, text, caption, type);
  196. }
  197. DWORD MsgBox(HWND hwnd, TCHAR *fmt, TCHAR *caption, UINT type, ... )
  198. {
  199. TCHAR text[S_SIZE];
  200. va_list vaList;
  201. assert(hwnd && text && caption && type);
  202. va_start(vaList, type);
  203. tvsprintf(text, fmt, vaList);
  204. va_end(vaList);
  205. return MessageBox(hwnd, text, caption, type);
  206. }
  207. DWORD MBox(LPCTSTR fmt, LPCTSTR caption, ... )
  208. {
  209. TCHAR text[S_SIZE];
  210. va_list vaList;
  211. assert(fmt && caption);
  212. va_start(vaList, caption);
  213. tvsprintf(text, fmt, vaList);
  214. va_end(vaList);
  215. return MessageBox(ghwnd, text, caption, MB_ICONINFORMATION | MB_OK);
  216. }
  217. DWORD TMBox(LPCTSTR fmt, ... )
  218. {
  219. TCHAR text[S_SIZE];
  220. va_list vaList;
  221. assert(fmt);
  222. va_start(vaList, fmt);
  223. tvsprintf(text, fmt, vaList);
  224. va_end(vaList);
  225. return MessageBox(ghwnd, text, gsTrace, MB_ICONINFORMATION | MB_OK);
  226. }
  227. /*
  228. * SysGetDebugLevel()
  229. */
  230. DWORD SysGetDebugLevel()
  231. {
  232. DWORD rc;
  233. DWORD err;
  234. DWORD size;
  235. DWORD type;
  236. HKEY hkey;
  237. err = RegOpenKey(HKEY_LOCAL_MACHINE,
  238. TEXT("SOFTWARE\\microsoft\\windows\\currentversion\\setup"),
  239. &hkey);
  240. if (err != ERROR_SUCCESS)
  241. return 0;
  242. size = sizeof(DWORD);
  243. err = RegQueryValueEx(hkey,
  244. TEXT("OCGen Debug Level"),
  245. 0,
  246. &type,
  247. (LPBYTE)&rc,
  248. &size);
  249. if (err != ERROR_SUCCESS || type != REG_DWORD)
  250. rc = 0;
  251. RegCloseKey(hkey);
  252. return rc;
  253. }
  254. /*
  255. * TCharStringToAnsiString
  256. */
  257. DWORD TCharStringToAnsiString(TCHAR *tsz ,char *asz)
  258. {
  259. DWORD count;
  260. assert(tsz && asz);
  261. #ifdef UNICODE
  262. count = WideCharToMultiByte(CP_ACP,
  263. 0,
  264. tsz,
  265. -1,
  266. NULL,
  267. 0,
  268. NULL,
  269. NULL);
  270. if (!count || count > S_SIZE)
  271. return count;
  272. return WideCharToMultiByte(CP_ACP,
  273. 0,
  274. tsz,
  275. -1,
  276. asz,
  277. count,
  278. NULL,
  279. NULL);
  280. #else
  281. _tcscpy(asz, tsz);
  282. return _tcslen(asz);
  283. #endif
  284. }
  285. void logOCNotification(DWORD msg, const TCHAR *component)
  286. {
  287. log(FMT("[%s - %s]"), component, NotificationText(msg));
  288. }
  289. void logOCNotificationCompletion()
  290. {
  291. log(gsLogCompletionMsg);
  292. }
  293. void loginit()
  294. {
  295. HANDLE hfile;
  296. TCHAR logfile[MAX_PATH];
  297. char fmt[S_SIZE];
  298. char output[S_SIZE];
  299. char time[S_SIZE];
  300. char date[S_SIZE];
  301. DWORD bytes;
  302. //#ifdef DEBUG
  303. TCharStringToAnsiString(gsLogInitMsg, fmt);
  304. _strdate(date);
  305. _strtime(time);
  306. sprintf(output, fmt, date, time);
  307. // open the log file
  308. ExpandEnvironmentStrings(gsLogFile, logfile, MAX_PATH);
  309. hfile = CreateFile(logfile,
  310. GENERIC_WRITE,
  311. 0,
  312. NULL,
  313. OPEN_EXISTING,
  314. 0,
  315. NULL);
  316. if (hfile == INVALID_HANDLE_VALUE)
  317. hfile = CreateFile(logfile,
  318. GENERIC_WRITE,
  319. 0,
  320. NULL,
  321. CREATE_ALWAYS,
  322. 0,
  323. NULL);
  324. if (hfile != INVALID_HANDLE_VALUE)
  325. {
  326. SetFilePointer(hfile, 0, NULL, FILE_END);
  327. WriteFile(hfile, output, strlen(output) * sizeof(char), &bytes, NULL);
  328. CloseHandle(hfile);
  329. }
  330. //#endif
  331. }
  332. void log(TCHAR *fmt, ...)
  333. {
  334. TCHAR logfile[MAX_PATH];
  335. TCHAR text[S_SIZE];
  336. char output[S_SIZE];
  337. DWORD bytes;
  338. HANDLE hfile;
  339. va_list vaList;
  340. //#ifdef DEBUG
  341. assert(fmt);
  342. // create the output string
  343. va_start(vaList, fmt);
  344. tvsprintf(text, fmt, vaList);
  345. va_end(vaList);
  346. TCharStringToAnsiString(text, output);
  347. // create the log file name in the root directory
  348. ExpandEnvironmentStrings(gsLogFile, logfile, MAX_PATH);
  349. // open the log file
  350. hfile = CreateFile(logfile,
  351. GENERIC_WRITE,
  352. 0,
  353. NULL,
  354. OPEN_EXISTING,
  355. 0,
  356. NULL);
  357. if (hfile != INVALID_HANDLE_VALUE)
  358. {
  359. SetFilePointer(hfile, 0, NULL, FILE_END);
  360. WriteFile(hfile, output, strlen(output) * sizeof(char), &bytes, NULL);
  361. CloseHandle(hfile);
  362. }
  363. //#endif
  364. }
  365. void AssureTrailingBackslash(TCHAR *path)
  366. {
  367. TCHAR *p;
  368. assert(path && *path);
  369. p = path + _tcslen(path) - 1;
  370. if (*p != TEXT('\\'))
  371. _tcscat(path, TEXT("\\"));
  372. }
  373. BOOL IsNT()
  374. {
  375. DWORD dwver;
  376. dwver = GetVersion();
  377. if (dwver < 0x8000000)
  378. return TRUE;
  379. return FALSE;
  380. }