|
|
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.