|
|
1.1 root 1: /**************************************************************************\
2: * install.c -- install c_*.nls conversion tables.
3: *
4: * Steve Firebaugh
5: * Microsoft Developer Support
6: * Copyright (c) 1992, 1993 Microsoft Corporation
7: *
8: *
9: *
10: * Note, this module must have UNICODE defined because the registry
11: * code will not work without it.
12: *
13: \**************************************************************************/
14: #define UNICODE
15:
16:
17: #include <windows.h>
18: #include <commdlg.h>
19: #include <string.h>
20: #include <stdio.h>
21: #include "uconvert.h"
22: #include "install.h"
23:
24: /**************************************************************************\
25: * Global variables.
26: \**************************************************************************/
27:
28: /* This is the registry key that we store conversion table information under. */
29: TCHAR NlsRegEntryStr[]=TEXT("SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage");
30:
31: /* MessageBox strings */
32: TCHAR szMBERROR[]= TEXT("Error");
33:
34:
35: /***************************************************************************\
36: * FUNCTION: InstallTableProc
37: *
38: * Dialog window procedure for the Install *.nls tables dialog.
39: *
40: \***************************************************************************/
41: LRESULT CALLBACK InstallTableProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
42: {
43:
44:
45: switch (message) {
46:
47: /**********************************************************************\
48: * WM_INITDIALOG
49: *
50: * Fill dialog with a list of the currently existing tables.
51: \**********************************************************************/
52: case WM_INITDIALOG:
53: if (!ListInstalledTables (GetDlgItem (hwnd, DID_LISTBOX), LB_ADDSTRING, FALSE))
54: EndDialog (hwnd, FALSE);
55: break;
56:
57: case WM_COMMAND:
58: switch (wParam) {
59: case IDCANCEL:
60: case IDOK:
61: EndDialog (hwnd, TRUE);
62: break;
63:
64:
65: /**********************************************************************\
66: * WM_COMMAND, BID_ADD
67: *
68: * Use common dialog, get new *.nls name, and try to install it.
69: \**********************************************************************/
70: case BID_ADD:
71: if (GetTableFileNames(hwnd))
72: ListInstalledTables (GetDlgItem (hwnd, DID_LISTBOX), LB_ADDSTRING, FALSE);
73: break;
74: }
75: break; /* end WM_COMMAND */
76:
77:
78: case WM_SYSCOMMAND:
79: if (wParam == SC_CLOSE)
80: EndDialog (hwnd, TRUE);
81: break; /* end WM_SYSCOMMAND */
82:
83:
84: } /* end switch */
85: return FALSE;
86: }
87:
88:
89:
90: /***************************************************************************\
91: * FUNCTION: GetTableFileNames
92: *
93: * Throw up a common dialog to the user, and let them search for the *.nls
94: * file to install.
95: *
96: * LIMITATION: Currently only works for one file at a time.
97: * Should rewrite to accept multiple files.
98: *
99: \***************************************************************************/
100: int GetTableFileNames (HWND hwnd)
101: {
102: OPENFILENAME OpenFileName;
103:
104:
105: /* buffers for the file names. */
106: TCHAR szFile[MAX_PATH],szFileTitle[MAX_PATH];
107: TCHAR szFilter[MAX_PATH], buffer[50];
108: TCHAR *p;
109:
110: /* Build up the correct filter strings for OPENFILENAME structure */
111:
112: p = szFilter;
113: lstrcpy (buffer,TEXT("Conversion Table (*.nls)"));
114: lstrcpy (p,buffer);
115: p += lstrlen (buffer) +1;
116: lstrcpy (buffer,TEXT("*.nls"));
117: lstrcpy (p,buffer);
118: p += lstrlen (buffer) +1;
119:
120: lstrcpy (p,TEXT("\0"));
121:
122:
123: wsprintf (szFile, TEXT(""));
124: wsprintf (szFileTitle, TEXT(""));
125:
126: OpenFileName.lStructSize = sizeof(OPENFILENAME);
127: OpenFileName.hwndOwner = hwnd;
128: OpenFileName.hInstance = NULL;
129: OpenFileName.lpstrFilter = szFilter;
130: OpenFileName.lpstrCustomFilter = NULL;
131: OpenFileName.nMaxCustFilter = 0L;
132: OpenFileName.nFilterIndex = 1L;
133: OpenFileName.lpstrFile = szFile;
134: OpenFileName.nMaxFile = MAX_PATH;
135: OpenFileName.lpstrFileTitle = szFileTitle;
136: OpenFileName.nMaxFileTitle = MAX_PATH;
137: OpenFileName.lpstrInitialDir = NULL;
138: OpenFileName.lpstrTitle = TEXT("Locate c_*.nls files from distribution media.");
139:
140: OpenFileName.nFileOffset = 0;
141: OpenFileName.nFileExtension = 0;
142: OpenFileName.lpstrDefExt = NULL;
143:
144: OpenFileName.lCustData = 0;
145: OpenFileName.lpfnHook = NULL;
146: OpenFileName.lpTemplateName = NULL;
147:
148: // OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
149: OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST ;
150:
151: if (!GetOpenFileName(&OpenFileName)) return 0;
152:
153:
154: return (InstallFile (szFile,szFileTitle));
155: }
156:
157:
158:
159:
160: /***************************************************************************\
161: * FUNCTION: InstallFile
162: *
163: * Given full path name, and just file name, copy that file into the
164: * system directory, and change the registry to indicate that the file
165: * has now been "installed."
166: *
167: \***************************************************************************/
168: int InstallFile (TCHAR* szPathAndName, TCHAR* szName)
169: {
170: TCHAR szTargetFile[MAX_PATH], buffer[MAX_PATH];
171: TCHAR keyname[MAX_PATH];
172: HKEY hKey;
173: int cp, nChar;
174: LONG rValue;
175:
176: /* First verify that they have selected a valid file name. */
177: CharLowerBuff (szName,lstrlen (szName));
178: if (myScanf (szName, &cp) != 1) {
179: MessageBox (NULL, TEXT("Incorrect file type.\n Need c_*.nls."),
180: szMBERROR, MB_ICONSTOP | MB_OK);
181: return FALSE;
182: }
183:
184:
185:
186:
187: /* Build up a complete path name for the target file.
188: * Get the system directory, and prepend it before szName.
189: */
190: GetSystemDirectory (buffer, MAX_PATH);
191: nChar = wsprintf (szTargetFile, TEXT("%s\\%s"), buffer, szName);
192:
193: if (nChar >= MAX_PATH) {
194: MessageBox (NULL, TEXT("File name overflow."),szMBERROR, MB_ICONSTOP | MB_OK);
195: return FALSE;
196: }
197:
198:
199:
200: /* Now, try to open the registry for writing... This may fail if
201: * the current user has insufficient privilege, or it may fail
202: * for other, unforeseen, reasons.
203: */
204: rValue = RegOpenKeyEx (HKEY_LOCAL_MACHINE, NlsRegEntryStr, 0, KEY_SET_VALUE, &hKey);
205: if (rValue == ERROR_ACCESS_DENIED) {
206: MessageBox (NULL, TEXT("Log on as Administrator to complete this action."),
207: TEXT("Access Denied, Insufficient Privilege") , MB_ICONSTOP | MB_OK);
208: return FALSE;
209: }
210: if (rValue != ERROR_SUCCESS) {
211: MessageBox (NULL, TEXT("RegOpenKeyEx() failed."),szMBERROR, MB_ICONSTOP | MB_OK);
212: return FALSE;
213: }
214:
215:
216: /* Try to copy file... one reason for failure is file already
217: * exists. If so, query the user to try again.
218: * If fails again, just report problem and exit.
219: */
220: if (!CopyFile (szPathAndName, szTargetFile, TRUE)) {
221:
222: /* if failure was from existing file, query user preference
223: * regarding replacing it.
224: */
225: if (GetLastError() == ERROR_FILE_EXISTS) {
226: if (MessageBox (NULL, TEXT("File already exists.\n Replace existing?"),
227: TEXT("Warning"), MB_ICONEXCLAMATION | MB_YESNO) == IDNO) {
228: goto close_and_exit;
229: } else {
230: if (!CopyFile (szPathAndName, szTargetFile, FALSE)) {
231: MessageBox (NULL, TEXT("File copy failed again."),
232: szMBERROR, MB_ICONSTOP | MB_OK);
233: goto close_and_exit;
234: }
235: }
236:
237: /* no duplicate file, CopyFile() failed for other reasons
238: * report failure and return.
239: */
240: } else {
241: MessageBox (NULL, TEXT("File copy failed."),
242: szMBERROR, MB_ICONSTOP | MB_OK);
243: goto close_and_exit;
244:
245: }
246: }
247:
248:
249: /* Finally, write the new key value to the registry. */
250: if (myScanf (szName, &cp) == 1) {
251: wsprintf (keyname, TEXT("%d"), cp);
252: RegSetValueEx (hKey, keyname, 0, REG_SZ, (LPBYTE)szName,
253: (DWORD)((lstrlen(szName) +1)*sizeof(TCHAR)));
254:
255: } else
256: MessageBox (NULL, szName, TEXT("Parsing file title failed."), MB_ICONSTOP | MB_OK);
257:
258:
259:
260: close_and_exit:
261:
262: RegCloseKey (hKey);
263:
264: return TRUE;
265: }
266:
267:
268: /***************************************************************************\
269: * FUNCTION: ListInstalledTables
270: *
271: * Display the *.nls conversion tables currently installed, according to the
272: * registry. Display either the file name, or just the codepage number.
273: *
274: * hwndFill - listbox or combobox to fill with names.
275: * message - LB_ADDSTRING or CB_ADDSTRING
276: * NumberOnly - FALSE then use full file name, TRUE then just use number.
277: *
278: * CRITERION for table being installed:
279: * value in registry is c_* where * is number.
280: *
281: \***************************************************************************/
282: int ListInstalledTables (HWND hwndFill, UINT message, int NumberOnly)
283: {
284:
285: TCHAR szKeyname[MAX_PATH], szValue[MAX_PATH];
286: DWORD cBytesName, cBytesValue, iSubKey;
287: int cp;
288: HKEY hKey;
289:
290: /* open the registry key for reading. If failure, report and exit. */
291: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, NlsRegEntryStr, 0, KEY_QUERY_VALUE, &hKey)) {
292: MessageBox (NULL, TEXT("RegOpenKeyEx() failed."), szMBERROR, MB_ICONSTOP | MB_OK);
293: return FALSE;
294: }
295:
296:
297: /* empty the current contents. */
298: if (message == LB_ADDSTRING)
299: SendMessage (hwndFill, LB_RESETCONTENT, 0, 0);
300: else if (message == CB_ADDSTRING)
301: SendMessage (hwndFill, CB_RESETCONTENT, 0, 0);
302:
303:
304: iSubKey = 0;
305: cBytesName = cBytesValue = MAX_PATH;
306: while (!RegEnumValue (hKey, iSubKey, szKeyname, &cBytesName, NULL, NULL, (LPBYTE)szValue, &cBytesValue)) {
307:
308: if (myScanf (szValue, &cp) == 1) {
309:
310: /* if we are to display only the number, then reformat szValue string */
311: if (NumberOnly)
312: wsprintf (szValue, TEXT("%d"), cp);
313:
314:
315: SendMessage (hwndFill, message, 0 ,(LPARAM) szValue);
316: }
317:
318: iSubKey++;
319: cBytesName = cBytesValue = MAX_PATH; // undoc.ed feature, must be set each time.
320: }
321:
322: RegCloseKey (hKey);
323:
324: return TRUE;
325: }
326:
327:
328:
329:
330:
331:
332:
333:
334: /***************************************************************************\
335: * FUNCTION: myScanf
336: *
337: * Convert a string into a number (like sscanf).
338: * However, this function works independent of UNICODE turned on.
339: *
340: * NOT a general function... looking for "c_%d.nls"
341: *
342: \***************************************************************************/
343: int myScanf (TCHAR* pSource, int* pValue)
344: {
345: char ansibuffer[MAX_PATH];
346: int iStrLen;
347:
348: iStrLen = lstrlen (pSource);
349: if (iStrLen == 0) return 0;
350:
351: #ifdef UNICODE
352: WideCharToMultiByte (CP_ACP, 0, pSource, -1,
353: ansibuffer, MAX_PATH, NULL, NULL);
354: #else
355: lstrcpy (ansibuffer, pSource);
356: #endif
357:
358: CharLowerBuffA (ansibuffer,lstrlenA (ansibuffer));
359:
360: return (sscanf (ansibuffer, "c_%d.nls", pValue)); // leave off TEXT()
361: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.