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.

559 lines
17 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. logonmsg.C
  5. Abstract:
  6. functions used to set the logon message and caption bar text
  7. on the current system.
  8. Author:
  9. Bob Watson (a-robw)
  10. Revision History:
  11. 23 Dec 94
  12. --*/
  13. #include <windows.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <c2dll.h>
  17. #include <c2inc.h>
  18. #include <c2utils.h>
  19. #include "c2funcs.h"
  20. #include "c2funres.h"
  21. // local constants
  22. // define action codes here. They are only meaningful in the
  23. // context of this module.
  24. #define AC_LOGONMSG_NOCHANGE 0
  25. #define AC_LOGONMSG_UPDATE 1
  26. // struct used by set function
  27. #define MAX_CAPTION_LENGTH 127
  28. #define MAX_MESSAGE_LENGTH 2047
  29. typedef struct _LOGON_MSG_UPDATE {
  30. TCHAR szCaption[MAX_CAPTION_LENGTH+1];
  31. TCHAR szMessage[MAX_MESSAGE_LENGTH+1];
  32. } LMU_DATA, *PLMU_DATA;
  33. #define SECURE C2DLL_SECURE
  34. static
  35. VOID
  36. EnableEditControls (
  37. HWND hDlg,
  38. BOOL bNewState
  39. )
  40. {
  41. EnableWindow (GetDlgItem (hDlg, IDC_LOGON_CAPTION_TITLE), bNewState);
  42. InvalidateRect (GetDlgItem (hDlg, IDC_LOGON_CAPTION_TITLE), NULL, TRUE);
  43. EnableWindow (GetDlgItem (hDlg, IDC_LOGON_CAPTION), bNewState);
  44. InvalidateRect (GetDlgItem (hDlg, IDC_LOGON_CAPTION), NULL, TRUE);
  45. EnableWindow (GetDlgItem (hDlg, IDC_LOGON_MESSAGE_TITLE), bNewState);
  46. InvalidateRect (GetDlgItem (hDlg, IDC_LOGON_MESSAGE_TITLE), NULL, TRUE);
  47. EnableWindow (GetDlgItem (hDlg, IDC_LOGON_MESSAGE), bNewState);
  48. InvalidateRect (GetDlgItem (hDlg, IDC_LOGON_MESSAGE), NULL, TRUE);
  49. }
  50. static
  51. BOOL
  52. SetLogonMessage (
  53. PLMU_DATA pLogonMsg
  54. )
  55. {
  56. HKEY hKeyWinlogon = NULL;
  57. LONG lStatus = ERROR_SUCCESS;
  58. BOOL bReturn = FALSE;
  59. SET_WAIT_CURSOR;
  60. lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  61. GetStringResource (GetDllInstance(), IDS_WINLOGON_KEY),
  62. 0L,
  63. KEY_SET_VALUE,
  64. &hKeyWinlogon);
  65. if (lStatus == ERROR_SUCCESS) {
  66. // key opened OK so set caption value
  67. lStatus = RegSetValueEx (
  68. hKeyWinlogon,
  69. GetStringResource (GetDllInstance(), IDS_LOGON_CAPTION_VALUE),
  70. 0L,
  71. REG_SZ,
  72. (CONST LPBYTE)pLogonMsg->szCaption,
  73. (lstrlen(pLogonMsg->szCaption) + 1) * sizeof(TCHAR));
  74. if (lStatus == ERROR_SUCCESS) {
  75. // value set OK so set message value
  76. lStatus = RegSetValueEx (
  77. hKeyWinlogon,
  78. GetStringResource (GetDllInstance(), IDS_LOGON_MESSAGE_VALUE),
  79. 0L,
  80. REG_SZ,
  81. (CONST LPBYTE)pLogonMsg->szMessage,
  82. (lstrlen(pLogonMsg->szMessage) + 1) * sizeof(TCHAR));
  83. if (lStatus == ERROR_SUCCESS) {
  84. bReturn = TRUE;
  85. } else {
  86. bReturn = FALSE;
  87. }
  88. } else {
  89. bReturn = FALSE;
  90. }
  91. RegCloseKey (hKeyWinlogon);
  92. } else {
  93. bReturn = FALSE;
  94. SetLastError (ERROR_BADKEY);
  95. }
  96. SET_ARROW_CURSOR;
  97. return bReturn;
  98. }
  99. static
  100. BOOL
  101. GetLogonMessage (
  102. PLMU_DATA pLogonMsg
  103. )
  104. {
  105. HKEY hKeyWinlogon = NULL;
  106. LONG lStatus = ERROR_SUCCESS;
  107. DWORD dwType = 0;
  108. DWORD dwValue = 0;
  109. DWORD dwValueSize = sizeof(DWORD);
  110. BOOL bReturn = FALSE;
  111. SET_WAIT_CURSOR;
  112. // clear the buffers
  113. pLogonMsg->szCaption[0] = 0;
  114. pLogonMsg->szMessage[0] = 0;
  115. lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  116. GetStringResource (GetDllInstance(), IDS_WINLOGON_KEY),
  117. 0L,
  118. KEY_READ,
  119. &hKeyWinlogon);
  120. if (lStatus == ERROR_SUCCESS) {
  121. // key opened OK so check value
  122. dwValueSize = MAX_CAPTION_LENGTH * sizeof(TCHAR);
  123. lStatus = RegQueryValueEx (
  124. hKeyWinlogon,
  125. (LPTSTR)GetStringResource (GetDllInstance(), IDS_LOGON_CAPTION_VALUE),
  126. (LPDWORD)NULL,
  127. &dwType,
  128. (LPBYTE)pLogonMsg->szCaption,
  129. &dwValueSize);
  130. if (lStatus == ERROR_SUCCESS) {
  131. // value read successfully so check it out
  132. if (dwType != REG_SZ) {
  133. // not a string so set string buffer to an empty string
  134. pLogonMsg->szCaption[0] = 0;
  135. }
  136. // get message text
  137. dwValueSize = MAX_MESSAGE_LENGTH * sizeof(TCHAR);
  138. lStatus = RegQueryValueEx (
  139. hKeyWinlogon,
  140. (LPTSTR)GetStringResource (GetDllInstance(), IDS_LOGON_MESSAGE_VALUE),
  141. (LPDWORD)NULL,
  142. &dwType,
  143. (LPBYTE)pLogonMsg->szMessage,
  144. &dwValueSize);
  145. if (lStatus == ERROR_SUCCESS) {
  146. // value read successfully so check it out
  147. if (dwType != REG_SZ) {
  148. // not a string so set string buffer to an empty string
  149. pLogonMsg->szMessage[0] = 0;
  150. }
  151. bReturn = TRUE;
  152. } else {
  153. bReturn = FALSE;
  154. SetLastError (ERROR_CANTREAD);
  155. }
  156. } else {
  157. // no value present
  158. bReturn = FALSE;
  159. SetLastError (ERROR_CANTREAD);
  160. }
  161. RegCloseKey (hKeyWinlogon);
  162. } else {
  163. bReturn = FALSE;
  164. SetLastError (ERROR_BADKEY);
  165. }
  166. SET_ARROW_CURSOR;
  167. return bReturn;
  168. }
  169. BOOL CALLBACK
  170. C2LogonMsgDlgProc(
  171. IN HWND hDlg, // window handle of the dialog box
  172. IN UINT message, // type of message
  173. IN WPARAM wParam,
  174. IN LPARAM lParam
  175. )
  176. /*++
  177. Routine Description:
  178. Window procedure for Audit Failure dialog box
  179. Arguments:
  180. Standard DlgProc arguments
  181. ReturnValue:
  182. TRUE the message was handled by this routine
  183. FALSE DefDialogProc should handle the message
  184. --*/
  185. {
  186. static PLMU_DATA plmuData; // save address of caller's data block
  187. DWORD dwLogSetting = 0;
  188. int nState;
  189. LONG lCaptionLen;
  190. LONG lMessageLen;
  191. switch (message) {
  192. case WM_INITDIALOG:
  193. // save the pointer to the new value
  194. plmuData = (PLMU_DATA)lParam;
  195. if ((lstrlen(plmuData->szCaption) > 0) &&
  196. (lstrlen(plmuData->szMessage) > 0)) {
  197. // then there's text so load edit fields and uncheck button
  198. SetDlgItemText (hDlg, IDC_LOGON_CAPTION, plmuData->szCaption);
  199. SetDlgItemText (hDlg, IDC_LOGON_MESSAGE, plmuData->szMessage);
  200. CheckDlgButton (hDlg, IDC_NO_LOGON_MESSAGE, UNCHECKED);
  201. } else {
  202. // there's no text so check button
  203. CheckDlgButton (hDlg, IDC_NO_LOGON_MESSAGE, CHECKED);
  204. // disable edit windows
  205. EnableEditControls (hDlg, DISABLED);
  206. }
  207. // set text limits on edit boxes
  208. SendDlgItemMessage (hDlg, IDC_LOGON_CAPTION, EM_LIMITTEXT,
  209. (WPARAM)MAX_CAPTION_LENGTH, 0);
  210. SendDlgItemMessage (hDlg, IDC_LOGON_MESSAGE, EM_LIMITTEXT,
  211. (WPARAM)MAX_MESSAGE_LENGTH, 0);
  212. SetFocus (GetDlgItem (hDlg, IDOK)); // set focus to OK Button
  213. return FALSE; // we don't want Windows to set the focus
  214. case WM_COMMAND:
  215. switch (LOWORD(wParam)){
  216. case IDOK:
  217. if (HIWORD(wParam) == BN_CLICKED) {
  218. if (IsDlgButtonChecked (hDlg, IDC_NO_LOGON_MESSAGE) == CHECKED) {
  219. // delete message text
  220. plmuData->szCaption[0] = 0;
  221. plmuData->szMessage[0] = 0;
  222. EndDialog (hDlg, (int)LOWORD(wParam));
  223. } else {
  224. // get the message text from the edit controls
  225. GetDlgItemText (hDlg, IDC_LOGON_CAPTION,
  226. plmuData->szCaption, MAX_CAPTION_LENGTH);
  227. GetDlgItemText (hDlg, IDC_LOGON_MESSAGE,
  228. plmuData->szMessage, MAX_MESSAGE_LENGTH);
  229. // make sure there's data in them!
  230. if ((lstrlen(plmuData->szCaption) > 0) &&
  231. (lstrlen(plmuData->szMessage) > 0)) {
  232. // then there's text so exit
  233. EndDialog (hDlg, (int)LOWORD(wParam));
  234. } else {
  235. // they've selected they want to have a
  236. // message, but haven't entered any text
  237. // so display the message
  238. DisplayDllMessageBox (hDlg,
  239. IDS_LOGON_MESSAGE_NO_TEXT,
  240. IDS_LOGON_MESSAGE_CAPTION,
  241. MBOK_INFO);
  242. if (lstrlen(plmuData->szCaption) == 0) {
  243. SetFocus (GetDlgItem (hDlg, IDC_LOGON_CAPTION));
  244. } else {
  245. SetFocus (GetDlgItem (hDlg, IDC_LOGON_MESSAGE));
  246. }
  247. }
  248. }
  249. return TRUE;
  250. } else {
  251. return FALSE;
  252. }
  253. case IDCANCEL:
  254. if (HIWORD(wParam) == BN_CLICKED) {
  255. // exit and return button that caused exit
  256. EndDialog (hDlg, (int)LOWORD(wParam));
  257. return TRUE;
  258. } else {
  259. return FALSE;
  260. }
  261. case IDC_C2:
  262. if (HIWORD(wParam) == BN_CLICKED) {
  263. nState = ENABLED;
  264. CheckDlgButton (hDlg, IDC_NO_LOGON_MESSAGE, UNCHECKED);
  265. // en/disable edit windows
  266. EnableEditControls (hDlg, nState);
  267. // if there is no text in both of the edit fields
  268. // then display information message
  269. lCaptionLen = SendDlgItemMessage (hDlg, IDC_LOGON_CAPTION,
  270. WM_GETTEXTLENGTH, 0, 0);
  271. lMessageLen = SendDlgItemMessage (hDlg, IDC_LOGON_MESSAGE,
  272. WM_GETTEXTLENGTH, 0, 0);
  273. if ((lCaptionLen == 0) || (lMessageLen == 0)) {
  274. DisplayDllMessageBox (hDlg,
  275. IDS_LOGON_MESSAGE_C2_BTN,
  276. IDS_LOGON_MESSAGE_CAPTION,
  277. MBOK_INFO);
  278. }
  279. // un-check the no message button
  280. // set focus to the first empty window
  281. if (lCaptionLen == 0) {
  282. SetFocus (GetDlgItem (hDlg, IDC_LOGON_CAPTION));
  283. } else if (lMessageLen == 0) {
  284. SetFocus (GetDlgItem (hDlg, IDC_LOGON_MESSAGE));
  285. } else {
  286. // if both have text, then goto the caption field
  287. SetFocus (GetDlgItem (hDlg, IDC_LOGON_CAPTION));
  288. }
  289. return TRUE;
  290. } else {
  291. return FALSE;
  292. }
  293. case IDC_NO_LOGON_MESSAGE:
  294. if (IsDlgButtonChecked (hDlg, IDC_NO_LOGON_MESSAGE) == CHECKED) {
  295. // currently checked so uncheck
  296. nState = ENABLED;
  297. CheckDlgButton (hDlg, IDC_NO_LOGON_MESSAGE, UNCHECKED);
  298. } else {
  299. // currently checked so check;
  300. nState = DISABLED;
  301. CheckDlgButton (hDlg, IDC_NO_LOGON_MESSAGE, CHECKED);
  302. }
  303. // en/disable edit windows
  304. EnableEditControls (hDlg, nState);
  305. return TRUE;
  306. case IDC_HELP:
  307. PostMessage (GetParent(hDlg), UM_SHOW_CONTEXT_HELP, 0, 0);
  308. return TRUE;
  309. default:
  310. return FALSE;
  311. }
  312. default:
  313. return (FALSE); // Didn't process the message
  314. }
  315. }
  316. LONG
  317. C2QueryLogonMessage (
  318. IN LPARAM lParam
  319. )
  320. /*++
  321. Routine Description:
  322. Function called to find out if there is a logon message
  323. on the system. For C2 compliance, a logon message must be
  324. defined on the system.
  325. Arguments:
  326. Pointer to the Dll data block passed as an LPARAM.
  327. ReturnValue:
  328. ERROR_SUCCESS if the function succeeds otherwise a
  329. WIN32 error is returned if an error occurs
  330. --*/
  331. {
  332. PC2DLL_DATA pC2Data;
  333. UINT nMsgString;
  334. LMU_DATA lmuData;
  335. if (lParam != 0) {
  336. pC2Data = (PC2DLL_DATA)lParam;
  337. pC2Data->lC2Compliance = SECURE; // assume true for now
  338. if (GetLogonMessage (&lmuData)) {
  339. if ((lstrlen(lmuData.szCaption) > 0) &&
  340. (lstrlen(lmuData.szMessage) > 0)) {
  341. // if there's a message defined then this is OK
  342. pC2Data->lC2Compliance = SECURE; // this is good
  343. nMsgString = IDS_LOGON_MESSAGE_DEFINED;
  344. } else {
  345. pC2Data->lC2Compliance = C2DLL_NOT_SECURE; // this is not good
  346. nMsgString = IDS_LOGON_MESSAGE_NOT_DEF;
  347. }
  348. } else {
  349. pC2Data->lC2Compliance = C2DLL_NOT_SECURE; // this is not good
  350. nMsgString = IDS_UNABLE_READ;
  351. }
  352. lstrcpy (pC2Data->szStatusName,
  353. GetStringResource (GetDllInstance(), nMsgString));
  354. } else {
  355. return ERROR_BAD_ARGUMENTS;
  356. }
  357. return ERROR_SUCCESS;
  358. }
  359. LONG
  360. C2SetLogonMessage (
  361. IN LPARAM lParam
  362. )
  363. /*++
  364. Routine Description:
  365. Function called to change the current state of this configuration
  366. item based on an action code passed in the DLL data block. If
  367. this function successfully sets the state of the configuration
  368. item, then the C2 Compliance flag and the Status string to reflect
  369. the new value of the configuration item.
  370. Arguments:
  371. Pointer to the Dll data block passed as an LPARAM.
  372. ReturnValue:
  373. ERROR_SUCCESS if the function succeeds otherwise a
  374. WIN32 error is returned if an error occurs
  375. --*/
  376. {
  377. PC2DLL_DATA pC2Data;
  378. UINT nMsgString;
  379. PLMU_DATA plmuData;
  380. if (lParam != 0) {
  381. pC2Data = (PC2DLL_DATA)lParam;
  382. // action value = the address of the data block used to update
  383. if (pC2Data->lActionCode == AC_LOGONMSG_UPDATE) {
  384. plmuData = (PLMU_DATA)pC2Data->lActionValue;
  385. if (SetLogonMessage (plmuData)) {
  386. if ((lstrlen(plmuData->szCaption) > 0) &&
  387. (lstrlen(plmuData->szMessage) > 0)) {
  388. // if there's a message defined then this is OK
  389. pC2Data->lC2Compliance = SECURE; // this is good
  390. nMsgString = IDS_LOGON_MESSAGE_DEFINED;
  391. } else {
  392. pC2Data->lC2Compliance = C2DLL_NOT_SECURE; // this is not good
  393. nMsgString = IDS_LOGON_MESSAGE_NOT_DEF;
  394. }
  395. lstrcpy (pC2Data->szStatusName,
  396. GetStringResource (GetDllInstance(), nMsgString));
  397. } else {
  398. DisplayDllMessageBox (
  399. pC2Data->hWnd,
  400. IDS_LOGON_MESSAGE_ERROR_SET,
  401. IDS_LOGON_MESSAGE_CAPTION,
  402. MBOK_EXCLAIM);
  403. }
  404. }
  405. // update action values
  406. pC2Data->lActionCode = 0;
  407. pC2Data->lActionValue = 0;
  408. } else {
  409. return ERROR_BAD_ARGUMENTS;
  410. }
  411. return ERROR_SUCCESS;
  412. }
  413. LONG
  414. C2DisplayLogonMessage (
  415. IN LPARAM lParam
  416. )
  417. /*++
  418. Routine Description:
  419. Function called to display more information on the configuration
  420. item and provide the user with the option to change the current
  421. setting (if appropriate). If the User "OK's" out of the UI,
  422. then the action code field in the DLL data block is set to the
  423. appropriate (and configuration item-specific) action code so the
  424. "Set" function can be called to perform the desired action. If
  425. the user Cancels out of the UI, then the Action code field is
  426. set to 0 (no action) and no action is performed.
  427. Arguments:
  428. Pointer to the Dll data block passed as an LPARAM.
  429. ReturnValue:
  430. ERROR_SUCCESS if the function succeeds otherwise a
  431. WIN32 error is returned if an error occurs
  432. --*/
  433. {
  434. PC2DLL_DATA pC2Data;
  435. static LMU_DATA lmuData;
  436. if (lParam != 0) {
  437. pC2Data = (PC2DLL_DATA)lParam;
  438. // load the current message strings
  439. GetLogonMessage (&lmuData);
  440. if (DialogBoxParam (
  441. GetDllInstance(),
  442. MAKEINTRESOURCE (IDD_LOGON_MESSAGE),
  443. pC2Data->hWnd,
  444. C2LogonMsgDlgProc,
  445. (LPARAM)&lmuData) == IDOK) {
  446. pC2Data->lActionCode = AC_LOGONMSG_UPDATE;
  447. pC2Data->lActionValue = (LONG)&lmuData;
  448. } else {
  449. // no action
  450. pC2Data->lActionCode = AC_LOGONMSG_NOCHANGE;
  451. }
  452. } else {
  453. return ERROR_BAD_ARGUMENTS;
  454. }
  455. return ERROR_SUCCESS;
  456. }
  457. 
  458.