1 |
/* OpenPGP Smart Card Mini Driver |
2 |
Copyright (C) 2009 Vincent Le Toux |
3 |
|
4 |
This library is Free software; you can redistribute it and/or |
5 |
modify it under the terms of the GNU Lesser General Public |
6 |
License version 2.1 as published by the Free Software Foundation. |
7 |
|
8 |
This library is distributed in the hope that it will be useful, |
9 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 |
Lesser General Public License for more details. |
12 |
|
13 |
You should have received a copy of the GNU Lesser General Public |
14 |
License along with this library; if not, write to the Free Software |
15 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
16 |
*/ |
17 |
|
18 |
#include <windows.h> |
19 |
#include <tchar.h> |
20 |
#include <cardmod.h> |
21 |
#include <commctrl.h> |
22 |
#include <Cryptuiapi.h> |
23 |
#include "dialog.h" |
24 |
#include "global.h" |
25 |
|
26 |
#pragma comment(lib,"comctl32") |
27 |
|
28 |
#ifdef UNICODE |
29 |
#if defined _M_IX86 |
30 |
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") |
31 |
#elif defined _M_IA64 |
32 |
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") |
33 |
#elif defined _M_X64 |
34 |
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") |
35 |
#else |
36 |
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") |
37 |
#endif |
38 |
#endif |
39 |
|
40 |
// Variables globales : |
41 |
HINSTANCE g_hinst; // instance actuelle |
42 |
|
43 |
INT_PTR CALLBACK WndProcConnect(HWND, UINT, WPARAM, LPARAM); |
44 |
INT_PTR CALLBACK WndProcPin(HWND, UINT, WPARAM, LPARAM); |
45 |
INT_PTR CALLBACK WndProcFile(HWND, UINT, WPARAM, LPARAM); |
46 |
INT_PTR CALLBACK WndProcCrypto(HWND, UINT, WPARAM, LPARAM); |
47 |
INT_PTR CALLBACK WndProcCryptoApi(HWND, UINT, WPARAM, LPARAM); |
48 |
INT_PTR CALLBACK WndProcEnroll(HWND, UINT, WPARAM, LPARAM); |
49 |
|
50 |
int APIENTRY _tWinMain(HINSTANCE hInstance, |
51 |
HINSTANCE hPrevInstance, |
52 |
LPTSTR lpCmdLine, |
53 |
int nCmdShow) |
54 |
{ |
55 |
UNREFERENCED_PARAMETER(hPrevInstance); |
56 |
UNREFERENCED_PARAMETER(lpCmdLine); |
57 |
g_hinst = hInstance; |
58 |
PROPSHEETPAGE psp[6]; |
59 |
PROPSHEETHEADER psh; |
60 |
psp[0].dwSize = sizeof(PROPSHEETPAGE); |
61 |
psp[0].dwFlags = PSP_USETITLE; |
62 |
psp[0].hInstance = g_hinst; |
63 |
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_CONNECT); |
64 |
psp[0].pszIcon = NULL; |
65 |
psp[0].pfnDlgProc = WndProcConnect; |
66 |
psp[0].pszTitle = TEXT("Connect"); |
67 |
psp[0].lParam = 0; |
68 |
psp[0].pfnCallback = NULL; |
69 |
psp[1].dwSize = sizeof(PROPSHEETPAGE); |
70 |
psp[1].dwFlags = PSP_USETITLE; |
71 |
psp[1].hInstance = g_hinst; |
72 |
psp[1].pszTemplate = MAKEINTRESOURCE(IDD_PIN); |
73 |
psp[1].pszIcon = NULL; |
74 |
psp[1].pfnDlgProc = WndProcPin; |
75 |
psp[1].pszTitle = TEXT("Pin"); |
76 |
psp[1].lParam = 0; |
77 |
psp[2].pfnCallback = NULL; |
78 |
psp[2].dwSize = sizeof(PROPSHEETPAGE); |
79 |
psp[2].dwFlags = PSP_USETITLE; |
80 |
psp[2].hInstance = g_hinst; |
81 |
psp[2].pszTemplate = MAKEINTRESOURCE(IDD_FILE); |
82 |
psp[2].pszIcon = NULL; |
83 |
psp[2].pfnDlgProc = WndProcFile; |
84 |
psp[2].pszTitle = TEXT("File"); |
85 |
psp[2].lParam = 0; |
86 |
psp[2].pfnCallback = NULL; |
87 |
psp[3].dwSize = sizeof(PROPSHEETPAGE); |
88 |
psp[3].dwFlags = PSP_USETITLE; |
89 |
psp[3].hInstance = g_hinst; |
90 |
psp[3].pszTemplate = MAKEINTRESOURCE(IDD_CRYPTO); |
91 |
psp[3].pszIcon = NULL; |
92 |
psp[3].pfnDlgProc = WndProcCrypto; |
93 |
psp[3].pszTitle = TEXT("Crypto"); |
94 |
psp[3].lParam = 0; |
95 |
psp[3].pfnCallback = NULL; |
96 |
psp[4].dwSize = sizeof(PROPSHEETPAGE); |
97 |
psp[4].dwFlags = PSP_USETITLE; |
98 |
psp[4].hInstance = g_hinst; |
99 |
psp[4].pszTemplate = MAKEINTRESOURCE(IDD_CRYPTOAPI); |
100 |
psp[4].pszIcon = NULL; |
101 |
psp[4].pfnDlgProc = WndProcCryptoApi; |
102 |
psp[4].pszTitle = TEXT("CryptoApi"); |
103 |
psp[4].lParam = 0; |
104 |
psp[4].pfnCallback = NULL; |
105 |
psp[5].dwSize = sizeof(PROPSHEETPAGE); |
106 |
psp[5].dwFlags = PSP_USETITLE; |
107 |
psp[5].hInstance = g_hinst; |
108 |
psp[5].pszTemplate = MAKEINTRESOURCE(IDD_ENROLL); |
109 |
psp[5].pszIcon = NULL; |
110 |
psp[5].pfnDlgProc = WndProcEnroll; |
111 |
psp[5].pszTitle = TEXT("Enroll"); |
112 |
psp[5].lParam = 0; |
113 |
psp[5].pfnCallback = NULL; |
114 |
psh.dwSize = sizeof(PROPSHEETHEADER); |
115 |
psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE; |
116 |
psh.hwndParent = NULL; |
117 |
psh.hInstance = g_hinst; |
118 |
psh.pszIcon =NULL; |
119 |
psh.pszCaption = TEXT("Test"); |
120 |
psh.nPages = ARRAYSIZE(psp); |
121 |
psh.nStartPage = 0; |
122 |
psh.ppsp = (LPCPROPSHEETPAGE) &psp; |
123 |
psh.pfnCallback = NULL; |
124 |
PropertySheet(&psh); |
125 |
return 0; |
126 |
|
127 |
} |
128 |
|
129 |
void MessageBoxWin32(DWORD status) { |
130 |
LPVOID Error; |
131 |
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, |
132 |
NULL,status,0,(LPTSTR)&Error,0,NULL); |
133 |
MessageBox(NULL,(LPCTSTR)Error,NULL,MB_ICONASTERISK); |
134 |
LocalFree(Error); |
135 |
} |
136 |
|
137 |
|
138 |
void ViewCertificate(HWND hWnd, PCCERT_CONTEXT pCertContext) |
139 |
{ |
140 |
CRYPTUI_VIEWCERTIFICATE_STRUCT certViewInfo; |
141 |
BOOL fPropertiesChanged = FALSE; |
142 |
certViewInfo.dwSize = sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT); |
143 |
certViewInfo.hwndParent = hWnd; |
144 |
certViewInfo.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_DISABLE_EXPORT | CRYPTUI_DISABLE_HTMLLINK; |
145 |
certViewInfo.szTitle = TEXT("Info"); |
146 |
certViewInfo.pCertContext = pCertContext; |
147 |
certViewInfo.cPurposes = 0; |
148 |
certViewInfo.rgszPurposes = 0; |
149 |
certViewInfo.pCryptProviderData = NULL; |
150 |
certViewInfo.hWVTStateData = NULL; |
151 |
certViewInfo.fpCryptProviderDataTrustedUsage = FALSE; |
152 |
certViewInfo.idxSigner = 0; |
153 |
certViewInfo.idxCert = 0; |
154 |
certViewInfo.fCounterSigner = FALSE; |
155 |
certViewInfo.idxCounterSigner = 0; |
156 |
certViewInfo.cStores = 0; |
157 |
certViewInfo.rghStores = NULL; |
158 |
certViewInfo.cPropSheetPages = 0; |
159 |
certViewInfo.rgPropSheetPages = NULL; |
160 |
certViewInfo.nStartPage = 0; |
161 |
|
162 |
CryptUIDlgViewCertificate(&certViewInfo,&fPropertiesChanged); |
163 |
} |
164 |
|
165 |
#define C_PAGES 5 |
166 |
|
167 |
typedef struct tag_dlghdr { |
168 |
HWND hwndTab; // tab control |
169 |
HWND hwndDisplay; // current child dialog box |
170 |
RECT rcDisplay; // display rectangle for the tab control |
171 |
DLGTEMPLATE *apRes[C_PAGES]; |
172 |
DLGPROC pDialogFunc[C_PAGES]; |
173 |
} DLGHDR; |
174 |
|
175 |
|
176 |
BOOL GetContainerName(HWND hWnd, PWSTR szContainer, PDWORD pdwKeySpec) |
177 |
{ |
178 |
DWORD iItem = (DWORD)SendMessage(GetDlgItem(hWnd, IDC_LSTCONTAINER),LB_GETCURSEL,0,0); |
179 |
if (iItem == LB_ERR) return FALSE; |
180 |
SendMessage( GetDlgItem(hWnd,IDC_LSTCONTAINER), LB_GETTEXT,iItem,(LPARAM)szContainer); |
181 |
*pdwKeySpec = _tstoi(szContainer + _tcslen(szContainer) - 1); |
182 |
szContainer[ _tcslen(szContainer) - 2] = 0; |
183 |
return TRUE; |
184 |
} |
185 |
|
186 |
|
187 |
INT_PTR CALLBACK WndProcConnect(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
188 |
{ |
189 |
int wmId, wmEvent; |
190 |
DWORD dwReturn; |
191 |
switch (message) |
192 |
{ |
193 |
case WM_INITDIALOG: |
194 |
CheckDlgButton(hWnd,IDC_CurrentDll,BST_CHECKED); |
195 |
break; |
196 |
case WM_COMMAND: |
197 |
wmId = LOWORD(wParam); |
198 |
wmEvent = HIWORD(wParam); |
199 |
|
200 |
switch (wmId) |
201 |
{ |
202 |
case IDC_CONNECT: |
203 |
if (IsDlgButtonChecked(hWnd,IDC_SystemDll)) |
204 |
{ |
205 |
dwReturn = Connect(TRUE); |
206 |
} |
207 |
else |
208 |
{ |
209 |
dwReturn = Connect(FALSE); |
210 |
} |
211 |
if (dwReturn) |
212 |
{ |
213 |
MessageBoxWin32(dwReturn); |
214 |
} |
215 |
break; |
216 |
case IDC_DISCONNECT: |
217 |
dwReturn = Disconnect(); |
218 |
if (dwReturn) |
219 |
{ |
220 |
MessageBoxWin32(dwReturn); |
221 |
} |
222 |
break; |
223 |
} |
224 |
break; |
225 |
} |
226 |
return FALSE; |
227 |
} |
228 |
|
229 |
INT_PTR CALLBACK WndProcPin(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
230 |
{ |
231 |
int wmId, wmEvent; |
232 |
DWORD dwReturn; |
233 |
CHAR szPin[256]; |
234 |
CHAR szPin2[256]; |
235 |
DWORD dwRemaining; |
236 |
switch (message) |
237 |
{ |
238 |
case WM_INITDIALOG: |
239 |
CheckDlgButton(hWnd,IDC_PINUSER,BST_CHECKED); |
240 |
SendMessage( GetDlgItem(hWnd, IDC_TXTPIN), WM_SETTEXT,0,(LPARAM) TEXT("123456")); |
241 |
break; |
242 |
case WM_COMMAND: |
243 |
wmId = LOWORD(wParam); |
244 |
wmEvent = HIWORD(wParam); |
245 |
|
246 |
switch (wmId) |
247 |
{ |
248 |
case IDC_PINUSER: |
249 |
SendMessage( GetDlgItem(hWnd, IDC_TXTPIN), WM_SETTEXT,0,(LPARAM) TEXT("123456")); |
250 |
break; |
251 |
case IDC_PINADMIN: |
252 |
SendMessage( GetDlgItem(hWnd, IDC_TXTPIN), WM_SETTEXT,0,(LPARAM) TEXT("12345678")); |
253 |
break; |
254 |
case IDC_PUK: |
255 |
SendMessage( GetDlgItem(hWnd, IDC_TXTPIN), WM_SETTEXT,0,(LPARAM) TEXT("000000")); |
256 |
break; |
257 |
case IDC_CHECKPIN: |
258 |
GetDlgItemTextA(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin)); |
259 |
|
260 |
if (IsDlgButtonChecked(hWnd,IDC_PINADMIN)) |
261 |
{ |
262 |
dwReturn = Authenticate(szPin, wszCARD_USER_ADMIN, &dwRemaining); |
263 |
} |
264 |
else |
265 |
{ |
266 |
dwReturn = Authenticate(szPin, wszCARD_USER_USER, &dwRemaining); |
267 |
} |
268 |
MessageBoxWin32(dwReturn); |
269 |
break; |
270 |
case IDC_UNBLOCKPIN: |
271 |
GetDlgItemTextA(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin)); |
272 |
GetDlgItemTextA(hWnd,IDC_TXTPIN2,szPin2,ARRAYSIZE(szPin2)); |
273 |
if (IsDlgButtonChecked(hWnd,IDC_PINADMIN)) |
274 |
{ |
275 |
dwReturn = ResetPin(szPin, szPin2, FALSE, &dwRemaining); |
276 |
} |
277 |
else if (IsDlgButtonChecked(hWnd,IDC_PUK)) |
278 |
{ |
279 |
dwReturn = ResetPin(szPin, szPin2, TRUE, &dwRemaining); |
280 |
} |
281 |
else |
282 |
{ |
283 |
dwReturn = E_INVALIDARG; |
284 |
} |
285 |
MessageBoxWin32(dwReturn); |
286 |
break; |
287 |
case IDC_CHANGEPIN: |
288 |
GetDlgItemTextA(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin)); |
289 |
GetDlgItemTextA(hWnd,IDC_TXTPIN2,szPin2,ARRAYSIZE(szPin2)); |
290 |
if (IsDlgButtonChecked(hWnd,IDC_PINADMIN)) |
291 |
{ |
292 |
dwReturn = ChangePin(szPin, szPin2, wszCARD_USER_ADMIN, &dwRemaining); |
293 |
} |
294 |
else if (IsDlgButtonChecked(hWnd,IDC_PINUSER)) |
295 |
{ |
296 |
dwReturn = ChangePin(szPin, szPin2, wszCARD_USER_USER, &dwRemaining); |
297 |
} |
298 |
else |
299 |
{ |
300 |
dwReturn = E_INVALIDARG; |
301 |
} |
302 |
MessageBoxWin32(dwReturn); |
303 |
break; |
304 |
case IDC_SETPUK: |
305 |
GetDlgItemTextA(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin)); |
306 |
GetDlgItemTextA(hWnd,IDC_TXTPIN2,szPin2,ARRAYSIZE(szPin2)); |
307 |
dwReturn = SetPuk(szPin, szPin2, &dwRemaining); |
308 |
MessageBoxWin32(dwReturn); |
309 |
break; |
310 |
case IDC_SETSM: |
311 |
GetDlgItemTextA(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin)); |
312 |
GetDlgItemTextA(hWnd,IDC_TXTPIN2,szPin2,ARRAYSIZE(szPin2)); |
313 |
dwReturn = SetSM(szPin, szPin2, &dwRemaining); |
314 |
MessageBoxWin32(dwReturn); |
315 |
break; |
316 |
case IDC_PERSONNALIZE: |
317 |
dwReturn = Personnalize(); |
318 |
MessageBoxWin32(dwReturn); |
319 |
break; |
320 |
} |
321 |
break; |
322 |
} |
323 |
return FALSE; |
324 |
} |
325 |
|
326 |
INT_PTR CALLBACK WndProcFile(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
327 |
{ |
328 |
int wmId, wmEvent; |
329 |
DWORD dwReturn; |
330 |
switch (message) |
331 |
{ |
332 |
case WM_INITDIALOG: |
333 |
break; |
334 |
case WM_COMMAND: |
335 |
wmId = LOWORD(wParam); |
336 |
wmEvent = HIWORD(wParam); |
337 |
|
338 |
switch (wmId) |
339 |
{ |
340 |
case IDC_LISTFILES: |
341 |
dwReturn = ListFiles(hWnd); |
342 |
if (dwReturn) |
343 |
{ |
344 |
MessageBoxWin32(dwReturn); |
345 |
} |
346 |
break; |
347 |
case IDC_FILES: |
348 |
switch(wmEvent) |
349 |
{ |
350 |
case LBN_SELCHANGE: |
351 |
dwReturn = ViewFile(hWnd); |
352 |
if (dwReturn) |
353 |
{ |
354 |
MessageBoxWin32(dwReturn); |
355 |
} |
356 |
break; |
357 |
} |
358 |
break; |
359 |
} |
360 |
break; |
361 |
} |
362 |
return FALSE; |
363 |
} |
364 |
|
365 |
INT_PTR CALLBACK WndProcCrypto(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
366 |
{ |
367 |
int wmId, wmEvent; |
368 |
DWORD dwReturn; |
369 |
switch (message) |
370 |
{ |
371 |
case WM_INITDIALOG: |
372 |
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Signature")); |
373 |
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Confidentiality")); |
374 |
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Authentication")); |
375 |
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX, CB_SETCURSEL, 0, 0); |
376 |
break; |
377 |
case WM_COMMAND: |
378 |
wmId = LOWORD(wParam); |
379 |
wmEvent = HIWORD(wParam); |
380 |
|
381 |
switch (wmId) |
382 |
{ |
383 |
case IDC_NEWKEY: |
384 |
dwReturn = GenerateNewKey((DWORD)SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX, CB_GETCURSEL, 0, 0)); |
385 |
MessageBoxWin32(dwReturn); |
386 |
break; |
387 |
case IDC_IMPORTKEY: |
388 |
dwReturn = ImportKey((DWORD)SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX, CB_GETCURSEL, 0, 0)); |
389 |
MessageBoxWin32(dwReturn); |
390 |
break; |
391 |
case IDC_SAMEKEY: |
392 |
dwReturn = SetTheSameKeyForAllContainers(); |
393 |
MessageBoxWin32(dwReturn); |
394 |
break; |
395 |
case IDC_SETREADONLY: |
396 |
dwReturn = SetReadOnly(TRUE); |
397 |
MessageBoxWin32(dwReturn); |
398 |
break; |
399 |
case IDC_UNSETREADONLY: |
400 |
dwReturn = SetReadOnly(FALSE); |
401 |
MessageBoxWin32(dwReturn); |
402 |
break; |
403 |
} |
404 |
break; |
405 |
} |
406 |
return FALSE; |
407 |
} |
408 |
|
409 |
INT_PTR CALLBACK WndProcCryptoApi(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
410 |
{ |
411 |
int wmId, wmEvent; |
412 |
DWORD dwReturn; |
413 |
TCHAR szContainer[256]; |
414 |
DWORD dwKeySpec; |
415 |
switch (message) |
416 |
{ |
417 |
case WM_INITDIALOG: |
418 |
break; |
419 |
case WM_COMMAND: |
420 |
wmId = LOWORD(wParam); |
421 |
wmEvent = HIWORD(wParam); |
422 |
|
423 |
switch (wmId) |
424 |
{ |
425 |
case IDC_CONTAINER: |
426 |
dwReturn = ListContainer(hWnd); |
427 |
if (dwReturn) |
428 |
{ |
429 |
MessageBoxWin32(dwReturn); |
430 |
} |
431 |
break; |
432 |
case IDC_SIGN: |
433 |
if (GetContainerName(hWnd, szContainer, &dwKeySpec)) |
434 |
{ |
435 |
dwReturn = Sign(szContainer, dwKeySpec); |
436 |
MessageBoxWin32(dwReturn); |
437 |
} |
438 |
break; |
439 |
case IDC_DECRYPT: |
440 |
if (GetContainerName(hWnd, szContainer, &dwKeySpec)) |
441 |
{ |
442 |
dwReturn = Decrypt(szContainer, dwKeySpec); |
443 |
MessageBoxWin32(dwReturn); |
444 |
} |
445 |
break; |
446 |
case IDC_LSTCONTAINER: |
447 |
switch(wmEvent) |
448 |
{ |
449 |
case LBN_DBLCLK: |
450 |
if (GetContainerName(hWnd, szContainer, &dwKeySpec)) |
451 |
{ |
452 |
dwReturn = ViewCertificate(hWnd, szContainer, dwKeySpec); |
453 |
if (dwReturn) |
454 |
{ |
455 |
MessageBoxWin32(dwReturn); |
456 |
} |
457 |
} |
458 |
break; |
459 |
} |
460 |
break; |
461 |
} |
462 |
break; |
463 |
} |
464 |
return FALSE; |
465 |
} |
466 |
|
467 |
INT_PTR CALLBACK WndProcEnroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
468 |
{ |
469 |
int wmId, wmEvent; |
470 |
DWORD dwReturn; |
471 |
switch (message) |
472 |
{ |
473 |
case WM_INITDIALOG: |
474 |
break; |
475 |
case WM_COMMAND: |
476 |
wmId = LOWORD(wParam); |
477 |
wmEvent = HIWORD(wParam); |
478 |
|
479 |
switch (wmId) |
480 |
{ |
481 |
case IDC_ENROLL: |
482 |
dwReturn = Enroll(); |
483 |
MessageBoxWin32(dwReturn); |
484 |
break; |
485 |
} |
486 |
} |
487 |
return FALSE; |
488 |
} |