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.

430 lines
12 KiB

  1. //THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. //ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright 1993-1995 Microsoft Corporation. All Rights Reserved.
  7. //
  8. // MODULE: util.c
  9. //
  10. // PURPOSE: Common utilities
  11. //
  12. // PLATFORMS: Windows 95
  13. //
  14. // FUNCTIONS:
  15. // InitACBList() - initializes the session control block list
  16. // DeInitACBList() - cleans up the session control block list
  17. // FindACBFromConn() - searches or allocates a session control block
  18. // CleanupACB() - removes the session control block
  19. // EnumCloseThreadWindow() - closes each window for the SMM thread
  20. // CloseThreadWindows() - enumerates the SMM thread window
  21. //
  22. // SPECIAL INSTRUCTIONS: N/A
  23. //
  24. #include "proj.h" // includes common header files and global declarations
  25. #include "rcids.h"
  26. #include <rtutils.h>
  27. DWORD g_dwRasscrptTraceId = INVALID_TRACEID;
  28. #pragma data_seg(DATASEG_READONLY)
  29. const static char c_szScriptEntry[] = {REGSTR_KEY_PROF"\\%s"};
  30. #pragma data_seg()
  31. /*----------------------------------------------------------
  32. Purpose: Determines the script info that may be associated with
  33. the given connection name.
  34. Returns: TRUE if an associated script was found (in registry)
  35. Cond: --
  36. */
  37. BOOL PUBLIC GetScriptInfo(
  38. LPCSTR pszConnection,
  39. PSCRIPT pscriptBuf)
  40. {
  41. #pragma data_seg(DATASEG_READONLY)
  42. const static char c_szScript[] = REGSTR_VAL_SCRIPT;
  43. const static char c_szMode[] = REGSTR_VAL_MODE;
  44. #pragma data_seg()
  45. BOOL bRet;
  46. char szSubKey[MAX_BUF];
  47. DWORD cbSize;
  48. DWORD dwType;
  49. HKEY hkey;
  50. ASSERT(pszConnection);
  51. ASSERT(pscriptBuf);
  52. // Assume non-test mode
  53. pscriptBuf->uMode = NORMAL_MODE;
  54. // Is there a script for this connection?
  55. cbSize = sizeof(pscriptBuf->szPath);
  56. wsprintf(szSubKey, c_szScriptEntry, pszConnection);
  57. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_ALL_ACCESS, &hkey))
  58. {
  59. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szScript, NULL,
  60. &dwType, pscriptBuf->szPath, &cbSize) &&
  61. REG_SZ == dwType)
  62. {
  63. // Yes
  64. TRACE_MSG(TF_GENERAL, "Found script \"%s\" for connection \"%s\"",
  65. pscriptBuf->szPath, pszConnection);
  66. // Get the test mode
  67. cbSize = sizeof(pscriptBuf->uMode);
  68. if (ERROR_SUCCESS != RegQueryValueEx(hkey, c_szMode, NULL,
  69. &dwType, (LPBYTE)&(pscriptBuf->uMode), &cbSize) ||
  70. REG_BINARY != dwType)
  71. {
  72. pscriptBuf->uMode = NORMAL_MODE;
  73. }
  74. bRet = TRUE;
  75. }
  76. else
  77. {
  78. // No
  79. TRACE_MSG(TF_GENERAL, "No script found for connection \"%s\"",
  80. pszConnection);
  81. *(pscriptBuf->szPath) = 0;
  82. bRet = FALSE;
  83. }
  84. RegCloseKey(hkey);
  85. }
  86. else
  87. {
  88. TRACE_MSG(TF_GENERAL, "Connection \"%s\" not found", pszConnection);
  89. bRet = FALSE;
  90. }
  91. return bRet;
  92. }
  93. /*----------------------------------------------------------
  94. Purpose: Get/set the window placement of the terminal window with
  95. the given connection name.
  96. Returns: TRUE if an associated script was found (in registry)
  97. Cond: --
  98. */
  99. BOOL PUBLIC GetSetTerminalPlacement(
  100. LPCSTR pszConnection,
  101. LPWINDOWPLACEMENT pwp,
  102. BOOL fGet)
  103. {
  104. #pragma data_seg(DATASEG_READONLY)
  105. const static char c_szPlacement[] = REGSTR_VAL_TERM;
  106. #pragma data_seg()
  107. BOOL bRet;
  108. char szSubKey[MAX_BUF];
  109. DWORD cbSize;
  110. DWORD dwType;
  111. HKEY hkey;
  112. ASSERT(pszConnection);
  113. ASSERT(pwp);
  114. bRet = FALSE;
  115. wsprintf(szSubKey, c_szScriptEntry, pszConnection);
  116. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_ALL_ACCESS, &hkey))
  117. {
  118. if (fGet)
  119. {
  120. cbSize = sizeof(*pwp);
  121. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szPlacement, NULL,
  122. &dwType, (LPBYTE)pwp, &cbSize) &&
  123. REG_BINARY == dwType)
  124. {
  125. bRet = TRUE;
  126. };
  127. }
  128. else
  129. {
  130. if (ERROR_SUCCESS == RegSetValueEx(hkey, c_szPlacement, 0,
  131. REG_BINARY, (LPBYTE)pwp, sizeof(*pwp)))
  132. {
  133. bRet = TRUE;
  134. };
  135. };
  136. RegCloseKey(hkey);
  137. };
  138. return bRet;
  139. }
  140. /*----------------------------------------------------------
  141. Purpose: This function gets the current character from the
  142. given psz string, and returns the pointer to the
  143. next character position.
  144. This function should increment on a byte-basis only.
  145. The callers need to compare or send on a byte basis.
  146. The *pbIsTailByte parameter is updated to reflect whether
  147. the current character is a DBCS lead-byte character.
  148. The caller may use this state information to determine
  149. whether *pch is part of a DBCS character.
  150. Returns: see above
  151. Cond: --
  152. */
  153. LPCSTR PUBLIC MyNextChar(
  154. LPCSTR psz,
  155. char * pch,
  156. DWORD * pdwFlags) // One of MNC_*
  157. {
  158. BOOL bIsTailByte;
  159. #define IS_CARET(ch) ('^' == (ch))
  160. #define IS_SPECIAL_LEAD(ch) ('<' == (ch))
  161. #define BYTE_CR 0x0D
  162. #define BYTE_LF 0x0A
  163. ASSERT(psz);
  164. ASSERT(pch);
  165. ASSERT(pdwFlags);
  166. bIsTailByte = IsFlagSet(*pdwFlags, MNC_ISTAILBYTE);
  167. // bIsTailByte should only be true for trailing bytes on entry
  168. ASSERT(FALSE == bIsTailByte || (bIsTailByte && !IsDBCSLeadByte(*psz)));
  169. // These flags must be mutually exclusive
  170. ASSERT(IsFlagSet(*pdwFlags, MNC_ISLEADBYTE) && IsFlagClear(*pdwFlags, MNC_ISTAILBYTE) ||
  171. IsFlagClear(*pdwFlags, MNC_ISLEADBYTE) && IsFlagSet(*pdwFlags, MNC_ISTAILBYTE) ||
  172. 0 == *pdwFlags);
  173. // Remember whether we're in a DBCS trailing byte for next time
  174. if (IsDBCSLeadByte(*psz))
  175. {
  176. SetFlag(*pdwFlags, MNC_ISLEADBYTE);
  177. ClearFlag(*pdwFlags, MNC_ISTAILBYTE);
  178. }
  179. else if (IsFlagSet(*pdwFlags, MNC_ISLEADBYTE))
  180. {
  181. ClearFlag(*pdwFlags, MNC_ISLEADBYTE);
  182. SetFlag(*pdwFlags, MNC_ISTAILBYTE);
  183. }
  184. else
  185. {
  186. *pdwFlags = 0;
  187. }
  188. // Is this a DBCS trailing byte?
  189. if (IsFlagSet(*pdwFlags, MNC_ISTAILBYTE))
  190. {
  191. // Yes
  192. *pch = *psz;
  193. }
  194. // Is this a lead control character?
  195. else if (IS_CARET(*psz))
  196. {
  197. // Yes; look at next character for control character
  198. LPCSTR pszT = psz + 1;
  199. if (0 == *pszT)
  200. {
  201. // Reached end of string
  202. *pch = '^';
  203. }
  204. else if (InRange(*pszT, '@', '_'))
  205. {
  206. *pch = *pszT - '@';
  207. psz = pszT;
  208. }
  209. else if (InRange(*pszT, 'a', 'z'))
  210. {
  211. *pch = *pszT - 'a' + 1;
  212. psz = pszT;
  213. }
  214. else
  215. {
  216. // Show the caret as a plain old caret
  217. *pch = *pszT;
  218. }
  219. }
  220. else if (IS_SPECIAL_LEAD(*psz))
  221. {
  222. // Is this <cr> or <lf>?
  223. int i;
  224. char rgch[4]; // big enough to hold "lf>" or "cr>"
  225. LPCSTR pszT = psz + 1;
  226. LPCSTR pszTPrev = psz;
  227. for (i = 0;
  228. *pszT && i < sizeof(rgch)-1;
  229. i++, pszT++)
  230. {
  231. rgch[i] = *pszT;
  232. pszTPrev = pszT;
  233. }
  234. rgch[i] = 0; // add null terminator
  235. if (IsSzEqualC(rgch, "cr>"))
  236. {
  237. *pch = BYTE_CR;
  238. psz = pszTPrev;
  239. }
  240. else if (IsSzEqual(rgch, "lf>"))
  241. {
  242. *pch = BYTE_LF;
  243. psz = pszTPrev;
  244. }
  245. else
  246. {
  247. *pch = *psz;
  248. }
  249. }
  250. else if (IS_BACKSLASH(*psz))
  251. {
  252. // Is this \", \^, \<, or \\?
  253. LPCSTR pszT = psz + 1;
  254. switch (*pszT)
  255. {
  256. case '"':
  257. case '\\':
  258. case '^':
  259. case '<':
  260. *pch = *pszT;
  261. psz = pszT;
  262. break;
  263. default:
  264. *pch = *psz;
  265. break;
  266. }
  267. }
  268. else
  269. {
  270. *pch = *psz;
  271. }
  272. return psz + 1;
  273. }
  274. #pragma data_seg(DATASEG_READONLY)
  275. struct tagMPRESIDS
  276. {
  277. RES res;
  278. UINT ids;
  279. } const c_mpresids[] = {
  280. { RES_E_FAIL, IDS_ERR_InternalError },
  281. { RES_E_INVALIDPARAM, IDS_ERR_InternalError },
  282. { RES_E_OUTOFMEMORY, IDS_ERR_OutOfMemory },
  283. { RES_E_EOF, IDS_ERR_UnexpectedEOF },
  284. { RES_E_MAINMISSING, IDS_ERR_MainProcMissing },
  285. { RES_E_SYNTAXERROR, IDS_ERR_SyntaxError },
  286. { RES_E_REDEFINED, IDS_ERR_Redefined },
  287. { RES_E_UNDEFINED, IDS_ERR_Undefined },
  288. { RES_E_IDENTMISSING, IDS_ERR_IdentifierMissing },
  289. { RES_E_EOFUNEXPECTED, IDS_ERR_UnexpectedEOF },
  290. { RES_E_STRINGMISSING, IDS_ERR_StringMissing },
  291. { RES_E_INTMISSING, IDS_ERR_IntMissing },
  292. { RES_E_INVALIDTYPE, IDS_ERR_InvalidType },
  293. { RES_E_INVALIDSETPARAM, IDS_ERR_InvalidParam },
  294. { RES_E_INVALIDIPPARAM, IDS_ERR_InvalidIPParam },
  295. { RES_E_INVALIDPORTPARAM, IDS_ERR_InvalidPortParam },
  296. { RES_E_INVALIDRANGE, IDS_ERR_InvalidRange },
  297. { RES_E_INVALIDSCRNPARAM, IDS_ERR_InvalidScreenParam },
  298. { RES_E_RPARENMISSING, IDS_ERR_RParenMissing },
  299. { RES_E_REQUIREINT, IDS_ERR_RequireInt },
  300. { RES_E_REQUIRESTRING, IDS_ERR_RequireString },
  301. { RES_E_REQUIREBOOL, IDS_ERR_RequireBool },
  302. { RES_E_REQUIREINTSTRING, IDS_ERR_RequireIntString },
  303. { RES_E_REQUIREINTSTRBOOL, IDS_ERR_RequireIntStrBool },
  304. { RES_E_REQUIRELABEL, IDS_ERR_RequireLabel },
  305. { RES_E_TYPEMISMATCH, IDS_ERR_TypeMismatch },
  306. { RES_E_DIVBYZERO, IDS_ERR_DivByZero },
  307. };
  308. #pragma data_seg()
  309. /*----------------------------------------------------------
  310. Purpose: Returns a string resource ID given the specific result
  311. value. This function returns 0 if the result does
  312. not have an associated message string.
  313. Returns: see above
  314. Cond: --
  315. */
  316. UINT PUBLIC IdsFromRes(
  317. RES res)
  318. {
  319. int i;
  320. for (i = 0; i < ARRAY_ELEMENTS(c_mpresids); i++)
  321. {
  322. if (res == c_mpresids[i].res)
  323. return c_mpresids[i].ids;
  324. }
  325. return 0;
  326. }
  327. #ifdef DEBUG
  328. #pragma data_seg(DATASEG_READONLY)
  329. struct tagRESMAP
  330. {
  331. RES res;
  332. LPCSTR psz;
  333. } const c_rgresmap[] = {
  334. DEBUG_STRING_MAP(RES_OK),
  335. DEBUG_STRING_MAP(RES_FALSE),
  336. DEBUG_STRING_MAP(RES_HALT),
  337. DEBUG_STRING_MAP(RES_E_FAIL),
  338. DEBUG_STRING_MAP(RES_E_OUTOFMEMORY),
  339. DEBUG_STRING_MAP(RES_E_INVALIDPARAM),
  340. DEBUG_STRING_MAP(RES_E_EOF),
  341. DEBUG_STRING_MAP(RES_E_MOREDATA),
  342. DEBUG_STRING_MAP(RES_E_MAINMISSING),
  343. DEBUG_STRING_MAP(RES_E_SYNTAXERROR),
  344. DEBUG_STRING_MAP(RES_E_REDEFINED),
  345. DEBUG_STRING_MAP(RES_E_UNDEFINED),
  346. DEBUG_STRING_MAP(RES_E_IDENTMISSING),
  347. DEBUG_STRING_MAP(RES_E_EOFUNEXPECTED),
  348. DEBUG_STRING_MAP(RES_E_STRINGMISSING),
  349. DEBUG_STRING_MAP(RES_E_INTMISSING),
  350. DEBUG_STRING_MAP(RES_E_INVALIDTYPE),
  351. DEBUG_STRING_MAP(RES_E_INVALIDSETPARAM),
  352. DEBUG_STRING_MAP(RES_E_INVALIDIPPARAM),
  353. DEBUG_STRING_MAP(RES_E_INVALIDPORTPARAM),
  354. DEBUG_STRING_MAP(RES_E_INVALIDRANGE),
  355. DEBUG_STRING_MAP(RES_E_INVALIDSCRNPARAM),
  356. DEBUG_STRING_MAP(RES_E_RPARENMISSING),
  357. DEBUG_STRING_MAP(RES_E_REQUIREINT),
  358. DEBUG_STRING_MAP(RES_E_REQUIRESTRING),
  359. DEBUG_STRING_MAP(RES_E_REQUIREBOOL),
  360. DEBUG_STRING_MAP(RES_E_REQUIREINTSTRING),
  361. DEBUG_STRING_MAP(RES_E_REQUIREINTSTRBOOL),
  362. DEBUG_STRING_MAP(RES_E_REQUIRELABEL),
  363. DEBUG_STRING_MAP(RES_E_TYPEMISMATCH),
  364. DEBUG_STRING_MAP(RES_E_DIVBYZERO),
  365. };
  366. #pragma data_seg()
  367. /*----------------------------------------------------------
  368. Purpose: Returns the string form of a RES value.
  369. Returns: String ptr
  370. Cond: --
  371. */
  372. LPCSTR PUBLIC Dbg_GetRes(
  373. RES res)
  374. {
  375. int i;
  376. for (i = 0; i < ARRAY_ELEMENTS(c_rgresmap); i++)
  377. {
  378. if (res == c_rgresmap[i].res)
  379. return c_rgresmap[i].psz;
  380. }
  381. return "Unknown RES";
  382. }
  383. #endif // DEBUG