的可能性,即使在打开/GS的情况下仍然存在。更重要的是,/GS选项不会检测堆中或数据段中的缓冲区溢出。
为举例说明,例2使用Win32 GUI重写了前面那个示例程序,这个程序提供一个带有一些简单选项的菜单栏--File菜单下有两个菜单项:"Login"和"Exit"。Login会用一个对话框来提示用户输入密码,一旦输入了密码,在用户点击"OK"按钮之后,将把输入的密码与之前记录的密码相比较。
例2:
1. #include "stdafx.h"
2. #include "TestItDan.h"
3. #include <stdlib.h>
4. #include <stdio.h>
5. #include <windows.h>
6. #define MAX_LOADSTRING 100
7. struct user {
8. wchar_t *name;
9. size_t len;
10. int uid;
11. };
13. HINSTANCE hInst;
14. TCHAR szTitle[MAX_LOADSTRING];
15. TCHAR szWindowClass[MAX_LOADSTRING];
16. TCHAR lpszUserName[16] = L"guest";
17. TCHAR lpszPassword[16] = L"0123456789abcde";
18. struct user *userP = (struct user *)0xcdcdcdcdcdcdcdcd;
19. size_t userNameLen = 16;
20. size_t userPasswordLen = 0xffffffff;
25. int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow) {
26. UNREFERENCED_PARAMETER(hPrevInstance);
27. UNREFERENCED_PARAMETER(lpCmdLine);
28. MSG msg;
29. HACCEL hAccelTable;
30. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
31. LoadString(hInstance, IDC_TESTITDAN, szWindowClass, MAX_LOADSTRING);
32. MyRegisterClass(hInstance);
33. userP = (struct user *)malloc(sizeof(user));
34. if (!InitInstance (hInstance, nCmdShow)) {
35. return FALSE;
36. }
37. hAccelTable =LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTITDAN));
38. while (GetMessage(&msg, NULL, 0, 0)) {
39. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
40. TranslateMessage(&msg);
41. DispatchMessage(&msg);
42. }
43. }
44. return (int) msg.wParam;
45. }
109. INT_PTR CALLBACK GetPassword(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
110. TCHAR lpszGuestPassword[16] = L"NCC-1701";
111. UNREFERENCED_PARAMETER(lParam);
112. switch (message) {
113. case WM_INITDIALOG:
114. return (INT_PTR)TRUE;
115. case WM_COMMAND:
116. if (LOWORD(wParam) == IDOK) {
117. EndDialog(hDlg, LOWORD(wParam));
118. SendDlgItemMessage(hDlg,
119. IDC_EDIT1,
120. EM_GETLINE,
121. (WPARAM) 0, // line 0
122. (LPARAM) lpszPassword
123. );
124. userP->len = userNameLen;
125. if (wcscmp(lpszPassword, lpszGuestPassword) == 0) {
126. return true;
127. }
128. else {
129. MessageBox(hDlg,
130. (LPCWSTR)L"Invalid Password",
131. (LPCWSTR)L"Login Failed",
132. MB_OK
133. );
134. }
135. return (INT_PTR)TRUE;
136. }
137. break;
138. }
139. return (INT_PTR)FALSE;
140. }
程序编译及测试的环境均与前例相同,除了在此使用了Unicode字符集及打开了缓冲区安全检查选项(/GS), |