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.

365 lines
9.7 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 2000
  3. Module Name:
  4. pindlg.c
  5. Abstract:
  6. Window procedure for the PIN dialog
  7. Notes:
  8. <Implementation Details>
  9. --*/
  10. #include <windows.h>
  11. // C RunTime Header Files
  12. #include <stdlib.h>
  13. #include <malloc.h>
  14. #include <memory.h>
  15. #include <tchar.h>
  16. #include "resource.h"
  17. #include "basecsp.h"
  18. #include "pinlib.h"
  19. #include "pindlg.h"
  20. // Offset added to the bottom of the reference control to determine
  21. // the bottom of the dialog
  22. #define BORDER_OFFSET 7
  23. /*++
  24. PinDlgProc:
  25. Message handler for PIN dialog box.
  26. Arguments:
  27. HWND hDlg handle to window
  28. UINT message message identifier
  29. WPARAM wParam first message parameter
  30. LPARAM lParam second message parameter
  31. Return Value:
  32. TRUE if the message was processed or FALSE if it wasn't
  33. Remarks:
  34. <usageDetails>
  35. --*/
  36. INT_PTR CALLBACK PinDlgProc(
  37. HWND hDlg,
  38. UINT message,
  39. WPARAM wParam,
  40. LPARAM lParam
  41. )
  42. {
  43. PPIN_SHOW_GET_PIN_UI_INFO pInfo = (PPIN_SHOW_GET_PIN_UI_INFO)
  44. GetWindowLongPtr(hDlg, GWLP_USERDATA);
  45. int wmId, wmEvent;
  46. DWORD cchPin = cchMAX_PIN_LENGTH;
  47. WCHAR wszPin [cchMAX_PIN_LENGTH + 1];
  48. DWORD cchNewPin = cchMAX_PIN_LENGTH;
  49. WCHAR wszNewPin [cchMAX_PIN_LENGTH];
  50. DWORD cchNewPinConfirm = cchMAX_PIN_LENGTH;
  51. WCHAR wszNewPinConfirm [cchMAX_PIN_LENGTH];
  52. DWORD dwSts = ERROR_SUCCESS;
  53. PINCACHE_PINS Pins;
  54. LPWSTR wszWrongPin = NULL;
  55. DWORD cchWrongPin = 0;
  56. switch (message)
  57. {
  58. case WM_INITDIALOG:
  59. // Store the caller's data - this is the buffer by which we'll return
  60. // the user's pin.
  61. SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR) lParam);
  62. // The dialog shall be initially "small"
  63. {
  64. RECT xRefRect, xRect;
  65. GetWindowRect(hDlg, &xRect);
  66. GetWindowRect(GetDlgItem(hDlg, IDOK), &xRefRect);
  67. xRect.bottom = xRefRect.bottom + BORDER_OFFSET;
  68. MoveWindow(hDlg,
  69. xRect.left, xRect.top,
  70. xRect.right - xRect.left, xRect.bottom - xRect.top,
  71. FALSE);
  72. }
  73. //
  74. // Set the max input length for the various pin input fields
  75. //
  76. SendDlgItemMessage(
  77. hDlg,
  78. IDC_EDITPIN,
  79. EM_LIMITTEXT,
  80. cchMAX_PIN_LENGTH,
  81. 0);
  82. SendDlgItemMessage(
  83. hDlg,
  84. IDC_EDITNEWPIN,
  85. EM_LIMITTEXT,
  86. cchMAX_PIN_LENGTH,
  87. 0);
  88. SendDlgItemMessage(
  89. hDlg,
  90. IDC_EDITNEWPIN2,
  91. EM_LIMITTEXT,
  92. cchMAX_PIN_LENGTH,
  93. 0);
  94. return TRUE;
  95. case WM_COMMAND:
  96. wmId = LOWORD(wParam);
  97. wmEvent = HIWORD(wParam);
  98. // Parse the menu selections:
  99. switch (wmId)
  100. {
  101. case IDOK:
  102. pInfo->dwError = ERROR_SUCCESS;
  103. memset(&Pins, 0, sizeof(Pins));
  104. //
  105. // Find out what the user typed in
  106. //
  107. cchPin = GetDlgItemText(
  108. hDlg,
  109. IDC_EDITPIN,
  110. wszPin,
  111. cchMAX_PIN_LENGTH);
  112. if (cchPin == 0)
  113. goto InvalidPin;
  114. // User entered something. See if it's a valid pin.
  115. dwSts = PinStringToBytesW(
  116. wszPin,
  117. &Pins.cbCurrentPin,
  118. &Pins.pbCurrentPin);
  119. switch (dwSts)
  120. {
  121. case ERROR_SUCCESS:
  122. // Just continue
  123. break;
  124. case ERROR_NOT_ENOUGH_MEMORY:
  125. goto OutOfMemoryRet;
  126. default:
  127. goto InvalidPin;
  128. }
  129. // See if the user is requesting a pinchange
  130. cchNewPin = GetDlgItemText(
  131. hDlg,
  132. IDC_EDITNEWPIN,
  133. wszNewPin,
  134. cchMAX_PIN_LENGTH);
  135. if (0 != cchNewPin)
  136. {
  137. // See if the "confirmed" new pin matches the first new pin
  138. cchNewPinConfirm = GetDlgItemText(
  139. hDlg,
  140. IDC_EDITNEWPIN2,
  141. wszNewPinConfirm,
  142. cchMAX_PIN_LENGTH);
  143. if (0 != wcscmp(wszNewPin, wszNewPinConfirm))
  144. {
  145. // Display a warning message and let the user try again
  146. MessageBoxEx(
  147. hDlg,
  148. pInfo->pStrings[StringNewPinMismatch].wszString,
  149. pInfo->pStrings[StringPinMessageBoxTitle].wszString,
  150. MB_OK | MB_ICONWARNING | MB_APPLMODAL,
  151. 0);
  152. return TRUE;
  153. }
  154. // See if the new pin is valid
  155. dwSts = PinStringToBytesW(
  156. wszNewPin,
  157. &Pins.cbNewPin,
  158. &Pins.pbNewPin);
  159. switch (dwSts)
  160. {
  161. case ERROR_SUCCESS:
  162. // Just continue
  163. break;
  164. case ERROR_NOT_ENOUGH_MEMORY:
  165. goto OutOfMemoryRet;
  166. default:
  167. goto InvalidPin;
  168. }
  169. }
  170. dwSts = pInfo->pfnVerify(
  171. &Pins,
  172. (PVOID) pInfo);
  173. if (ERROR_SUCCESS != dwSts)
  174. goto InvalidPin;
  175. // Pin appears to be good. We're done.
  176. // Return the appropriate validated pin to the caller
  177. if (NULL != Pins.pbNewPin)
  178. {
  179. pInfo->pbPin = Pins.pbNewPin;
  180. pInfo->cbPin = Pins.cbNewPin;
  181. Pins.pbNewPin = NULL;
  182. }
  183. else
  184. {
  185. pInfo->pbPin = Pins.pbCurrentPin;
  186. pInfo->cbPin = Pins.cbCurrentPin;
  187. Pins.pbCurrentPin = NULL;
  188. }
  189. EndDialog(hDlg, wmId);
  190. goto CommonRet;
  191. case IDCANCEL:
  192. pInfo->dwError = SCARD_W_CANCELLED_BY_USER;
  193. EndDialog(hDlg, wmId);
  194. return TRUE;
  195. case IDC_BUTTONOPTIONS:
  196. {
  197. RECT xRefRect, xRect;
  198. LPCTSTR lpszNewText;
  199. HWND hWnd;
  200. GetWindowRect(hDlg, &xRect);
  201. GetWindowRect(GetDlgItem(hDlg, IDOK), &xRefRect);
  202. if (xRect.bottom == xRefRect.bottom + BORDER_OFFSET)
  203. { // if dialog is small, make it big
  204. GetWindowRect(GetDlgItem(hDlg, IDC_EDITNEWPIN2), &xRefRect);
  205. // Change the button label accordingly
  206. lpszNewText = _T("&Options <<");
  207. }
  208. else // otherwise shrink it
  209. {
  210. // Change the button label accordingly
  211. lpszNewText = _T("&Options >>");
  212. }
  213. xRect.bottom = xRefRect.bottom + BORDER_OFFSET;
  214. MoveWindow(hDlg,
  215. xRect.left, xRect.top,
  216. xRect.right - xRect.left, xRect.bottom - xRect.top,
  217. TRUE);
  218. SetDlgItemText(hDlg, IDC_BUTTONOPTIONS, lpszNewText);
  219. }
  220. return TRUE;
  221. }
  222. break;
  223. }
  224. return FALSE;
  225. InvalidPin:
  226. // See if valid "Attempts Remaining" info was supplied. If so, display
  227. // it to the user.
  228. if (((DWORD) -1) != pInfo->cAttemptsRemaining)
  229. {
  230. cchWrongPin =
  231. wcslen(pInfo->pStrings[StringWrongPin].wszString) + 3 +
  232. wcslen(pInfo->pStrings[StringPinRetries].wszString) + 3 + 2 + 1;
  233. wszWrongPin = (LPWSTR) CspAllocH(cchWrongPin * sizeof(WCHAR));
  234. if (NULL == wszWrongPin)
  235. goto OutOfMemoryRet;
  236. wsprintf(
  237. wszWrongPin,
  238. L"%s. %s: %02d",
  239. pInfo->pStrings[StringWrongPin].wszString,
  240. pInfo->pStrings[StringPinRetries].wszString,
  241. pInfo->cAttemptsRemaining & 0x0F);
  242. }
  243. else
  244. {
  245. cchWrongPin =
  246. wcslen(pInfo->pStrings[StringWrongPin].wszString) + 2;
  247. wszWrongPin = (LPWSTR) CspAllocH(cchWrongPin * sizeof(WCHAR));
  248. if (NULL == wszWrongPin)
  249. goto OutOfMemoryRet;
  250. wsprintf(
  251. wszWrongPin,
  252. L"%s.",
  253. pInfo->pStrings[StringWrongPin].wszString);
  254. }
  255. // Display a warning message and let the user try again, if they'd like.
  256. MessageBoxEx(
  257. hDlg,
  258. wszWrongPin,
  259. pInfo->pStrings[StringPinMessageBoxTitle].wszString,
  260. MB_OK | MB_ICONWARNING | MB_APPLMODAL,
  261. 0);
  262. //
  263. // Clear the pin edit boxes since the current pin is wrong
  264. //
  265. SetDlgItemText(hDlg, IDC_EDITPIN, L"");
  266. SetDlgItemText(hDlg, IDC_EDITNEWPIN, L"");
  267. SetDlgItemText(hDlg, IDC_EDITNEWPIN2, L"");
  268. CommonRet:
  269. if (NULL != wszWrongPin)
  270. CspFreeH(wszWrongPin);
  271. if (NULL != Pins.pbCurrentPin)
  272. {
  273. RtlSecureZeroMemory(Pins.pbCurrentPin, Pins.cbCurrentPin);
  274. CspFreeH(Pins.pbCurrentPin);
  275. }
  276. if (NULL != Pins.pbNewPin)
  277. {
  278. RtlSecureZeroMemory(Pins.pbNewPin, Pins.cbNewPin);
  279. CspFreeH(Pins.pbNewPin);
  280. }
  281. if (ERROR_SUCCESS != pInfo->dwError)
  282. EndDialog(hDlg, wmId);
  283. return TRUE;
  284. OutOfMemoryRet:
  285. pInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
  286. goto CommonRet;
  287. }