home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / uconvert / install.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  11KB  |  361 lines

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